This tutorial teaches you how to use the Optimism SDK to view the transactions passed between L1 (Syscoin) and L2 (Rollux) by an address.
The node script makes these assumptions:
- You have Node.js running on your computer, as well as yarn.
- Access to L1 (Syscoin mainnet) and L2 (Rollux) providers.
-
Use
yarn
to download the packages the script needs.yarn
-
Copy
.env.example
to.env
and specify the URLs for L1 and L2. -
Use Node to run the script
node view-tx.js
Here are the expected results. Note that by the time you read this there might be additional transactions reported.
Deposits by address 0xBCf86Fd70a0183433763ab0c14E7a760194f3a9F
tx:0xa35a3085e025e2addd59c5ef2a2e5529be5141522c3cce78a1b137f2eb992d19
Amount: 0.01 SYS
Relayed: true
Withdrawals by address 0xBCf86Fd70a0183433763ab0c14E7a760194f3a9F
tx:0x7826399958c6bb3831ef0b02b658e7e3e69f334e20e27a3c14d7caae545c3d0d
Amount: 1 DAI
Relayed: false
tx:0xd9fd11fd12a58d9115afa2ad677745b1f7f5bbafab2142ae2cede61f80e90e8a
Amount: 0.001 SYS
Relayed: true
In this section we go over the script line by line to learn how to use the SDK to view deposits and withdrawals.
#! /usr/local/bin/node
// View transfers between L1 and L2 using the Optimism SDK
const ethers = require("ethers")
const optimismSDK = require("@eth-optimism/sdk")
require('dotenv').config()
// Global variable because we need them almost everywhere
let crossChainMessenger
const setup = async() => {
l1SignerOrProvider = new ethers.providers.JsonRpcProvider(process.env.L1URL)
l2SignerOrProvider = new ethers.providers.JsonRpcProvider(process.env.L2URL)
crossChainMessenger = new optimismSDK.CrossChainMessenger({
l1ChainId: (await l1SignerOrProvider._networkPromise).chainId,
l2ChainId: (await l2SignerOrProvider._networkPromise).chainId,
l1SignerOrProvider: l1SignerOrProvider,
l2SignerOrProvider: l2SignerOrProvider
})
} // setup
Create the CrossChainMessenger
object that we use to view information.
Note that we do not need signers here, since we are only calling view
functions.
However, we do need the chainId values.
// Only the part of the ABI we need to get the symbol
const ERC20ABI = [
{
"constant": true,
"inputs": [],
"name": "symbol",
"outputs": [
{
"name": "",
"type": "string"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
}
] // ERC20ABI
const getSymbol = async l1Addr => {
if (l1Addr == '0x0000000000000000000000000000000000000000')
return "SYS"
If l1Addr
is all zeroes, it means the transfer was SYS.
const l1Contract = new ethers.Contract(l1Addr, ERC20ABI, crossChainMessenger.l1SignerOrProvider)
return await l1Contract.symbol()
Otherwise, ask the contract (we could have used the L1 or the L2) what is the correct symbol.
} // getSymbol
// Describe a cross domain transaction, either deposit or withdrawal
const describeTx = async tx => {
console.log(`tx:${tx.transactionHash}`)
// Assume all tokens have decimals = 18
console.log(`\tAmount: ${tx.amount/1e18} ${await getSymbol(tx.l1Token)}`)
console.log(`\tRelayed: ${await crossChainMessenger.getMessageStatus(tx.transactionHash)
== optimismSDK.MessageStatus.RELAYED}`)
The result of crossDomainMessenger.getMessageStatus
is a MessageStatus
enumerated value.
In this case we only care whether the deposit/withdrawal is still in process or if it is done.
} // describeTx
const main = async () => {
await setup()
// The address we trace
const addr = "0xBCf86Fd70a0183433763ab0c14E7a760194f3a9F"
const deposits = await crossChainMessenger.getDepositsByAddress(addr)
The crossChainMessenger.getDepositsByAddress
function gives us all the deposits by an address.
console.log(`Deposits by address ${addr}`)
for (var i=0; i<deposits.length; i++)
await describeTx(deposits[i])
const withdrawals = await crossChainMessenger.getWithdrawalsByAddress(addr)
The crossChainMessenger.getWithdrawalsByAddress
function gives us all the deposits by an address.
console.log(`\n\n\nWithdrawals by address ${addr}`)
for (var i=0; i<withdrawals.length; i++)
await describeTx(withdrawals[i])
} // main
main().then(() => process.exit(0))
.catch((error) => {
console.error(error)
process.exit(1)
})
You should now know how to identify all the deposits and/or withdrawals done by a specific address.
There are some additional tracing functions in CrossChainMessenger
, but they are very similar in operation.
Of course, if you have any problems you can ask on our Discord.