diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f351a157..a0dc60dc 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,10 +1,10 @@ name: Run tests on: push: - branches: [ main ] + branches: [ main, beta ] workflow_dispatch: pull_request: - branches: [ main ] + branches: [ main, beta ] types: [ opened, reopened, synchronize ] permissions: @@ -33,10 +33,8 @@ jobs: run: | git clone https://github.com/matter-labs/local-setup.git pushd local-setup - ./start.sh v22-before-shared-bridge + ./start.sh popd - - name: Wait for local-setup to be ready - run: yarn test:wait - name: Prepare environment run: yarn test:prepare - name: Run tests diff --git a/abi/IBridgehub.json b/abi/IBridgehub.json new file mode 100644 index 00000000..22db2fd4 --- /dev/null +++ b/abi/IBridgehub.json @@ -0,0 +1,631 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldAdmin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "NewAdmin", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "stateTransitionManager", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "chainGovernance", + "type": "address" + } + ], + "name": "NewChain", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldPendingAdmin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newPendingAdmin", + "type": "address" + } + ], + "name": "NewPendingAdmin", + "type": "event" + }, + { + "inputs": [], + "name": "acceptAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_stateTransitionManager", + "type": "address" + } + ], + "name": "addStateTransitionManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "addToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + } + ], + "name": "baseToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_stateTransitionManager", + "type": "address" + }, + { + "internalType": "address", + "name": "_baseToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_admin", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_initData", + "type": "bytes" + } + ], + "name": "createNewChain", + "outputs": [ + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + } + ], + "name": "getStateTransition", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_gasPrice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2GasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2GasPerPubdataByteLimit", + "type": "uint256" + } + ], + "name": "l2TransactionBaseCost", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "_l2TxHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_l2BatchNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2MessageIndex", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "_l2TxNumberInBatch", + "type": "uint16" + }, + { + "internalType": "bytes32[]", + "name": "_merkleProof", + "type": "bytes32[]" + }, + { + "internalType": "enum TxStatus", + "name": "_status", + "type": "uint8" + } + ], + "name": "proveL1ToL2TransactionStatus", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_batchNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint8", + "name": "l2ShardId", + "type": "uint8" + }, + { + "internalType": "bool", + "name": "isService", + "type": "bool" + }, + { + "internalType": "uint16", + "name": "txNumberInBatch", + "type": "uint16" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "key", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "value", + "type": "bytes32" + } + ], + "internalType": "struct L2Log", + "name": "_log", + "type": "tuple" + }, + { + "internalType": "bytes32[]", + "name": "_proof", + "type": "bytes32[]" + } + ], + "name": "proveL2LogInclusion", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_batchNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint16", + "name": "txNumberInBatch", + "type": "uint16" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct L2Message", + "name": "_message", + "type": "tuple" + }, + { + "internalType": "bytes32[]", + "name": "_proof", + "type": "bytes32[]" + } + ], + "name": "proveL2MessageInclusion", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_stateTransitionManager", + "type": "address" + } + ], + "name": "removeStateTransitionManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "mintValue", + "type": "uint256" + }, + { + "internalType": "address", + "name": "l2Contract", + "type": "address" + }, + { + "internalType": "uint256", + "name": "l2Value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "l2Calldata", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "l2GasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "l2GasPerPubdataByteLimit", + "type": "uint256" + }, + { + "internalType": "bytes[]", + "name": "factoryDeps", + "type": "bytes[]" + }, + { + "internalType": "address", + "name": "refundRecipient", + "type": "address" + } + ], + "internalType": "struct L2TransactionRequestDirect", + "name": "_request", + "type": "tuple" + } + ], + "name": "requestL2TransactionDirect", + "outputs": [ + { + "internalType": "bytes32", + "name": "canonicalTxHash", + "type": "bytes32" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "mintValue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "l2Value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "l2GasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "l2GasPerPubdataByteLimit", + "type": "uint256" + }, + { + "internalType": "address", + "name": "refundRecipient", + "type": "address" + }, + { + "internalType": "address", + "name": "secondBridgeAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "secondBridgeValue", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "secondBridgeCalldata", + "type": "bytes" + } + ], + "internalType": "struct L2TransactionRequestTwoBridgesOuter", + "name": "_request", + "type": "tuple" + } + ], + "name": "requestL2TransactionTwoBridges", + "outputs": [ + { + "internalType": "bytes32", + "name": "canonicalTxHash", + "type": "bytes32" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newPendingAdmin", + "type": "address" + } + ], + "name": "setPendingAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_sharedBridge", + "type": "address" + } + ], + "name": "setSharedBridge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "sharedBridge", + "outputs": [ + { + "internalType": "contract IL1SharedBridge", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + } + ], + "name": "stateTransitionManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_stateTransitionManager", + "type": "address" + } + ], + "name": "stateTransitionManagerIsRegistered", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_baseToken", + "type": "address" + } + ], + "name": "tokenIsRegistered", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/abi/IContractDeployer.json b/abi/IContractDeployer.json index 8f54565c..2525a786 100644 --- a/abi/IContractDeployer.json +++ b/abi/IContractDeployer.json @@ -84,7 +84,7 @@ "outputs": [ { "internalType": "address", - "name": "newAddress", + "name": "", "type": "address" } ], @@ -113,7 +113,7 @@ "outputs": [ { "internalType": "address", - "name": "newAddress", + "name": "", "type": "address" } ], @@ -147,7 +147,7 @@ "outputs": [ { "internalType": "address", - "name": "newAddress", + "name": "", "type": "address" } ], @@ -158,7 +158,7 @@ "inputs": [ { "internalType": "bytes32", - "name": "_salt", + "name": "", "type": "bytes32" }, { @@ -181,10 +181,114 @@ "outputs": [ { "internalType": "address", - "name": "newAddress", + "name": "", + "type": "address" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_address", + "type": "address" + } + ], + "name": "extendedAccountVersion", + "outputs": [ + { + "internalType": "enum IContractDeployer.AccountAbstractionVersion", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "bytecodeHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "newAddress", + "type": "address" + }, + { + "internalType": "bool", + "name": "callConstructor", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "input", + "type": "bytes" + } + ], + "internalType": "struct ContractDeployer.ForceDeployment", + "name": "_deployment", + "type": "tuple" + }, + { + "internalType": "address", + "name": "_sender", "type": "address" } ], + "name": "forceDeployOnAddress", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "bytecodeHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "newAddress", + "type": "address" + }, + { + "internalType": "bool", + "name": "callConstructor", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "input", + "type": "bytes" + } + ], + "internalType": "struct ContractDeployer.ForceDeployment[]", + "name": "_deployments", + "type": "tuple[]" + } + ], + "name": "forceDeployOnAddresses", + "outputs": [], "stateMutability": "payable", "type": "function" }, diff --git a/abi/IL1Bridge.json b/abi/IL1Bridge.json index 36bc6b52..7069b2de 100644 --- a/abi/IL1Bridge.json +++ b/abi/IL1Bridge.json @@ -2,6 +2,80 @@ { "anonymous": false, "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "txDataHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "l2DepositTxHash", + "type": "bytes32" + } + ], + "name": "BridgehubDepositFinalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "txDataHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "l1Token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "BridgehubDepositInitiatedSharedBridge", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, { "indexed": true, "internalType": "address", @@ -21,12 +95,18 @@ "type": "uint256" } ], - "name": "ClaimedFailedDeposit", + "name": "ClaimedFailedDepositSharedBridge", "type": "event" }, { "anonymous": false, "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, { "indexed": true, "internalType": "bytes32", @@ -40,7 +120,7 @@ "type": "address" }, { - "indexed": true, + "indexed": false, "internalType": "address", "name": "to", "type": "address" @@ -58,12 +138,18 @@ "type": "uint256" } ], - "name": "DepositInitiated", + "name": "DepositInitiatedSharedBridge", "type": "event" }, { "anonymous": false, "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, { "indexed": true, "internalType": "address", @@ -83,11 +169,136 @@ "type": "uint256" } ], - "name": "WithdrawalFinalized", + "name": "WithdrawalFinalizedSharedBridge", "type": "event" }, + { + "inputs": [], + "name": "bridgehub", + "outputs": [ + { + "internalType": "contract IBridgehub", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "_txDataHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "_txHash", + "type": "bytes32" + } + ], + "name": "bridgehubConfirmL2Transaction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_prevMsgSender", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "bridgehubDeposit", + "outputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "magicValue", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "l2Contract", + "type": "address" + }, + { + "internalType": "bytes", + "name": "l2Calldata", + "type": "bytes" + }, + { + "internalType": "bytes[]", + "name": "factoryDeps", + "type": "bytes[]" + }, + { + "internalType": "bytes32", + "name": "txDataHash", + "type": "bytes32" + } + ], + "internalType": "struct L2TransactionRequestTwoBridgesInner", + "name": "request", + "type": "tuple" + } + ], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_prevMsgSender", + "type": "address" + }, + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "bridgehubDepositBaseToken", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, { "internalType": "address", "name": "_depositSender", @@ -98,6 +309,11 @@ "name": "_l1Token", "type": "address" }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, { "internalType": "bytes32", "name": "_l2TxHash", @@ -131,6 +347,11 @@ }, { "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, { "internalType": "address", "name": "_l2Receiver", @@ -141,6 +362,11 @@ "name": "_l1Token", "type": "address" }, + { + "internalType": "uint256", + "name": "_mintValue", + "type": "uint256" + }, { "internalType": "uint256", "name": "_amount", @@ -175,6 +401,35 @@ }, { "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "_l2TxHash", + "type": "bytes32" + } + ], + "name": "depositHappened", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, { "internalType": "uint256", "name": "_l2BatchNumber", @@ -208,6 +463,11 @@ }, { "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, { "internalType": "uint256", "name": "_l2BatchNumber", @@ -219,7 +479,7 @@ "type": "uint256" } ], - "name": "isWithdrawalFinalized", + "name": "isWithdrawalFinalizedShared", "outputs": [ { "internalType": "bool", @@ -230,28 +490,15 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [], - "name": "l2Bridge", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { - "internalType": "address", - "name": "_l1Token", - "type": "address" + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" } ], - "name": "l2TokenAddress", + "name": "l2BridgeAddress", "outputs": [ { "internalType": "address", diff --git a/abi/IL1ERC20Bridge.json b/abi/IL1ERC20Bridge.json new file mode 100644 index 00000000..bdade3c8 --- /dev/null +++ b/abi/IL1ERC20Bridge.json @@ -0,0 +1,377 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "l1Token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ClaimedFailedDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "l2DepositTxHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "l1Token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "DepositInitiated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "l1Token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawalFinalized", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_depositSender", + "type": "address" + }, + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "_l2TxHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_l2BatchNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2MessageIndex", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "_l2TxNumberInBatch", + "type": "uint16" + }, + { + "internalType": "bytes32[]", + "name": "_merkleProof", + "type": "bytes32[]" + } + ], + "name": "claimFailedDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_l2Receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2TxGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2TxGasPerPubdataByte", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "bytes32", + "name": "txHash", + "type": "bytes32" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_l2Receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2TxGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2TxGasPerPubdataByte", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_refundRecipient", + "type": "address" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "bytes32", + "name": "txHash", + "type": "bytes32" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + }, + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "_depositL2TxHash", + "type": "bytes32" + } + ], + "name": "depositAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_l2BatchNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2MessageIndex", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "_l2TxNumberInBatch", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_message", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "_merkleProof", + "type": "bytes32[]" + } + ], + "name": "finalizeWithdrawal", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_l2BatchNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2MessageIndex", + "type": "uint256" + } + ], + "name": "isWithdrawalFinalized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "l2Bridge", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + } + ], + "name": "l2TokenAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "l2TokenBeacon", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sharedBridge", + "outputs": [ + { + "internalType": "contract IL1SharedBridge", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "transferTokenToSharedBridge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/abi/IL1SharedBridge.json b/abi/IL1SharedBridge.json new file mode 100644 index 00000000..a56f86eb --- /dev/null +++ b/abi/IL1SharedBridge.json @@ -0,0 +1,692 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "l1Token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "BridgehubDepositBaseTokenInitiated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "txDataHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "l2DepositTxHash", + "type": "bytes32" + } + ], + "name": "BridgehubDepositFinalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "txDataHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "l1Token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "BridgehubDepositInitiated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "l1Token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ClaimedFailedDepositSharedBridge", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "l2DepositTxHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "l1Token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "LegacyDepositInitiated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "l1Token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawalFinalizedSharedBridge", + "type": "event" + }, + { + "inputs": [], + "name": "bridgehub", + "outputs": [ + { + "internalType": "contract IBridgehub", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "_txDataHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "_txHash", + "type": "bytes32" + } + ], + "name": "bridgehubConfirmL2Transaction", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_prevMsgSender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_l2Value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "bridgehubDeposit", + "outputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "magicValue", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "l2Contract", + "type": "address" + }, + { + "internalType": "bytes", + "name": "l2Calldata", + "type": "bytes" + }, + { + "internalType": "bytes[]", + "name": "factoryDeps", + "type": "bytes[]" + }, + { + "internalType": "bytes32", + "name": "txDataHash", + "type": "bytes32" + } + ], + "internalType": "struct L2TransactionRequestTwoBridgesInner", + "name": "request", + "type": "tuple" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_prevMsgSender", + "type": "address" + }, + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "bridgehubDepositBaseToken", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_depositSender", + "type": "address" + }, + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "_l2TxHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_l2BatchNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2MessageIndex", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "_l2TxNumberInBatch", + "type": "uint16" + }, + { + "internalType": "bytes32[]", + "name": "_merkleProof", + "type": "bytes32[]" + } + ], + "name": "claimFailedDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_depositSender", + "type": "address" + }, + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "_l2TxHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_l2BatchNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2MessageIndex", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "_l2TxNumberInBatch", + "type": "uint16" + }, + { + "internalType": "bytes32[]", + "name": "_merkleProof", + "type": "bytes32[]" + } + ], + "name": "claimFailedDepositLegacyErc20Bridge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "_l2TxHash", + "type": "bytes32" + } + ], + "name": "depositHappened", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_msgSender", + "type": "address" + }, + { + "internalType": "address", + "name": "_l2Receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_l1Token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2TxGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2TxGasPerPubdataByte", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_refundRecipient", + "type": "address" + } + ], + "name": "depositLegacyErc20Bridge", + "outputs": [ + { + "internalType": "bytes32", + "name": "txHash", + "type": "bytes32" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2BatchNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2MessageIndex", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "_l2TxNumberInBatch", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_message", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "_merkleProof", + "type": "bytes32[]" + } + ], + "name": "finalizeWithdrawal", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_l2BatchNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2MessageIndex", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "_l2TxNumberInBatch", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_message", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "_merkleProof", + "type": "bytes32[]" + } + ], + "name": "finalizeWithdrawalLegacyErc20Bridge", + "outputs": [ + { + "internalType": "address", + "name": "l1Receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "l1Token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2BatchNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2MessageIndex", + "type": "uint256" + } + ], + "name": "isWithdrawalFinalized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "l1WethAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + } + ], + "name": "l2BridgeAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "legacyBridge", + "outputs": [ + { + "internalType": "contract IL1ERC20Bridge", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + } + ], + "name": "receiveEth", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_eraFirstPostUpgradeBatch", + "type": "uint256" + } + ], + "name": "setEraFirstPostUpgradeBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abi/ITestnetERC20Token.json b/abi/ITestnetERC20Token.json new file mode 100644 index 00000000..3c4bbc4e --- /dev/null +++ b/abi/ITestnetERC20Token.json @@ -0,0 +1,39 @@ +[ + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abi/IZkSyncStateTransition.json b/abi/IZkSyncStateTransition.json new file mode 100644 index 00000000..d7f8622d --- /dev/null +++ b/abi/IZkSyncStateTransition.json @@ -0,0 +1,2403 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "batchNumber", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "commitment", + "type": "bytes32" + } + ], + "name": "BlockCommit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "batchNumber", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "commitment", + "type": "bytes32" + } + ], + "name": "BlockExecution", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "totalBatchesCommitted", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalBatchesVerified", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalBatchesExecuted", + "type": "uint256" + } + ], + "name": "BlocksRevert", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "previousLastVerifiedBatch", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "currentLastVerifiedBatch", + "type": "uint256" + } + ], + "name": "BlocksVerification", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "EthWithdrawalFinalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "address", + "name": "facet", + "type": "address" + }, + { + "internalType": "enum Diamond.Action", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bool", + "name": "isFreezable", + "type": "bool" + }, + { + "internalType": "bytes4[]", + "name": "selectors", + "type": "bytes4[]" + } + ], + "internalType": "struct Diamond.FacetCut[]", + "name": "facetCuts", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "initAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "initCalldata", + "type": "bytes" + } + ], + "indexed": false, + "internalType": "struct Diamond.DiamondCutData", + "name": "diamondCut", + "type": "tuple" + } + ], + "name": "ExecuteUpgrade", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "Freeze", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "isPorterAvailable", + "type": "bool" + } + ], + "name": "IsPorterAvailableStatusUpdate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldAdmin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "NewAdmin", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint128", + "name": "oldNominator", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "oldDenominator", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "newNominator", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "newDenominator", + "type": "uint128" + } + ], + "name": "NewBaseTokenMultiplier", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "enum PubdataPricingMode", + "name": "pubdataPricingMode", + "type": "uint8" + }, + { + "internalType": "uint32", + "name": "batchOverheadL1Gas", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "maxPubdataPerBatch", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "maxL2GasPerBatch", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "priorityTxMaxPubdata", + "type": "uint32" + }, + { + "internalType": "uint64", + "name": "minimalL2GasPrice", + "type": "uint64" + } + ], + "indexed": false, + "internalType": "struct FeeParams", + "name": "oldFeeParams", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "enum PubdataPricingMode", + "name": "pubdataPricingMode", + "type": "uint8" + }, + { + "internalType": "uint32", + "name": "batchOverheadL1Gas", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "maxPubdataPerBatch", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "maxL2GasPerBatch", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "priorityTxMaxPubdata", + "type": "uint32" + }, + { + "internalType": "uint64", + "name": "minimalL2GasPrice", + "type": "uint64" + } + ], + "indexed": false, + "internalType": "struct FeeParams", + "name": "newFeeParams", + "type": "tuple" + } + ], + "name": "NewFeeParams", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldPendingAdmin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newPendingAdmin", + "type": "address" + } + ], + "name": "NewPendingAdmin", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "txId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "txHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "expirationTimestamp", + "type": "uint64" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "txType", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "from", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "to", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gasPerPubdataByteLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "paymaster", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256[4]", + "name": "reserved", + "type": "uint256[4]" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + }, + { + "internalType": "uint256[]", + "name": "factoryDeps", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "paymasterInput", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "reservedDynamic", + "type": "bytes" + } + ], + "indexed": false, + "internalType": "struct L2CanonicalTransaction", + "name": "transaction", + "type": "tuple" + }, + { + "indexed": false, + "internalType": "bytes[]", + "name": "factoryDeps", + "type": "bytes[]" + } + ], + "name": "NewPriorityRequest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldPriorityTxMaxGasLimit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newPriorityTxMaxGasLimit", + "type": "uint256" + } + ], + "name": "NewPriorityTxMaxGasLimit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldTransactionFilterer", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newTransactionFilterer", + "type": "address" + } + ], + "name": "NewTransactionFilterer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "address", + "name": "facet", + "type": "address" + }, + { + "internalType": "enum Diamond.Action", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bool", + "name": "isFreezable", + "type": "bool" + }, + { + "internalType": "bytes4[]", + "name": "selectors", + "type": "bytes4[]" + } + ], + "internalType": "struct Diamond.FacetCut[]", + "name": "facetCuts", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "initAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "initCalldata", + "type": "bytes" + } + ], + "indexed": false, + "internalType": "struct Diamond.DiamondCutData", + "name": "diamondCut", + "type": "tuple" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "proposalId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "proposalSalt", + "type": "bytes32" + } + ], + "name": "ProposeTransparentUpgrade", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "Unfreeze", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "validatorAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "isActive", + "type": "bool" + } + ], + "name": "ValidatorStatusUpdate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "enum PubdataPricingMode", + "name": "validiumMode", + "type": "uint8" + } + ], + "name": "ValidiumModeStatusUpdate", + "type": "event" + }, + { + "inputs": [], + "name": "acceptAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "baseTokenGasPriceMultiplierDenominator", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "baseTokenGasPriceMultiplierNominator", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "contractL2", + "type": "address" + }, + { + "internalType": "uint256", + "name": "mintValue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "l2Value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "l2Calldata", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "l2GasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "l2GasPerPubdataByteLimit", + "type": "uint256" + }, + { + "internalType": "bytes[]", + "name": "factoryDeps", + "type": "bytes[]" + }, + { + "internalType": "address", + "name": "refundRecipient", + "type": "address" + } + ], + "internalType": "struct BridgehubL2TransactionRequest", + "name": "_request", + "type": "tuple" + } + ], + "name": "bridgehubRequestL2Transaction", + "outputs": [ + { + "internalType": "bytes32", + "name": "canonicalTxHash", + "type": "bytes32" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "enum PubdataPricingMode", + "name": "pubdataPricingMode", + "type": "uint8" + }, + { + "internalType": "uint32", + "name": "batchOverheadL1Gas", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "maxPubdataPerBatch", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "maxL2GasPerBatch", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "priorityTxMaxPubdata", + "type": "uint32" + }, + { + "internalType": "uint64", + "name": "minimalL2GasPrice", + "type": "uint64" + } + ], + "internalType": "struct FeeParams", + "name": "_newFeeParams", + "type": "tuple" + } + ], + "name": "changeFeeParams", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint64", + "name": "batchNumber", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" + }, + { + "internalType": "uint64", + "name": "indexRepeatedStorageChanges", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "numberOfLayer1Txs", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "priorityOperationsHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "l2LogsTreeRoot", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "commitment", + "type": "bytes32" + } + ], + "internalType": "struct IExecutor.StoredBatchInfo", + "name": "_lastCommittedBatchData", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint64", + "name": "batchNumber", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "timestamp", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "indexRepeatedStorageChanges", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "newStateRoot", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "numberOfLayer1Txs", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "priorityOperationsHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "bootloaderHeapInitialContentsHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "eventsQueueStateHash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "systemLogs", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "pubdataCommitments", + "type": "bytes" + } + ], + "internalType": "struct IExecutor.CommitBatchInfo[]", + "name": "_newBatchesData", + "type": "tuple[]" + } + ], + "name": "commitBatches", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint64", + "name": "batchNumber", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" + }, + { + "internalType": "uint64", + "name": "indexRepeatedStorageChanges", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "numberOfLayer1Txs", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "priorityOperationsHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "l2LogsTreeRoot", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "commitment", + "type": "bytes32" + } + ], + "internalType": "struct IExecutor.StoredBatchInfo", + "name": "_lastCommittedBatchData", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint64", + "name": "batchNumber", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "timestamp", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "indexRepeatedStorageChanges", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "newStateRoot", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "numberOfLayer1Txs", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "priorityOperationsHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "bootloaderHeapInitialContentsHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "eventsQueueStateHash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "systemLogs", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "pubdataCommitments", + "type": "bytes" + } + ], + "internalType": "struct IExecutor.CommitBatchInfo[]", + "name": "_newBatchesData", + "type": "tuple[]" + } + ], + "name": "commitBatchesSharedBridge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint64", + "name": "batchNumber", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" + }, + { + "internalType": "uint64", + "name": "indexRepeatedStorageChanges", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "numberOfLayer1Txs", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "priorityOperationsHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "l2LogsTreeRoot", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "commitment", + "type": "bytes32" + } + ], + "internalType": "struct IExecutor.StoredBatchInfo[]", + "name": "_batchesData", + "type": "tuple[]" + } + ], + "name": "executeBatches", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint64", + "name": "batchNumber", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" + }, + { + "internalType": "uint64", + "name": "indexRepeatedStorageChanges", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "numberOfLayer1Txs", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "priorityOperationsHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "l2LogsTreeRoot", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "commitment", + "type": "bytes32" + } + ], + "internalType": "struct IExecutor.StoredBatchInfo[]", + "name": "_batchesData", + "type": "tuple[]" + } + ], + "name": "executeBatchesSharedBridge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "address", + "name": "facet", + "type": "address" + }, + { + "internalType": "enum Diamond.Action", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bool", + "name": "isFreezable", + "type": "bool" + }, + { + "internalType": "bytes4[]", + "name": "selectors", + "type": "bytes4[]" + } + ], + "internalType": "struct Diamond.FacetCut[]", + "name": "facetCuts", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "initAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "initCalldata", + "type": "bytes" + } + ], + "internalType": "struct Diamond.DiamondCutData", + "name": "_diamondCut", + "type": "tuple" + } + ], + "name": "executeUpgrade", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facet", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facets", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "selectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IGetters.Facet[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_l2BatchNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2MessageIndex", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "_l2TxNumberInBatch", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_message", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "_merkleProof", + "type": "bytes32[]" + } + ], + "name": "finalizeEthWithdrawal", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "freezeDiamond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBaseToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBaseTokenBridge", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBridgehub", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getFirstUnprocessedPriorityTx", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getL2BootloaderBytecodeHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getL2DefaultAccountBytecodeHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getL2SystemContractsUpgradeBatchNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getL2SystemContractsUpgradeTxHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getName", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPendingAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPriorityQueueSize", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPriorityTxMaxGasLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getProtocolVersion", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPubdataPricingMode", + "outputs": [ + { + "internalType": "enum PubdataPricingMode", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getStateTransitionManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTotalBatchesCommitted", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTotalBatchesExecuted", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTotalBatchesVerified", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTotalPriorityTxs", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getVerifier", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getVerifierParams", + "outputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "recursionNodeLevelVkHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "recursionLeafLevelVkHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "recursionCircuitsSetVksHash", + "type": "bytes32" + } + ], + "internalType": "struct VerifierParams", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isDiamondStorageFrozen", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_l2BatchNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2MessageIndex", + "type": "uint256" + } + ], + "name": "isEthWithdrawalFinalized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "isFacetFreezable", + "outputs": [ + { + "internalType": "bool", + "name": "isFreezable", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + } + ], + "name": "isFunctionFreezable", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_address", + "type": "address" + } + ], + "name": "isValidator", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_batchNumber", + "type": "uint256" + } + ], + "name": "l2LogsRootHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "merkleRoot", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_gasPrice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2GasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2GasPerPubdataByteLimit", + "type": "uint256" + } + ], + "name": "l2TransactionBaseCost", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "priorityQueueFrontOperation", + "outputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "canonicalTxHash", + "type": "bytes32" + }, + { + "internalType": "uint64", + "name": "expirationTimestamp", + "type": "uint64" + }, + { + "internalType": "uint192", + "name": "layer2Tip", + "type": "uint192" + } + ], + "internalType": "struct PriorityOperation", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint64", + "name": "batchNumber", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" + }, + { + "internalType": "uint64", + "name": "indexRepeatedStorageChanges", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "numberOfLayer1Txs", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "priorityOperationsHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "l2LogsTreeRoot", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "commitment", + "type": "bytes32" + } + ], + "internalType": "struct IExecutor.StoredBatchInfo", + "name": "_prevBatch", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint64", + "name": "batchNumber", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" + }, + { + "internalType": "uint64", + "name": "indexRepeatedStorageChanges", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "numberOfLayer1Txs", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "priorityOperationsHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "l2LogsTreeRoot", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "commitment", + "type": "bytes32" + } + ], + "internalType": "struct IExecutor.StoredBatchInfo[]", + "name": "_committedBatches", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "uint256[]", + "name": "recursiveAggregationInput", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "serializedProof", + "type": "uint256[]" + } + ], + "internalType": "struct IExecutor.ProofInput", + "name": "_proof", + "type": "tuple" + } + ], + "name": "proveBatches", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint64", + "name": "batchNumber", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" + }, + { + "internalType": "uint64", + "name": "indexRepeatedStorageChanges", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "numberOfLayer1Txs", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "priorityOperationsHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "l2LogsTreeRoot", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "commitment", + "type": "bytes32" + } + ], + "internalType": "struct IExecutor.StoredBatchInfo", + "name": "_prevBatch", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint64", + "name": "batchNumber", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" + }, + { + "internalType": "uint64", + "name": "indexRepeatedStorageChanges", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "numberOfLayer1Txs", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "priorityOperationsHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "l2LogsTreeRoot", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "commitment", + "type": "bytes32" + } + ], + "internalType": "struct IExecutor.StoredBatchInfo[]", + "name": "_committedBatches", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "uint256[]", + "name": "recursiveAggregationInput", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "serializedProof", + "type": "uint256[]" + } + ], + "internalType": "struct IExecutor.ProofInput", + "name": "_proof", + "type": "tuple" + } + ], + "name": "proveBatchesSharedBridge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_l2TxHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_l2BatchNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2MessageIndex", + "type": "uint256" + }, + { + "internalType": "uint16", + "name": "_l2TxNumberInBatch", + "type": "uint16" + }, + { + "internalType": "bytes32[]", + "name": "_merkleProof", + "type": "bytes32[]" + }, + { + "internalType": "enum TxStatus", + "name": "_status", + "type": "uint8" + } + ], + "name": "proveL1ToL2TransactionStatus", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_batchNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint8", + "name": "l2ShardId", + "type": "uint8" + }, + { + "internalType": "bool", + "name": "isService", + "type": "bool" + }, + { + "internalType": "uint16", + "name": "txNumberInBatch", + "type": "uint16" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "key", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "value", + "type": "bytes32" + } + ], + "internalType": "struct L2Log", + "name": "_log", + "type": "tuple" + }, + { + "internalType": "bytes32[]", + "name": "_proof", + "type": "bytes32[]" + } + ], + "name": "proveL2LogInclusion", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_batchNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint16", + "name": "txNumberInBatch", + "type": "uint16" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct L2Message", + "name": "_message", + "type": "tuple" + }, + { + "internalType": "bytes32[]", + "name": "_proof", + "type": "bytes32[]" + } + ], + "name": "proveL2MessageInclusion", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_contractL2", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_l2Value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_l2GasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_l2GasPerPubdataByteLimit", + "type": "uint256" + }, + { + "internalType": "bytes[]", + "name": "_factoryDeps", + "type": "bytes[]" + }, + { + "internalType": "address", + "name": "_refundRecipient", + "type": "address" + } + ], + "name": "requestL2Transaction", + "outputs": [ + { + "internalType": "bytes32", + "name": "canonicalTxHash", + "type": "bytes32" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newLastBatch", + "type": "uint256" + } + ], + "name": "revertBatches", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_chainId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_newLastBatch", + "type": "uint256" + } + ], + "name": "revertBatchesSharedBridge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newPendingAdmin", + "type": "address" + } + ], + "name": "setPendingAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_zkPorterIsAvailable", + "type": "bool" + } + ], + "name": "setPorterAvailability", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newPriorityTxMaxGasLimit", + "type": "uint256" + } + ], + "name": "setPriorityTxMaxGasLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint128", + "name": "_nominator", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "_denominator", + "type": "uint128" + } + ], + "name": "setTokenMultiplier", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_transactionFilterer", + "type": "address" + } + ], + "name": "setTransactionFilterer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_validator", + "type": "address" + }, + { + "internalType": "bool", + "name": "_active", + "type": "bool" + } + ], + "name": "setValidator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum PubdataPricingMode", + "name": "_validiumMode", + "type": "uint8" + } + ], + "name": "setValidiumMode", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_batchNumber", + "type": "uint256" + } + ], + "name": "storedBatchHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "transferEthToSharedBridge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unfreezeDiamond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_protocolVersion", + "type": "uint256" + }, + { + "components": [ + { + "components": [ + { + "internalType": "address", + "name": "facet", + "type": "address" + }, + { + "internalType": "enum Diamond.Action", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bool", + "name": "isFreezable", + "type": "bool" + }, + { + "internalType": "bytes4[]", + "name": "selectors", + "type": "bytes4[]" + } + ], + "internalType": "struct Diamond.FacetCut[]", + "name": "facetCuts", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "initAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "initCalldata", + "type": "bytes" + } + ], + "internalType": "struct Diamond.DiamondCutData", + "name": "_cutData", + "type": "tuple" + } + ], + "name": "upgradeChainFromVersion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh index ede263b0..bfa96e0c 100755 --- a/scripts/entrypoint.sh +++ b/scripts/entrypoint.sh @@ -16,11 +16,15 @@ yarn install echo "Generate ABIs" solc --base-path l1-contracts/ \ - --include-path ./node_modules/ \ + --include-path l1-contracts/node_modules/ \ -o l1-abi \ --abi \ - l1-contracts/contracts/zksync/interfaces/IZkSync.sol \ - l1-contracts/contracts/bridge/interfaces/IL1Bridge.sol \ + l1-contracts/contracts/bridgehub/IBridgehub.sol \ + l1-contracts/contracts/state-transition/chain-interfaces/IZkSyncStateTransition.sol \ + l1-contracts/contracts/dev-contracts/interfaces/ITestnetERC20Token.sol \ + l1-contracts/contracts/bridge/interfaces/IL1ERC20Bridge.sol \ + l1-contracts/contracts/bridge/interfaces/IL1WethBridge.sol \ + l1-contracts/contracts/bridge/interfaces/IL1Erc20Bridge.sol \ l1-contracts/contracts/bridge/interfaces/IL2Bridge.sol solc --base-path system-contracts \ @@ -35,7 +39,7 @@ solc --base-path system-contracts \ mkdir abi /abi mv l1-abi/* system-contracts-abi/* abi -contracts="IZkSync.abi IL1Bridge.abi IL2Bridge.abi IContractDeployer.abi IEthToken.abi IL1Messenger.abi INonceHolder.abi IPaymasterFlow.abi" +contracts="IBridgehub.abi IZkSyncStateTransition.abi IL1ERC20Bridge.abi IL1WethBridge.abi IL1Erc20Bridge.abi IL2Bridge.abi IContractDeployer.abi IEthToken.abi IL1Messenger.abi INonceHolder.abi IPaymasterFlow.abi ITestnetERC20Token.abi" for filename in $contracts; do jq '.' "abi/$filename" > "/abi/${filename%.abi}.json" diff --git a/src/adapters.ts b/src/adapters.ts index 2095b562..879b2992 100644 --- a/src/adapters.ts +++ b/src/adapters.ts @@ -14,7 +14,6 @@ import { DEFAULT_GAS_PER_PUBDATA_LIMIT, estimateCustomBridgeDepositL2Gas, estimateDefaultBridgeDepositL2Gas, - ETH_ADDRESS, getERC20DefaultBridgeData, isETH, L1_MESSENGER_ADDRESS, @@ -25,16 +24,24 @@ import { scaleGasLimit, undoL1ToL2Alias, NONCE_HOLDER_ADDRESS, + ETH_ADDRESS_IN_CONTRACTS, + LEGACY_ETH_ADDRESS, + isAddressEq, } from './utils'; import { + IBridgehub, + IBridgehub__factory, IERC20__factory, - IL1Bridge, + IL1ERC20Bridge, + IL1ERC20Bridge__factory, IL1Bridge__factory, + IL1SharedBridge, + IL1SharedBridge__factory, IL2Bridge, IL2Bridge__factory, INonceHolder__factory, - IZkSync, - IZkSync__factory, + IZkSyncStateTransition, + IZkSyncStateTransition__factory, } from './typechain'; import { Address, @@ -83,24 +90,62 @@ export function AdapterL1>(Base: TBase) { /** * Returns `Contract` wrapper of the zkSync Era smart contract. */ - async getMainContract(): Promise { + async getMainContract(): Promise { const address = await this._providerL2().getMainContractAddress(); - return IZkSync__factory.connect(address, this._signerL1()); + return IZkSyncStateTransition__factory.connect(address, this._signerL1()); + } + + /** + * Returns `Contract` wrapper of the Bridgehub smart contract. + */ + async getBridgehubContract(): Promise { + const address = await this._providerL2().getBridgehubContractAddress(); + return IBridgehub__factory.connect(address, this._signerL1()); } /** * Returns L1 bridge contracts. * - * @remarks There is no separate Ether bridge contract, {@link getMainContract Main contract} is used instead. + * @remarks There is no separate Ether bridge contract, {@link getBridgehubContract Bridgehub} is used instead. */ - async getL1BridgeContracts(): Promise<{erc20: IL1Bridge; weth: IL1Bridge}> { + async getL1BridgeContracts(): Promise<{ + erc20: IL1ERC20Bridge; + weth: IL1ERC20Bridge; + shared: IL1SharedBridge; + }> { const addresses = await this._providerL2().getDefaultBridgeAddresses(); return { - erc20: IL1Bridge__factory.connect(addresses.erc20L1!, this._signerL1()), - weth: IL1Bridge__factory.connect(addresses.wethL1!, this._signerL1()), + erc20: IL1ERC20Bridge__factory.connect( + addresses.erc20L1, + this._signerL1() + ), + weth: IL1ERC20Bridge__factory.connect( + addresses.wethL1, + this._signerL1() + ), + shared: IL1SharedBridge__factory.connect( + addresses.sharedL1, + this._signerL1() + ), }; } + /** + * Returns the address of the base token on L1. + */ + async getBaseToken(): Promise { + const bridgehub = await this.getBridgehubContract(); + const chainId = (await this._providerL2().getNetwork()).chainId; + return await bridgehub.baseToken(chainId); + } + + /** + * Returns whether the chain is ETH-based. + */ + async isETHBasedChain(): Promise { + return this._providerL2().isEthBasedChain(); + } + /** * Returns the amount of the token held by the account on the L1 network. * @@ -109,7 +154,7 @@ export function AdapterL1>(Base: TBase) { * Defaults to 'committed', i.e., the latest processed block. */ async getBalanceL1(token?: Address, blockTag?: BlockTag): Promise { - token ??= ETH_ADDRESS; + token ??= LEGACY_ETH_ADDRESS; if (isETH(token)) { return await this._providerL1().getBalance( await this.getAddress(), @@ -140,18 +185,7 @@ export function AdapterL1>(Base: TBase) { ): Promise { if (!bridgeAddress) { const bridgeContracts = await this.getL1BridgeContracts(); - let l2WethToken = ethers.ZeroAddress; - try { - l2WethToken = await bridgeContracts.weth.l2TokenAddress(token); - } catch (e) { - // skip - } - - // If the token is Wrapped Ether, return allowance to its own bridge, otherwise to the default ERC20 bridge. - bridgeAddress = - l2WethToken !== ethers.ZeroAddress - ? await bridgeContracts.weth.getAddress() - : await bridgeContracts.erc20.getAddress(); + bridgeAddress = await bridgeContracts.shared.getAddress(); } const erc20contract = IERC20__factory.connect(token, this._providerL1()); @@ -173,20 +207,7 @@ export function AdapterL1>(Base: TBase) { * @param token The address of the token on L1. */ async l2TokenAddress(token: Address): Promise { - if (token === ETH_ADDRESS) { - return ETH_ADDRESS; - } - const bridgeContracts = await this.getL1BridgeContracts(); - try { - const l2WethToken = await bridgeContracts.weth.l2TokenAddress(token); - // If the token is Wrapped Ether, return its L2 token address. - if (l2WethToken !== ethers.ZeroAddress) { - return l2WethToken; - } - } catch (e) { - // skip - } - return await bridgeContracts.erc20.l2TokenAddress(token); + return this._providerL2().l2TokenAddress(token); } /** @@ -210,27 +231,18 @@ export function AdapterL1>(Base: TBase) { } overrides ??= {}; - let bridgeAddress = overrides?.bridgeAddress; + let bridgeAddress = overrides.bridgeAddress; const erc20contract = IERC20__factory.connect(token, this._signerL1()); if (!bridgeAddress) { - const bridgeContracts = await this.getL1BridgeContracts(); - let l2WethToken = ethers.ZeroAddress; - try { - l2WethToken = await bridgeContracts.weth.l2TokenAddress(token); - } catch (e) { - // skip - } - // If the token is Wrapped Ether, return corresponding bridge, otherwise return default ERC20 bridge - bridgeAddress = - l2WethToken !== ethers.ZeroAddress - ? await bridgeContracts.weth.getAddress() - : await bridgeContracts.erc20.getAddress(); + bridgeAddress = await ( + await this.getL1BridgeContracts() + ).shared.getAddress(); } else { delete overrides.bridgeAddress; } - return await erc20contract.approve(bridgeAddress!, amount, overrides); + return await erc20contract.approve(bridgeAddress, amount, overrides); } /** @@ -246,25 +258,92 @@ export function AdapterL1>(Base: TBase) { gasPerPubdataByte?: BigNumberish; gasPrice?: BigNumberish; }): Promise { - const zksyncContract = await this.getMainContract(); + const bridgehub = await this.getBridgehubContract(); const parameters = {...layer1TxDefaults(), ...params}; parameters.gasPrice ??= (await this._providerL1().getFeeData()).gasPrice!; parameters.gasPerPubdataByte ??= REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT; - return await zksyncContract.l2TransactionBaseCost( + return await bridgehub.l2TransactionBaseCost( + (await this._providerL2().getNetwork()).chainId, parameters.gasPrice, parameters.gasLimit, parameters.gasPerPubdataByte ); } + /** + * Returns the parameters for the approval token transaction based on the deposit token and amount. + * Some deposit transactions require multiple approvals. Existing allowance for the bridge is not checked; + * allowance is calculated solely based on the specified amount. + * + * @param token The address of the token to deposit. + * @param amount The amount of the token to deposit. + */ + async getDepositAllowanceParams( + token: Address, + amount: BigNumberish + ): Promise<{token: Address; allowance: BigNumberish}[]> { + if (isAddressEq(token, LEGACY_ETH_ADDRESS)) { + token = ETH_ADDRESS_IN_CONTRACTS; + } + const baseTokenAddress = await this.getBaseToken(); + const isETHBasedChain = await this.isETHBasedChain(); + + if (isETHBasedChain && isAddressEq(token, ETH_ADDRESS_IN_CONTRACTS)) { + throw new Error( + "ETH token can't be approved! The address of the token does not exist on L1." + ); + } else if (isAddressEq(baseTokenAddress, ETH_ADDRESS_IN_CONTRACTS)) { + return [{token, allowance: amount}]; + } else if (isAddressEq(token, ETH_ADDRESS_IN_CONTRACTS)) { + return [ + { + token: baseTokenAddress, + allowance: ( + await this._getDepositETHOnNonETHBasedChainTx({token, amount}) + ).mintValue, + }, + ]; + } else if (isAddressEq(token, baseTokenAddress)) { + return [ + { + token: baseTokenAddress, + allowance: ( + await this._getDepositBaseTokenOnNonETHBasedChainTx({ + token, + amount, + }) + ).mintValue, + }, + ]; + } else { + // A deposit of a non-base token to a non-ETH-based chain requires two approvals. + return [ + { + token: baseTokenAddress, + allowance: ( + await this._getDepositNonBaseTokenToNonETHBasedChainTx({ + token, + amount, + }) + ).mintValue, + }, + { + token: token, + allowance: amount, + }, + ]; + } + } + /** * Transfers the specified token from the associated account on the L1 network to the target account on the L2 network. * The token can be either ETH or any ERC20 token. For ERC20 tokens, enough approved tokens must be associated with * the specified L1 bridge (default one or the one defined in `transaction.bridgeAddress`). - * In this case, `transaction.approveERC20` can be enabled to perform token approval. If there are already enough - * approved tokens for the L1 bridge, token approval will be skipped. - * To check the amount of approved tokens for a specific bridge, use the {@link getAllowanceL1} method. + * In this case, depending on is the chain ETH-based or not `transaction.approveERC20` or `transaction.approveBaseERC20` + * can be enabled to perform token approval. If there are already enough approved tokens for the L1 bridge, + * token approval will be skipped. To check the amount of approved tokens for a specific bridge, + * use the {@link getAllowanceL1} method. * * @param transaction The transaction object containing deposit details. * @param transaction.token The address of the token to deposit. ETH by default. @@ -276,13 +355,19 @@ export function AdapterL1>(Base: TBase) { * @param [transaction.bridgeAddress] The address of the bridge contract to be used. * Defaults to the default zkSync Era bridge (either `L1EthBridge` or `L1Erc20Bridge`). * @param [transaction.approveERC20] Whether or not token approval should be performed under the hood. - * Set this flag to true if you bridge an ERC20 token and didn't call the {@link approveERC20} function beforehand. + * Set this flag to true if you bridge an ERC20 token and didn't call the {@link approveERC20} function beforehand. + * @param [transaction.approveBaseERC20] Whether or not base token approval should be performed under the hood. + * Set this flag to true if you bridge a base token and didn't call the {@link approveERC20} function beforehand. * @param [transaction.l2GasLimit] Maximum amount of L2 gas that the transaction can consume during execution on L2. * @param [transaction.gasPerPubdataByte] The L2 gas price for each published L1 calldata byte. * @param [transaction.refundRecipient] The address on L2 that will receive the refund for the transaction. * If the transaction fails, it will also be the address to receive `l2Value`. - * @param [transaction.overrides] Transaction's overrides which may be used to pass L1 `gasLimit`, `gasPrice`, `value`, etc. - * @param [transaction.approveOverrides] Transaction's overrides which may be used to pass L1 `gasLimit`, `gasPrice`, `value`, etc. + * @param [transaction.overrides] Transaction's overrides for deposit which may be used to pass + * L1 `gasLimit`, `gasPrice`, `value`, etc. + * @param [transaction.approveOverrides] Transaction's overrides for approval of an ERC20 token which may be used + * to pass L1 `gasLimit`, `gasPrice`, `value`, etc. + * @param [transaction.approveBaseOverrides] Transaction's overrides for approval of a base token which may be used + * to pass L1 `gasLimit`, `gasPrice`, `value`, etc. * @param [transaction.customBridgeData] Additional data that can be sent to a bridge. */ async deposit(transaction: { @@ -292,73 +377,319 @@ export function AdapterL1>(Base: TBase) { operatorTip?: BigNumberish; bridgeAddress?: Address; approveERC20?: boolean; + approveBaseERC20?: boolean; l2GasLimit?: BigNumberish; gasPerPubdataByte?: BigNumberish; refundRecipient?: Address; overrides?: ethers.Overrides; approveOverrides?: ethers.Overrides; + approveBaseOverrides?: ethers.Overrides; customBridgeData?: BytesLike; }): Promise { - const depositTx = await this.getDepositTx(transaction); + if (isAddressEq(transaction.token, LEGACY_ETH_ADDRESS)) { + transaction.token = ETH_ADDRESS_IN_CONTRACTS; + } + const bridgehub = await this.getBridgehubContract(); + const chainId = (await this._providerL2().getNetwork()).chainId; + const baseTokenAddress = await bridgehub.baseToken(chainId); + const isETHBasedChain = isAddressEq( + baseTokenAddress, + ETH_ADDRESS_IN_CONTRACTS + ); - if (transaction.token === ETH_ADDRESS) { - const baseGasLimit = await this.estimateGasRequestExecute(depositTx); - const gasLimit = scaleGasLimit(baseGasLimit); - depositTx.overrides.gasLimit ??= gasLimit; - return this.requestExecute(depositTx); + if ( + isETHBasedChain && + isAddressEq(transaction.token, ETH_ADDRESS_IN_CONTRACTS) + ) { + return await this._depositETHToETHBasedChain(transaction); + } else if (isAddressEq(baseTokenAddress, ETH_ADDRESS_IN_CONTRACTS)) { + return await this._depositTokenToETHBasedChain(transaction); + } else if (isAddressEq(transaction.token, ETH_ADDRESS_IN_CONTRACTS)) { + return await this._depositETHToNonETHBasedChain(transaction); + } else if (isAddressEq(transaction.token, baseTokenAddress)) { + return await this._depositBaseTokenToNonETHBasedChain(transaction); } else { - const bridgeContracts = await this.getL1BridgeContracts(); - if (transaction.approveERC20) { - let l2WethToken = ethers.ZeroAddress; - try { - l2WethToken = await bridgeContracts.weth.l2TokenAddress( - transaction.token - ); - } catch (e) { - // skip - } - // If the token is Wrapped Ether, use its bridge. - const proposedBridge = - l2WethToken !== ethers.ZeroAddress - ? await bridgeContracts.weth.getAddress() - : await bridgeContracts.erc20.getAddress(); - const bridgeAddress = transaction.bridgeAddress - ? transaction.bridgeAddress - : proposedBridge; - - // We only request the allowance if the current one is not enough. - const allowance = await this.getAllowanceL1( + return await this._depositNonBaseTokenToNonETHBasedChain(transaction); + } + } + + async _depositNonBaseTokenToNonETHBasedChain(transaction: { + token: Address; + amount: BigNumberish; + to?: Address; + operatorTip?: BigNumberish; + bridgeAddress?: Address; + approveERC20?: boolean; + approveBaseERC20?: boolean; + l2GasLimit?: BigNumberish; + gasPerPubdataByte?: BigNumberish; + refundRecipient?: Address; + overrides?: ethers.Overrides; + approveOverrides?: ethers.Overrides; + approveBaseOverrides?: ethers.Overrides; + customBridgeData?: BytesLike; + }): Promise { + // Deposit a non-ETH and non-base token to a non-ETH-based chain. + // Go through the BridgeHub and obtain approval for both tokens. + const bridgehub = await this.getBridgehubContract(); + const chainId = (await this._providerL2().getNetwork()).chainId; + const baseTokenAddress = await bridgehub.baseToken(chainId); + const bridgeContracts = await this.getL1BridgeContracts(); + const {tx, mintValue} = + await this._getDepositNonBaseTokenToNonETHBasedChainTx(transaction); + + if (transaction.approveBaseERC20) { + // Only request the allowance if the current one is not enough. + const allowance = await this.getAllowanceL1( + baseTokenAddress, + await bridgeContracts.shared.getAddress() + ); + if (allowance < mintValue) { + const approveTx = await this.approveERC20( + baseTokenAddress, + mintValue, + { + bridgeAddress: await bridgeContracts.shared.getAddress(), + ...transaction.approveBaseOverrides, + } + ); + await approveTx.wait(); + } + } + + if (transaction.approveERC20) { + const bridgeAddress = transaction.bridgeAddress + ? transaction.bridgeAddress + : await bridgeContracts.shared.getAddress(); + + // Only request the allowance if the current one is not enough. + const allowance = await this.getAllowanceL1( + transaction.token, + bridgeAddress + ); + if (allowance < BigInt(transaction.amount)) { + const approveTx = await this.approveERC20( transaction.token, - bridgeAddress + transaction.amount, + { + bridgeAddress, + ...transaction.approveOverrides, + } ); - if (allowance < BigInt(transaction.amount)) { - const approveTx = await this.approveERC20( - transaction.token, - transaction.amount, - { - bridgeAddress, - ...transaction.approveOverrides, - } - ); - await approveTx.wait(); - } + await approveTx.wait(); + } + } + + const baseGasLimit = await this._providerL1().estimateGas(tx); + const gasLimit = scaleGasLimit(baseGasLimit); + + tx.gasLimit ??= gasLimit; + + return await this._providerL2().getPriorityOpResponse( + await this._signerL1().sendTransaction(tx) + ); + } + + async _depositBaseTokenToNonETHBasedChain(transaction: { + token: Address; + amount: BigNumberish; + to?: Address; + operatorTip?: BigNumberish; + bridgeAddress?: Address; + approveERC20?: boolean; + approveBaseERC20?: boolean; + l2GasLimit?: BigNumberish; + gasPerPubdataByte?: BigNumberish; + refundRecipient?: Address; + overrides?: ethers.Overrides; + approveOverrides?: ethers.Overrides; + approveBaseOverrides?: ethers.Overrides; + customBridgeData?: BytesLike; + }): Promise { + // Bridging the base token to a non-ETH-based chain. + // Go through the BridgeHub, and give approval. + const bridgehub = await this.getBridgehubContract(); + const chainId = (await this._providerL2().getNetwork()).chainId; + const baseTokenAddress = await bridgehub.baseToken(chainId); + const sharedBridge = await ( + await this.getL1BridgeContracts() + ).shared.getAddress(); + const {tx, mintValue} = + await this._getDepositBaseTokenOnNonETHBasedChainTx(transaction); + + if (transaction.approveERC20 || transaction.approveBaseERC20) { + const approveOverrides = + transaction.approveBaseOverrides ?? transaction.approveOverrides!; + // Only request the allowance if the current one is not enough. + const allowance = await this.getAllowanceL1( + baseTokenAddress, + sharedBridge + ); + if (allowance < mintValue) { + const approveTx = await this.approveERC20( + baseTokenAddress, + mintValue, + { + bridgeAddress: sharedBridge, + ...approveOverrides, + } + ); + await approveTx.wait(); } + } + const baseGasLimit = await this.estimateGasRequestExecute(tx); + const gasLimit = scaleGasLimit(baseGasLimit); - const baseGasLimit = await this._providerL1().estimateGas(depositTx); - const gasLimit = scaleGasLimit(baseGasLimit); + tx.overrides ??= {}; + tx.overrides.gasLimit ??= gasLimit; - depositTx.gasLimit ??= gasLimit; + return this.requestExecute(tx); + } - return await this._providerL2().getPriorityOpResponse( - await this._signerL1().sendTransaction(depositTx) + async _depositETHToNonETHBasedChain(transaction: { + token: Address; + amount: BigNumberish; + to?: Address; + operatorTip?: BigNumberish; + bridgeAddress?: Address; + approveERC20?: boolean; + approveBaseERC20?: boolean; + l2GasLimit?: BigNumberish; + gasPerPubdataByte?: BigNumberish; + refundRecipient?: Address; + overrides?: ethers.Overrides; + approveOverrides?: ethers.Overrides; + approveBaseOverrides?: ethers.Overrides; + customBridgeData?: BytesLike; + }): Promise { + // Depositing ETH into a non-ETH-based chain. + // Use requestL2TransactionTwoBridges, secondBridge is the wETH bridge. + const bridgehub = await this.getBridgehubContract(); + const chainId = (await this._providerL2().getNetwork()).chainId; + const baseTokenAddress = await bridgehub.baseToken(chainId); + const sharedBridge = await ( + await this.getL1BridgeContracts() + ).shared.getAddress(); + const {tx, mintValue} = + await this._getDepositETHOnNonETHBasedChainTx(transaction); + + if (transaction.approveBaseERC20) { + // Only request the allowance if the current one is not enough. + const allowance = await this.getAllowanceL1( + baseTokenAddress, + sharedBridge ); + if (allowance < mintValue) { + const approveTx = await this.approveERC20( + baseTokenAddress, + mintValue, + { + bridgeAddress: sharedBridge, + ...transaction.approveBaseOverrides, + } + ); + await approveTx.wait(); + } } + + const baseGasLimit = await this._providerL1().estimateGas(tx); + const gasLimit = scaleGasLimit(baseGasLimit); + + tx.gasLimit ??= gasLimit; + + return await this._providerL2().getPriorityOpResponse( + await this._signerL1().sendTransaction(tx) + ); + } + + async _depositTokenToETHBasedChain(transaction: { + token: Address; + amount: BigNumberish; + to?: Address; + operatorTip?: BigNumberish; + bridgeAddress?: Address; + approveERC20?: boolean; + approveBaseERC20?: boolean; + l2GasLimit?: BigNumberish; + gasPerPubdataByte?: BigNumberish; + refundRecipient?: Address; + overrides?: ethers.Overrides; + approveOverrides?: ethers.Overrides; + approveBaseOverrides?: ethers.Overrides; + customBridgeData?: BytesLike; + }): Promise { + const bridgeContracts = await this.getL1BridgeContracts(); + const tx = await this._getDepositTokenOnETHBasedChainTx(transaction); + + if (transaction.approveERC20) { + const proposedBridge = await bridgeContracts.shared.getAddress(); + const bridgeAddress = transaction.bridgeAddress + ? transaction.bridgeAddress + : proposedBridge; + + // Only request the allowance if the current one is not enough. + const allowance = await this.getAllowanceL1( + transaction.token, + bridgeAddress + ); + if (allowance < BigInt(transaction.amount)) { + const approveTx = await this.approveERC20( + transaction.token, + transaction.amount, + { + bridgeAddress, + ...transaction.approveOverrides, + } + ); + await approveTx.wait(); + } + } + + const baseGasLimit = await this._providerL1().estimateGas(tx); + const gasLimit = scaleGasLimit(baseGasLimit); + + tx.gasLimit ??= gasLimit; + + return await this._providerL2().getPriorityOpResponse( + await this._signerL1().sendTransaction(tx) + ); + } + + async _depositETHToETHBasedChain(transaction: { + token: Address; + amount: BigNumberish; + to?: Address; + operatorTip?: BigNumberish; + bridgeAddress?: Address; + approveERC20?: boolean; + approveBaseERC20?: boolean; + l2GasLimit?: BigNumberish; + gasPerPubdataByte?: BigNumberish; + refundRecipient?: Address; + overrides?: ethers.Overrides; + approveOverrides?: ethers.Overrides; + approveBaseOverrides?: ethers.Overrides; + customBridgeData?: BytesLike; + }): Promise { + const tx = await this._getDepositETHOnETHBasedChainTx(transaction); + + const baseGasLimit = await this.estimateGasRequestExecute(tx); + const gasLimit = scaleGasLimit(baseGasLimit); + + tx.overrides ??= {}; + tx.overrides.gasLimit ??= gasLimit; + + return this.requestExecute(tx); } /** * Estimates the amount of gas required for a deposit transaction on the L1 network. * Gas for approving ERC20 tokens is not included in the estimation. * + * In order for estimation to work, enough token allowance is required in the following cases: + * - Depositing ERC20 tokens on an ETH-based chain. + * - Depositing any token (including ETH) on a non-ETH-based chain. + * * @param transaction The transaction details. * @param transaction.token The address of the token to deposit. ETH by default. * @param transaction.amount The amount of the token to deposit. @@ -387,13 +718,16 @@ export function AdapterL1>(Base: TBase) { refundRecipient?: Address; overrides?: ethers.Overrides; }): Promise { - const depositTx = await this.getDepositTx(transaction); + if (isAddressEq(transaction.token, LEGACY_ETH_ADDRESS)) { + transaction.token = ETH_ADDRESS_IN_CONTRACTS; + } + const tx = await this.getDepositTx(transaction); let baseGasLimit: bigint; - if (transaction.token === ETH_ADDRESS) { - baseGasLimit = await this.estimateGasRequestExecute(depositTx); + if (tx.token && isAddressEq(tx.token, await this.getBaseToken())) { + baseGasLimit = await this.estimateGasRequestExecute(tx); } else { - baseGasLimit = await this._providerL1().estimateGas(depositTx); + baseGasLimit = await this._providerL1().estimateGas(tx); } return scaleGasLimit(baseGasLimit); @@ -430,114 +764,449 @@ export function AdapterL1>(Base: TBase) { refundRecipient?: Address; overrides?: ethers.Overrides; }): Promise { - const bridgeContracts = await this.getL1BridgeContracts(); - if (transaction.bridgeAddress) { - bridgeContracts.erc20 = bridgeContracts.erc20.attach( - transaction.bridgeAddress - ) as IL1Bridge; + if (isAddressEq(transaction.token, LEGACY_ETH_ADDRESS)) { + transaction.token = ETH_ADDRESS_IN_CONTRACTS; } + const bridgehub = await this.getBridgehubContract(); + const chainId = (await this._providerL2().getNetwork()).chainId; + const baseTokenAddress = await bridgehub.baseToken(chainId); + const isETHBasedChain = isAddressEq( + baseTokenAddress, + ETH_ADDRESS_IN_CONTRACTS + ); - const {...tx} = transaction; - tx.to ??= await this.getAddress(); - tx.operatorTip ??= 0; - tx.overrides ??= {}; - tx.overrides.from ??= await this.getAddress(); - tx.gasPerPubdataByte ??= REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT; - if (tx.bridgeAddress) { - const customBridgeData = - tx.customBridgeData ?? - (await bridgeContracts.weth.getAddress()) === tx.bridgeAddress - ? '0x' - : await getERC20DefaultBridgeData(tx.token, this._providerL1()); - const bridge = IL1Bridge__factory.connect( - tx.bridgeAddress, - this._signerL1() - ); - const l2Address = await bridge.l2Bridge(); - tx.l2GasLimit ??= await estimateCustomBridgeDepositL2Gas( - this._providerL2(), - tx.bridgeAddress, - l2Address, - tx.token, - tx.amount, - tx.to, - customBridgeData, - await this.getAddress(), - tx.gasPerPubdataByte - ); + if ( + isETHBasedChain && + isAddressEq(transaction.token, ETH_ADDRESS_IN_CONTRACTS) + ) { + return await this._getDepositETHOnETHBasedChainTx(transaction); + } else if (isETHBasedChain) { + return await this._getDepositTokenOnETHBasedChainTx(transaction); + } else if (isAddressEq(transaction.token, ETH_ADDRESS_IN_CONTRACTS)) { + return (await this._getDepositETHOnNonETHBasedChainTx(transaction)).tx; + } else if (isAddressEq(transaction.token, baseTokenAddress)) { + return ( + await this._getDepositBaseTokenOnNonETHBasedChainTx(transaction) + ).tx; } else { - tx.l2GasLimit ??= await estimateDefaultBridgeDepositL2Gas( - this._providerL1(), - this._providerL2(), - tx.token, - tx.amount, - tx.to, - await this.getAddress(), - tx.gasPerPubdataByte - ); + return ( + await this._getDepositNonBaseTokenToNonETHBasedChainTx(transaction) + ).tx; } + } - const {to, token, amount, operatorTip, overrides} = tx; + async _getDepositNonBaseTokenToNonETHBasedChainTx(transaction: { + token: Address; + amount: BigNumberish; + to?: Address; + operatorTip?: BigNumberish; + bridgeAddress?: Address; + l2GasLimit?: BigNumberish; + gasPerPubdataByte?: BigNumberish; + customBridgeData?: BytesLike; + refundRecipient?: Address; + overrides?: ethers.Overrides; + }) { + const bridgehub = await this.getBridgehubContract(); + const chainId = (await this._providerL2().getNetwork()).chainId; + const bridgeContracts = await this.getL1BridgeContracts(); + + const tx = await this._getDepositTxWithDefaults(transaction); + const { + token, + operatorTip, + amount, + overrides, + l2GasLimit, + to, + refundRecipient, + gasPerPubdataByte, + } = tx; - await insertGasPrice(this._providerL1(), overrides); const gasPriceForEstimation = overrides.maxFeePerGas || overrides.gasPrice; + const baseCost = await bridgehub.l2TransactionBaseCost( + chainId as BigNumberish, + gasPriceForEstimation as BigNumberish, + l2GasLimit, + gasPerPubdataByte + ); - const zksyncContract = await this.getMainContract(); + const mintValue = baseCost + BigInt(operatorTip); + await checkBaseCost(baseCost, mintValue); + overrides.value ??= 0; - const baseCost = await zksyncContract.l2TransactionBaseCost( - gasPriceForEstimation!, - tx.l2GasLimit, - tx.gasPerPubdataByte - ); + return { + tx: await bridgehub.requestL2TransactionTwoBridges.populateTransaction( + { + chainId: chainId, + mintValue, + l2Value: 0, + l2GasLimit: l2GasLimit, + l2GasPerPubdataByteLimit: gasPerPubdataByte, + refundRecipient: refundRecipient ?? ethers.ZeroAddress, + secondBridgeAddress: await bridgeContracts.shared.getAddress(), + secondBridgeValue: 0, + secondBridgeCalldata: ethers.AbiCoder.defaultAbiCoder().encode( + ['address', 'uint256', 'address'], + [token, amount, to] + ), + }, + overrides + ), + mintValue: mintValue, + }; + } - if (token === ETH_ADDRESS) { - overrides.value ??= baseCost + BigInt(operatorTip) + BigInt(amount); + async _getDepositBaseTokenOnNonETHBasedChainTx(transaction: { + token: Address; + amount: BigNumberish; + to?: Address; + operatorTip?: BigNumberish; + bridgeAddress?: Address; + l2GasLimit?: BigNumberish; + gasPerPubdataByte?: BigNumberish; + customBridgeData?: BytesLike; + refundRecipient?: Address; + overrides?: ethers.Overrides; + }) { + // Depositing the base token to a non-ETH-based chain. + // Goes through the BridgeHub. + // Have to give approvals for the sharedBridge. + const bridgehub = await this.getBridgehubContract(); + const chainId = (await this._providerL2().getNetwork()).chainId; + + const tx = await this._getDepositTxWithDefaults(transaction); + const { + operatorTip, + amount, + to, + overrides, + l2GasLimit, + gasPerPubdataByte, + } = tx; - return { + const gasPriceForEstimation = + overrides.maxFeePerGas || overrides.gasPrice; + const baseCost = await bridgehub.l2TransactionBaseCost( + chainId as BigNumberish, + gasPriceForEstimation as BigNumberish, + l2GasLimit, + gasPerPubdataByte + ); + + tx.overrides.value = 0; + return { + tx: { contractAddress: to, calldata: '0x', + mintValue: baseCost + BigInt(operatorTip) + BigInt(amount), l2Value: amount, ...tx, - }; + }, + mintValue: baseCost + BigInt(operatorTip) + BigInt(amount), + }; + } + + async _getDepositETHOnNonETHBasedChainTx(transaction: { + token: Address; + amount: BigNumberish; + to?: Address; + operatorTip?: BigNumberish; + bridgeAddress?: Address; + l2GasLimit?: BigNumberish; + gasPerPubdataByte?: BigNumberish; + customBridgeData?: BytesLike; + refundRecipient?: Address; + overrides?: ethers.Overrides; + }) { + const bridgehub = await this.getBridgehubContract(); + const chainId = (await this._providerL2().getNetwork()).chainId; + const sharedBridge = await ( + await this.getL1BridgeContracts() + ).shared.getAddress(); + + const tx = await this._getDepositTxWithDefaults(transaction); + const { + operatorTip, + amount, + overrides, + l2GasLimit, + to, + refundRecipient, + gasPerPubdataByte, + } = tx; + + const gasPriceForEstimation = + overrides.maxFeePerGas || overrides.gasPrice; + const baseCost = await bridgehub.l2TransactionBaseCost( + chainId as BigNumberish, + gasPriceForEstimation as BigNumberish, + l2GasLimit, + gasPerPubdataByte + ); + + overrides.value ??= amount; + const mintValue = baseCost + BigInt(operatorTip); + await checkBaseCost(baseCost, mintValue); + + return { + tx: await bridgehub.requestL2TransactionTwoBridges.populateTransaction( + { + chainId, + mintValue, + l2Value: 0, + l2GasLimit: l2GasLimit, + l2GasPerPubdataByteLimit: gasPerPubdataByte, + refundRecipient: refundRecipient ?? ethers.ZeroAddress, + secondBridgeAddress: sharedBridge, + secondBridgeValue: amount, + secondBridgeCalldata: ethers.AbiCoder.defaultAbiCoder().encode( + ['address', 'uint256', 'address'], + [ETH_ADDRESS_IN_CONTRACTS, 0, to] + ), + }, + overrides + ), + mintValue: mintValue, + }; + } + + async _getDepositTokenOnETHBasedChainTx(transaction: { + token: Address; + amount: BigNumberish; + to?: Address; + operatorTip?: BigNumberish; + bridgeAddress?: Address; + l2GasLimit?: BigNumberish; + gasPerPubdataByte?: BigNumberish; + customBridgeData?: BytesLike; + refundRecipient?: Address; + overrides?: ethers.Overrides; + }): Promise { + // Depositing token to an ETH-based chain. Use the ERC20 bridge as done before. + const bridgehub = await this.getBridgehubContract(); + const chainId = (await this._providerL2().getNetwork()).chainId; + + const tx = await this._getDepositTxWithDefaults(transaction); + const { + token, + operatorTip, + amount, + overrides, + l2GasLimit, + to, + refundRecipient, + gasPerPubdataByte, + } = tx; + + const gasPriceForEstimation = + overrides.maxFeePerGas || overrides.gasPrice; + const baseCost = await bridgehub.l2TransactionBaseCost( + chainId as BigNumberish, + gasPriceForEstimation as BigNumberish, + tx.l2GasLimit, + tx.gasPerPubdataByte + ); + + const mintValue = baseCost + BigInt(operatorTip); + overrides.value ??= mintValue; + await checkBaseCost(baseCost, mintValue); + + let secondBridgeAddress: string; + let secondBridgeCalldata: BytesLike; + if (tx.bridgeAddress) { + secondBridgeAddress = tx.bridgeAddress; + secondBridgeCalldata = await getERC20DefaultBridgeData( + transaction.token, + this._providerL1() + ); } else { - const refundRecipient = tx.refundRecipient ?? ethers.ZeroAddress; - const args: [ - Address, - Address, - BigNumberish, - BigNumberish, - BigNumberish, - Address, - ] = [ - to, - token, - amount, - tx.l2GasLimit, - tx.gasPerPubdataByte, - refundRecipient, - ]; + secondBridgeAddress = await ( + await this.getL1BridgeContracts() + ).shared.getAddress(); + secondBridgeCalldata = ethers.AbiCoder.defaultAbiCoder().encode( + ['address', 'uint256', 'address'], + [token, amount, to] + ); + } - overrides.value ??= baseCost + BigInt(operatorTip); - await checkBaseCost(baseCost, overrides.value); - overrides.from ??= await this.getAddress(); + return await bridgehub.requestL2TransactionTwoBridges.populateTransaction( + { + chainId, + mintValue, + l2Value: 0, + l2GasLimit, + l2GasPerPubdataByteLimit: gasPerPubdataByte, + refundRecipient: refundRecipient ?? ethers.ZeroAddress, + secondBridgeAddress, + secondBridgeValue: 0, + secondBridgeCalldata, + }, + overrides + ); + } - let l2WethToken = ethers.ZeroAddress; - try { - l2WethToken = await bridgeContracts.weth.l2TokenAddress(tx.token); - } catch (e) { - // skip - } + async _getDepositETHOnETHBasedChainTx(transaction: { + token: Address; + amount: BigNumberish; + to?: Address; + operatorTip?: BigNumberish; + bridgeAddress?: Address; + l2GasLimit?: BigNumberish; + gasPerPubdataByte?: BigNumberish; + customBridgeData?: BytesLike; + refundRecipient?: Address; + overrides?: ethers.Overrides; + }) { + // Call the BridgeHub directly, like it's done with the DiamondProxy. + const bridgehub = await this.getBridgehubContract(); + const chainId = (await this._providerL2().getNetwork()).chainId; + + const tx = await this._getDepositTxWithDefaults(transaction); + const { + operatorTip, + amount, + overrides, + l2GasLimit, + gasPerPubdataByte, + to, + } = tx; + + const gasPriceForEstimation = + overrides.maxFeePerGas || overrides.gasPrice; + const baseCost = await bridgehub.l2TransactionBaseCost( + chainId as BigNumberish, + gasPriceForEstimation as BigNumberish, + l2GasLimit, + gasPerPubdataByte + ); + + overrides.value ??= baseCost + BigInt(operatorTip) + BigInt(amount); + + return { + contractAddress: to, + calldata: '0x', + mintValue: overrides.value, + l2Value: amount, + ...tx, + }; + } + + // Creates a shallow copy of a transaction and populates missing fields with defaults. + async _getDepositTxWithDefaults(transaction: { + token: Address; + amount: BigNumberish; + to?: Address; + operatorTip?: BigNumberish; + bridgeAddress?: Address; + l2GasLimit?: BigNumberish; + gasPerPubdataByte?: BigNumberish; + customBridgeData?: BytesLike; + refundRecipient?: Address; + overrides?: ethers.Overrides; + }): Promise<{ + token: Address; + amount: BigNumberish; + to: Address; + operatorTip: BigNumberish; + bridgeAddress?: Address; + l2GasLimit: BigNumberish; + gasPerPubdataByte: BigNumberish; + customBridgeData?: BytesLike; + refundRecipient?: Address; + overrides: ethers.Overrides; + }> { + const {...tx} = transaction; + tx.to = tx.to ?? (await this.getAddress()); + tx.operatorTip ??= 0; + tx.overrides ??= {}; + tx.overrides.from = await this.getAddress(); + tx.gasPerPubdataByte ??= REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT; + tx.l2GasLimit ??= await this._getL2GasLimit(tx); + await insertGasPrice(this._providerL1(), tx.overrides); - const bridge = - l2WethToken !== ethers.ZeroAddress - ? bridgeContracts.weth - : bridgeContracts.erc20; + return tx as { + token: Address; + amount: BigNumberish; + to: Address; + operatorTip: BigNumberish; + bridgeAddress?: Address; + l2GasLimit: BigNumberish; + gasPerPubdataByte: BigNumberish; + customBridgeData?: BytesLike; + refundRecipient?: Address; + overrides: ethers.Overrides; + }; + } - return await bridge.deposit.populateTransaction(...args, overrides); + // Default behaviour for calculating l2GasLimit of deposit transaction. + async _getL2GasLimit(transaction: { + token: Address; + amount: BigNumberish; + to?: Address; + operatorTip?: BigNumberish; + bridgeAddress?: Address; + l2GasLimit?: BigNumberish; + gasPerPubdataByte?: BigNumberish; + customBridgeData?: BytesLike; + refundRecipient?: Address; + overrides?: ethers.Overrides; + }): Promise { + if (transaction.bridgeAddress) { + return await this._getL2GasLimitFromCustomBridge(transaction); + } else { + return await estimateDefaultBridgeDepositL2Gas( + this._providerL1(), + this._providerL2(), + transaction.token, + transaction.amount, + transaction.to!, + await this.getAddress(), + transaction.gasPerPubdataByte + ); } } + // Calculates the l2GasLimit of deposit transaction using custom bridge. + async _getL2GasLimitFromCustomBridge(transaction: { + token: Address; + amount: BigNumberish; + to?: Address; + operatorTip?: BigNumberish; + bridgeAddress?: Address; + l2GasLimit?: BigNumberish; + gasPerPubdataByte?: BigNumberish; + customBridgeData?: BytesLike; + refundRecipient?: Address; + overrides?: ethers.Overrides; + }): Promise { + const customBridgeData = + transaction.customBridgeData ?? + (await getERC20DefaultBridgeData( + transaction.token, + this._providerL1() + )); + const bridge = IL1Bridge__factory.connect( + transaction.bridgeAddress!, + this._signerL1() + ); + const chainId = (await this._providerL2().getNetwork()) + .chainId as BigNumberish; + const l2Address = await bridge.l2BridgeAddress(chainId); + return await estimateCustomBridgeDepositL2Gas( + this._providerL2(), + transaction.bridgeAddress!, + l2Address, + transaction.token, + transaction.amount, + transaction.to!, + customBridgeData, + await this.getAddress(), + transaction.gasPerPubdataByte + ); + } + /** * Retrieves the full needed ETH fee for the deposit. Returns the L1 fee and the L2 fee {@link FullDepositFee}. * @@ -561,93 +1230,79 @@ export function AdapterL1>(Base: TBase) { gasPerPubdataByte?: BigNumberish; overrides?: ethers.Overrides; }): Promise { + if (isAddressEq(transaction.token, LEGACY_ETH_ADDRESS)) { + transaction.token = ETH_ADDRESS_IN_CONTRACTS; + } // It is assumed that the L2 fee for the transaction does not depend on its value. const dummyAmount = 1n; + const bridgehub = await this.getBridgehubContract(); + const chainId = (await this._providerL2().getNetwork()).chainId; + const baseTokenAddress = await bridgehub.baseToken(chainId); + const isETHBasedChain = isAddressEq( + baseTokenAddress, + ETH_ADDRESS_IN_CONTRACTS + ); - const {...tx} = transaction; - const zksyncContract = await this.getMainContract(); + const tx = await this._getDepositTxWithDefaults({ + ...transaction, + amount: dummyAmount, + }); - tx.overrides ??= {}; - await insertGasPrice(this._providerL1(), tx.overrides); - const gasPriceForMessages = + const gasPriceForEstimation = tx.overrides.maxFeePerGas || tx.overrides.gasPrice; - - tx.to ??= await this.getAddress(); - tx.gasPerPubdataByte ??= REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT; - - let l2GasLimit: bigint; - if (tx.bridgeAddress) { - const bridgeContracts = await this.getL1BridgeContracts(); - const customBridgeData = - tx.customBridgeData ?? - (await bridgeContracts.weth.getAddress()) === tx.bridgeAddress - ? '0x' - : await getERC20DefaultBridgeData(tx.token, this._providerL1()); - const bridge = IL1Bridge__factory.connect( - tx.bridgeAddress, - this._signerL1() - ); - const l2Address = await bridge.l2Bridge(); - l2GasLimit = await estimateCustomBridgeDepositL2Gas( - this._providerL2(), - tx.bridgeAddress, - l2Address, - tx.token, - dummyAmount, - tx.to, - customBridgeData, - await this.getAddress(), - tx.gasPerPubdataByte - ); - } else { - l2GasLimit = await estimateDefaultBridgeDepositL2Gas( - this._providerL1(), - this._providerL2(), - tx.token, - dummyAmount, - tx.to, - await this.getAddress(), - tx.gasPerPubdataByte - ); - } - - const baseCost = await zksyncContract.l2TransactionBaseCost( - gasPriceForMessages!, - l2GasLimit, + const baseCost = await bridgehub.l2TransactionBaseCost( + chainId as BigNumberish, + gasPriceForEstimation as BigNumberish, + tx.l2GasLimit, tx.gasPerPubdataByte ); - const selfBalanceETH = await this.getBalanceL1(); - - // We could zero in, because the final fee will anyway be bigger than - if (baseCost >= selfBalanceETH + dummyAmount) { - const recommendedETHBalance = - BigInt( - tx.token === ETH_ADDRESS - ? L1_RECOMMENDED_MIN_ETH_DEPOSIT_GAS_LIMIT - : L1_RECOMMENDED_MIN_ERC20_DEPOSIT_GAS_LIMIT - ) * - BigInt(gasPriceForMessages!) + - baseCost; - const formattedRecommendedBalance = ethers.formatEther( - recommendedETHBalance - ); - throw new Error( - `Not enough balance for deposit! Under the provided gas price, the recommended balance to perform a deposit is ${formattedRecommendedBalance} ETH.` - ); - } - - // For ETH token the value that the user passes to the estimation is the one which has the - // value for the L2 commission subtracted. - let amountForEstimate: bigint; - if (isETH(tx.token)) { - amountForEstimate = dummyAmount; - } else { - amountForEstimate = dummyAmount; - - if ((await this.getAllowanceL1(tx.token)) < amountForEstimate) { + if (isETHBasedChain) { + // To ensure that L1 gas estimation succeeds when using estimateGasDeposit, + // the account needs to have a sufficient ETH balance. + const selfBalanceETH = await this.getBalanceL1(); + if (baseCost >= selfBalanceETH + dummyAmount) { + const recommendedL1GasLimit = isAddressEq( + tx.token, + LEGACY_ETH_ADDRESS + ) + ? L1_RECOMMENDED_MIN_ETH_DEPOSIT_GAS_LIMIT + : L1_RECOMMENDED_MIN_ERC20_DEPOSIT_GAS_LIMIT; + const recommendedETHBalance = + BigInt(recommendedL1GasLimit) * BigInt(gasPriceForEstimation!) + + baseCost; + const formattedRecommendedBalance = ethers.formatEther( + recommendedETHBalance + ); + throw new Error( + `Not enough balance for deposit! Under the provided gas price, the recommended balance to perform a deposit is ${formattedRecommendedBalance} ETH` + ); + } + // In case of token deposit, a sufficient token allowance is also required. + if ( + !isAddressEq(tx.token, ETH_ADDRESS_IN_CONTRACTS) && + (await this.getAllowanceL1(tx.token, tx.bridgeAddress)) < dummyAmount + ) { throw new Error('Not enough allowance to cover the deposit!'); } + } else { + const mintValue = baseCost + BigInt(tx.operatorTip); + if ((await this.getAllowanceL1(baseTokenAddress)) < mintValue) { + throw new Error( + 'Not enough base token allowance to cover the deposit!' + ); + } + if ( + isAddressEq(tx.token, ETH_ADDRESS_IN_CONTRACTS) || + isAddressEq(tx.token, baseTokenAddress) + ) { + tx.overrides.value ??= tx.amount; + } else { + tx.overrides.value ??= 0; + if ((await this.getAllowanceL1(tx.token)) < dummyAmount) { + throw new Error('Not enough token allowance to cover the deposit!'); + } + } } // Deleting the explicit gas limits in the fee estimation @@ -660,15 +1315,15 @@ export function AdapterL1>(Base: TBase) { const l1GasLimit = await this.estimateGasDeposit({ ...tx, - amount: amountForEstimate, + amount: dummyAmount, overrides: estimationOverrides, - l2GasLimit, + l2GasLimit: tx.l2GasLimit, }); const fullCost: FullDepositFee = { baseCost, l1GasLimit, - l2GasLimit, + l2GasLimit: BigInt(tx.l2GasLimit), }; if (tx.overrides.gasPrice) { @@ -683,12 +1338,24 @@ export function AdapterL1>(Base: TBase) { return fullCost; } + /** + * Returns the transaction confirmation data that is part of `L2->L1` message. + * + * @param txHash The hash of the L2 transaction where the message was initiated. + * @param [index=0] In case there were multiple transactions in one message, you may pass an index of the + * transaction which confirmation data should be fetched. + * @throws {Error} If log proof can not be found. + */ + async getPriorityOpConfirmation(txHash: string, index = 0) { + return this._providerL2().getPriorityOpConfirmation(txHash, index); + } + async _getWithdrawalLog(withdrawalHash: BytesLike, index = 0) { const hash = ethers.hexlify(withdrawalHash); const receipt = await this._providerL2().getTransactionReceipt(hash); const log = receipt.logs.filter( log => - log.address === L1_MESSENGER_ADDRESS && + isAddressEq(log.address, L1_MESSENGER_ADDRESS) && log.topics[0] === ethers.id('L1MessageSent(address,bytes32,bytes)') )[index]; @@ -702,7 +1369,7 @@ export function AdapterL1>(Base: TBase) { const hash = ethers.hexlify(withdrawalHash); const receipt = await this._providerL2().getTransactionReceipt(hash); const messages = Array.from(receipt.l2ToL1Logs.entries()).filter( - ([, log]) => log.sender === L1_MESSENGER_ADDRESS + ([, log]) => isAddressEq(log.sender, L1_MESSENGER_ADDRESS) ); const [l2ToL1LogIndex, l2ToL1Log] = messages[index]; @@ -770,60 +1437,18 @@ export function AdapterL1>(Base: TBase) { index = 0, overrides?: ethers.Overrides ): Promise { - const { - l1BatchNumber, - l2MessageIndex, - l2TxNumberInBlock, - message, - sender, - proof, - } = await this.finalizeWithdrawalParams(withdrawalHash, index); - - if (isETH(sender)) { - const withdrawTo = ethers.dataSlice(message, 4, 24); - const l1Bridges = await this.getL1BridgeContracts(); - // If the destination address matches the address of the L1 WETH contract, - // the withdrawal request is processed through the WETH bridge. - if ( - withdrawTo.toLowerCase() === - (await l1Bridges.weth.getAddress()).toLowerCase() - ) { - return await l1Bridges.weth.finalizeWithdrawal( - l1BatchNumber!, - l2MessageIndex, - l2TxNumberInBlock!, - message, - proof, - overrides ?? {} - ); - } + const {l1BatchNumber, l2MessageIndex, l2TxNumberInBlock, message, proof} = + await this.finalizeWithdrawalParams(withdrawalHash, index); - const contractAddress = - await this._providerL2().getMainContractAddress(); - const zksync = IZkSync__factory.connect( - contractAddress, - this._signerL1() - ); - - return await zksync.finalizeEthWithdrawal( - l1BatchNumber!, - l2MessageIndex!, - l2TxNumberInBlock!, - message, - proof, - overrides ?? {} - ); - } - - const l2Bridge = IL2Bridge__factory.connect(sender, this._providerL2()); - const l1Bridge = IL1Bridge__factory.connect( - await l2Bridge.l1Bridge(), + const l1SharedBridge = IL1SharedBridge__factory.connect( + await (await this.getL1BridgeContracts()).shared.getAddress(), this._signerL1() ); - return await l1Bridge.finalizeWithdrawal( - l1BatchNumber!, - l2MessageIndex!, - l2TxNumberInBlock!, + return await l1SharedBridge.finalizeWithdrawal( + (await this._providerL2().getNetwork()).chainId as BigNumberish, + l1BatchNumber as BigNumberish, + l2MessageIndex as BigNumberish, + l2TxNumberInBlock as BigNumberish, message, proof, overrides ?? {} @@ -859,27 +1484,25 @@ export function AdapterL1>(Base: TBase) { throw new Error('Log proof not found!'); } - if (isETH(sender)) { - const contractAddress = - await this._providerL2().getMainContractAddress(); - const zksync = IZkSync__factory.connect( - contractAddress, - this._signerL1() - ); + const chainId = (await this._providerL2().getNetwork()).chainId; + + let l1Bridge: IL1SharedBridge; - return await zksync.isEthWithdrawalFinalized( - log.l1BatchNumber!, - proof.id + if (await this._providerL2().isBaseToken(sender)) { + l1Bridge = (await this.getL1BridgeContracts()).shared; + } else { + const l2Bridge = IL2Bridge__factory.connect(sender, this._providerL2()); + l1Bridge = IL1SharedBridge__factory.connect( + await l2Bridge.l1Bridge(), + this._providerL1() ); } - const l2Bridge = IL2Bridge__factory.connect(sender, this._providerL2()); - const l1Bridge = IL1Bridge__factory.connect( - await l2Bridge.l1Bridge(), - this._providerL1() + return await l1Bridge.isWithdrawalFinalized( + chainId, + log.l1BatchNumber!, + proof.id ); - - return await l1Bridge.isWithdrawalFinalized(log.l1BatchNumber!, proof.id); } /** @@ -901,7 +1524,7 @@ export function AdapterL1>(Base: TBase) { ); const successL2ToL1LogIndex = receipt.l2ToL1Logs.findIndex( l2ToL1log => - l2ToL1log.sender === BOOTLOADER_FORMAL_ADDRESS && + isAddressEq(l2ToL1log.sender, BOOTLOADER_FORMAL_ADDRESS) && l2ToL1log.key === depositHash ); const successL2ToL1Log = receipt.l2ToL1Logs[successL2ToL1LogIndex]; @@ -920,7 +1543,7 @@ export function AdapterL1>(Base: TBase) { throw new Error('L2 bridge address not found!'); } - const l1Bridge = IL1Bridge__factory.connect( + const l1Bridge = IL1SharedBridge__factory.connect( l1BridgeAddress, this._signerL1() ); @@ -942,8 +1565,10 @@ export function AdapterL1>(Base: TBase) { throw new Error('Log proof not found!'); } return await l1Bridge.claimFailedDeposit( + (await this._providerL2().getNetwork()).chainId as BigNumberish, calldata['_l1Sender'], calldata['_l1Token'], + calldata['_amount'], depositHash, receipt.l1BatchNumber!, proof.id, @@ -960,6 +1585,7 @@ export function AdapterL1>(Base: TBase) { * @param transaction.contractAddress The L2 contract to be called. * @param transaction.calldata The input of the L2 transaction. * @param [transaction.l2GasLimit] Maximum amount of L2 gas that transaction can consume during execution on L2. + * @param [transaction.mintValue] The amount of base token that needs to be minted on non-ETH-based L2. * @param [transaction.l2Value] `msg.value` of L2 transaction. * @param [transaction.factoryDeps] An array of L2 bytecodes that will be marked as known on L2. * @param [transaction.operatorTip] (currently not used) If the ETH value passed with the transaction is not @@ -975,6 +1601,7 @@ export function AdapterL1>(Base: TBase) { contractAddress: Address; calldata: string; l2GasLimit?: BigNumberish; + mintValue?: BigNumberish; l2Value?: BigNumberish; factoryDeps?: ethers.BytesLike[]; operatorTip?: BigNumberish; @@ -995,6 +1622,7 @@ export function AdapterL1>(Base: TBase) { * @param transaction.contractAddress The L2 contract to be called. * @param transaction.calldata The input of the L2 transaction. * @param [transaction.l2GasLimit] Maximum amount of L2 gas that transaction can consume during execution on L2. + * @param [transaction.mintValue] The amount of base token that needs to be minted on non-ETH-based L2. * @param [transaction.l2Value] `msg.value` of L2 transaction. * @param [transaction.factoryDeps] An array of L2 bytecodes that will be marked as known on L2. * @param [transaction.operatorTip] (currently not used) If the ETH value passed with the transaction is not @@ -1009,6 +1637,7 @@ export function AdapterL1>(Base: TBase) { contractAddress: Address; calldata: string; l2GasLimit?: BigNumberish; + mintValue?: BigNumberish; l2Value?: BigNumberish; factoryDeps?: ethers.BytesLike[]; operatorTip?: BigNumberish; @@ -1025,6 +1654,65 @@ export function AdapterL1>(Base: TBase) { return this._providerL1().estimateGas(requestExecuteTx); } + /** + * Returns the parameters for the approval token transaction based on the request execute transaction. + * Existing allowance for the bridge is not checked; allowance is calculated solely based on the specified transaction. + * + * @param transaction The request execute transaction on which approval parameters are calculated. + */ + async getRequestExecuteAllowanceParams(transaction: { + contractAddress: Address; + calldata: string; + l2GasLimit?: BigNumberish; + l2Value?: BigNumberish; + factoryDeps?: ethers.BytesLike[]; + operatorTip?: BigNumberish; + gasPerPubdataByte?: BigNumberish; + refundRecipient?: Address; + overrides?: ethers.Overrides; + }): Promise<{token: Address; allowance: BigNumberish}> { + const bridgehub = await this.getBridgehubContract(); + const chainId = (await this._providerL2().getNetwork()).chainId; + const isETHBaseToken = isAddressEq( + await bridgehub.baseToken(chainId), + ETH_ADDRESS_IN_CONTRACTS + ); + + if (isETHBaseToken) { + throw new Error( + "ETH token can't be approved! The address of the token does not exist on L1." + ); + } + + const {...tx} = transaction; + tx.l2Value ??= 0n; + tx.operatorTip ??= 0n; + tx.factoryDeps ??= []; + tx.overrides ??= {}; + tx.gasPerPubdataByte ??= REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT; + tx.refundRecipient ??= await this.getAddress(); + tx.l2GasLimit ??= + await this._providerL2().estimateL1ToL2Execute(transaction); + + const {l2Value, l2GasLimit, operatorTip, overrides, gasPerPubdataByte} = + tx; + + await insertGasPrice(this._providerL1(), overrides); + const gasPriceForEstimation = + overrides.maxFeePerGas || overrides.gasPrice; + + const baseCost = await this.getBaseCost({ + gasPrice: gasPriceForEstimation!, + gasPerPubdataByte, + gasLimit: l2GasLimit, + }); + + return { + token: await this.getBaseToken(), + allowance: baseCost + BigInt(operatorTip) + BigInt(l2Value), + }; + } + /** * Returns a populated request execute transaction. * @@ -1032,6 +1720,7 @@ export function AdapterL1>(Base: TBase) { * @param transaction.contractAddress The L2 contract to be called. * @param transaction.calldata The input of the L2 transaction. * @param [transaction.l2GasLimit] Maximum amount of L2 gas that transaction can consume during execution on L2. + * @param [transaction.mintValue] The amount of base token that needs to be minted on non-ETH-based L2. * @param [transaction.l2Value] `msg.value` of L2 transaction. * @param [transaction.factoryDeps] An array of L2 bytecodes that will be marked as known on L2. * @param [transaction.operatorTip] (currently not used) If the ETH value passed with the transaction is not @@ -1046,6 +1735,7 @@ export function AdapterL1>(Base: TBase) { contractAddress: Address; calldata: string; l2GasLimit?: BigNumberish; + mintValue?: BigNumberish; l2Value?: BigNumberish; factoryDeps?: ethers.BytesLike[]; operatorTip?: BigNumberish; @@ -1053,10 +1743,16 @@ export function AdapterL1>(Base: TBase) { refundRecipient?: Address; overrides?: ethers.Overrides; }): Promise { - const zksyncContract = await this.getMainContract(); + const bridgehub = await this.getBridgehubContract(); + const chainId = (await this._providerL2().getNetwork()).chainId; + const isETHBaseToken = isAddressEq( + await bridgehub.baseToken(chainId), + ETH_ADDRESS_IN_CONTRACTS + ); const {...tx} = transaction; tx.l2Value ??= 0; + tx.mintValue ??= 0; tx.operatorTip ??= 0; tx.factoryDeps ??= []; tx.overrides ??= {}; @@ -1068,6 +1764,7 @@ export function AdapterL1>(Base: TBase) { const { contractAddress, + mintValue, l2Value, calldata, l2GasLimit, @@ -1088,18 +1785,30 @@ export function AdapterL1>(Base: TBase) { gasLimit: l2GasLimit, }); - overrides.value ??= baseCost + BigInt(operatorTip) + BigInt(l2Value); - - await checkBaseCost(baseCost, overrides.value); + const l2Costs = baseCost + BigInt(operatorTip) + BigInt(l2Value); + let providedValue = isETHBaseToken ? overrides.value : mintValue; + if ( + providedValue === undefined || + providedValue === null || + BigInt(providedValue) === 0n + ) { + providedValue = l2Costs; + if (isETHBaseToken) overrides.value = providedValue; + } + await checkBaseCost(baseCost, providedValue); - return await zksyncContract.requestL2Transaction.populateTransaction( - contractAddress, - l2Value, - calldata, - l2GasLimit, - REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT, - factoryDeps, - refundRecipient, + return await bridgehub.requestL2TransactionDirect.populateTransaction( + { + chainId, + mintValue: providedValue, + l2Contract: contractAddress, + l2Value: l2Value, + l2Calldata: calldata, + l2GasLimit: l2GasLimit, + l2GasPerPubdataByteLimit: REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT, + factoryDeps: factoryDeps, + refundRecipient: refundRecipient, + }, overrides ); } @@ -1161,11 +1870,19 @@ export function AdapterL2>(Base: TBase) { /** * Returns L2 bridge contracts. */ - async getL2BridgeContracts(): Promise<{erc20: IL2Bridge; weth: IL2Bridge}> { + async getL2BridgeContracts(): Promise<{ + erc20: IL2Bridge; + weth: IL2Bridge; + shared: IL2Bridge; + }> { const addresses = await this._providerL2().getDefaultBridgeAddresses(); return { - erc20: IL2Bridge__factory.connect(addresses.erc20L2!, this._signerL2()), - weth: IL2Bridge__factory.connect(addresses.wethL2!, this._signerL2()), + erc20: IL2Bridge__factory.connect(addresses.erc20L2, this._signerL2()), + weth: IL2Bridge__factory.connect(addresses.wethL2, this._signerL2()), + shared: IL2Bridge__factory.connect( + addresses.sharedL2, + this._signerL2() + ), }; } diff --git a/src/provider.ts b/src/provider.ts index 44843c19..10447543 100644 --- a/src/provider.ts +++ b/src/provider.ts @@ -48,11 +48,14 @@ import { getL2HashFromPriorityOp, CONTRACT_DEPLOYER_ADDRESS, CONTRACT_DEPLOYER, - ETH_ADDRESS, sleep, - L2_ETH_TOKEN_ADDRESS, EIP712_TX_TYPE, REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT, + BOOTLOADER_FORMAL_ADDRESS, + ETH_ADDRESS_IN_CONTRACTS, + L2_BASE_TOKEN_ADDRESS, + LEGACY_ETH_ADDRESS, + isAddressEq, } from './utils'; import {Signer} from './signer'; @@ -86,11 +89,15 @@ export function JsonRpcApiProvider< * Returns the addresses of the main contract and default zkSync Era bridge contracts on both L1 and L2. */ contractAddresses(): { + bridgehubContract?: Address; mainContract?: Address; erc20BridgeL1?: Address; erc20BridgeL2?: Address; wethBridgeL1?: Address; wethBridgeL2?: Address; + sharedBridgeL1?: Address; + sharedBridgeL2?: Address; + baseToken?: Address; } { throw new Error('Must be implemented by the derived class!'); } @@ -194,7 +201,7 @@ export function JsonRpcApiProvider< blockTag?: BlockTag, tokenAddress?: Address ): Promise { - if (!tokenAddress || isETH(tokenAddress)) { + if (!tokenAddress || (await this.isBaseToken(tokenAddress))) { return await super.getBalance(address, blockTag); } else { try { @@ -215,29 +222,21 @@ export function JsonRpcApiProvider< * @param token The address of the token on L1. */ async l2TokenAddress(token: Address): Promise { - if (token === ETH_ADDRESS) { - return ETH_ADDRESS; - } else { - const bridgeAddresses = await this.getDefaultBridgeAddresses(); - const l2WethBridge = IL2Bridge__factory.connect( - bridgeAddresses.wethL2!, - this - ); - try { - const l2WethToken = await l2WethBridge.l2TokenAddress(token); - if (l2WethToken !== ethers.ZeroAddress) { - return l2WethToken; - } - } catch (e) { - // skip - } + if (isAddressEq(token, LEGACY_ETH_ADDRESS)) { + token = ETH_ADDRESS_IN_CONTRACTS; + } - const erc20Bridge = IL2Bridge__factory.connect( - bridgeAddresses.erc20L2!, - this - ); - return await erc20Bridge.l2TokenAddress(token); + const baseToken = await this.getBaseTokenContractAddress(); + if (isAddressEq(token, baseToken)) { + return L2_BASE_TOKEN_ADDRESS; } + + const bridgeAddresses = await this.getDefaultBridgeAddresses(); + const l2SharedBridge = IL2Bridge__factory.connect( + bridgeAddresses.sharedL2, + this + ); + return await l2SharedBridge.l2TokenAddress(token); } /** @@ -249,28 +248,17 @@ export function JsonRpcApiProvider< * @param token The address of the token on L2. */ async l1TokenAddress(token: Address): Promise { - if (token === ETH_ADDRESS) { - return ETH_ADDRESS; - } else { - const bridgeAddresses = await this.getDefaultBridgeAddresses(); - const l2WethBridge = IL2Bridge__factory.connect( - bridgeAddresses.wethL2!, - this - ); - try { - const l1WethToken = await l2WethBridge.l1TokenAddress(token); - if (l1WethToken !== ethers.ZeroAddress) { - return l1WethToken; - } - } catch (e) { - // skip - } - const erc20Bridge = IL2Bridge__factory.connect( - bridgeAddresses.erc20L2!, - this - ); - return await erc20Bridge.l1TokenAddress(token); + if (isAddressEq(token, LEGACY_ETH_ADDRESS)) { + return LEGACY_ETH_ADDRESS; } + + const bridgeAddresses = await this.getDefaultBridgeAddresses(); + + const sharedBridge = IL2Bridge__factory.connect( + bridgeAddresses.sharedL2, + this + ); + return await sharedBridge.l1TokenAddress(token); } /** @@ -340,6 +328,21 @@ export function JsonRpcApiProvider< return [parseInt(range[0], 16), parseInt(range[1], 16)]; } + /** + * Returns the Bridgehub smart contract address. + * + * Calls the {@link https://docs.zksync.io/build/api.html#zks-getbridgehubcontract zks_getBridgehubContract} JSON-RPC method. + */ + async getBridgehubContractAddress(): Promise
{ + if (!this.contractAddresses().bridgehubContract) { + this.contractAddresses().bridgehubContract = await this.send( + 'zks_getBridgehubContract', + [] + ); + } + return this.contractAddresses().bridgehubContract!; + } + /** * Returns the main zkSync Era smart contract address. * @@ -355,6 +358,39 @@ export function JsonRpcApiProvider< return this.contractAddresses().mainContract!; } + /** + * Returns the L1 base token address. + */ + async getBaseTokenContractAddress(): Promise
{ + if (!this.contractAddresses().baseToken) { + this.contractAddresses().baseToken = await this.send( + 'zks_getBaseTokenL1Address', + [] + ); + } + return ethers.getAddress(this.contractAddresses().baseToken!); + } + + /** + * Returns whether the chain is ETH-based. + */ + async isEthBasedChain(): Promise { + return isAddressEq( + await this.getBaseTokenContractAddress(), + ETH_ADDRESS_IN_CONTRACTS + ); + } + + /** + * Returns whether the `token` is the base token. + */ + async isBaseToken(token: Address): Promise { + return ( + isAddressEq(token, await this.getBaseTokenContractAddress()) || + isAddressEq(token, L2_BASE_TOKEN_ADDRESS) + ); + } + /** * Returns the testnet {@link https://docs.zksync.io/build/developer-reference/account-abstraction.html#paymasters paymaster address} * if available, or `null`. @@ -373,10 +409,12 @@ export function JsonRpcApiProvider< * Calls the {@link https://docs.zksync.io/build/api.html#zks-getbridgecontracts zks_getBridgeContracts} JSON-RPC method. */ async getDefaultBridgeAddresses(): Promise<{ - erc20L1: string | undefined; - erc20L2: string | undefined; - wethL1: string | undefined; - wethL2: string | undefined; + erc20L1: string; + erc20L2: string; + wethL1: string; + wethL2: string; + sharedL1: string; + sharedL2: string; }> { if (!this.contractAddresses().erc20BridgeL1) { const addresses: { @@ -384,17 +422,26 @@ export function JsonRpcApiProvider< l2Erc20DefaultBridge: string; l1WethBridge: string; l2WethBridge: string; + l1SharedDefaultBridge: string; + l2SharedDefaultBridge: string; } = await this.send('zks_getBridgeContracts', []); + this.contractAddresses().erc20BridgeL1 = addresses.l1Erc20DefaultBridge; this.contractAddresses().erc20BridgeL2 = addresses.l2Erc20DefaultBridge; this.contractAddresses().wethBridgeL1 = addresses.l1WethBridge; this.contractAddresses().wethBridgeL2 = addresses.l2WethBridge; + this.contractAddresses().sharedBridgeL1 = + addresses.l1SharedDefaultBridge; + this.contractAddresses().sharedBridgeL2 = + addresses.l2SharedDefaultBridge; } return { - erc20L1: this.contractAddresses().erc20BridgeL1, - erc20L2: this.contractAddresses().erc20BridgeL2, - wethL1: this.contractAddresses().wethBridgeL1, - wethL2: this.contractAddresses().wethBridgeL2, + erc20L1: this.contractAddresses().erc20BridgeL1!, + erc20L2: this.contractAddresses().erc20BridgeL2!, + wethL1: this.contractAddresses().wethBridgeL1!, + wethL2: this.contractAddresses().wethBridgeL2!, + sharedL1: this.contractAddresses().sharedBridgeL1!, + sharedL2: this.contractAddresses().sharedBridgeL2!, }; } @@ -532,6 +579,9 @@ export function JsonRpcApiProvider< overrides?: ethers.Overrides; }): Promise { const {...tx} = transaction; + if (isAddressEq(tx.token, LEGACY_ETH_ADDRESS)) { + tx.token = ETH_ADDRESS_IN_CONTRACTS; + } if ( (tx.to === null || tx.to === undefined) && @@ -558,7 +608,7 @@ export function JsonRpcApiProvider< } const ethL2Token = IEthToken__factory.connect( - L2_ETH_TOKEN_ADDRESS, + L2_BASE_TOKEN_ADDRESS, this ); const populatedTx = await ethL2Token.withdraw.populateTransaction( @@ -578,20 +628,7 @@ export function JsonRpcApiProvider< if (!tx.bridgeAddress) { const bridgeAddresses = await this.getDefaultBridgeAddresses(); - const l2WethBridge = IL2Bridge__factory.connect( - bridgeAddresses.wethL2!, - this - ); - let l1WethToken = ethers.ZeroAddress; - try { - l1WethToken = await l2WethBridge.l1TokenAddress(tx.token); - } catch (e) { - // skip - } - tx.bridgeAddress = - l1WethToken !== ethers.ZeroAddress - ? bridgeAddresses.wethL2 - : bridgeAddresses.erc20L2; + tx.bridgeAddress = bridgeAddresses.sharedL2; } const bridge = IL2Bridge__factory.connect(tx.bridgeAddress!, this); @@ -659,7 +696,11 @@ export function JsonRpcApiProvider< tx.overrides ??= {}; tx.overrides.from ??= tx.from; - if (!tx.token || tx.token === ETH_ADDRESS) { + if ( + !tx.token || + isAddressEq(tx.token, LEGACY_ETH_ADDRESS) || + (await this.isBaseToken(tx.token)) + ) { if (tx.paymasterParams) { return { ...tx.overrides, @@ -860,6 +901,41 @@ export function JsonRpcApiProvider< return l2Response; } + async _getPriorityOpConfirmationL2ToL1Log(txHash: string, index = 0) { + const hash = ethers.hexlify(txHash); + const receipt = await this.getTransactionReceipt(hash); + const messages = Array.from(receipt.l2ToL1Logs.entries()).filter( + ([, log]) => isAddressEq(log.sender, BOOTLOADER_FORMAL_ADDRESS) + ); + const [l2ToL1LogIndex, l2ToL1Log] = messages[index]; + + return { + l2ToL1LogIndex, + l2ToL1Log, + l1BatchTxId: receipt.l1BatchTxIndex, + }; + } + + /** + * Returns the transaction confirmation data that is part of `L2->L1` message. + * + * @param txHash The hash of the L2 transaction where the message was initiated. + * @param [index=0] In case there were multiple transactions in one message, you may pass an index of the + * transaction which confirmation data should be fetched. + * @throws {Error} If log proof can not be found. + */ + async getPriorityOpConfirmation(txHash: string, index = 0) { + const {l2ToL1LogIndex, l2ToL1Log, l1BatchTxId} = + await this._getPriorityOpConfirmationL2ToL1Log(txHash, index); + const proof = await this.getLogProof(txHash, l2ToL1LogIndex); + return { + l1BatchNumber: l2ToL1Log.l1BatchNumber, + l2MessageIndex: proof!.id, + l2TxNumberInBlock: l1BatchTxId, + proof: proof!.proof, + }; + } + /** * Returns the version of the supported account abstraction and nonce ordering from a given contract address. * @@ -1246,6 +1322,60 @@ export class Provider extends JsonRpcApiProvider(ethers.JsonRpcProvider) { return super.getMainContractAddress(); } + /** + * @inheritDoc + * + * @example + * + * import { Provider, types } from "zksync-ethers"; + * + * const provider = Provider.getDefaultProvider(types.Network.Sepolia); + * console.log(`Bridgehub: ${await provider.getBridgehubContractAddress()}`); + */ + override async getBridgehubContractAddress(): Promise
{ + return super.getBridgehubContractAddress(); + } + + /** + * @inheritDoc + * + * @example + * + * import { Provider, types } from "zksync-ethers"; + * + * const provider = Provider.getDefaultProvider(types.Network.Sepolia); + * console.log(`Base token: ${await provider.getBaseTokenContractAddress()}`); + */ + override async getBaseTokenContractAddress(): Promise
{ + return super.getBaseTokenContractAddress(); + } + + /** + * @inheritDoc + * + * import { Provider, types } from "zksync-ethers"; + * + * const provider = Provider.getDefaultProvider(types.Network.Sepolia); + * console.log(`Is ETH based chain: ${await provider.isEthBasedChain()}`); + */ + override async isEthBasedChain(): Promise { + return super.isEthBasedChain(); + } + + /** + * @inheritDoc + * + * @example + * + * import { Provider, types } from "zksync-ethers"; + * + * const provider = Provider.getDefaultProvider(types.Network.Sepolia); + * console.log(`Is base token: ${await provider.isBaseToken("0x5C221E77624690fff6dd741493D735a17716c26B")}`); + */ + override async isBaseToken(token: Address): Promise { + return super.isBaseToken(token); + } + /** * @inheritDoc * @@ -1271,10 +1401,12 @@ export class Provider extends JsonRpcApiProvider(ethers.JsonRpcProvider) { * console.log(`Default bridges: ${utils.toJSON(await provider.getDefaultBridgeAddresses())}`); */ override async getDefaultBridgeAddresses(): Promise<{ - erc20L1: string | undefined; - erc20L2: string | undefined; - wethL1: string | undefined; - wethL2: string | undefined; + erc20L1: string; + erc20L2: string; + wethL1: string; + wethL2: string; + sharedL1: string; + sharedL2: string; }> { return super.getDefaultBridgeAddresses(); } @@ -1731,6 +1863,31 @@ export class Provider extends JsonRpcApiProvider(ethers.JsonRpcProvider) { return super.getPriorityOpResponse(l1TxResponse); } + /** + * @inheritDoc + * + * @example + * + * import { Provider, types, utils } from "zksync-ethers"; + * + * const provider = Provider.getDefaultProvider(types.Network.Sepolia); + * // Any L2 -> L1 transaction can be used. + * // In this case, withdrawal transaction is used. + * const tx = "0x2a1c6c74b184965c0cb015aae9ea134fd96215d2e4f4979cfec12563295f610e"; + * console.log(`Confirmation data: ${utils.toJSON(await provider.getPriorityOpConfirmation(tx, 0))}`); + */ + override async getPriorityOpConfirmation( + txHash: string, + index = 0 + ): Promise<{ + l1BatchNumber: number; + l2MessageIndex: number; + l2TxNumberInBlock: number | null; + proof: string[]; + }> { + return super.getPriorityOpConfirmation(txHash, index); + } + /** * @inheritDoc * @@ -1799,6 +1956,8 @@ export class Provider extends JsonRpcApiProvider(ethers.JsonRpcProvider) { * * @param zksyncNetwork The type of zkSync network. * + * @example + * * import { Provider, types } from "zksync-ethers"; * * const provider = Provider.getDefaultProvider(types.Network.Sepolia); @@ -2117,6 +2276,60 @@ export class BrowserProvider extends JsonRpcApiProvider( return super.getMainContractAddress(); } + /** + * @inheritDoc + * + * @example + * + * import { BrowserProvider } from "zksync-ethers"; + * + * const provider = new BrowserProvider(window.ethereum); + * console.log(`Bridgehub: ${await provider.getBridgehubContractAddress()}`); + */ + override async getBridgehubContractAddress(): Promise
{ + return super.getBridgehubContractAddress(); + } + + /** + * @inheritDoc + * + * @example + * + * import { BrowserProvider } from "zksync-ethers"; + * + * const provider = new BrowserProvider(window.ethereum); + * console.log(`Base token: ${await provider.getBaseTokenContractAddress()}`); + */ + override async getBaseTokenContractAddress(): Promise
{ + return super.getBaseTokenContractAddress(); + } + + /** + * @inheritDoc + * + * import { BrowserProvider } from "zksync-ethers"; + * + * const provider = new BrowserProvider(window.ethereum); + * console.log(`Is ETH based chain: ${await provider.isEthBasedChain()}`); + */ + override async isEthBasedChain(): Promise { + return super.isEthBasedChain(); + } + + /** + * @inheritDoc + * + * @example + * + * import { BrowserProvider } from "zksync-ethers"; + * + * const provider = new BrowserProvider(window.ethereum); + * console.log(`Is base token: ${await provider.isBaseToken("0x5C221E77624690fff6dd741493D735a17716c26B")}`); + */ + override async isBaseToken(token: Address): Promise { + return super.isBaseToken(token); + } + /** * @inheritDoc * @@ -2142,10 +2355,12 @@ export class BrowserProvider extends JsonRpcApiProvider( * console.log(`Default bridges: ${utils.toJSON(await provider.getDefaultBridgeAddresses())}`); */ override async getDefaultBridgeAddresses(): Promise<{ - erc20L1: string | undefined; - erc20L2: string | undefined; - wethL1: string | undefined; - wethL2: string | undefined; + erc20L1: string; + erc20L2: string; + wethL1: string; + wethL2: string; + sharedL1: string; + sharedL2: string; }> { return super.getDefaultBridgeAddresses(); } @@ -2602,6 +2817,30 @@ export class BrowserProvider extends JsonRpcApiProvider( return super.getPriorityOpResponse(l1TxResponse); } + /** + * + * @example + * + * import { BrowserProvider, utils } from "zksync-ethers"; + * + * const provider = new BrowserProvider(window.ethereum); + * // Any L2 -> L1 transaction can be used. + * // In this case, withdrawal transaction is used. + * const tx = "0x2a1c6c74b184965c0cb015aae9ea134fd96215d2e4f4979cfec12563295f610e"; + * console.log(`Confirmation data: ${utils.toJSON(await provider.getPriorityOpConfirmation(tx, 0))}`); + */ + override async getPriorityOpConfirmation( + txHash: string, + index = 0 + ): Promise<{ + l1BatchNumber: number; + l2MessageIndex: number; + l2TxNumberInBlock: number | null; + proof: string[]; + }> { + return super.getPriorityOpConfirmation(txHash, index); + } + /** * @inheritDoc * @@ -2708,9 +2947,9 @@ export class BrowserProvider extends JsonRpcApiProvider( return accounts.length > address; } - address = address.toLowerCase(); return ( - accounts.filter((a: string) => a.toLowerCase() === address).length !== 0 + accounts.filter((a: string) => isAddressEq(a, address as string)) + .length !== 0 ); } diff --git a/src/signer.ts b/src/signer.ts index e4cde360..6545ed1f 100644 --- a/src/signer.ts +++ b/src/signer.ts @@ -11,6 +11,7 @@ import { DEFAULT_GAS_PER_PUBDATA_LIMIT, EIP712_TX_TYPE, hashBytecode, + isAddressEq, serializeEip712, } from './utils'; import { @@ -26,7 +27,13 @@ import { TransactionResponse, } from './types'; import {AdapterL1, AdapterL2} from './adapters'; -import {IL1Bridge, IL2Bridge, IZkSync} from './typechain'; +import { + IBridgehub, + IL1ERC20Bridge, + IL1SharedBridge, + IL2Bridge, + IZkSyncStateTransition, +} from './typechain'; /** * All typed data conforming to the EIP712 standard within zkSync Era. @@ -177,7 +184,7 @@ export class Signer extends AdapterL2(ethers.JsonRpcSigner) { } override _providerL2() { - // Make it compatible when singer is created with Web3Provider.getSigner() + // Make it compatible when singer is created with BrowserProvider.getSigner() return this.providerL2 ? this.providerL2 : this.provider; } @@ -278,6 +285,7 @@ export class Signer extends AdapterL2(ethers.JsonRpcSigner) { override async getL2BridgeContracts(): Promise<{ erc20: IL2Bridge; weth: IL2Bridge; + shared: IL2Bridge; }> { return super.getL2BridgeContracts(); } @@ -285,7 +293,7 @@ export class Signer extends AdapterL2(ethers.JsonRpcSigner) { /** * @inheritDoc * - * @example Withdraw ETH. + * @example Withdraw token. * * import { BrowserProvider, Provider, types, utils } from "zksync-ethers"; * import { ethers } from "ethers"; @@ -589,7 +597,7 @@ export class Signer extends AdapterL2(ethers.JsonRpcSigner) { const from = !transaction.from ? address : await ethers.resolveAddress(transaction.from); - if (from.toLowerCase() !== address.toLowerCase()) { + if (!isAddressEq(from, address)) { throw new Error('Transaction `from` address mismatch!'); } const tx: TransactionLike = { @@ -651,12 +659,31 @@ export class L1Signer extends AdapterL1(ethers.JsonRpcSigner) { * ); * * const mainContract = await signer.getMainContract(); - * console.log(mainContract.address); */ - override async getMainContract(): Promise { + override async getMainContract(): Promise { return super.getMainContract(); } + /** + * @inheritDoc + * + * @example + * + * import { Provider, L1Signer, types } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const browserProvider = new ethers.BrowserProvider(window.ethereum); + * const signer = L1Signer.from( + * await browserProvider.getSigner(), + * Provider.getDefaultProvider(types.Network.Sepolia) + * ); + * + * const bridgehub = await signer.getBridgehubContract(); + */ + override async getBridgehubContract(): Promise { + return super.getBridgehubContract(); + } + /** * @inheritDoc * @@ -674,8 +701,9 @@ export class L1Signer extends AdapterL1(ethers.JsonRpcSigner) { * const l1BridgeContracts = await signer.getL1BridgeContracts(); */ override async getL1BridgeContracts(): Promise<{ - erc20: IL1Bridge; - weth: IL1Bridge; + erc20: IL1ERC20Bridge; + weth: IL1ERC20Bridge; + shared: IL1SharedBridge; }> { return super.getL1BridgeContracts(); } @@ -819,7 +847,133 @@ export class L1Signer extends AdapterL1(ethers.JsonRpcSigner) { /** * @inheritDoc * - * @example Deposit ETH. + * @example + * + * import { Provider, L1Signer, types } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const browserProvider = new ethers.BrowserProvider(window.ethereum); + * const signer = L1Signer.from( + * await browserProvider.getSigner(), + * Provider.getDefaultProvider(types.Network.Sepolia) + * ); + * + * console.log(`Base token: ${await signer.getBaseToken()}`); + */ + override async getBaseToken(): Promise { + return super.getBaseToken(); + } + + /** + * @inheritDoc + * + * @example + * + * import { Provider, L1Signer, types } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const browserProvider = new ethers.BrowserProvider(window.ethereum); + * const signer = L1Signer.from( + * await browserProvider.getSigner(), + * Provider.getDefaultProvider(types.Network.Sepolia) + * ); + * + * console.log(`Is ETH-based chain: ${await signer.isETHBasedChain()}`); + */ + override async isETHBasedChain(): Promise { + return super.isETHBasedChain(); + } + + /** + * @inheritDoc + * + * @example Get allowance parameters for depositing ETH on non-ETH-based chain. + * + * import { Provider, L1Signer, types } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const browserProvider = new ethers.BrowserProvider(window.ethereum); + * const signer = L1Signer.from( + * await browserProvider.getSigner(), + * Provider.getDefaultProvider(types.Network.Sepolia) + * ); + * + * const token = utils.LEGACY_ETH_ADDRESS; + * const amount = 5; + * const approveParams = await signer.getDepositAllowanceParams(token, amount); + * await ( + * await signer.approveERC20( + * approveParams[0].token, + * approveParams[0].allowance + * ) + * ).wait(); + * + * @example Get allowance parameters for depositing base token on non-ETH-based chain. + * + * import { Provider, L1Signer, types } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const browserProvider = new ethers.BrowserProvider(window.ethereum); + * const signer = L1Signer.from( + * await browserProvider.getSigner(), + * Provider.getDefaultProvider(types.Network.Sepolia) + * ); + * + * const token = await signer.getBaseToken(); + * const amount = 5; + * const approveParams = await signer.getDepositAllowanceParams(token, amount); + * await ( + * await signer.approveERC20( + * approveParams[0].token, + * approveParams[0].allowance + * ) + * ).wait(); + * + * @example Get allowance parameters for depositing non-base token on non-ETH-based chain. + * + * import { Provider, L1Signer, types } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const browserProvider = new ethers.BrowserProvider(window.ethereum); + * const signer = L1Signer.from( + * await browserProvider.getSigner(), + * Provider.getDefaultProvider(types.Network.Sepolia) + * ); + * + * const token = ""; + * const amount = 5; + * const approveParams = await signer.getDepositAllowanceParams(token, amount); + * + * await ( + * await signer.approveERC20( + * approveParams[0].token, + * approveParams[0].allowance + * ) + * ).wait(); + * + * await ( + * await signer.approveERC20( + * approveParams[1].token, + * approveParams[1].allowance + * ) + * ).wait(); + */ + override async getDepositAllowanceParams( + token: Address, + amount: BigNumberish + ): Promise< + { + token: Address; + allowance: BigNumberish; + }[] + > { + return super.getDepositAllowanceParams(token, amount); + } + + /** + * @inheritDoc + * + * @example Deposit ETH on ETH-based chain. * * import { Provider, L1Signer, types } from "zksync-ethers"; * import { ethers } from "ethers"; @@ -835,7 +989,7 @@ export class L1Signer extends AdapterL1(ethers.JsonRpcSigner) { * amount: 10_000_000n, * }); * - * @example Deposit token. + * @example Deposit token on ETH-based chain. * * import { Provider, L1Signer, types } from "zksync-ethers"; * import { ethers } from "ethers"; @@ -852,6 +1006,59 @@ export class L1Signer extends AdapterL1(ethers.JsonRpcSigner) { * amount: 10_000_000n, * approveERC20: true, * }); + * + * @example Deposit ETH on non-ETH-chain. + * + * import { Provider, L1Signer, types } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const browserProvider = new ethers.BrowserProvider(window.ethereum); + * const signer = L1Signer.from( + * await browserProvider.getSigner(), + * Provider.getDefaultProvider(types.Network.Sepolia) + * ); + * + * await signer.deposit({ + * token: utils.ETH_ADDRESS, + * amount: 10_000_000, + * approveBaseERC20: true, + * }); + * + * @example Deposit base token on non-ETH-based chain. + * + * import { Provider, L1Signer, types } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const browserProvider = new ethers.BrowserProvider(window.ethereum); + * const signer = L1Signer.from( + * await browserProvider.getSigner(), + * Provider.getDefaultProvider(types.Network.Sepolia) + * ); + * + * await signer.deposit({ + * token: await signer.getBaseToken(), + * amount: 10_000_000, + * approveERC20: true, // or approveBaseERC20: true + * }); + * + * @example Deposit non-base token on non-ETH-based chain. + * + * import { Provider, L1Signer, types } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const browserProvider = new ethers.BrowserProvider(window.ethereum); + * const signer = L1Signer.from( + * await browserProvider.getSigner(), + * Provider.getDefaultProvider(types.Network.Sepolia) + * ); + * + * const tokenL1 = "0x56E69Fa1BB0d1402c89E3A4E3417882DeA6B14Be"; + * await signer.deposit({ + * token: tokenL1, + * amount: 10_000_000, + * approveERC20: true, + * approveBaseERC20: true, + * }); */ override async deposit(transaction: { token: Address; @@ -860,11 +1067,13 @@ export class L1Signer extends AdapterL1(ethers.JsonRpcSigner) { operatorTip?: BigNumberish; bridgeAddress?: Address; approveERC20?: boolean; + approveBaseERC20?: boolean; l2GasLimit?: BigNumberish; gasPerPubdataByte?: BigNumberish; refundRecipient?: Address; overrides?: Overrides; approveOverrides?: Overrides; + approveBaseOverrides?: Overrides; customBridgeData?: BytesLike; }): Promise { return super.deposit(transaction); @@ -1070,6 +1279,48 @@ export class L1Signer extends AdapterL1(ethers.JsonRpcSigner) { return super.claimFailedDeposit(depositHash, overrides); } + /** + * @inheritDoc + * + * @example + * + * import { Provider, L1Signer, types } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const browserProvider = new ethers.BrowserProvider(window.ethereum); + * const signer = L1Signer.from( + * await browserProvider.getSigner(), + * Provider.getDefaultProvider(types.Network.Sepolia) + * ); + * + * const tx = { + * contractAddress: await signer.getAddress(), + * calldata: '0x', + * l2Value: 7_000_000_000, + * }; + * + * const approveParams = await signer.getRequestExecuteAllowanceParams(tx); + * await ( + * await signer.approveERC20( + * approveParams.token, + * approveParams.allowance + * ) + * ).wait(); + */ + override async getRequestExecuteAllowanceParams(transaction: { + contractAddress: Address; + calldata: string; + l2GasLimit?: BigNumberish; + l2Value?: BigNumberish; + factoryDeps?: BytesLike[]; + operatorTip?: BigNumberish; + gasPerPubdataByte?: BigNumberish; + refundRecipient?: Address; + overrides?: Overrides; + }): Promise<{token: Address; allowance: BigNumberish}> { + return super.getRequestExecuteAllowanceParams(transaction); + } + /** * @inheritDoc * @@ -1093,7 +1344,8 @@ export class L1Signer extends AdapterL1(ethers.JsonRpcSigner) { override async requestExecute(transaction: { contractAddress: Address; calldata: string; - l2GasLimit: BigNumberish; + l2GasLimit?: BigNumberish; + mintValue?: BigNumberish; l2Value?: BigNumberish; factoryDeps?: BytesLike[]; operatorTip?: BigNumberish; @@ -1129,6 +1381,7 @@ export class L1Signer extends AdapterL1(ethers.JsonRpcSigner) { contractAddress: Address; calldata: string; l2GasLimit?: BigNumberish; + mintValue?: BigNumberish; l2Value?: BigNumberish; factoryDeps?: BytesLike[]; operatorTip?: BigNumberish; @@ -1163,6 +1416,7 @@ export class L1Signer extends AdapterL1(ethers.JsonRpcSigner) { contractAddress: Address; calldata: string; l2GasLimit?: BigNumberish; + mintValue?: BigNumberish; l2Value?: BigNumberish; factoryDeps?: BytesLike[]; operatorTip?: BigNumberish; @@ -1173,6 +1427,37 @@ export class L1Signer extends AdapterL1(ethers.JsonRpcSigner) { return super.getRequestExecuteTx(transaction); } + /** + * @inheritDoc + * + * @example + * + * import { Provider, L1Signer, types } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const browserProvider = new ethers.BrowserProvider(window.ethereum); + * const signer = L1Signer.from( + * await browserProvider.getSigner(), + * Provider.getDefaultProvider(types.Network.Sepolia) + * ); + * + * // Any L2 -> L1 transaction can be used. + * // In this case, withdrawal transaction is used. + * const tx = "0x2a1c6c74b184965c0cb015aae9ea134fd96215d2e4f4979cfec12563295f610e"; + * console.log(`Confirmation data: ${utils.toJSON(await signer.getPriorityOpConfirmation(tx, 0))}`); + */ + override async getPriorityOpConfirmation( + txHash: string, + index = 0 + ): Promise<{ + l1BatchNumber: number; + l2MessageIndex: number; + l2TxNumberInBlock: number | null; + proof: string[]; + }> { + return super.getPriorityOpConfirmation(txHash, index); + } + /** * Creates a new L1Singer with provided `signer` and `zksyncProvider`. * diff --git a/src/typechain/IAllowList.ts b/src/typechain/IAllowList.ts deleted file mode 100644 index 1a513456..00000000 --- a/src/typechain/IAllowList.ts +++ /dev/null @@ -1,441 +0,0 @@ -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ -import type { - BaseContract, - BigNumberish, - BytesLike, - FunctionFragment, - Result, - Interface, - EventFragment, - AddressLike, - ContractRunner, - ContractMethod, - Listener, -} from "ethers"; -import type { - TypedContractEvent, - TypedDeferredTopicFilter, - TypedEventLog, - TypedLogDescription, - TypedListener, - TypedContractMethod, -} from "./common"; - -export declare namespace IAllowList { - export type DepositStruct = { - depositLimitation: boolean; - depositCap: BigNumberish; - }; - - export type DepositStructOutput = [ - depositLimitation: boolean, - depositCap: bigint - ] & { depositLimitation: boolean; depositCap: bigint }; -} - -export interface IAllowListInterface extends Interface { - getFunction( - nameOrSignature: - | "canCall" - | "getAccessMode" - | "getTokenDepositLimitData" - | "hasSpecialAccessToCall" - | "setAccessMode" - | "setBatchAccessMode" - | "setBatchPermissionToCall" - | "setDepositLimit" - | "setPermissionToCall" - ): FunctionFragment; - - getEvent( - nameOrSignatureOrTopic: - | "UpdateAccessMode" - | "UpdateCallPermission" - | "UpdateDepositLimit" - ): EventFragment; - - encodeFunctionData( - functionFragment: "canCall", - values: [AddressLike, AddressLike, BytesLike] - ): string; - encodeFunctionData( - functionFragment: "getAccessMode", - values: [AddressLike] - ): string; - encodeFunctionData( - functionFragment: "getTokenDepositLimitData", - values: [AddressLike] - ): string; - encodeFunctionData( - functionFragment: "hasSpecialAccessToCall", - values: [AddressLike, AddressLike, BytesLike] - ): string; - encodeFunctionData( - functionFragment: "setAccessMode", - values: [AddressLike, BigNumberish] - ): string; - encodeFunctionData( - functionFragment: "setBatchAccessMode", - values: [AddressLike[], BigNumberish[]] - ): string; - encodeFunctionData( - functionFragment: "setBatchPermissionToCall", - values: [AddressLike[], AddressLike[], BytesLike[], boolean[]] - ): string; - encodeFunctionData( - functionFragment: "setDepositLimit", - values: [AddressLike, boolean, BigNumberish] - ): string; - encodeFunctionData( - functionFragment: "setPermissionToCall", - values: [AddressLike, AddressLike, BytesLike, boolean] - ): string; - - decodeFunctionResult(functionFragment: "canCall", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "getAccessMode", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "getTokenDepositLimitData", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "hasSpecialAccessToCall", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "setAccessMode", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "setBatchAccessMode", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "setBatchPermissionToCall", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "setDepositLimit", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "setPermissionToCall", - data: BytesLike - ): Result; -} - -export namespace UpdateAccessModeEvent { - export type InputTuple = [ - target: AddressLike, - previousMode: BigNumberish, - newMode: BigNumberish - ]; - export type OutputTuple = [ - target: string, - previousMode: bigint, - newMode: bigint - ]; - export interface OutputObject { - target: string; - previousMode: bigint; - newMode: bigint; - } - export type Event = TypedContractEvent; - export type Filter = TypedDeferredTopicFilter; - export type Log = TypedEventLog; - export type LogDescription = TypedLogDescription; -} - -export namespace UpdateCallPermissionEvent { - export type InputTuple = [ - caller: AddressLike, - target: AddressLike, - functionSig: BytesLike, - status: boolean - ]; - export type OutputTuple = [ - caller: string, - target: string, - functionSig: string, - status: boolean - ]; - export interface OutputObject { - caller: string; - target: string; - functionSig: string; - status: boolean; - } - export type Event = TypedContractEvent; - export type Filter = TypedDeferredTopicFilter; - export type Log = TypedEventLog; - export type LogDescription = TypedLogDescription; -} - -export namespace UpdateDepositLimitEvent { - export type InputTuple = [ - l1Token: AddressLike, - depositLimitation: boolean, - depositCap: BigNumberish - ]; - export type OutputTuple = [ - l1Token: string, - depositLimitation: boolean, - depositCap: bigint - ]; - export interface OutputObject { - l1Token: string; - depositLimitation: boolean; - depositCap: bigint; - } - export type Event = TypedContractEvent; - export type Filter = TypedDeferredTopicFilter; - export type Log = TypedEventLog; - export type LogDescription = TypedLogDescription; -} - -export interface IAllowList extends BaseContract { - connect(runner?: ContractRunner | null): IAllowList; - waitForDeployment(): Promise; - - interface: IAllowListInterface; - - queryFilter( - event: TCEvent, - fromBlockOrBlockhash?: string | number | undefined, - toBlock?: string | number | undefined - ): Promise>>; - queryFilter( - filter: TypedDeferredTopicFilter, - fromBlockOrBlockhash?: string | number | undefined, - toBlock?: string | number | undefined - ): Promise>>; - - on( - event: TCEvent, - listener: TypedListener - ): Promise; - on( - filter: TypedDeferredTopicFilter, - listener: TypedListener - ): Promise; - - once( - event: TCEvent, - listener: TypedListener - ): Promise; - once( - filter: TypedDeferredTopicFilter, - listener: TypedListener - ): Promise; - - listeners( - event: TCEvent - ): Promise>>; - listeners(eventName?: string): Promise>; - removeAllListeners( - event?: TCEvent - ): Promise; - - canCall: TypedContractMethod< - [_caller: AddressLike, _target: AddressLike, _functionSig: BytesLike], - [boolean], - "view" - >; - - getAccessMode: TypedContractMethod<[_target: AddressLike], [bigint], "view">; - - getTokenDepositLimitData: TypedContractMethod< - [_l1Token: AddressLike], - [IAllowList.DepositStructOutput], - "view" - >; - - hasSpecialAccessToCall: TypedContractMethod< - [_caller: AddressLike, _target: AddressLike, _functionSig: BytesLike], - [boolean], - "view" - >; - - setAccessMode: TypedContractMethod< - [_target: AddressLike, _accessMode: BigNumberish], - [void], - "nonpayable" - >; - - setBatchAccessMode: TypedContractMethod< - [_targets: AddressLike[], _accessMode: BigNumberish[]], - [void], - "nonpayable" - >; - - setBatchPermissionToCall: TypedContractMethod< - [ - _callers: AddressLike[], - _targets: AddressLike[], - _functionSigs: BytesLike[], - _enables: boolean[] - ], - [void], - "nonpayable" - >; - - setDepositLimit: TypedContractMethod< - [ - _l1Token: AddressLike, - _depositLimitation: boolean, - _depositCap: BigNumberish - ], - [void], - "nonpayable" - >; - - setPermissionToCall: TypedContractMethod< - [ - _caller: AddressLike, - _target: AddressLike, - _functionSig: BytesLike, - _enable: boolean - ], - [void], - "nonpayable" - >; - - getFunction( - key: string | FunctionFragment - ): T; - - getFunction( - nameOrSignature: "canCall" - ): TypedContractMethod< - [_caller: AddressLike, _target: AddressLike, _functionSig: BytesLike], - [boolean], - "view" - >; - getFunction( - nameOrSignature: "getAccessMode" - ): TypedContractMethod<[_target: AddressLike], [bigint], "view">; - getFunction( - nameOrSignature: "getTokenDepositLimitData" - ): TypedContractMethod< - [_l1Token: AddressLike], - [IAllowList.DepositStructOutput], - "view" - >; - getFunction( - nameOrSignature: "hasSpecialAccessToCall" - ): TypedContractMethod< - [_caller: AddressLike, _target: AddressLike, _functionSig: BytesLike], - [boolean], - "view" - >; - getFunction( - nameOrSignature: "setAccessMode" - ): TypedContractMethod< - [_target: AddressLike, _accessMode: BigNumberish], - [void], - "nonpayable" - >; - getFunction( - nameOrSignature: "setBatchAccessMode" - ): TypedContractMethod< - [_targets: AddressLike[], _accessMode: BigNumberish[]], - [void], - "nonpayable" - >; - getFunction( - nameOrSignature: "setBatchPermissionToCall" - ): TypedContractMethod< - [ - _callers: AddressLike[], - _targets: AddressLike[], - _functionSigs: BytesLike[], - _enables: boolean[] - ], - [void], - "nonpayable" - >; - getFunction( - nameOrSignature: "setDepositLimit" - ): TypedContractMethod< - [ - _l1Token: AddressLike, - _depositLimitation: boolean, - _depositCap: BigNumberish - ], - [void], - "nonpayable" - >; - getFunction( - nameOrSignature: "setPermissionToCall" - ): TypedContractMethod< - [ - _caller: AddressLike, - _target: AddressLike, - _functionSig: BytesLike, - _enable: boolean - ], - [void], - "nonpayable" - >; - - getEvent( - key: "UpdateAccessMode" - ): TypedContractEvent< - UpdateAccessModeEvent.InputTuple, - UpdateAccessModeEvent.OutputTuple, - UpdateAccessModeEvent.OutputObject - >; - getEvent( - key: "UpdateCallPermission" - ): TypedContractEvent< - UpdateCallPermissionEvent.InputTuple, - UpdateCallPermissionEvent.OutputTuple, - UpdateCallPermissionEvent.OutputObject - >; - getEvent( - key: "UpdateDepositLimit" - ): TypedContractEvent< - UpdateDepositLimitEvent.InputTuple, - UpdateDepositLimitEvent.OutputTuple, - UpdateDepositLimitEvent.OutputObject - >; - - filters: { - "UpdateAccessMode(address,uint8,uint8)": TypedContractEvent< - UpdateAccessModeEvent.InputTuple, - UpdateAccessModeEvent.OutputTuple, - UpdateAccessModeEvent.OutputObject - >; - UpdateAccessMode: TypedContractEvent< - UpdateAccessModeEvent.InputTuple, - UpdateAccessModeEvent.OutputTuple, - UpdateAccessModeEvent.OutputObject - >; - - "UpdateCallPermission(address,address,bytes4,bool)": TypedContractEvent< - UpdateCallPermissionEvent.InputTuple, - UpdateCallPermissionEvent.OutputTuple, - UpdateCallPermissionEvent.OutputObject - >; - UpdateCallPermission: TypedContractEvent< - UpdateCallPermissionEvent.InputTuple, - UpdateCallPermissionEvent.OutputTuple, - UpdateCallPermissionEvent.OutputObject - >; - - "UpdateDepositLimit(address,bool,uint256)": TypedContractEvent< - UpdateDepositLimitEvent.InputTuple, - UpdateDepositLimitEvent.OutputTuple, - UpdateDepositLimitEvent.OutputObject - >; - UpdateDepositLimit: TypedContractEvent< - UpdateDepositLimitEvent.InputTuple, - UpdateDepositLimitEvent.OutputTuple, - UpdateDepositLimitEvent.OutputObject - >; - }; -} diff --git a/src/typechain/IBridgehub.ts b/src/typechain/IBridgehub.ts new file mode 100644 index 00000000..82688f66 --- /dev/null +++ b/src/typechain/IBridgehub.ts @@ -0,0 +1,743 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { + BaseContract, + BigNumberish, + BytesLike, + FunctionFragment, + Result, + Interface, + EventFragment, + AddressLike, + ContractRunner, + ContractMethod, + Listener, +} from "ethers"; +import type { + TypedContractEvent, + TypedDeferredTopicFilter, + TypedEventLog, + TypedLogDescription, + TypedListener, + TypedContractMethod, +} from "./common"; + +export type L2LogStruct = { + l2ShardId: BigNumberish; + isService: boolean; + txNumberInBatch: BigNumberish; + sender: AddressLike; + key: BytesLike; + value: BytesLike; +}; + +export type L2LogStructOutput = [ + l2ShardId: bigint, + isService: boolean, + txNumberInBatch: bigint, + sender: string, + key: string, + value: string +] & { + l2ShardId: bigint; + isService: boolean; + txNumberInBatch: bigint; + sender: string; + key: string; + value: string; +}; + +export type L2MessageStruct = { + txNumberInBatch: BigNumberish; + sender: AddressLike; + data: BytesLike; +}; + +export type L2MessageStructOutput = [ + txNumberInBatch: bigint, + sender: string, + data: string +] & { txNumberInBatch: bigint; sender: string; data: string }; + +export type L2TransactionRequestDirectStruct = { + chainId: BigNumberish; + mintValue: BigNumberish; + l2Contract: AddressLike; + l2Value: BigNumberish; + l2Calldata: BytesLike; + l2GasLimit: BigNumberish; + l2GasPerPubdataByteLimit: BigNumberish; + factoryDeps: BytesLike[]; + refundRecipient: AddressLike; +}; + +export type L2TransactionRequestDirectStructOutput = [ + chainId: bigint, + mintValue: bigint, + l2Contract: string, + l2Value: bigint, + l2Calldata: string, + l2GasLimit: bigint, + l2GasPerPubdataByteLimit: bigint, + factoryDeps: string[], + refundRecipient: string +] & { + chainId: bigint; + mintValue: bigint; + l2Contract: string; + l2Value: bigint; + l2Calldata: string; + l2GasLimit: bigint; + l2GasPerPubdataByteLimit: bigint; + factoryDeps: string[]; + refundRecipient: string; +}; + +export type L2TransactionRequestTwoBridgesOuterStruct = { + chainId: BigNumberish; + mintValue: BigNumberish; + l2Value: BigNumberish; + l2GasLimit: BigNumberish; + l2GasPerPubdataByteLimit: BigNumberish; + refundRecipient: AddressLike; + secondBridgeAddress: AddressLike; + secondBridgeValue: BigNumberish; + secondBridgeCalldata: BytesLike; +}; + +export type L2TransactionRequestTwoBridgesOuterStructOutput = [ + chainId: bigint, + mintValue: bigint, + l2Value: bigint, + l2GasLimit: bigint, + l2GasPerPubdataByteLimit: bigint, + refundRecipient: string, + secondBridgeAddress: string, + secondBridgeValue: bigint, + secondBridgeCalldata: string +] & { + chainId: bigint; + mintValue: bigint; + l2Value: bigint; + l2GasLimit: bigint; + l2GasPerPubdataByteLimit: bigint; + refundRecipient: string; + secondBridgeAddress: string; + secondBridgeValue: bigint; + secondBridgeCalldata: string; +}; + +export interface IBridgehubInterface extends Interface { + getFunction( + nameOrSignature: + | "acceptAdmin" + | "addStateTransitionManager" + | "addToken" + | "baseToken" + | "createNewChain" + | "getStateTransition" + | "l2TransactionBaseCost" + | "proveL1ToL2TransactionStatus" + | "proveL2LogInclusion" + | "proveL2MessageInclusion" + | "removeStateTransitionManager" + | "requestL2TransactionDirect" + | "requestL2TransactionTwoBridges" + | "setPendingAdmin" + | "setSharedBridge" + | "sharedBridge" + | "stateTransitionManager" + | "stateTransitionManagerIsRegistered" + | "tokenIsRegistered" + ): FunctionFragment; + + getEvent( + nameOrSignatureOrTopic: "NewAdmin" | "NewChain" | "NewPendingAdmin" + ): EventFragment; + + encodeFunctionData( + functionFragment: "acceptAdmin", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "addStateTransitionManager", + values: [AddressLike] + ): string; + encodeFunctionData( + functionFragment: "addToken", + values: [AddressLike] + ): string; + encodeFunctionData( + functionFragment: "baseToken", + values: [BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "createNewChain", + values: [ + BigNumberish, + AddressLike, + AddressLike, + BigNumberish, + AddressLike, + BytesLike + ] + ): string; + encodeFunctionData( + functionFragment: "getStateTransition", + values: [BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "l2TransactionBaseCost", + values: [BigNumberish, BigNumberish, BigNumberish, BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "proveL1ToL2TransactionStatus", + values: [ + BigNumberish, + BytesLike, + BigNumberish, + BigNumberish, + BigNumberish, + BytesLike[], + BigNumberish + ] + ): string; + encodeFunctionData( + functionFragment: "proveL2LogInclusion", + values: [BigNumberish, BigNumberish, BigNumberish, L2LogStruct, BytesLike[]] + ): string; + encodeFunctionData( + functionFragment: "proveL2MessageInclusion", + values: [ + BigNumberish, + BigNumberish, + BigNumberish, + L2MessageStruct, + BytesLike[] + ] + ): string; + encodeFunctionData( + functionFragment: "removeStateTransitionManager", + values: [AddressLike] + ): string; + encodeFunctionData( + functionFragment: "requestL2TransactionDirect", + values: [L2TransactionRequestDirectStruct] + ): string; + encodeFunctionData( + functionFragment: "requestL2TransactionTwoBridges", + values: [L2TransactionRequestTwoBridgesOuterStruct] + ): string; + encodeFunctionData( + functionFragment: "setPendingAdmin", + values: [AddressLike] + ): string; + encodeFunctionData( + functionFragment: "setSharedBridge", + values: [AddressLike] + ): string; + encodeFunctionData( + functionFragment: "sharedBridge", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "stateTransitionManager", + values: [BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "stateTransitionManagerIsRegistered", + values: [AddressLike] + ): string; + encodeFunctionData( + functionFragment: "tokenIsRegistered", + values: [AddressLike] + ): string; + + decodeFunctionResult( + functionFragment: "acceptAdmin", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "addStateTransitionManager", + data: BytesLike + ): Result; + decodeFunctionResult(functionFragment: "addToken", data: BytesLike): Result; + decodeFunctionResult(functionFragment: "baseToken", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "createNewChain", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "getStateTransition", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "l2TransactionBaseCost", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "proveL1ToL2TransactionStatus", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "proveL2LogInclusion", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "proveL2MessageInclusion", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "removeStateTransitionManager", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "requestL2TransactionDirect", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "requestL2TransactionTwoBridges", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "setPendingAdmin", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "setSharedBridge", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "sharedBridge", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "stateTransitionManager", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "stateTransitionManagerIsRegistered", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "tokenIsRegistered", + data: BytesLike + ): Result; +} + +export namespace NewAdminEvent { + export type InputTuple = [oldAdmin: AddressLike, newAdmin: AddressLike]; + export type OutputTuple = [oldAdmin: string, newAdmin: string]; + export interface OutputObject { + oldAdmin: string; + newAdmin: string; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace NewChainEvent { + export type InputTuple = [ + chainId: BigNumberish, + stateTransitionManager: AddressLike, + chainGovernance: AddressLike + ]; + export type OutputTuple = [ + chainId: bigint, + stateTransitionManager: string, + chainGovernance: string + ]; + export interface OutputObject { + chainId: bigint; + stateTransitionManager: string; + chainGovernance: string; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace NewPendingAdminEvent { + export type InputTuple = [ + oldPendingAdmin: AddressLike, + newPendingAdmin: AddressLike + ]; + export type OutputTuple = [oldPendingAdmin: string, newPendingAdmin: string]; + export interface OutputObject { + oldPendingAdmin: string; + newPendingAdmin: string; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export interface IBridgehub extends BaseContract { + connect(runner?: ContractRunner | null): IBridgehub; + waitForDeployment(): Promise; + + interface: IBridgehubInterface; + + queryFilter( + event: TCEvent, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>>; + queryFilter( + filter: TypedDeferredTopicFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>>; + + on( + event: TCEvent, + listener: TypedListener + ): Promise; + on( + filter: TypedDeferredTopicFilter, + listener: TypedListener + ): Promise; + + once( + event: TCEvent, + listener: TypedListener + ): Promise; + once( + filter: TypedDeferredTopicFilter, + listener: TypedListener + ): Promise; + + listeners( + event: TCEvent + ): Promise>>; + listeners(eventName?: string): Promise>; + removeAllListeners( + event?: TCEvent + ): Promise; + + acceptAdmin: TypedContractMethod<[], [void], "nonpayable">; + + addStateTransitionManager: TypedContractMethod< + [_stateTransitionManager: AddressLike], + [void], + "nonpayable" + >; + + addToken: TypedContractMethod<[_token: AddressLike], [void], "nonpayable">; + + baseToken: TypedContractMethod<[_chainId: BigNumberish], [string], "view">; + + createNewChain: TypedContractMethod< + [ + _chainId: BigNumberish, + _stateTransitionManager: AddressLike, + _baseToken: AddressLike, + _salt: BigNumberish, + _admin: AddressLike, + _initData: BytesLike + ], + [bigint], + "nonpayable" + >; + + getStateTransition: TypedContractMethod< + [_chainId: BigNumberish], + [string], + "view" + >; + + l2TransactionBaseCost: TypedContractMethod< + [ + _chainId: BigNumberish, + _gasPrice: BigNumberish, + _l2GasLimit: BigNumberish, + _l2GasPerPubdataByteLimit: BigNumberish + ], + [bigint], + "view" + >; + + proveL1ToL2TransactionStatus: TypedContractMethod< + [ + _chainId: BigNumberish, + _l2TxHash: BytesLike, + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish, + _l2TxNumberInBatch: BigNumberish, + _merkleProof: BytesLike[], + _status: BigNumberish + ], + [boolean], + "view" + >; + + proveL2LogInclusion: TypedContractMethod< + [ + _chainId: BigNumberish, + _batchNumber: BigNumberish, + _index: BigNumberish, + _log: L2LogStruct, + _proof: BytesLike[] + ], + [boolean], + "view" + >; + + proveL2MessageInclusion: TypedContractMethod< + [ + _chainId: BigNumberish, + _batchNumber: BigNumberish, + _index: BigNumberish, + _message: L2MessageStruct, + _proof: BytesLike[] + ], + [boolean], + "view" + >; + + removeStateTransitionManager: TypedContractMethod< + [_stateTransitionManager: AddressLike], + [void], + "nonpayable" + >; + + requestL2TransactionDirect: TypedContractMethod< + [_request: L2TransactionRequestDirectStruct], + [string], + "payable" + >; + + requestL2TransactionTwoBridges: TypedContractMethod< + [_request: L2TransactionRequestTwoBridgesOuterStruct], + [string], + "payable" + >; + + setPendingAdmin: TypedContractMethod< + [_newPendingAdmin: AddressLike], + [void], + "nonpayable" + >; + + setSharedBridge: TypedContractMethod< + [_sharedBridge: AddressLike], + [void], + "nonpayable" + >; + + sharedBridge: TypedContractMethod<[], [string], "view">; + + stateTransitionManager: TypedContractMethod< + [_chainId: BigNumberish], + [string], + "view" + >; + + stateTransitionManagerIsRegistered: TypedContractMethod< + [_stateTransitionManager: AddressLike], + [boolean], + "view" + >; + + tokenIsRegistered: TypedContractMethod< + [_baseToken: AddressLike], + [boolean], + "view" + >; + + getFunction( + key: string | FunctionFragment + ): T; + + getFunction( + nameOrSignature: "acceptAdmin" + ): TypedContractMethod<[], [void], "nonpayable">; + getFunction( + nameOrSignature: "addStateTransitionManager" + ): TypedContractMethod< + [_stateTransitionManager: AddressLike], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "addToken" + ): TypedContractMethod<[_token: AddressLike], [void], "nonpayable">; + getFunction( + nameOrSignature: "baseToken" + ): TypedContractMethod<[_chainId: BigNumberish], [string], "view">; + getFunction( + nameOrSignature: "createNewChain" + ): TypedContractMethod< + [ + _chainId: BigNumberish, + _stateTransitionManager: AddressLike, + _baseToken: AddressLike, + _salt: BigNumberish, + _admin: AddressLike, + _initData: BytesLike + ], + [bigint], + "nonpayable" + >; + getFunction( + nameOrSignature: "getStateTransition" + ): TypedContractMethod<[_chainId: BigNumberish], [string], "view">; + getFunction( + nameOrSignature: "l2TransactionBaseCost" + ): TypedContractMethod< + [ + _chainId: BigNumberish, + _gasPrice: BigNumberish, + _l2GasLimit: BigNumberish, + _l2GasPerPubdataByteLimit: BigNumberish + ], + [bigint], + "view" + >; + getFunction( + nameOrSignature: "proveL1ToL2TransactionStatus" + ): TypedContractMethod< + [ + _chainId: BigNumberish, + _l2TxHash: BytesLike, + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish, + _l2TxNumberInBatch: BigNumberish, + _merkleProof: BytesLike[], + _status: BigNumberish + ], + [boolean], + "view" + >; + getFunction( + nameOrSignature: "proveL2LogInclusion" + ): TypedContractMethod< + [ + _chainId: BigNumberish, + _batchNumber: BigNumberish, + _index: BigNumberish, + _log: L2LogStruct, + _proof: BytesLike[] + ], + [boolean], + "view" + >; + getFunction( + nameOrSignature: "proveL2MessageInclusion" + ): TypedContractMethod< + [ + _chainId: BigNumberish, + _batchNumber: BigNumberish, + _index: BigNumberish, + _message: L2MessageStruct, + _proof: BytesLike[] + ], + [boolean], + "view" + >; + getFunction( + nameOrSignature: "removeStateTransitionManager" + ): TypedContractMethod< + [_stateTransitionManager: AddressLike], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "requestL2TransactionDirect" + ): TypedContractMethod< + [_request: L2TransactionRequestDirectStruct], + [string], + "payable" + >; + getFunction( + nameOrSignature: "requestL2TransactionTwoBridges" + ): TypedContractMethod< + [_request: L2TransactionRequestTwoBridgesOuterStruct], + [string], + "payable" + >; + getFunction( + nameOrSignature: "setPendingAdmin" + ): TypedContractMethod<[_newPendingAdmin: AddressLike], [void], "nonpayable">; + getFunction( + nameOrSignature: "setSharedBridge" + ): TypedContractMethod<[_sharedBridge: AddressLike], [void], "nonpayable">; + getFunction( + nameOrSignature: "sharedBridge" + ): TypedContractMethod<[], [string], "view">; + getFunction( + nameOrSignature: "stateTransitionManager" + ): TypedContractMethod<[_chainId: BigNumberish], [string], "view">; + getFunction( + nameOrSignature: "stateTransitionManagerIsRegistered" + ): TypedContractMethod< + [_stateTransitionManager: AddressLike], + [boolean], + "view" + >; + getFunction( + nameOrSignature: "tokenIsRegistered" + ): TypedContractMethod<[_baseToken: AddressLike], [boolean], "view">; + + getEvent( + key: "NewAdmin" + ): TypedContractEvent< + NewAdminEvent.InputTuple, + NewAdminEvent.OutputTuple, + NewAdminEvent.OutputObject + >; + getEvent( + key: "NewChain" + ): TypedContractEvent< + NewChainEvent.InputTuple, + NewChainEvent.OutputTuple, + NewChainEvent.OutputObject + >; + getEvent( + key: "NewPendingAdmin" + ): TypedContractEvent< + NewPendingAdminEvent.InputTuple, + NewPendingAdminEvent.OutputTuple, + NewPendingAdminEvent.OutputObject + >; + + filters: { + "NewAdmin(address,address)": TypedContractEvent< + NewAdminEvent.InputTuple, + NewAdminEvent.OutputTuple, + NewAdminEvent.OutputObject + >; + NewAdmin: TypedContractEvent< + NewAdminEvent.InputTuple, + NewAdminEvent.OutputTuple, + NewAdminEvent.OutputObject + >; + + "NewChain(uint256,address,address)": TypedContractEvent< + NewChainEvent.InputTuple, + NewChainEvent.OutputTuple, + NewChainEvent.OutputObject + >; + NewChain: TypedContractEvent< + NewChainEvent.InputTuple, + NewChainEvent.OutputTuple, + NewChainEvent.OutputObject + >; + + "NewPendingAdmin(address,address)": TypedContractEvent< + NewPendingAdminEvent.InputTuple, + NewPendingAdminEvent.OutputTuple, + NewPendingAdminEvent.OutputObject + >; + NewPendingAdmin: TypedContractEvent< + NewPendingAdminEvent.InputTuple, + NewPendingAdminEvent.OutputTuple, + NewPendingAdminEvent.OutputObject + >; + }; +} diff --git a/src/typechain/IContractDeployer.ts b/src/typechain/IContractDeployer.ts index fa895ec3..be362c11 100644 --- a/src/typechain/IContractDeployer.ts +++ b/src/typechain/IContractDeployer.ts @@ -23,6 +23,30 @@ import type { TypedContractMethod, } from "./common"; +export declare namespace ContractDeployer { + export type ForceDeploymentStruct = { + bytecodeHash: BytesLike; + newAddress: AddressLike; + callConstructor: boolean; + value: BigNumberish; + input: BytesLike; + }; + + export type ForceDeploymentStructOutput = [ + bytecodeHash: string, + newAddress: string, + callConstructor: boolean, + value: bigint, + input: string + ] & { + bytecodeHash: string; + newAddress: string; + callConstructor: boolean; + value: bigint; + input: string; + }; +} + export declare namespace IContractDeployer { export type AccountInfoStruct = { supportedAAVersion: BigNumberish; @@ -42,6 +66,9 @@ export interface IContractDeployerInterface extends Interface { | "create2" | "create2Account" | "createAccount" + | "extendedAccountVersion" + | "forceDeployOnAddress" + | "forceDeployOnAddresses" | "getAccountInfo" | "getNewAddressCreate" | "getNewAddressCreate2" @@ -72,6 +99,18 @@ export interface IContractDeployerInterface extends Interface { functionFragment: "createAccount", values: [BytesLike, BytesLike, BytesLike, BigNumberish] ): string; + encodeFunctionData( + functionFragment: "extendedAccountVersion", + values: [AddressLike] + ): string; + encodeFunctionData( + functionFragment: "forceDeployOnAddress", + values: [ContractDeployer.ForceDeploymentStruct, AddressLike] + ): string; + encodeFunctionData( + functionFragment: "forceDeployOnAddresses", + values: [ContractDeployer.ForceDeploymentStruct[]] + ): string; encodeFunctionData( functionFragment: "getAccountInfo", values: [AddressLike] @@ -103,6 +142,18 @@ export interface IContractDeployerInterface extends Interface { functionFragment: "createAccount", data: BytesLike ): Result; + decodeFunctionResult( + functionFragment: "extendedAccountVersion", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "forceDeployOnAddress", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "forceDeployOnAddresses", + data: BytesLike + ): Result; decodeFunctionResult( functionFragment: "getAccountInfo", data: BytesLike @@ -247,7 +298,7 @@ export interface IContractDeployer extends BaseContract { createAccount: TypedContractMethod< [ - _salt: BytesLike, + arg0: BytesLike, _bytecodeHash: BytesLike, _input: BytesLike, _aaVersion: BigNumberish @@ -256,6 +307,24 @@ export interface IContractDeployer extends BaseContract { "payable" >; + extendedAccountVersion: TypedContractMethod< + [_address: AddressLike], + [bigint], + "view" + >; + + forceDeployOnAddress: TypedContractMethod< + [_deployment: ContractDeployer.ForceDeploymentStruct, _sender: AddressLike], + [void], + "payable" + >; + + forceDeployOnAddresses: TypedContractMethod< + [_deployments: ContractDeployer.ForceDeploymentStruct[]], + [void], + "payable" + >; + getAccountInfo: TypedContractMethod< [_address: AddressLike], [IContractDeployer.AccountInfoStructOutput], @@ -325,7 +394,7 @@ export interface IContractDeployer extends BaseContract { nameOrSignature: "createAccount" ): TypedContractMethod< [ - _salt: BytesLike, + arg0: BytesLike, _bytecodeHash: BytesLike, _input: BytesLike, _aaVersion: BigNumberish @@ -333,6 +402,23 @@ export interface IContractDeployer extends BaseContract { [string], "payable" >; + getFunction( + nameOrSignature: "extendedAccountVersion" + ): TypedContractMethod<[_address: AddressLike], [bigint], "view">; + getFunction( + nameOrSignature: "forceDeployOnAddress" + ): TypedContractMethod< + [_deployment: ContractDeployer.ForceDeploymentStruct, _sender: AddressLike], + [void], + "payable" + >; + getFunction( + nameOrSignature: "forceDeployOnAddresses" + ): TypedContractMethod< + [_deployments: ContractDeployer.ForceDeploymentStruct[]], + [void], + "payable" + >; getFunction( nameOrSignature: "getAccountInfo" ): TypedContractMethod< diff --git a/src/typechain/IL1Bridge.ts b/src/typechain/IL1Bridge.ts index 11a60cf1..e1461a73 100644 --- a/src/typechain/IL1Bridge.ts +++ b/src/typechain/IL1Bridge.ts @@ -23,29 +23,72 @@ import type { TypedContractMethod, } from "./common"; +export type L2TransactionRequestTwoBridgesInnerStruct = { + magicValue: BytesLike; + l2Contract: AddressLike; + l2Calldata: BytesLike; + factoryDeps: BytesLike[]; + txDataHash: BytesLike; +}; + +export type L2TransactionRequestTwoBridgesInnerStructOutput = [ + magicValue: string, + l2Contract: string, + l2Calldata: string, + factoryDeps: string[], + txDataHash: string +] & { + magicValue: string; + l2Contract: string; + l2Calldata: string; + factoryDeps: string[]; + txDataHash: string; +}; + export interface IL1BridgeInterface extends Interface { getFunction( nameOrSignature: + | "bridgehub" + | "bridgehubConfirmL2Transaction" + | "bridgehubDeposit" + | "bridgehubDepositBaseToken" | "claimFailedDeposit" | "deposit" + | "depositHappened" | "finalizeWithdrawal" - | "isWithdrawalFinalized" - | "l2Bridge" - | "l2TokenAddress" + | "isWithdrawalFinalizedShared" + | "l2BridgeAddress" ): FunctionFragment; getEvent( nameOrSignatureOrTopic: - | "ClaimedFailedDeposit" - | "DepositInitiated" - | "WithdrawalFinalized" + | "BridgehubDepositFinalized" + | "BridgehubDepositInitiatedSharedBridge" + | "ClaimedFailedDepositSharedBridge" + | "DepositInitiatedSharedBridge" + | "WithdrawalFinalizedSharedBridge" ): EventFragment; + encodeFunctionData(functionFragment: "bridgehub", values?: undefined): string; + encodeFunctionData( + functionFragment: "bridgehubConfirmL2Transaction", + values: [BigNumberish, BytesLike, BytesLike] + ): string; + encodeFunctionData( + functionFragment: "bridgehubDeposit", + values: [BigNumberish, AddressLike, BytesLike] + ): string; + encodeFunctionData( + functionFragment: "bridgehubDepositBaseToken", + values: [BigNumberish, AddressLike, AddressLike, BigNumberish] + ): string; encodeFunctionData( functionFragment: "claimFailedDeposit", values: [ + BigNumberish, AddressLike, AddressLike, + BigNumberish, BytesLike, BigNumberish, BigNumberish, @@ -56,56 +99,119 @@ export interface IL1BridgeInterface extends Interface { encodeFunctionData( functionFragment: "deposit", values: [ + BigNumberish, AddressLike, AddressLike, BigNumberish, BigNumberish, BigNumberish, + BigNumberish, AddressLike ] ): string; + encodeFunctionData( + functionFragment: "depositHappened", + values: [BigNumberish, BytesLike] + ): string; encodeFunctionData( functionFragment: "finalizeWithdrawal", - values: [BigNumberish, BigNumberish, BigNumberish, BytesLike, BytesLike[]] + values: [ + BigNumberish, + BigNumberish, + BigNumberish, + BigNumberish, + BytesLike, + BytesLike[] + ] ): string; encodeFunctionData( - functionFragment: "isWithdrawalFinalized", - values: [BigNumberish, BigNumberish] + functionFragment: "isWithdrawalFinalizedShared", + values: [BigNumberish, BigNumberish, BigNumberish] ): string; - encodeFunctionData(functionFragment: "l2Bridge", values?: undefined): string; encodeFunctionData( - functionFragment: "l2TokenAddress", - values: [AddressLike] + functionFragment: "l2BridgeAddress", + values: [BigNumberish] ): string; + decodeFunctionResult(functionFragment: "bridgehub", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "bridgehubConfirmL2Transaction", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "bridgehubDeposit", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "bridgehubDepositBaseToken", + data: BytesLike + ): Result; decodeFunctionResult( functionFragment: "claimFailedDeposit", data: BytesLike ): Result; decodeFunctionResult(functionFragment: "deposit", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "depositHappened", + data: BytesLike + ): Result; decodeFunctionResult( functionFragment: "finalizeWithdrawal", data: BytesLike ): Result; decodeFunctionResult( - functionFragment: "isWithdrawalFinalized", + functionFragment: "isWithdrawalFinalizedShared", data: BytesLike ): Result; - decodeFunctionResult(functionFragment: "l2Bridge", data: BytesLike): Result; decodeFunctionResult( - functionFragment: "l2TokenAddress", + functionFragment: "l2BridgeAddress", data: BytesLike ): Result; } -export namespace ClaimedFailedDepositEvent { +export namespace BridgehubDepositFinalizedEvent { + export type InputTuple = [ + chainId: BigNumberish, + txDataHash: BytesLike, + l2DepositTxHash: BytesLike + ]; + export type OutputTuple = [ + chainId: bigint, + txDataHash: string, + l2DepositTxHash: string + ]; + export interface OutputObject { + chainId: bigint; + txDataHash: string; + l2DepositTxHash: string; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace BridgehubDepositInitiatedSharedBridgeEvent { export type InputTuple = [ + chainId: BigNumberish, + txDataHash: BytesLike, + from: AddressLike, to: AddressLike, l1Token: AddressLike, amount: BigNumberish ]; - export type OutputTuple = [to: string, l1Token: string, amount: bigint]; + export type OutputTuple = [ + chainId: bigint, + txDataHash: string, + from: string, + to: string, + l1Token: string, + amount: bigint + ]; export interface OutputObject { + chainId: bigint; + txDataHash: string; + from: string; to: string; l1Token: string; amount: bigint; @@ -116,8 +222,34 @@ export namespace ClaimedFailedDepositEvent { export type LogDescription = TypedLogDescription; } -export namespace DepositInitiatedEvent { +export namespace ClaimedFailedDepositSharedBridgeEvent { export type InputTuple = [ + chainId: BigNumberish, + to: AddressLike, + l1Token: AddressLike, + amount: BigNumberish + ]; + export type OutputTuple = [ + chainId: bigint, + to: string, + l1Token: string, + amount: bigint + ]; + export interface OutputObject { + chainId: bigint; + to: string; + l1Token: string; + amount: bigint; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace DepositInitiatedSharedBridgeEvent { + export type InputTuple = [ + chainId: BigNumberish, l2DepositTxHash: BytesLike, from: AddressLike, to: AddressLike, @@ -125,6 +257,7 @@ export namespace DepositInitiatedEvent { amount: BigNumberish ]; export type OutputTuple = [ + chainId: bigint, l2DepositTxHash: string, from: string, to: string, @@ -132,6 +265,7 @@ export namespace DepositInitiatedEvent { amount: bigint ]; export interface OutputObject { + chainId: bigint; l2DepositTxHash: string; from: string; to: string; @@ -144,14 +278,21 @@ export namespace DepositInitiatedEvent { export type LogDescription = TypedLogDescription; } -export namespace WithdrawalFinalizedEvent { +export namespace WithdrawalFinalizedSharedBridgeEvent { export type InputTuple = [ + chainId: BigNumberish, to: AddressLike, l1Token: AddressLike, amount: BigNumberish ]; - export type OutputTuple = [to: string, l1Token: string, amount: bigint]; + export type OutputTuple = [ + chainId: bigint, + to: string, + l1Token: string, + amount: bigint + ]; export interface OutputObject { + chainId: bigint; to: string; l1Token: string; amount: bigint; @@ -205,10 +346,37 @@ export interface IL1Bridge extends BaseContract { event?: TCEvent ): Promise; + bridgehub: TypedContractMethod<[], [string], "view">; + + bridgehubConfirmL2Transaction: TypedContractMethod< + [_chainId: BigNumberish, _txDataHash: BytesLike, _txHash: BytesLike], + [void], + "nonpayable" + >; + + bridgehubDeposit: TypedContractMethod< + [_chainId: BigNumberish, _prevMsgSender: AddressLike, _data: BytesLike], + [L2TransactionRequestTwoBridgesInnerStructOutput], + "payable" + >; + + bridgehubDepositBaseToken: TypedContractMethod< + [ + _chainId: BigNumberish, + _prevMsgSender: AddressLike, + _l1Token: AddressLike, + _amount: BigNumberish + ], + [void], + "payable" + >; + claimFailedDeposit: TypedContractMethod< [ + _chainId: BigNumberish, _depositSender: AddressLike, _l1Token: AddressLike, + _amount: BigNumberish, _l2TxHash: BytesLike, _l2BatchNumber: BigNumberish, _l2MessageIndex: BigNumberish, @@ -221,8 +389,10 @@ export interface IL1Bridge extends BaseContract { deposit: TypedContractMethod< [ + _chainId: BigNumberish, _l2Receiver: AddressLike, _l1Token: AddressLike, + _mintValue: BigNumberish, _amount: BigNumberish, _l2TxGasLimit: BigNumberish, _l2TxGasPerPubdataByte: BigNumberish, @@ -232,8 +402,15 @@ export interface IL1Bridge extends BaseContract { "payable" >; + depositHappened: TypedContractMethod< + [_chainId: BigNumberish, _l2TxHash: BytesLike], + [string], + "view" + >; + finalizeWithdrawal: TypedContractMethod< [ + _chainId: BigNumberish, _l2BatchNumber: BigNumberish, _l2MessageIndex: BigNumberish, _l2TxNumberInBatch: BigNumberish, @@ -244,16 +421,18 @@ export interface IL1Bridge extends BaseContract { "nonpayable" >; - isWithdrawalFinalized: TypedContractMethod< - [_l2BatchNumber: BigNumberish, _l2MessageIndex: BigNumberish], + isWithdrawalFinalizedShared: TypedContractMethod< + [ + _chainId: BigNumberish, + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish + ], [boolean], "view" >; - l2Bridge: TypedContractMethod<[], [string], "view">; - - l2TokenAddress: TypedContractMethod< - [_l1Token: AddressLike], + l2BridgeAddress: TypedContractMethod< + [_chainId: BigNumberish], [string], "view" >; @@ -262,12 +441,43 @@ export interface IL1Bridge extends BaseContract { key: string | FunctionFragment ): T; + getFunction( + nameOrSignature: "bridgehub" + ): TypedContractMethod<[], [string], "view">; + getFunction( + nameOrSignature: "bridgehubConfirmL2Transaction" + ): TypedContractMethod< + [_chainId: BigNumberish, _txDataHash: BytesLike, _txHash: BytesLike], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "bridgehubDeposit" + ): TypedContractMethod< + [_chainId: BigNumberish, _prevMsgSender: AddressLike, _data: BytesLike], + [L2TransactionRequestTwoBridgesInnerStructOutput], + "payable" + >; + getFunction( + nameOrSignature: "bridgehubDepositBaseToken" + ): TypedContractMethod< + [ + _chainId: BigNumberish, + _prevMsgSender: AddressLike, + _l1Token: AddressLike, + _amount: BigNumberish + ], + [void], + "payable" + >; getFunction( nameOrSignature: "claimFailedDeposit" ): TypedContractMethod< [ + _chainId: BigNumberish, _depositSender: AddressLike, _l1Token: AddressLike, + _amount: BigNumberish, _l2TxHash: BytesLike, _l2BatchNumber: BigNumberish, _l2MessageIndex: BigNumberish, @@ -281,8 +491,10 @@ export interface IL1Bridge extends BaseContract { nameOrSignature: "deposit" ): TypedContractMethod< [ + _chainId: BigNumberish, _l2Receiver: AddressLike, _l1Token: AddressLike, + _mintValue: BigNumberish, _amount: BigNumberish, _l2TxGasLimit: BigNumberish, _l2TxGasPerPubdataByte: BigNumberish, @@ -291,10 +503,18 @@ export interface IL1Bridge extends BaseContract { [string], "payable" >; + getFunction( + nameOrSignature: "depositHappened" + ): TypedContractMethod< + [_chainId: BigNumberish, _l2TxHash: BytesLike], + [string], + "view" + >; getFunction( nameOrSignature: "finalizeWithdrawal" ): TypedContractMethod< [ + _chainId: BigNumberish, _l2BatchNumber: BigNumberish, _l2MessageIndex: BigNumberish, _l2TxNumberInBatch: BigNumberish, @@ -305,73 +525,110 @@ export interface IL1Bridge extends BaseContract { "nonpayable" >; getFunction( - nameOrSignature: "isWithdrawalFinalized" + nameOrSignature: "isWithdrawalFinalizedShared" ): TypedContractMethod< - [_l2BatchNumber: BigNumberish, _l2MessageIndex: BigNumberish], + [ + _chainId: BigNumberish, + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish + ], [boolean], "view" >; getFunction( - nameOrSignature: "l2Bridge" - ): TypedContractMethod<[], [string], "view">; - getFunction( - nameOrSignature: "l2TokenAddress" - ): TypedContractMethod<[_l1Token: AddressLike], [string], "view">; + nameOrSignature: "l2BridgeAddress" + ): TypedContractMethod<[_chainId: BigNumberish], [string], "view">; getEvent( - key: "ClaimedFailedDeposit" + key: "BridgehubDepositFinalized" + ): TypedContractEvent< + BridgehubDepositFinalizedEvent.InputTuple, + BridgehubDepositFinalizedEvent.OutputTuple, + BridgehubDepositFinalizedEvent.OutputObject + >; + getEvent( + key: "BridgehubDepositInitiatedSharedBridge" ): TypedContractEvent< - ClaimedFailedDepositEvent.InputTuple, - ClaimedFailedDepositEvent.OutputTuple, - ClaimedFailedDepositEvent.OutputObject + BridgehubDepositInitiatedSharedBridgeEvent.InputTuple, + BridgehubDepositInitiatedSharedBridgeEvent.OutputTuple, + BridgehubDepositInitiatedSharedBridgeEvent.OutputObject >; getEvent( - key: "DepositInitiated" + key: "ClaimedFailedDepositSharedBridge" ): TypedContractEvent< - DepositInitiatedEvent.InputTuple, - DepositInitiatedEvent.OutputTuple, - DepositInitiatedEvent.OutputObject + ClaimedFailedDepositSharedBridgeEvent.InputTuple, + ClaimedFailedDepositSharedBridgeEvent.OutputTuple, + ClaimedFailedDepositSharedBridgeEvent.OutputObject >; getEvent( - key: "WithdrawalFinalized" + key: "DepositInitiatedSharedBridge" ): TypedContractEvent< - WithdrawalFinalizedEvent.InputTuple, - WithdrawalFinalizedEvent.OutputTuple, - WithdrawalFinalizedEvent.OutputObject + DepositInitiatedSharedBridgeEvent.InputTuple, + DepositInitiatedSharedBridgeEvent.OutputTuple, + DepositInitiatedSharedBridgeEvent.OutputObject + >; + getEvent( + key: "WithdrawalFinalizedSharedBridge" + ): TypedContractEvent< + WithdrawalFinalizedSharedBridgeEvent.InputTuple, + WithdrawalFinalizedSharedBridgeEvent.OutputTuple, + WithdrawalFinalizedSharedBridgeEvent.OutputObject >; filters: { - "ClaimedFailedDeposit(address,address,uint256)": TypedContractEvent< - ClaimedFailedDepositEvent.InputTuple, - ClaimedFailedDepositEvent.OutputTuple, - ClaimedFailedDepositEvent.OutputObject + "BridgehubDepositFinalized(uint256,bytes32,bytes32)": TypedContractEvent< + BridgehubDepositFinalizedEvent.InputTuple, + BridgehubDepositFinalizedEvent.OutputTuple, + BridgehubDepositFinalizedEvent.OutputObject + >; + BridgehubDepositFinalized: TypedContractEvent< + BridgehubDepositFinalizedEvent.InputTuple, + BridgehubDepositFinalizedEvent.OutputTuple, + BridgehubDepositFinalizedEvent.OutputObject + >; + + "BridgehubDepositInitiatedSharedBridge(uint256,bytes32,address,address,address,uint256)": TypedContractEvent< + BridgehubDepositInitiatedSharedBridgeEvent.InputTuple, + BridgehubDepositInitiatedSharedBridgeEvent.OutputTuple, + BridgehubDepositInitiatedSharedBridgeEvent.OutputObject + >; + BridgehubDepositInitiatedSharedBridge: TypedContractEvent< + BridgehubDepositInitiatedSharedBridgeEvent.InputTuple, + BridgehubDepositInitiatedSharedBridgeEvent.OutputTuple, + BridgehubDepositInitiatedSharedBridgeEvent.OutputObject + >; + + "ClaimedFailedDepositSharedBridge(uint256,address,address,uint256)": TypedContractEvent< + ClaimedFailedDepositSharedBridgeEvent.InputTuple, + ClaimedFailedDepositSharedBridgeEvent.OutputTuple, + ClaimedFailedDepositSharedBridgeEvent.OutputObject >; - ClaimedFailedDeposit: TypedContractEvent< - ClaimedFailedDepositEvent.InputTuple, - ClaimedFailedDepositEvent.OutputTuple, - ClaimedFailedDepositEvent.OutputObject + ClaimedFailedDepositSharedBridge: TypedContractEvent< + ClaimedFailedDepositSharedBridgeEvent.InputTuple, + ClaimedFailedDepositSharedBridgeEvent.OutputTuple, + ClaimedFailedDepositSharedBridgeEvent.OutputObject >; - "DepositInitiated(bytes32,address,address,address,uint256)": TypedContractEvent< - DepositInitiatedEvent.InputTuple, - DepositInitiatedEvent.OutputTuple, - DepositInitiatedEvent.OutputObject + "DepositInitiatedSharedBridge(uint256,bytes32,address,address,address,uint256)": TypedContractEvent< + DepositInitiatedSharedBridgeEvent.InputTuple, + DepositInitiatedSharedBridgeEvent.OutputTuple, + DepositInitiatedSharedBridgeEvent.OutputObject >; - DepositInitiated: TypedContractEvent< - DepositInitiatedEvent.InputTuple, - DepositInitiatedEvent.OutputTuple, - DepositInitiatedEvent.OutputObject + DepositInitiatedSharedBridge: TypedContractEvent< + DepositInitiatedSharedBridgeEvent.InputTuple, + DepositInitiatedSharedBridgeEvent.OutputTuple, + DepositInitiatedSharedBridgeEvent.OutputObject >; - "WithdrawalFinalized(address,address,uint256)": TypedContractEvent< - WithdrawalFinalizedEvent.InputTuple, - WithdrawalFinalizedEvent.OutputTuple, - WithdrawalFinalizedEvent.OutputObject + "WithdrawalFinalizedSharedBridge(uint256,address,address,uint256)": TypedContractEvent< + WithdrawalFinalizedSharedBridgeEvent.InputTuple, + WithdrawalFinalizedSharedBridgeEvent.OutputTuple, + WithdrawalFinalizedSharedBridgeEvent.OutputObject >; - WithdrawalFinalized: TypedContractEvent< - WithdrawalFinalizedEvent.InputTuple, - WithdrawalFinalizedEvent.OutputTuple, - WithdrawalFinalizedEvent.OutputObject + WithdrawalFinalizedSharedBridge: TypedContractEvent< + WithdrawalFinalizedSharedBridgeEvent.InputTuple, + WithdrawalFinalizedSharedBridgeEvent.OutputTuple, + WithdrawalFinalizedSharedBridgeEvent.OutputObject >; }; } diff --git a/src/typechain/IL1ERC20Bridge.ts b/src/typechain/IL1ERC20Bridge.ts new file mode 100644 index 00000000..ac3d9395 --- /dev/null +++ b/src/typechain/IL1ERC20Bridge.ts @@ -0,0 +1,486 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { + BaseContract, + BigNumberish, + BytesLike, + FunctionFragment, + Result, + Interface, + EventFragment, + AddressLike, + ContractRunner, + ContractMethod, + Listener, +} from "ethers"; +import type { + TypedContractEvent, + TypedDeferredTopicFilter, + TypedEventLog, + TypedLogDescription, + TypedListener, + TypedContractMethod, +} from "./common"; + +export interface IL1ERC20BridgeInterface extends Interface { + getFunction( + nameOrSignature: + | "claimFailedDeposit" + | "deposit(address,address,uint256,uint256,uint256)" + | "deposit(address,address,uint256,uint256,uint256,address)" + | "depositAmount" + | "finalizeWithdrawal" + | "isWithdrawalFinalized" + | "l2Bridge" + | "l2TokenAddress" + | "l2TokenBeacon" + | "sharedBridge" + | "transferTokenToSharedBridge" + ): FunctionFragment; + + getEvent( + nameOrSignatureOrTopic: + | "ClaimedFailedDeposit" + | "DepositInitiated" + | "WithdrawalFinalized" + ): EventFragment; + + encodeFunctionData( + functionFragment: "claimFailedDeposit", + values: [ + AddressLike, + AddressLike, + BytesLike, + BigNumberish, + BigNumberish, + BigNumberish, + BytesLike[] + ] + ): string; + encodeFunctionData( + functionFragment: "deposit(address,address,uint256,uint256,uint256)", + values: [AddressLike, AddressLike, BigNumberish, BigNumberish, BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "deposit(address,address,uint256,uint256,uint256,address)", + values: [ + AddressLike, + AddressLike, + BigNumberish, + BigNumberish, + BigNumberish, + AddressLike + ] + ): string; + encodeFunctionData( + functionFragment: "depositAmount", + values: [AddressLike, AddressLike, BytesLike] + ): string; + encodeFunctionData( + functionFragment: "finalizeWithdrawal", + values: [BigNumberish, BigNumberish, BigNumberish, BytesLike, BytesLike[]] + ): string; + encodeFunctionData( + functionFragment: "isWithdrawalFinalized", + values: [BigNumberish, BigNumberish] + ): string; + encodeFunctionData(functionFragment: "l2Bridge", values?: undefined): string; + encodeFunctionData( + functionFragment: "l2TokenAddress", + values: [AddressLike] + ): string; + encodeFunctionData( + functionFragment: "l2TokenBeacon", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "sharedBridge", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "transferTokenToSharedBridge", + values: [AddressLike, BigNumberish] + ): string; + + decodeFunctionResult( + functionFragment: "claimFailedDeposit", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "deposit(address,address,uint256,uint256,uint256)", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "deposit(address,address,uint256,uint256,uint256,address)", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "depositAmount", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "finalizeWithdrawal", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "isWithdrawalFinalized", + data: BytesLike + ): Result; + decodeFunctionResult(functionFragment: "l2Bridge", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "l2TokenAddress", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "l2TokenBeacon", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "sharedBridge", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "transferTokenToSharedBridge", + data: BytesLike + ): Result; +} + +export namespace ClaimedFailedDepositEvent { + export type InputTuple = [ + to: AddressLike, + l1Token: AddressLike, + amount: BigNumberish + ]; + export type OutputTuple = [to: string, l1Token: string, amount: bigint]; + export interface OutputObject { + to: string; + l1Token: string; + amount: bigint; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace DepositInitiatedEvent { + export type InputTuple = [ + l2DepositTxHash: BytesLike, + from: AddressLike, + to: AddressLike, + l1Token: AddressLike, + amount: BigNumberish + ]; + export type OutputTuple = [ + l2DepositTxHash: string, + from: string, + to: string, + l1Token: string, + amount: bigint + ]; + export interface OutputObject { + l2DepositTxHash: string; + from: string; + to: string; + l1Token: string; + amount: bigint; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace WithdrawalFinalizedEvent { + export type InputTuple = [ + to: AddressLike, + l1Token: AddressLike, + amount: BigNumberish + ]; + export type OutputTuple = [to: string, l1Token: string, amount: bigint]; + export interface OutputObject { + to: string; + l1Token: string; + amount: bigint; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export interface IL1ERC20Bridge extends BaseContract { + connect(runner?: ContractRunner | null): IL1ERC20Bridge; + waitForDeployment(): Promise; + + interface: IL1ERC20BridgeInterface; + + queryFilter( + event: TCEvent, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>>; + queryFilter( + filter: TypedDeferredTopicFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>>; + + on( + event: TCEvent, + listener: TypedListener + ): Promise; + on( + filter: TypedDeferredTopicFilter, + listener: TypedListener + ): Promise; + + once( + event: TCEvent, + listener: TypedListener + ): Promise; + once( + filter: TypedDeferredTopicFilter, + listener: TypedListener + ): Promise; + + listeners( + event: TCEvent + ): Promise>>; + listeners(eventName?: string): Promise>; + removeAllListeners( + event?: TCEvent + ): Promise; + + claimFailedDeposit: TypedContractMethod< + [ + _depositSender: AddressLike, + _l1Token: AddressLike, + _l2TxHash: BytesLike, + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish, + _l2TxNumberInBatch: BigNumberish, + _merkleProof: BytesLike[] + ], + [void], + "nonpayable" + >; + + "deposit(address,address,uint256,uint256,uint256)": TypedContractMethod< + [ + _l2Receiver: AddressLike, + _l1Token: AddressLike, + _amount: BigNumberish, + _l2TxGasLimit: BigNumberish, + _l2TxGasPerPubdataByte: BigNumberish + ], + [string], + "payable" + >; + + "deposit(address,address,uint256,uint256,uint256,address)": TypedContractMethod< + [ + _l2Receiver: AddressLike, + _l1Token: AddressLike, + _amount: BigNumberish, + _l2TxGasLimit: BigNumberish, + _l2TxGasPerPubdataByte: BigNumberish, + _refundRecipient: AddressLike + ], + [string], + "payable" + >; + + depositAmount: TypedContractMethod< + [_account: AddressLike, _l1Token: AddressLike, _depositL2TxHash: BytesLike], + [bigint], + "nonpayable" + >; + + finalizeWithdrawal: TypedContractMethod< + [ + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish, + _l2TxNumberInBatch: BigNumberish, + _message: BytesLike, + _merkleProof: BytesLike[] + ], + [void], + "nonpayable" + >; + + isWithdrawalFinalized: TypedContractMethod< + [_l2BatchNumber: BigNumberish, _l2MessageIndex: BigNumberish], + [boolean], + "view" + >; + + l2Bridge: TypedContractMethod<[], [string], "view">; + + l2TokenAddress: TypedContractMethod< + [_l1Token: AddressLike], + [string], + "view" + >; + + l2TokenBeacon: TypedContractMethod<[], [string], "view">; + + sharedBridge: TypedContractMethod<[], [string], "view">; + + transferTokenToSharedBridge: TypedContractMethod< + [_token: AddressLike, _amount: BigNumberish], + [void], + "nonpayable" + >; + + getFunction( + key: string | FunctionFragment + ): T; + + getFunction( + nameOrSignature: "claimFailedDeposit" + ): TypedContractMethod< + [ + _depositSender: AddressLike, + _l1Token: AddressLike, + _l2TxHash: BytesLike, + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish, + _l2TxNumberInBatch: BigNumberish, + _merkleProof: BytesLike[] + ], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "deposit(address,address,uint256,uint256,uint256)" + ): TypedContractMethod< + [ + _l2Receiver: AddressLike, + _l1Token: AddressLike, + _amount: BigNumberish, + _l2TxGasLimit: BigNumberish, + _l2TxGasPerPubdataByte: BigNumberish + ], + [string], + "payable" + >; + getFunction( + nameOrSignature: "deposit(address,address,uint256,uint256,uint256,address)" + ): TypedContractMethod< + [ + _l2Receiver: AddressLike, + _l1Token: AddressLike, + _amount: BigNumberish, + _l2TxGasLimit: BigNumberish, + _l2TxGasPerPubdataByte: BigNumberish, + _refundRecipient: AddressLike + ], + [string], + "payable" + >; + getFunction( + nameOrSignature: "depositAmount" + ): TypedContractMethod< + [_account: AddressLike, _l1Token: AddressLike, _depositL2TxHash: BytesLike], + [bigint], + "nonpayable" + >; + getFunction( + nameOrSignature: "finalizeWithdrawal" + ): TypedContractMethod< + [ + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish, + _l2TxNumberInBatch: BigNumberish, + _message: BytesLike, + _merkleProof: BytesLike[] + ], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "isWithdrawalFinalized" + ): TypedContractMethod< + [_l2BatchNumber: BigNumberish, _l2MessageIndex: BigNumberish], + [boolean], + "view" + >; + getFunction( + nameOrSignature: "l2Bridge" + ): TypedContractMethod<[], [string], "view">; + getFunction( + nameOrSignature: "l2TokenAddress" + ): TypedContractMethod<[_l1Token: AddressLike], [string], "view">; + getFunction( + nameOrSignature: "l2TokenBeacon" + ): TypedContractMethod<[], [string], "view">; + getFunction( + nameOrSignature: "sharedBridge" + ): TypedContractMethod<[], [string], "view">; + getFunction( + nameOrSignature: "transferTokenToSharedBridge" + ): TypedContractMethod< + [_token: AddressLike, _amount: BigNumberish], + [void], + "nonpayable" + >; + + getEvent( + key: "ClaimedFailedDeposit" + ): TypedContractEvent< + ClaimedFailedDepositEvent.InputTuple, + ClaimedFailedDepositEvent.OutputTuple, + ClaimedFailedDepositEvent.OutputObject + >; + getEvent( + key: "DepositInitiated" + ): TypedContractEvent< + DepositInitiatedEvent.InputTuple, + DepositInitiatedEvent.OutputTuple, + DepositInitiatedEvent.OutputObject + >; + getEvent( + key: "WithdrawalFinalized" + ): TypedContractEvent< + WithdrawalFinalizedEvent.InputTuple, + WithdrawalFinalizedEvent.OutputTuple, + WithdrawalFinalizedEvent.OutputObject + >; + + filters: { + "ClaimedFailedDeposit(address,address,uint256)": TypedContractEvent< + ClaimedFailedDepositEvent.InputTuple, + ClaimedFailedDepositEvent.OutputTuple, + ClaimedFailedDepositEvent.OutputObject + >; + ClaimedFailedDeposit: TypedContractEvent< + ClaimedFailedDepositEvent.InputTuple, + ClaimedFailedDepositEvent.OutputTuple, + ClaimedFailedDepositEvent.OutputObject + >; + + "DepositInitiated(bytes32,address,address,address,uint256)": TypedContractEvent< + DepositInitiatedEvent.InputTuple, + DepositInitiatedEvent.OutputTuple, + DepositInitiatedEvent.OutputObject + >; + DepositInitiated: TypedContractEvent< + DepositInitiatedEvent.InputTuple, + DepositInitiatedEvent.OutputTuple, + DepositInitiatedEvent.OutputObject + >; + + "WithdrawalFinalized(address,address,uint256)": TypedContractEvent< + WithdrawalFinalizedEvent.InputTuple, + WithdrawalFinalizedEvent.OutputTuple, + WithdrawalFinalizedEvent.OutputObject + >; + WithdrawalFinalized: TypedContractEvent< + WithdrawalFinalizedEvent.InputTuple, + WithdrawalFinalizedEvent.OutputTuple, + WithdrawalFinalizedEvent.OutputObject + >; + }; +} diff --git a/src/typechain/IL1SharedBridge.ts b/src/typechain/IL1SharedBridge.ts new file mode 100644 index 00000000..72fc5872 --- /dev/null +++ b/src/typechain/IL1SharedBridge.ts @@ -0,0 +1,844 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { + BaseContract, + BigNumberish, + BytesLike, + FunctionFragment, + Result, + Interface, + EventFragment, + AddressLike, + ContractRunner, + ContractMethod, + Listener, +} from "ethers"; +import type { + TypedContractEvent, + TypedDeferredTopicFilter, + TypedEventLog, + TypedLogDescription, + TypedListener, + TypedContractMethod, +} from "./common"; + +export type L2TransactionRequestTwoBridgesInnerStruct = { + magicValue: BytesLike; + l2Contract: AddressLike; + l2Calldata: BytesLike; + factoryDeps: BytesLike[]; + txDataHash: BytesLike; +}; + +export type L2TransactionRequestTwoBridgesInnerStructOutput = [ + magicValue: string, + l2Contract: string, + l2Calldata: string, + factoryDeps: string[], + txDataHash: string +] & { + magicValue: string; + l2Contract: string; + l2Calldata: string; + factoryDeps: string[]; + txDataHash: string; +}; + +export interface IL1SharedBridgeInterface extends Interface { + getFunction( + nameOrSignature: + | "bridgehub" + | "bridgehubConfirmL2Transaction" + | "bridgehubDeposit" + | "bridgehubDepositBaseToken" + | "claimFailedDeposit" + | "claimFailedDepositLegacyErc20Bridge" + | "depositHappened" + | "depositLegacyErc20Bridge" + | "finalizeWithdrawal" + | "finalizeWithdrawalLegacyErc20Bridge" + | "isWithdrawalFinalized" + | "l1WethAddress" + | "l2BridgeAddress" + | "legacyBridge" + | "receiveEth" + | "setEraFirstPostUpgradeBatch" + ): FunctionFragment; + + getEvent( + nameOrSignatureOrTopic: + | "BridgehubDepositBaseTokenInitiated" + | "BridgehubDepositFinalized" + | "BridgehubDepositInitiated" + | "ClaimedFailedDepositSharedBridge" + | "LegacyDepositInitiated" + | "WithdrawalFinalizedSharedBridge" + ): EventFragment; + + encodeFunctionData(functionFragment: "bridgehub", values?: undefined): string; + encodeFunctionData( + functionFragment: "bridgehubConfirmL2Transaction", + values: [BigNumberish, BytesLike, BytesLike] + ): string; + encodeFunctionData( + functionFragment: "bridgehubDeposit", + values: [BigNumberish, AddressLike, BigNumberish, BytesLike] + ): string; + encodeFunctionData( + functionFragment: "bridgehubDepositBaseToken", + values: [BigNumberish, AddressLike, AddressLike, BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "claimFailedDeposit", + values: [ + BigNumberish, + AddressLike, + AddressLike, + BigNumberish, + BytesLike, + BigNumberish, + BigNumberish, + BigNumberish, + BytesLike[] + ] + ): string; + encodeFunctionData( + functionFragment: "claimFailedDepositLegacyErc20Bridge", + values: [ + AddressLike, + AddressLike, + BigNumberish, + BytesLike, + BigNumberish, + BigNumberish, + BigNumberish, + BytesLike[] + ] + ): string; + encodeFunctionData( + functionFragment: "depositHappened", + values: [BigNumberish, BytesLike] + ): string; + encodeFunctionData( + functionFragment: "depositLegacyErc20Bridge", + values: [ + AddressLike, + AddressLike, + AddressLike, + BigNumberish, + BigNumberish, + BigNumberish, + AddressLike + ] + ): string; + encodeFunctionData( + functionFragment: "finalizeWithdrawal", + values: [ + BigNumberish, + BigNumberish, + BigNumberish, + BigNumberish, + BytesLike, + BytesLike[] + ] + ): string; + encodeFunctionData( + functionFragment: "finalizeWithdrawalLegacyErc20Bridge", + values: [BigNumberish, BigNumberish, BigNumberish, BytesLike, BytesLike[]] + ): string; + encodeFunctionData( + functionFragment: "isWithdrawalFinalized", + values: [BigNumberish, BigNumberish, BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "l1WethAddress", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "l2BridgeAddress", + values: [BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "legacyBridge", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "receiveEth", + values: [BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "setEraFirstPostUpgradeBatch", + values: [BigNumberish] + ): string; + + decodeFunctionResult(functionFragment: "bridgehub", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "bridgehubConfirmL2Transaction", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "bridgehubDeposit", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "bridgehubDepositBaseToken", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "claimFailedDeposit", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "claimFailedDepositLegacyErc20Bridge", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "depositHappened", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "depositLegacyErc20Bridge", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "finalizeWithdrawal", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "finalizeWithdrawalLegacyErc20Bridge", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "isWithdrawalFinalized", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "l1WethAddress", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "l2BridgeAddress", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "legacyBridge", + data: BytesLike + ): Result; + decodeFunctionResult(functionFragment: "receiveEth", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "setEraFirstPostUpgradeBatch", + data: BytesLike + ): Result; +} + +export namespace BridgehubDepositBaseTokenInitiatedEvent { + export type InputTuple = [ + chainId: BigNumberish, + from: AddressLike, + l1Token: AddressLike, + amount: BigNumberish + ]; + export type OutputTuple = [ + chainId: bigint, + from: string, + l1Token: string, + amount: bigint + ]; + export interface OutputObject { + chainId: bigint; + from: string; + l1Token: string; + amount: bigint; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace BridgehubDepositFinalizedEvent { + export type InputTuple = [ + chainId: BigNumberish, + txDataHash: BytesLike, + l2DepositTxHash: BytesLike + ]; + export type OutputTuple = [ + chainId: bigint, + txDataHash: string, + l2DepositTxHash: string + ]; + export interface OutputObject { + chainId: bigint; + txDataHash: string; + l2DepositTxHash: string; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace BridgehubDepositInitiatedEvent { + export type InputTuple = [ + chainId: BigNumberish, + txDataHash: BytesLike, + from: AddressLike, + to: AddressLike, + l1Token: AddressLike, + amount: BigNumberish + ]; + export type OutputTuple = [ + chainId: bigint, + txDataHash: string, + from: string, + to: string, + l1Token: string, + amount: bigint + ]; + export interface OutputObject { + chainId: bigint; + txDataHash: string; + from: string; + to: string; + l1Token: string; + amount: bigint; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace ClaimedFailedDepositSharedBridgeEvent { + export type InputTuple = [ + chainId: BigNumberish, + to: AddressLike, + l1Token: AddressLike, + amount: BigNumberish + ]; + export type OutputTuple = [ + chainId: bigint, + to: string, + l1Token: string, + amount: bigint + ]; + export interface OutputObject { + chainId: bigint; + to: string; + l1Token: string; + amount: bigint; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace LegacyDepositInitiatedEvent { + export type InputTuple = [ + chainId: BigNumberish, + l2DepositTxHash: BytesLike, + from: AddressLike, + to: AddressLike, + l1Token: AddressLike, + amount: BigNumberish + ]; + export type OutputTuple = [ + chainId: bigint, + l2DepositTxHash: string, + from: string, + to: string, + l1Token: string, + amount: bigint + ]; + export interface OutputObject { + chainId: bigint; + l2DepositTxHash: string; + from: string; + to: string; + l1Token: string; + amount: bigint; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace WithdrawalFinalizedSharedBridgeEvent { + export type InputTuple = [ + chainId: BigNumberish, + to: AddressLike, + l1Token: AddressLike, + amount: BigNumberish + ]; + export type OutputTuple = [ + chainId: bigint, + to: string, + l1Token: string, + amount: bigint + ]; + export interface OutputObject { + chainId: bigint; + to: string; + l1Token: string; + amount: bigint; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export interface IL1SharedBridge extends BaseContract { + connect(runner?: ContractRunner | null): IL1SharedBridge; + waitForDeployment(): Promise; + + interface: IL1SharedBridgeInterface; + + queryFilter( + event: TCEvent, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>>; + queryFilter( + filter: TypedDeferredTopicFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>>; + + on( + event: TCEvent, + listener: TypedListener + ): Promise; + on( + filter: TypedDeferredTopicFilter, + listener: TypedListener + ): Promise; + + once( + event: TCEvent, + listener: TypedListener + ): Promise; + once( + filter: TypedDeferredTopicFilter, + listener: TypedListener + ): Promise; + + listeners( + event: TCEvent + ): Promise>>; + listeners(eventName?: string): Promise>; + removeAllListeners( + event?: TCEvent + ): Promise; + + bridgehub: TypedContractMethod<[], [string], "view">; + + bridgehubConfirmL2Transaction: TypedContractMethod< + [_chainId: BigNumberish, _txDataHash: BytesLike, _txHash: BytesLike], + [void], + "nonpayable" + >; + + bridgehubDeposit: TypedContractMethod< + [ + _chainId: BigNumberish, + _prevMsgSender: AddressLike, + _l2Value: BigNumberish, + _data: BytesLike + ], + [L2TransactionRequestTwoBridgesInnerStructOutput], + "payable" + >; + + bridgehubDepositBaseToken: TypedContractMethod< + [ + _chainId: BigNumberish, + _prevMsgSender: AddressLike, + _l1Token: AddressLike, + _amount: BigNumberish + ], + [void], + "payable" + >; + + claimFailedDeposit: TypedContractMethod< + [ + _chainId: BigNumberish, + _depositSender: AddressLike, + _l1Token: AddressLike, + _amount: BigNumberish, + _l2TxHash: BytesLike, + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish, + _l2TxNumberInBatch: BigNumberish, + _merkleProof: BytesLike[] + ], + [void], + "nonpayable" + >; + + claimFailedDepositLegacyErc20Bridge: TypedContractMethod< + [ + _depositSender: AddressLike, + _l1Token: AddressLike, + _amount: BigNumberish, + _l2TxHash: BytesLike, + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish, + _l2TxNumberInBatch: BigNumberish, + _merkleProof: BytesLike[] + ], + [void], + "nonpayable" + >; + + depositHappened: TypedContractMethod< + [_chainId: BigNumberish, _l2TxHash: BytesLike], + [string], + "view" + >; + + depositLegacyErc20Bridge: TypedContractMethod< + [ + _msgSender: AddressLike, + _l2Receiver: AddressLike, + _l1Token: AddressLike, + _amount: BigNumberish, + _l2TxGasLimit: BigNumberish, + _l2TxGasPerPubdataByte: BigNumberish, + _refundRecipient: AddressLike + ], + [string], + "payable" + >; + + finalizeWithdrawal: TypedContractMethod< + [ + _chainId: BigNumberish, + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish, + _l2TxNumberInBatch: BigNumberish, + _message: BytesLike, + _merkleProof: BytesLike[] + ], + [void], + "nonpayable" + >; + + finalizeWithdrawalLegacyErc20Bridge: TypedContractMethod< + [ + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish, + _l2TxNumberInBatch: BigNumberish, + _message: BytesLike, + _merkleProof: BytesLike[] + ], + [ + [string, string, bigint] & { + l1Receiver: string; + l1Token: string; + amount: bigint; + } + ], + "nonpayable" + >; + + isWithdrawalFinalized: TypedContractMethod< + [ + _chainId: BigNumberish, + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish + ], + [boolean], + "view" + >; + + l1WethAddress: TypedContractMethod<[], [string], "view">; + + l2BridgeAddress: TypedContractMethod< + [_chainId: BigNumberish], + [string], + "view" + >; + + legacyBridge: TypedContractMethod<[], [string], "view">; + + receiveEth: TypedContractMethod<[_chainId: BigNumberish], [void], "payable">; + + setEraFirstPostUpgradeBatch: TypedContractMethod< + [_eraFirstPostUpgradeBatch: BigNumberish], + [void], + "nonpayable" + >; + + getFunction( + key: string | FunctionFragment + ): T; + + getFunction( + nameOrSignature: "bridgehub" + ): TypedContractMethod<[], [string], "view">; + getFunction( + nameOrSignature: "bridgehubConfirmL2Transaction" + ): TypedContractMethod< + [_chainId: BigNumberish, _txDataHash: BytesLike, _txHash: BytesLike], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "bridgehubDeposit" + ): TypedContractMethod< + [ + _chainId: BigNumberish, + _prevMsgSender: AddressLike, + _l2Value: BigNumberish, + _data: BytesLike + ], + [L2TransactionRequestTwoBridgesInnerStructOutput], + "payable" + >; + getFunction( + nameOrSignature: "bridgehubDepositBaseToken" + ): TypedContractMethod< + [ + _chainId: BigNumberish, + _prevMsgSender: AddressLike, + _l1Token: AddressLike, + _amount: BigNumberish + ], + [void], + "payable" + >; + getFunction( + nameOrSignature: "claimFailedDeposit" + ): TypedContractMethod< + [ + _chainId: BigNumberish, + _depositSender: AddressLike, + _l1Token: AddressLike, + _amount: BigNumberish, + _l2TxHash: BytesLike, + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish, + _l2TxNumberInBatch: BigNumberish, + _merkleProof: BytesLike[] + ], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "claimFailedDepositLegacyErc20Bridge" + ): TypedContractMethod< + [ + _depositSender: AddressLike, + _l1Token: AddressLike, + _amount: BigNumberish, + _l2TxHash: BytesLike, + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish, + _l2TxNumberInBatch: BigNumberish, + _merkleProof: BytesLike[] + ], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "depositHappened" + ): TypedContractMethod< + [_chainId: BigNumberish, _l2TxHash: BytesLike], + [string], + "view" + >; + getFunction( + nameOrSignature: "depositLegacyErc20Bridge" + ): TypedContractMethod< + [ + _msgSender: AddressLike, + _l2Receiver: AddressLike, + _l1Token: AddressLike, + _amount: BigNumberish, + _l2TxGasLimit: BigNumberish, + _l2TxGasPerPubdataByte: BigNumberish, + _refundRecipient: AddressLike + ], + [string], + "payable" + >; + getFunction( + nameOrSignature: "finalizeWithdrawal" + ): TypedContractMethod< + [ + _chainId: BigNumberish, + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish, + _l2TxNumberInBatch: BigNumberish, + _message: BytesLike, + _merkleProof: BytesLike[] + ], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "finalizeWithdrawalLegacyErc20Bridge" + ): TypedContractMethod< + [ + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish, + _l2TxNumberInBatch: BigNumberish, + _message: BytesLike, + _merkleProof: BytesLike[] + ], + [ + [string, string, bigint] & { + l1Receiver: string; + l1Token: string; + amount: bigint; + } + ], + "nonpayable" + >; + getFunction( + nameOrSignature: "isWithdrawalFinalized" + ): TypedContractMethod< + [ + _chainId: BigNumberish, + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish + ], + [boolean], + "view" + >; + getFunction( + nameOrSignature: "l1WethAddress" + ): TypedContractMethod<[], [string], "view">; + getFunction( + nameOrSignature: "l2BridgeAddress" + ): TypedContractMethod<[_chainId: BigNumberish], [string], "view">; + getFunction( + nameOrSignature: "legacyBridge" + ): TypedContractMethod<[], [string], "view">; + getFunction( + nameOrSignature: "receiveEth" + ): TypedContractMethod<[_chainId: BigNumberish], [void], "payable">; + getFunction( + nameOrSignature: "setEraFirstPostUpgradeBatch" + ): TypedContractMethod< + [_eraFirstPostUpgradeBatch: BigNumberish], + [void], + "nonpayable" + >; + + getEvent( + key: "BridgehubDepositBaseTokenInitiated" + ): TypedContractEvent< + BridgehubDepositBaseTokenInitiatedEvent.InputTuple, + BridgehubDepositBaseTokenInitiatedEvent.OutputTuple, + BridgehubDepositBaseTokenInitiatedEvent.OutputObject + >; + getEvent( + key: "BridgehubDepositFinalized" + ): TypedContractEvent< + BridgehubDepositFinalizedEvent.InputTuple, + BridgehubDepositFinalizedEvent.OutputTuple, + BridgehubDepositFinalizedEvent.OutputObject + >; + getEvent( + key: "BridgehubDepositInitiated" + ): TypedContractEvent< + BridgehubDepositInitiatedEvent.InputTuple, + BridgehubDepositInitiatedEvent.OutputTuple, + BridgehubDepositInitiatedEvent.OutputObject + >; + getEvent( + key: "ClaimedFailedDepositSharedBridge" + ): TypedContractEvent< + ClaimedFailedDepositSharedBridgeEvent.InputTuple, + ClaimedFailedDepositSharedBridgeEvent.OutputTuple, + ClaimedFailedDepositSharedBridgeEvent.OutputObject + >; + getEvent( + key: "LegacyDepositInitiated" + ): TypedContractEvent< + LegacyDepositInitiatedEvent.InputTuple, + LegacyDepositInitiatedEvent.OutputTuple, + LegacyDepositInitiatedEvent.OutputObject + >; + getEvent( + key: "WithdrawalFinalizedSharedBridge" + ): TypedContractEvent< + WithdrawalFinalizedSharedBridgeEvent.InputTuple, + WithdrawalFinalizedSharedBridgeEvent.OutputTuple, + WithdrawalFinalizedSharedBridgeEvent.OutputObject + >; + + filters: { + "BridgehubDepositBaseTokenInitiated(uint256,address,address,uint256)": TypedContractEvent< + BridgehubDepositBaseTokenInitiatedEvent.InputTuple, + BridgehubDepositBaseTokenInitiatedEvent.OutputTuple, + BridgehubDepositBaseTokenInitiatedEvent.OutputObject + >; + BridgehubDepositBaseTokenInitiated: TypedContractEvent< + BridgehubDepositBaseTokenInitiatedEvent.InputTuple, + BridgehubDepositBaseTokenInitiatedEvent.OutputTuple, + BridgehubDepositBaseTokenInitiatedEvent.OutputObject + >; + + "BridgehubDepositFinalized(uint256,bytes32,bytes32)": TypedContractEvent< + BridgehubDepositFinalizedEvent.InputTuple, + BridgehubDepositFinalizedEvent.OutputTuple, + BridgehubDepositFinalizedEvent.OutputObject + >; + BridgehubDepositFinalized: TypedContractEvent< + BridgehubDepositFinalizedEvent.InputTuple, + BridgehubDepositFinalizedEvent.OutputTuple, + BridgehubDepositFinalizedEvent.OutputObject + >; + + "BridgehubDepositInitiated(uint256,bytes32,address,address,address,uint256)": TypedContractEvent< + BridgehubDepositInitiatedEvent.InputTuple, + BridgehubDepositInitiatedEvent.OutputTuple, + BridgehubDepositInitiatedEvent.OutputObject + >; + BridgehubDepositInitiated: TypedContractEvent< + BridgehubDepositInitiatedEvent.InputTuple, + BridgehubDepositInitiatedEvent.OutputTuple, + BridgehubDepositInitiatedEvent.OutputObject + >; + + "ClaimedFailedDepositSharedBridge(uint256,address,address,uint256)": TypedContractEvent< + ClaimedFailedDepositSharedBridgeEvent.InputTuple, + ClaimedFailedDepositSharedBridgeEvent.OutputTuple, + ClaimedFailedDepositSharedBridgeEvent.OutputObject + >; + ClaimedFailedDepositSharedBridge: TypedContractEvent< + ClaimedFailedDepositSharedBridgeEvent.InputTuple, + ClaimedFailedDepositSharedBridgeEvent.OutputTuple, + ClaimedFailedDepositSharedBridgeEvent.OutputObject + >; + + "LegacyDepositInitiated(uint256,bytes32,address,address,address,uint256)": TypedContractEvent< + LegacyDepositInitiatedEvent.InputTuple, + LegacyDepositInitiatedEvent.OutputTuple, + LegacyDepositInitiatedEvent.OutputObject + >; + LegacyDepositInitiated: TypedContractEvent< + LegacyDepositInitiatedEvent.InputTuple, + LegacyDepositInitiatedEvent.OutputTuple, + LegacyDepositInitiatedEvent.OutputObject + >; + + "WithdrawalFinalizedSharedBridge(uint256,address,address,uint256)": TypedContractEvent< + WithdrawalFinalizedSharedBridgeEvent.InputTuple, + WithdrawalFinalizedSharedBridgeEvent.OutputTuple, + WithdrawalFinalizedSharedBridgeEvent.OutputObject + >; + WithdrawalFinalizedSharedBridge: TypedContractEvent< + WithdrawalFinalizedSharedBridgeEvent.InputTuple, + WithdrawalFinalizedSharedBridgeEvent.OutputTuple, + WithdrawalFinalizedSharedBridgeEvent.OutputObject + >; + }; +} diff --git a/src/typechain/ITestnetERC20Token.ts b/src/typechain/ITestnetERC20Token.ts new file mode 100644 index 00000000..d13cc526 --- /dev/null +++ b/src/typechain/ITestnetERC20Token.ts @@ -0,0 +1,104 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { + BaseContract, + BigNumberish, + BytesLike, + FunctionFragment, + Result, + Interface, + AddressLike, + ContractRunner, + ContractMethod, + Listener, +} from "ethers"; +import type { + TypedContractEvent, + TypedDeferredTopicFilter, + TypedEventLog, + TypedListener, + TypedContractMethod, +} from "./common"; + +export interface ITestnetERC20TokenInterface extends Interface { + getFunction(nameOrSignature: "decimals" | "mint"): FunctionFragment; + + encodeFunctionData(functionFragment: "decimals", values?: undefined): string; + encodeFunctionData( + functionFragment: "mint", + values: [AddressLike, BigNumberish] + ): string; + + decodeFunctionResult(functionFragment: "decimals", data: BytesLike): Result; + decodeFunctionResult(functionFragment: "mint", data: BytesLike): Result; +} + +export interface ITestnetERC20Token extends BaseContract { + connect(runner?: ContractRunner | null): ITestnetERC20Token; + waitForDeployment(): Promise; + + interface: ITestnetERC20TokenInterface; + + queryFilter( + event: TCEvent, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>>; + queryFilter( + filter: TypedDeferredTopicFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>>; + + on( + event: TCEvent, + listener: TypedListener + ): Promise; + on( + filter: TypedDeferredTopicFilter, + listener: TypedListener + ): Promise; + + once( + event: TCEvent, + listener: TypedListener + ): Promise; + once( + filter: TypedDeferredTopicFilter, + listener: TypedListener + ): Promise; + + listeners( + event: TCEvent + ): Promise>>; + listeners(eventName?: string): Promise>; + removeAllListeners( + event?: TCEvent + ): Promise; + + decimals: TypedContractMethod<[], [bigint], "nonpayable">; + + mint: TypedContractMethod< + [_to: AddressLike, _amount: BigNumberish], + [boolean], + "nonpayable" + >; + + getFunction( + key: string | FunctionFragment + ): T; + + getFunction( + nameOrSignature: "decimals" + ): TypedContractMethod<[], [bigint], "nonpayable">; + getFunction( + nameOrSignature: "mint" + ): TypedContractMethod< + [_to: AddressLike, _amount: BigNumberish], + [boolean], + "nonpayable" + >; + + filters: {}; +} diff --git a/src/typechain/IZkSyncStateTransition.ts b/src/typechain/IZkSyncStateTransition.ts new file mode 100644 index 00000000..2675853b --- /dev/null +++ b/src/typechain/IZkSyncStateTransition.ts @@ -0,0 +1,2336 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { + BaseContract, + BigNumberish, + BytesLike, + FunctionFragment, + Result, + Interface, + EventFragment, + AddressLike, + ContractRunner, + ContractMethod, + Listener, +} from "ethers"; +import type { + TypedContractEvent, + TypedDeferredTopicFilter, + TypedEventLog, + TypedLogDescription, + TypedListener, + TypedContractMethod, +} from "./common"; + +export type FeeParamsStruct = { + pubdataPricingMode: BigNumberish; + batchOverheadL1Gas: BigNumberish; + maxPubdataPerBatch: BigNumberish; + maxL2GasPerBatch: BigNumberish; + priorityTxMaxPubdata: BigNumberish; + minimalL2GasPrice: BigNumberish; +}; + +export type FeeParamsStructOutput = [ + pubdataPricingMode: bigint, + batchOverheadL1Gas: bigint, + maxPubdataPerBatch: bigint, + maxL2GasPerBatch: bigint, + priorityTxMaxPubdata: bigint, + minimalL2GasPrice: bigint +] & { + pubdataPricingMode: bigint; + batchOverheadL1Gas: bigint; + maxPubdataPerBatch: bigint; + maxL2GasPerBatch: bigint; + priorityTxMaxPubdata: bigint; + minimalL2GasPrice: bigint; +}; + +export type L2CanonicalTransactionStruct = { + txType: BigNumberish; + from: BigNumberish; + to: BigNumberish; + gasLimit: BigNumberish; + gasPerPubdataByteLimit: BigNumberish; + maxFeePerGas: BigNumberish; + maxPriorityFeePerGas: BigNumberish; + paymaster: BigNumberish; + nonce: BigNumberish; + value: BigNumberish; + reserved: [BigNumberish, BigNumberish, BigNumberish, BigNumberish]; + data: BytesLike; + signature: BytesLike; + factoryDeps: BigNumberish[]; + paymasterInput: BytesLike; + reservedDynamic: BytesLike; +}; + +export type L2CanonicalTransactionStructOutput = [ + txType: bigint, + from: bigint, + to: bigint, + gasLimit: bigint, + gasPerPubdataByteLimit: bigint, + maxFeePerGas: bigint, + maxPriorityFeePerGas: bigint, + paymaster: bigint, + nonce: bigint, + value: bigint, + reserved: [bigint, bigint, bigint, bigint], + data: string, + signature: string, + factoryDeps: bigint[], + paymasterInput: string, + reservedDynamic: string +] & { + txType: bigint; + from: bigint; + to: bigint; + gasLimit: bigint; + gasPerPubdataByteLimit: bigint; + maxFeePerGas: bigint; + maxPriorityFeePerGas: bigint; + paymaster: bigint; + nonce: bigint; + value: bigint; + reserved: [bigint, bigint, bigint, bigint]; + data: string; + signature: string; + factoryDeps: bigint[]; + paymasterInput: string; + reservedDynamic: string; +}; + +export type BridgehubL2TransactionRequestStruct = { + sender: AddressLike; + contractL2: AddressLike; + mintValue: BigNumberish; + l2Value: BigNumberish; + l2Calldata: BytesLike; + l2GasLimit: BigNumberish; + l2GasPerPubdataByteLimit: BigNumberish; + factoryDeps: BytesLike[]; + refundRecipient: AddressLike; +}; + +export type BridgehubL2TransactionRequestStructOutput = [ + sender: string, + contractL2: string, + mintValue: bigint, + l2Value: bigint, + l2Calldata: string, + l2GasLimit: bigint, + l2GasPerPubdataByteLimit: bigint, + factoryDeps: string[], + refundRecipient: string +] & { + sender: string; + contractL2: string; + mintValue: bigint; + l2Value: bigint; + l2Calldata: string; + l2GasLimit: bigint; + l2GasPerPubdataByteLimit: bigint; + factoryDeps: string[]; + refundRecipient: string; +}; + +export type VerifierParamsStruct = { + recursionNodeLevelVkHash: BytesLike; + recursionLeafLevelVkHash: BytesLike; + recursionCircuitsSetVksHash: BytesLike; +}; + +export type VerifierParamsStructOutput = [ + recursionNodeLevelVkHash: string, + recursionLeafLevelVkHash: string, + recursionCircuitsSetVksHash: string +] & { + recursionNodeLevelVkHash: string; + recursionLeafLevelVkHash: string; + recursionCircuitsSetVksHash: string; +}; + +export type PriorityOperationStruct = { + canonicalTxHash: BytesLike; + expirationTimestamp: BigNumberish; + layer2Tip: BigNumberish; +}; + +export type PriorityOperationStructOutput = [ + canonicalTxHash: string, + expirationTimestamp: bigint, + layer2Tip: bigint +] & { canonicalTxHash: string; expirationTimestamp: bigint; layer2Tip: bigint }; + +export type L2LogStruct = { + l2ShardId: BigNumberish; + isService: boolean; + txNumberInBatch: BigNumberish; + sender: AddressLike; + key: BytesLike; + value: BytesLike; +}; + +export type L2LogStructOutput = [ + l2ShardId: bigint, + isService: boolean, + txNumberInBatch: bigint, + sender: string, + key: string, + value: string +] & { + l2ShardId: bigint; + isService: boolean; + txNumberInBatch: bigint; + sender: string; + key: string; + value: string; +}; + +export type L2MessageStruct = { + txNumberInBatch: BigNumberish; + sender: AddressLike; + data: BytesLike; +}; + +export type L2MessageStructOutput = [ + txNumberInBatch: bigint, + sender: string, + data: string +] & { txNumberInBatch: bigint; sender: string; data: string }; + +export declare namespace Diamond { + export type FacetCutStruct = { + facet: AddressLike; + action: BigNumberish; + isFreezable: boolean; + selectors: BytesLike[]; + }; + + export type FacetCutStructOutput = [ + facet: string, + action: bigint, + isFreezable: boolean, + selectors: string[] + ] & { + facet: string; + action: bigint; + isFreezable: boolean; + selectors: string[]; + }; + + export type DiamondCutDataStruct = { + facetCuts: Diamond.FacetCutStruct[]; + initAddress: AddressLike; + initCalldata: BytesLike; + }; + + export type DiamondCutDataStructOutput = [ + facetCuts: Diamond.FacetCutStructOutput[], + initAddress: string, + initCalldata: string + ] & { + facetCuts: Diamond.FacetCutStructOutput[]; + initAddress: string; + initCalldata: string; + }; +} + +export declare namespace IExecutor { + export type StoredBatchInfoStruct = { + batchNumber: BigNumberish; + batchHash: BytesLike; + indexRepeatedStorageChanges: BigNumberish; + numberOfLayer1Txs: BigNumberish; + priorityOperationsHash: BytesLike; + l2LogsTreeRoot: BytesLike; + timestamp: BigNumberish; + commitment: BytesLike; + }; + + export type StoredBatchInfoStructOutput = [ + batchNumber: bigint, + batchHash: string, + indexRepeatedStorageChanges: bigint, + numberOfLayer1Txs: bigint, + priorityOperationsHash: string, + l2LogsTreeRoot: string, + timestamp: bigint, + commitment: string + ] & { + batchNumber: bigint; + batchHash: string; + indexRepeatedStorageChanges: bigint; + numberOfLayer1Txs: bigint; + priorityOperationsHash: string; + l2LogsTreeRoot: string; + timestamp: bigint; + commitment: string; + }; + + export type CommitBatchInfoStruct = { + batchNumber: BigNumberish; + timestamp: BigNumberish; + indexRepeatedStorageChanges: BigNumberish; + newStateRoot: BytesLike; + numberOfLayer1Txs: BigNumberish; + priorityOperationsHash: BytesLike; + bootloaderHeapInitialContentsHash: BytesLike; + eventsQueueStateHash: BytesLike; + systemLogs: BytesLike; + pubdataCommitments: BytesLike; + }; + + export type CommitBatchInfoStructOutput = [ + batchNumber: bigint, + timestamp: bigint, + indexRepeatedStorageChanges: bigint, + newStateRoot: string, + numberOfLayer1Txs: bigint, + priorityOperationsHash: string, + bootloaderHeapInitialContentsHash: string, + eventsQueueStateHash: string, + systemLogs: string, + pubdataCommitments: string + ] & { + batchNumber: bigint; + timestamp: bigint; + indexRepeatedStorageChanges: bigint; + newStateRoot: string; + numberOfLayer1Txs: bigint; + priorityOperationsHash: string; + bootloaderHeapInitialContentsHash: string; + eventsQueueStateHash: string; + systemLogs: string; + pubdataCommitments: string; + }; + + export type ProofInputStruct = { + recursiveAggregationInput: BigNumberish[]; + serializedProof: BigNumberish[]; + }; + + export type ProofInputStructOutput = [ + recursiveAggregationInput: bigint[], + serializedProof: bigint[] + ] & { recursiveAggregationInput: bigint[]; serializedProof: bigint[] }; +} + +export declare namespace IGetters { + export type FacetStruct = { addr: AddressLike; selectors: BytesLike[] }; + + export type FacetStructOutput = [addr: string, selectors: string[]] & { + addr: string; + selectors: string[]; + }; +} + +export interface IZkSyncStateTransitionInterface extends Interface { + getFunction( + nameOrSignature: + | "acceptAdmin" + | "baseTokenGasPriceMultiplierDenominator" + | "baseTokenGasPriceMultiplierNominator" + | "bridgehubRequestL2Transaction" + | "changeFeeParams" + | "commitBatches" + | "commitBatchesSharedBridge" + | "executeBatches" + | "executeBatchesSharedBridge" + | "executeUpgrade" + | "facetAddress" + | "facetAddresses" + | "facetFunctionSelectors" + | "facets" + | "finalizeEthWithdrawal" + | "freezeDiamond" + | "getAdmin" + | "getBaseToken" + | "getBaseTokenBridge" + | "getBridgehub" + | "getFirstUnprocessedPriorityTx" + | "getL2BootloaderBytecodeHash" + | "getL2DefaultAccountBytecodeHash" + | "getL2SystemContractsUpgradeBatchNumber" + | "getL2SystemContractsUpgradeTxHash" + | "getName" + | "getPendingAdmin" + | "getPriorityQueueSize" + | "getPriorityTxMaxGasLimit" + | "getProtocolVersion" + | "getPubdataPricingMode" + | "getStateTransitionManager" + | "getTotalBatchesCommitted" + | "getTotalBatchesExecuted" + | "getTotalBatchesVerified" + | "getTotalPriorityTxs" + | "getVerifier" + | "getVerifierParams" + | "isDiamondStorageFrozen" + | "isEthWithdrawalFinalized" + | "isFacetFreezable" + | "isFunctionFreezable" + | "isValidator" + | "l2LogsRootHash" + | "l2TransactionBaseCost" + | "priorityQueueFrontOperation" + | "proveBatches" + | "proveBatchesSharedBridge" + | "proveL1ToL2TransactionStatus" + | "proveL2LogInclusion" + | "proveL2MessageInclusion" + | "requestL2Transaction" + | "revertBatches" + | "revertBatchesSharedBridge" + | "setPendingAdmin" + | "setPorterAvailability" + | "setPriorityTxMaxGasLimit" + | "setTokenMultiplier" + | "setTransactionFilterer" + | "setValidator" + | "setValidiumMode" + | "storedBatchHash" + | "transferEthToSharedBridge" + | "unfreezeDiamond" + | "upgradeChainFromVersion" + ): FunctionFragment; + + getEvent( + nameOrSignatureOrTopic: + | "BlockCommit" + | "BlockExecution" + | "BlocksRevert" + | "BlocksVerification" + | "EthWithdrawalFinalized" + | "ExecuteUpgrade" + | "Freeze" + | "IsPorterAvailableStatusUpdate" + | "NewAdmin" + | "NewBaseTokenMultiplier" + | "NewFeeParams" + | "NewPendingAdmin" + | "NewPriorityRequest" + | "NewPriorityTxMaxGasLimit" + | "NewTransactionFilterer" + | "ProposeTransparentUpgrade" + | "Unfreeze" + | "ValidatorStatusUpdate" + | "ValidiumModeStatusUpdate" + ): EventFragment; + + encodeFunctionData( + functionFragment: "acceptAdmin", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "baseTokenGasPriceMultiplierDenominator", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "baseTokenGasPriceMultiplierNominator", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "bridgehubRequestL2Transaction", + values: [BridgehubL2TransactionRequestStruct] + ): string; + encodeFunctionData( + functionFragment: "changeFeeParams", + values: [FeeParamsStruct] + ): string; + encodeFunctionData( + functionFragment: "commitBatches", + values: [IExecutor.StoredBatchInfoStruct, IExecutor.CommitBatchInfoStruct[]] + ): string; + encodeFunctionData( + functionFragment: "commitBatchesSharedBridge", + values: [ + BigNumberish, + IExecutor.StoredBatchInfoStruct, + IExecutor.CommitBatchInfoStruct[] + ] + ): string; + encodeFunctionData( + functionFragment: "executeBatches", + values: [IExecutor.StoredBatchInfoStruct[]] + ): string; + encodeFunctionData( + functionFragment: "executeBatchesSharedBridge", + values: [BigNumberish, IExecutor.StoredBatchInfoStruct[]] + ): string; + encodeFunctionData( + functionFragment: "executeUpgrade", + values: [Diamond.DiamondCutDataStruct] + ): string; + encodeFunctionData( + functionFragment: "facetAddress", + values: [BytesLike] + ): string; + encodeFunctionData( + functionFragment: "facetAddresses", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "facetFunctionSelectors", + values: [AddressLike] + ): string; + encodeFunctionData(functionFragment: "facets", values?: undefined): string; + encodeFunctionData( + functionFragment: "finalizeEthWithdrawal", + values: [BigNumberish, BigNumberish, BigNumberish, BytesLike, BytesLike[]] + ): string; + encodeFunctionData( + functionFragment: "freezeDiamond", + values?: undefined + ): string; + encodeFunctionData(functionFragment: "getAdmin", values?: undefined): string; + encodeFunctionData( + functionFragment: "getBaseToken", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "getBaseTokenBridge", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "getBridgehub", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "getFirstUnprocessedPriorityTx", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "getL2BootloaderBytecodeHash", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "getL2DefaultAccountBytecodeHash", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "getL2SystemContractsUpgradeBatchNumber", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "getL2SystemContractsUpgradeTxHash", + values?: undefined + ): string; + encodeFunctionData(functionFragment: "getName", values?: undefined): string; + encodeFunctionData( + functionFragment: "getPendingAdmin", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "getPriorityQueueSize", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "getPriorityTxMaxGasLimit", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "getProtocolVersion", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "getPubdataPricingMode", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "getStateTransitionManager", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "getTotalBatchesCommitted", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "getTotalBatchesExecuted", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "getTotalBatchesVerified", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "getTotalPriorityTxs", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "getVerifier", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "getVerifierParams", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "isDiamondStorageFrozen", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "isEthWithdrawalFinalized", + values: [BigNumberish, BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "isFacetFreezable", + values: [AddressLike] + ): string; + encodeFunctionData( + functionFragment: "isFunctionFreezable", + values: [BytesLike] + ): string; + encodeFunctionData( + functionFragment: "isValidator", + values: [AddressLike] + ): string; + encodeFunctionData( + functionFragment: "l2LogsRootHash", + values: [BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "l2TransactionBaseCost", + values: [BigNumberish, BigNumberish, BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "priorityQueueFrontOperation", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "proveBatches", + values: [ + IExecutor.StoredBatchInfoStruct, + IExecutor.StoredBatchInfoStruct[], + IExecutor.ProofInputStruct + ] + ): string; + encodeFunctionData( + functionFragment: "proveBatchesSharedBridge", + values: [ + BigNumberish, + IExecutor.StoredBatchInfoStruct, + IExecutor.StoredBatchInfoStruct[], + IExecutor.ProofInputStruct + ] + ): string; + encodeFunctionData( + functionFragment: "proveL1ToL2TransactionStatus", + values: [ + BytesLike, + BigNumberish, + BigNumberish, + BigNumberish, + BytesLike[], + BigNumberish + ] + ): string; + encodeFunctionData( + functionFragment: "proveL2LogInclusion", + values: [BigNumberish, BigNumberish, L2LogStruct, BytesLike[]] + ): string; + encodeFunctionData( + functionFragment: "proveL2MessageInclusion", + values: [BigNumberish, BigNumberish, L2MessageStruct, BytesLike[]] + ): string; + encodeFunctionData( + functionFragment: "requestL2Transaction", + values: [ + AddressLike, + BigNumberish, + BytesLike, + BigNumberish, + BigNumberish, + BytesLike[], + AddressLike + ] + ): string; + encodeFunctionData( + functionFragment: "revertBatches", + values: [BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "revertBatchesSharedBridge", + values: [BigNumberish, BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "setPendingAdmin", + values: [AddressLike] + ): string; + encodeFunctionData( + functionFragment: "setPorterAvailability", + values: [boolean] + ): string; + encodeFunctionData( + functionFragment: "setPriorityTxMaxGasLimit", + values: [BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "setTokenMultiplier", + values: [BigNumberish, BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "setTransactionFilterer", + values: [AddressLike] + ): string; + encodeFunctionData( + functionFragment: "setValidator", + values: [AddressLike, boolean] + ): string; + encodeFunctionData( + functionFragment: "setValidiumMode", + values: [BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "storedBatchHash", + values: [BigNumberish] + ): string; + encodeFunctionData( + functionFragment: "transferEthToSharedBridge", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "unfreezeDiamond", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "upgradeChainFromVersion", + values: [BigNumberish, Diamond.DiamondCutDataStruct] + ): string; + + decodeFunctionResult( + functionFragment: "acceptAdmin", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "baseTokenGasPriceMultiplierDenominator", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "baseTokenGasPriceMultiplierNominator", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "bridgehubRequestL2Transaction", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "changeFeeParams", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "commitBatches", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "commitBatchesSharedBridge", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "executeBatches", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "executeBatchesSharedBridge", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "executeUpgrade", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "facetAddress", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "facetAddresses", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "facetFunctionSelectors", + data: BytesLike + ): Result; + decodeFunctionResult(functionFragment: "facets", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "finalizeEthWithdrawal", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "freezeDiamond", + data: BytesLike + ): Result; + decodeFunctionResult(functionFragment: "getAdmin", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "getBaseToken", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "getBaseTokenBridge", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "getBridgehub", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "getFirstUnprocessedPriorityTx", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "getL2BootloaderBytecodeHash", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "getL2DefaultAccountBytecodeHash", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "getL2SystemContractsUpgradeBatchNumber", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "getL2SystemContractsUpgradeTxHash", + data: BytesLike + ): Result; + decodeFunctionResult(functionFragment: "getName", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "getPendingAdmin", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "getPriorityQueueSize", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "getPriorityTxMaxGasLimit", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "getProtocolVersion", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "getPubdataPricingMode", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "getStateTransitionManager", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "getTotalBatchesCommitted", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "getTotalBatchesExecuted", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "getTotalBatchesVerified", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "getTotalPriorityTxs", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "getVerifier", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "getVerifierParams", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "isDiamondStorageFrozen", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "isEthWithdrawalFinalized", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "isFacetFreezable", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "isFunctionFreezable", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "isValidator", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "l2LogsRootHash", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "l2TransactionBaseCost", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "priorityQueueFrontOperation", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "proveBatches", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "proveBatchesSharedBridge", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "proveL1ToL2TransactionStatus", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "proveL2LogInclusion", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "proveL2MessageInclusion", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "requestL2Transaction", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "revertBatches", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "revertBatchesSharedBridge", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "setPendingAdmin", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "setPorterAvailability", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "setPriorityTxMaxGasLimit", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "setTokenMultiplier", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "setTransactionFilterer", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "setValidator", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "setValidiumMode", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "storedBatchHash", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "transferEthToSharedBridge", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "unfreezeDiamond", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "upgradeChainFromVersion", + data: BytesLike + ): Result; +} + +export namespace BlockCommitEvent { + export type InputTuple = [ + batchNumber: BigNumberish, + batchHash: BytesLike, + commitment: BytesLike + ]; + export type OutputTuple = [ + batchNumber: bigint, + batchHash: string, + commitment: string + ]; + export interface OutputObject { + batchNumber: bigint; + batchHash: string; + commitment: string; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace BlockExecutionEvent { + export type InputTuple = [ + batchNumber: BigNumberish, + batchHash: BytesLike, + commitment: BytesLike + ]; + export type OutputTuple = [ + batchNumber: bigint, + batchHash: string, + commitment: string + ]; + export interface OutputObject { + batchNumber: bigint; + batchHash: string; + commitment: string; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace BlocksRevertEvent { + export type InputTuple = [ + totalBatchesCommitted: BigNumberish, + totalBatchesVerified: BigNumberish, + totalBatchesExecuted: BigNumberish + ]; + export type OutputTuple = [ + totalBatchesCommitted: bigint, + totalBatchesVerified: bigint, + totalBatchesExecuted: bigint + ]; + export interface OutputObject { + totalBatchesCommitted: bigint; + totalBatchesVerified: bigint; + totalBatchesExecuted: bigint; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace BlocksVerificationEvent { + export type InputTuple = [ + previousLastVerifiedBatch: BigNumberish, + currentLastVerifiedBatch: BigNumberish + ]; + export type OutputTuple = [ + previousLastVerifiedBatch: bigint, + currentLastVerifiedBatch: bigint + ]; + export interface OutputObject { + previousLastVerifiedBatch: bigint; + currentLastVerifiedBatch: bigint; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace EthWithdrawalFinalizedEvent { + export type InputTuple = [to: AddressLike, amount: BigNumberish]; + export type OutputTuple = [to: string, amount: bigint]; + export interface OutputObject { + to: string; + amount: bigint; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace ExecuteUpgradeEvent { + export type InputTuple = [diamondCut: Diamond.DiamondCutDataStruct]; + export type OutputTuple = [diamondCut: Diamond.DiamondCutDataStructOutput]; + export interface OutputObject { + diamondCut: Diamond.DiamondCutDataStructOutput; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace FreezeEvent { + export type InputTuple = []; + export type OutputTuple = []; + export interface OutputObject {} + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace IsPorterAvailableStatusUpdateEvent { + export type InputTuple = [isPorterAvailable: boolean]; + export type OutputTuple = [isPorterAvailable: boolean]; + export interface OutputObject { + isPorterAvailable: boolean; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace NewAdminEvent { + export type InputTuple = [oldAdmin: AddressLike, newAdmin: AddressLike]; + export type OutputTuple = [oldAdmin: string, newAdmin: string]; + export interface OutputObject { + oldAdmin: string; + newAdmin: string; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace NewBaseTokenMultiplierEvent { + export type InputTuple = [ + oldNominator: BigNumberish, + oldDenominator: BigNumberish, + newNominator: BigNumberish, + newDenominator: BigNumberish + ]; + export type OutputTuple = [ + oldNominator: bigint, + oldDenominator: bigint, + newNominator: bigint, + newDenominator: bigint + ]; + export interface OutputObject { + oldNominator: bigint; + oldDenominator: bigint; + newNominator: bigint; + newDenominator: bigint; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace NewFeeParamsEvent { + export type InputTuple = [ + oldFeeParams: FeeParamsStruct, + newFeeParams: FeeParamsStruct + ]; + export type OutputTuple = [ + oldFeeParams: FeeParamsStructOutput, + newFeeParams: FeeParamsStructOutput + ]; + export interface OutputObject { + oldFeeParams: FeeParamsStructOutput; + newFeeParams: FeeParamsStructOutput; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace NewPendingAdminEvent { + export type InputTuple = [ + oldPendingAdmin: AddressLike, + newPendingAdmin: AddressLike + ]; + export type OutputTuple = [oldPendingAdmin: string, newPendingAdmin: string]; + export interface OutputObject { + oldPendingAdmin: string; + newPendingAdmin: string; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace NewPriorityRequestEvent { + export type InputTuple = [ + txId: BigNumberish, + txHash: BytesLike, + expirationTimestamp: BigNumberish, + transaction: L2CanonicalTransactionStruct, + factoryDeps: BytesLike[] + ]; + export type OutputTuple = [ + txId: bigint, + txHash: string, + expirationTimestamp: bigint, + transaction: L2CanonicalTransactionStructOutput, + factoryDeps: string[] + ]; + export interface OutputObject { + txId: bigint; + txHash: string; + expirationTimestamp: bigint; + transaction: L2CanonicalTransactionStructOutput; + factoryDeps: string[]; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace NewPriorityTxMaxGasLimitEvent { + export type InputTuple = [ + oldPriorityTxMaxGasLimit: BigNumberish, + newPriorityTxMaxGasLimit: BigNumberish + ]; + export type OutputTuple = [ + oldPriorityTxMaxGasLimit: bigint, + newPriorityTxMaxGasLimit: bigint + ]; + export interface OutputObject { + oldPriorityTxMaxGasLimit: bigint; + newPriorityTxMaxGasLimit: bigint; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace NewTransactionFiltererEvent { + export type InputTuple = [ + oldTransactionFilterer: AddressLike, + newTransactionFilterer: AddressLike + ]; + export type OutputTuple = [ + oldTransactionFilterer: string, + newTransactionFilterer: string + ]; + export interface OutputObject { + oldTransactionFilterer: string; + newTransactionFilterer: string; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace ProposeTransparentUpgradeEvent { + export type InputTuple = [ + diamondCut: Diamond.DiamondCutDataStruct, + proposalId: BigNumberish, + proposalSalt: BytesLike + ]; + export type OutputTuple = [ + diamondCut: Diamond.DiamondCutDataStructOutput, + proposalId: bigint, + proposalSalt: string + ]; + export interface OutputObject { + diamondCut: Diamond.DiamondCutDataStructOutput; + proposalId: bigint; + proposalSalt: string; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace UnfreezeEvent { + export type InputTuple = []; + export type OutputTuple = []; + export interface OutputObject {} + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace ValidatorStatusUpdateEvent { + export type InputTuple = [validatorAddress: AddressLike, isActive: boolean]; + export type OutputTuple = [validatorAddress: string, isActive: boolean]; + export interface OutputObject { + validatorAddress: string; + isActive: boolean; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace ValidiumModeStatusUpdateEvent { + export type InputTuple = [validiumMode: BigNumberish]; + export type OutputTuple = [validiumMode: bigint]; + export interface OutputObject { + validiumMode: bigint; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export interface IZkSyncStateTransition extends BaseContract { + connect(runner?: ContractRunner | null): IZkSyncStateTransition; + waitForDeployment(): Promise; + + interface: IZkSyncStateTransitionInterface; + + queryFilter( + event: TCEvent, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>>; + queryFilter( + filter: TypedDeferredTopicFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>>; + + on( + event: TCEvent, + listener: TypedListener + ): Promise; + on( + filter: TypedDeferredTopicFilter, + listener: TypedListener + ): Promise; + + once( + event: TCEvent, + listener: TypedListener + ): Promise; + once( + filter: TypedDeferredTopicFilter, + listener: TypedListener + ): Promise; + + listeners( + event: TCEvent + ): Promise>>; + listeners(eventName?: string): Promise>; + removeAllListeners( + event?: TCEvent + ): Promise; + + acceptAdmin: TypedContractMethod<[], [void], "nonpayable">; + + baseTokenGasPriceMultiplierDenominator: TypedContractMethod< + [], + [bigint], + "view" + >; + + baseTokenGasPriceMultiplierNominator: TypedContractMethod< + [], + [bigint], + "view" + >; + + bridgehubRequestL2Transaction: TypedContractMethod< + [_request: BridgehubL2TransactionRequestStruct], + [string], + "payable" + >; + + changeFeeParams: TypedContractMethod< + [_newFeeParams: FeeParamsStruct], + [void], + "nonpayable" + >; + + commitBatches: TypedContractMethod< + [ + _lastCommittedBatchData: IExecutor.StoredBatchInfoStruct, + _newBatchesData: IExecutor.CommitBatchInfoStruct[] + ], + [void], + "nonpayable" + >; + + commitBatchesSharedBridge: TypedContractMethod< + [ + _chainId: BigNumberish, + _lastCommittedBatchData: IExecutor.StoredBatchInfoStruct, + _newBatchesData: IExecutor.CommitBatchInfoStruct[] + ], + [void], + "nonpayable" + >; + + executeBatches: TypedContractMethod< + [_batchesData: IExecutor.StoredBatchInfoStruct[]], + [void], + "nonpayable" + >; + + executeBatchesSharedBridge: TypedContractMethod< + [_chainId: BigNumberish, _batchesData: IExecutor.StoredBatchInfoStruct[]], + [void], + "nonpayable" + >; + + executeUpgrade: TypedContractMethod< + [_diamondCut: Diamond.DiamondCutDataStruct], + [void], + "nonpayable" + >; + + facetAddress: TypedContractMethod<[_selector: BytesLike], [string], "view">; + + facetAddresses: TypedContractMethod<[], [string[]], "view">; + + facetFunctionSelectors: TypedContractMethod< + [_facet: AddressLike], + [string[]], + "view" + >; + + facets: TypedContractMethod<[], [IGetters.FacetStructOutput[]], "view">; + + finalizeEthWithdrawal: TypedContractMethod< + [ + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish, + _l2TxNumberInBatch: BigNumberish, + _message: BytesLike, + _merkleProof: BytesLike[] + ], + [void], + "nonpayable" + >; + + freezeDiamond: TypedContractMethod<[], [void], "nonpayable">; + + getAdmin: TypedContractMethod<[], [string], "view">; + + getBaseToken: TypedContractMethod<[], [string], "view">; + + getBaseTokenBridge: TypedContractMethod<[], [string], "view">; + + getBridgehub: TypedContractMethod<[], [string], "view">; + + getFirstUnprocessedPriorityTx: TypedContractMethod<[], [bigint], "view">; + + getL2BootloaderBytecodeHash: TypedContractMethod<[], [string], "view">; + + getL2DefaultAccountBytecodeHash: TypedContractMethod<[], [string], "view">; + + getL2SystemContractsUpgradeBatchNumber: TypedContractMethod< + [], + [bigint], + "view" + >; + + getL2SystemContractsUpgradeTxHash: TypedContractMethod<[], [string], "view">; + + getName: TypedContractMethod<[], [string], "view">; + + getPendingAdmin: TypedContractMethod<[], [string], "view">; + + getPriorityQueueSize: TypedContractMethod<[], [bigint], "view">; + + getPriorityTxMaxGasLimit: TypedContractMethod<[], [bigint], "view">; + + getProtocolVersion: TypedContractMethod<[], [bigint], "view">; + + getPubdataPricingMode: TypedContractMethod<[], [bigint], "view">; + + getStateTransitionManager: TypedContractMethod<[], [string], "view">; + + getTotalBatchesCommitted: TypedContractMethod<[], [bigint], "view">; + + getTotalBatchesExecuted: TypedContractMethod<[], [bigint], "view">; + + getTotalBatchesVerified: TypedContractMethod<[], [bigint], "view">; + + getTotalPriorityTxs: TypedContractMethod<[], [bigint], "view">; + + getVerifier: TypedContractMethod<[], [string], "view">; + + getVerifierParams: TypedContractMethod< + [], + [VerifierParamsStructOutput], + "view" + >; + + isDiamondStorageFrozen: TypedContractMethod<[], [boolean], "view">; + + isEthWithdrawalFinalized: TypedContractMethod< + [_l2BatchNumber: BigNumberish, _l2MessageIndex: BigNumberish], + [boolean], + "view" + >; + + isFacetFreezable: TypedContractMethod< + [_facet: AddressLike], + [boolean], + "view" + >; + + isFunctionFreezable: TypedContractMethod< + [_selector: BytesLike], + [boolean], + "view" + >; + + isValidator: TypedContractMethod<[_address: AddressLike], [boolean], "view">; + + l2LogsRootHash: TypedContractMethod< + [_batchNumber: BigNumberish], + [string], + "view" + >; + + l2TransactionBaseCost: TypedContractMethod< + [ + _gasPrice: BigNumberish, + _l2GasLimit: BigNumberish, + _l2GasPerPubdataByteLimit: BigNumberish + ], + [bigint], + "view" + >; + + priorityQueueFrontOperation: TypedContractMethod< + [], + [PriorityOperationStructOutput], + "view" + >; + + proveBatches: TypedContractMethod< + [ + _prevBatch: IExecutor.StoredBatchInfoStruct, + _committedBatches: IExecutor.StoredBatchInfoStruct[], + _proof: IExecutor.ProofInputStruct + ], + [void], + "nonpayable" + >; + + proveBatchesSharedBridge: TypedContractMethod< + [ + _chainId: BigNumberish, + _prevBatch: IExecutor.StoredBatchInfoStruct, + _committedBatches: IExecutor.StoredBatchInfoStruct[], + _proof: IExecutor.ProofInputStruct + ], + [void], + "nonpayable" + >; + + proveL1ToL2TransactionStatus: TypedContractMethod< + [ + _l2TxHash: BytesLike, + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish, + _l2TxNumberInBatch: BigNumberish, + _merkleProof: BytesLike[], + _status: BigNumberish + ], + [boolean], + "view" + >; + + proveL2LogInclusion: TypedContractMethod< + [ + _batchNumber: BigNumberish, + _index: BigNumberish, + _log: L2LogStruct, + _proof: BytesLike[] + ], + [boolean], + "view" + >; + + proveL2MessageInclusion: TypedContractMethod< + [ + _batchNumber: BigNumberish, + _index: BigNumberish, + _message: L2MessageStruct, + _proof: BytesLike[] + ], + [boolean], + "view" + >; + + requestL2Transaction: TypedContractMethod< + [ + _contractL2: AddressLike, + _l2Value: BigNumberish, + _calldata: BytesLike, + _l2GasLimit: BigNumberish, + _l2GasPerPubdataByteLimit: BigNumberish, + _factoryDeps: BytesLike[], + _refundRecipient: AddressLike + ], + [string], + "payable" + >; + + revertBatches: TypedContractMethod< + [_newLastBatch: BigNumberish], + [void], + "nonpayable" + >; + + revertBatchesSharedBridge: TypedContractMethod< + [_chainId: BigNumberish, _newLastBatch: BigNumberish], + [void], + "nonpayable" + >; + + setPendingAdmin: TypedContractMethod< + [_newPendingAdmin: AddressLike], + [void], + "nonpayable" + >; + + setPorterAvailability: TypedContractMethod< + [_zkPorterIsAvailable: boolean], + [void], + "nonpayable" + >; + + setPriorityTxMaxGasLimit: TypedContractMethod< + [_newPriorityTxMaxGasLimit: BigNumberish], + [void], + "nonpayable" + >; + + setTokenMultiplier: TypedContractMethod< + [_nominator: BigNumberish, _denominator: BigNumberish], + [void], + "nonpayable" + >; + + setTransactionFilterer: TypedContractMethod< + [_transactionFilterer: AddressLike], + [void], + "nonpayable" + >; + + setValidator: TypedContractMethod< + [_validator: AddressLike, _active: boolean], + [void], + "nonpayable" + >; + + setValidiumMode: TypedContractMethod< + [_validiumMode: BigNumberish], + [void], + "nonpayable" + >; + + storedBatchHash: TypedContractMethod< + [_batchNumber: BigNumberish], + [string], + "view" + >; + + transferEthToSharedBridge: TypedContractMethod<[], [void], "nonpayable">; + + unfreezeDiamond: TypedContractMethod<[], [void], "nonpayable">; + + upgradeChainFromVersion: TypedContractMethod< + [_protocolVersion: BigNumberish, _cutData: Diamond.DiamondCutDataStruct], + [void], + "nonpayable" + >; + + getFunction( + key: string | FunctionFragment + ): T; + + getFunction( + nameOrSignature: "acceptAdmin" + ): TypedContractMethod<[], [void], "nonpayable">; + getFunction( + nameOrSignature: "baseTokenGasPriceMultiplierDenominator" + ): TypedContractMethod<[], [bigint], "view">; + getFunction( + nameOrSignature: "baseTokenGasPriceMultiplierNominator" + ): TypedContractMethod<[], [bigint], "view">; + getFunction( + nameOrSignature: "bridgehubRequestL2Transaction" + ): TypedContractMethod< + [_request: BridgehubL2TransactionRequestStruct], + [string], + "payable" + >; + getFunction( + nameOrSignature: "changeFeeParams" + ): TypedContractMethod< + [_newFeeParams: FeeParamsStruct], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "commitBatches" + ): TypedContractMethod< + [ + _lastCommittedBatchData: IExecutor.StoredBatchInfoStruct, + _newBatchesData: IExecutor.CommitBatchInfoStruct[] + ], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "commitBatchesSharedBridge" + ): TypedContractMethod< + [ + _chainId: BigNumberish, + _lastCommittedBatchData: IExecutor.StoredBatchInfoStruct, + _newBatchesData: IExecutor.CommitBatchInfoStruct[] + ], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "executeBatches" + ): TypedContractMethod< + [_batchesData: IExecutor.StoredBatchInfoStruct[]], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "executeBatchesSharedBridge" + ): TypedContractMethod< + [_chainId: BigNumberish, _batchesData: IExecutor.StoredBatchInfoStruct[]], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "executeUpgrade" + ): TypedContractMethod< + [_diamondCut: Diamond.DiamondCutDataStruct], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "facetAddress" + ): TypedContractMethod<[_selector: BytesLike], [string], "view">; + getFunction( + nameOrSignature: "facetAddresses" + ): TypedContractMethod<[], [string[]], "view">; + getFunction( + nameOrSignature: "facetFunctionSelectors" + ): TypedContractMethod<[_facet: AddressLike], [string[]], "view">; + getFunction( + nameOrSignature: "facets" + ): TypedContractMethod<[], [IGetters.FacetStructOutput[]], "view">; + getFunction( + nameOrSignature: "finalizeEthWithdrawal" + ): TypedContractMethod< + [ + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish, + _l2TxNumberInBatch: BigNumberish, + _message: BytesLike, + _merkleProof: BytesLike[] + ], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "freezeDiamond" + ): TypedContractMethod<[], [void], "nonpayable">; + getFunction( + nameOrSignature: "getAdmin" + ): TypedContractMethod<[], [string], "view">; + getFunction( + nameOrSignature: "getBaseToken" + ): TypedContractMethod<[], [string], "view">; + getFunction( + nameOrSignature: "getBaseTokenBridge" + ): TypedContractMethod<[], [string], "view">; + getFunction( + nameOrSignature: "getBridgehub" + ): TypedContractMethod<[], [string], "view">; + getFunction( + nameOrSignature: "getFirstUnprocessedPriorityTx" + ): TypedContractMethod<[], [bigint], "view">; + getFunction( + nameOrSignature: "getL2BootloaderBytecodeHash" + ): TypedContractMethod<[], [string], "view">; + getFunction( + nameOrSignature: "getL2DefaultAccountBytecodeHash" + ): TypedContractMethod<[], [string], "view">; + getFunction( + nameOrSignature: "getL2SystemContractsUpgradeBatchNumber" + ): TypedContractMethod<[], [bigint], "view">; + getFunction( + nameOrSignature: "getL2SystemContractsUpgradeTxHash" + ): TypedContractMethod<[], [string], "view">; + getFunction( + nameOrSignature: "getName" + ): TypedContractMethod<[], [string], "view">; + getFunction( + nameOrSignature: "getPendingAdmin" + ): TypedContractMethod<[], [string], "view">; + getFunction( + nameOrSignature: "getPriorityQueueSize" + ): TypedContractMethod<[], [bigint], "view">; + getFunction( + nameOrSignature: "getPriorityTxMaxGasLimit" + ): TypedContractMethod<[], [bigint], "view">; + getFunction( + nameOrSignature: "getProtocolVersion" + ): TypedContractMethod<[], [bigint], "view">; + getFunction( + nameOrSignature: "getPubdataPricingMode" + ): TypedContractMethod<[], [bigint], "view">; + getFunction( + nameOrSignature: "getStateTransitionManager" + ): TypedContractMethod<[], [string], "view">; + getFunction( + nameOrSignature: "getTotalBatchesCommitted" + ): TypedContractMethod<[], [bigint], "view">; + getFunction( + nameOrSignature: "getTotalBatchesExecuted" + ): TypedContractMethod<[], [bigint], "view">; + getFunction( + nameOrSignature: "getTotalBatchesVerified" + ): TypedContractMethod<[], [bigint], "view">; + getFunction( + nameOrSignature: "getTotalPriorityTxs" + ): TypedContractMethod<[], [bigint], "view">; + getFunction( + nameOrSignature: "getVerifier" + ): TypedContractMethod<[], [string], "view">; + getFunction( + nameOrSignature: "getVerifierParams" + ): TypedContractMethod<[], [VerifierParamsStructOutput], "view">; + getFunction( + nameOrSignature: "isDiamondStorageFrozen" + ): TypedContractMethod<[], [boolean], "view">; + getFunction( + nameOrSignature: "isEthWithdrawalFinalized" + ): TypedContractMethod< + [_l2BatchNumber: BigNumberish, _l2MessageIndex: BigNumberish], + [boolean], + "view" + >; + getFunction( + nameOrSignature: "isFacetFreezable" + ): TypedContractMethod<[_facet: AddressLike], [boolean], "view">; + getFunction( + nameOrSignature: "isFunctionFreezable" + ): TypedContractMethod<[_selector: BytesLike], [boolean], "view">; + getFunction( + nameOrSignature: "isValidator" + ): TypedContractMethod<[_address: AddressLike], [boolean], "view">; + getFunction( + nameOrSignature: "l2LogsRootHash" + ): TypedContractMethod<[_batchNumber: BigNumberish], [string], "view">; + getFunction( + nameOrSignature: "l2TransactionBaseCost" + ): TypedContractMethod< + [ + _gasPrice: BigNumberish, + _l2GasLimit: BigNumberish, + _l2GasPerPubdataByteLimit: BigNumberish + ], + [bigint], + "view" + >; + getFunction( + nameOrSignature: "priorityQueueFrontOperation" + ): TypedContractMethod<[], [PriorityOperationStructOutput], "view">; + getFunction( + nameOrSignature: "proveBatches" + ): TypedContractMethod< + [ + _prevBatch: IExecutor.StoredBatchInfoStruct, + _committedBatches: IExecutor.StoredBatchInfoStruct[], + _proof: IExecutor.ProofInputStruct + ], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "proveBatchesSharedBridge" + ): TypedContractMethod< + [ + _chainId: BigNumberish, + _prevBatch: IExecutor.StoredBatchInfoStruct, + _committedBatches: IExecutor.StoredBatchInfoStruct[], + _proof: IExecutor.ProofInputStruct + ], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "proveL1ToL2TransactionStatus" + ): TypedContractMethod< + [ + _l2TxHash: BytesLike, + _l2BatchNumber: BigNumberish, + _l2MessageIndex: BigNumberish, + _l2TxNumberInBatch: BigNumberish, + _merkleProof: BytesLike[], + _status: BigNumberish + ], + [boolean], + "view" + >; + getFunction( + nameOrSignature: "proveL2LogInclusion" + ): TypedContractMethod< + [ + _batchNumber: BigNumberish, + _index: BigNumberish, + _log: L2LogStruct, + _proof: BytesLike[] + ], + [boolean], + "view" + >; + getFunction( + nameOrSignature: "proveL2MessageInclusion" + ): TypedContractMethod< + [ + _batchNumber: BigNumberish, + _index: BigNumberish, + _message: L2MessageStruct, + _proof: BytesLike[] + ], + [boolean], + "view" + >; + getFunction( + nameOrSignature: "requestL2Transaction" + ): TypedContractMethod< + [ + _contractL2: AddressLike, + _l2Value: BigNumberish, + _calldata: BytesLike, + _l2GasLimit: BigNumberish, + _l2GasPerPubdataByteLimit: BigNumberish, + _factoryDeps: BytesLike[], + _refundRecipient: AddressLike + ], + [string], + "payable" + >; + getFunction( + nameOrSignature: "revertBatches" + ): TypedContractMethod<[_newLastBatch: BigNumberish], [void], "nonpayable">; + getFunction( + nameOrSignature: "revertBatchesSharedBridge" + ): TypedContractMethod< + [_chainId: BigNumberish, _newLastBatch: BigNumberish], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "setPendingAdmin" + ): TypedContractMethod<[_newPendingAdmin: AddressLike], [void], "nonpayable">; + getFunction( + nameOrSignature: "setPorterAvailability" + ): TypedContractMethod<[_zkPorterIsAvailable: boolean], [void], "nonpayable">; + getFunction( + nameOrSignature: "setPriorityTxMaxGasLimit" + ): TypedContractMethod< + [_newPriorityTxMaxGasLimit: BigNumberish], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "setTokenMultiplier" + ): TypedContractMethod< + [_nominator: BigNumberish, _denominator: BigNumberish], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "setTransactionFilterer" + ): TypedContractMethod< + [_transactionFilterer: AddressLike], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "setValidator" + ): TypedContractMethod< + [_validator: AddressLike, _active: boolean], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "setValidiumMode" + ): TypedContractMethod<[_validiumMode: BigNumberish], [void], "nonpayable">; + getFunction( + nameOrSignature: "storedBatchHash" + ): TypedContractMethod<[_batchNumber: BigNumberish], [string], "view">; + getFunction( + nameOrSignature: "transferEthToSharedBridge" + ): TypedContractMethod<[], [void], "nonpayable">; + getFunction( + nameOrSignature: "unfreezeDiamond" + ): TypedContractMethod<[], [void], "nonpayable">; + getFunction( + nameOrSignature: "upgradeChainFromVersion" + ): TypedContractMethod< + [_protocolVersion: BigNumberish, _cutData: Diamond.DiamondCutDataStruct], + [void], + "nonpayable" + >; + + getEvent( + key: "BlockCommit" + ): TypedContractEvent< + BlockCommitEvent.InputTuple, + BlockCommitEvent.OutputTuple, + BlockCommitEvent.OutputObject + >; + getEvent( + key: "BlockExecution" + ): TypedContractEvent< + BlockExecutionEvent.InputTuple, + BlockExecutionEvent.OutputTuple, + BlockExecutionEvent.OutputObject + >; + getEvent( + key: "BlocksRevert" + ): TypedContractEvent< + BlocksRevertEvent.InputTuple, + BlocksRevertEvent.OutputTuple, + BlocksRevertEvent.OutputObject + >; + getEvent( + key: "BlocksVerification" + ): TypedContractEvent< + BlocksVerificationEvent.InputTuple, + BlocksVerificationEvent.OutputTuple, + BlocksVerificationEvent.OutputObject + >; + getEvent( + key: "EthWithdrawalFinalized" + ): TypedContractEvent< + EthWithdrawalFinalizedEvent.InputTuple, + EthWithdrawalFinalizedEvent.OutputTuple, + EthWithdrawalFinalizedEvent.OutputObject + >; + getEvent( + key: "ExecuteUpgrade" + ): TypedContractEvent< + ExecuteUpgradeEvent.InputTuple, + ExecuteUpgradeEvent.OutputTuple, + ExecuteUpgradeEvent.OutputObject + >; + getEvent( + key: "Freeze" + ): TypedContractEvent< + FreezeEvent.InputTuple, + FreezeEvent.OutputTuple, + FreezeEvent.OutputObject + >; + getEvent( + key: "IsPorterAvailableStatusUpdate" + ): TypedContractEvent< + IsPorterAvailableStatusUpdateEvent.InputTuple, + IsPorterAvailableStatusUpdateEvent.OutputTuple, + IsPorterAvailableStatusUpdateEvent.OutputObject + >; + getEvent( + key: "NewAdmin" + ): TypedContractEvent< + NewAdminEvent.InputTuple, + NewAdminEvent.OutputTuple, + NewAdminEvent.OutputObject + >; + getEvent( + key: "NewBaseTokenMultiplier" + ): TypedContractEvent< + NewBaseTokenMultiplierEvent.InputTuple, + NewBaseTokenMultiplierEvent.OutputTuple, + NewBaseTokenMultiplierEvent.OutputObject + >; + getEvent( + key: "NewFeeParams" + ): TypedContractEvent< + NewFeeParamsEvent.InputTuple, + NewFeeParamsEvent.OutputTuple, + NewFeeParamsEvent.OutputObject + >; + getEvent( + key: "NewPendingAdmin" + ): TypedContractEvent< + NewPendingAdminEvent.InputTuple, + NewPendingAdminEvent.OutputTuple, + NewPendingAdminEvent.OutputObject + >; + getEvent( + key: "NewPriorityRequest" + ): TypedContractEvent< + NewPriorityRequestEvent.InputTuple, + NewPriorityRequestEvent.OutputTuple, + NewPriorityRequestEvent.OutputObject + >; + getEvent( + key: "NewPriorityTxMaxGasLimit" + ): TypedContractEvent< + NewPriorityTxMaxGasLimitEvent.InputTuple, + NewPriorityTxMaxGasLimitEvent.OutputTuple, + NewPriorityTxMaxGasLimitEvent.OutputObject + >; + getEvent( + key: "NewTransactionFilterer" + ): TypedContractEvent< + NewTransactionFiltererEvent.InputTuple, + NewTransactionFiltererEvent.OutputTuple, + NewTransactionFiltererEvent.OutputObject + >; + getEvent( + key: "ProposeTransparentUpgrade" + ): TypedContractEvent< + ProposeTransparentUpgradeEvent.InputTuple, + ProposeTransparentUpgradeEvent.OutputTuple, + ProposeTransparentUpgradeEvent.OutputObject + >; + getEvent( + key: "Unfreeze" + ): TypedContractEvent< + UnfreezeEvent.InputTuple, + UnfreezeEvent.OutputTuple, + UnfreezeEvent.OutputObject + >; + getEvent( + key: "ValidatorStatusUpdate" + ): TypedContractEvent< + ValidatorStatusUpdateEvent.InputTuple, + ValidatorStatusUpdateEvent.OutputTuple, + ValidatorStatusUpdateEvent.OutputObject + >; + getEvent( + key: "ValidiumModeStatusUpdate" + ): TypedContractEvent< + ValidiumModeStatusUpdateEvent.InputTuple, + ValidiumModeStatusUpdateEvent.OutputTuple, + ValidiumModeStatusUpdateEvent.OutputObject + >; + + filters: { + "BlockCommit(uint256,bytes32,bytes32)": TypedContractEvent< + BlockCommitEvent.InputTuple, + BlockCommitEvent.OutputTuple, + BlockCommitEvent.OutputObject + >; + BlockCommit: TypedContractEvent< + BlockCommitEvent.InputTuple, + BlockCommitEvent.OutputTuple, + BlockCommitEvent.OutputObject + >; + + "BlockExecution(uint256,bytes32,bytes32)": TypedContractEvent< + BlockExecutionEvent.InputTuple, + BlockExecutionEvent.OutputTuple, + BlockExecutionEvent.OutputObject + >; + BlockExecution: TypedContractEvent< + BlockExecutionEvent.InputTuple, + BlockExecutionEvent.OutputTuple, + BlockExecutionEvent.OutputObject + >; + + "BlocksRevert(uint256,uint256,uint256)": TypedContractEvent< + BlocksRevertEvent.InputTuple, + BlocksRevertEvent.OutputTuple, + BlocksRevertEvent.OutputObject + >; + BlocksRevert: TypedContractEvent< + BlocksRevertEvent.InputTuple, + BlocksRevertEvent.OutputTuple, + BlocksRevertEvent.OutputObject + >; + + "BlocksVerification(uint256,uint256)": TypedContractEvent< + BlocksVerificationEvent.InputTuple, + BlocksVerificationEvent.OutputTuple, + BlocksVerificationEvent.OutputObject + >; + BlocksVerification: TypedContractEvent< + BlocksVerificationEvent.InputTuple, + BlocksVerificationEvent.OutputTuple, + BlocksVerificationEvent.OutputObject + >; + + "EthWithdrawalFinalized(address,uint256)": TypedContractEvent< + EthWithdrawalFinalizedEvent.InputTuple, + EthWithdrawalFinalizedEvent.OutputTuple, + EthWithdrawalFinalizedEvent.OutputObject + >; + EthWithdrawalFinalized: TypedContractEvent< + EthWithdrawalFinalizedEvent.InputTuple, + EthWithdrawalFinalizedEvent.OutputTuple, + EthWithdrawalFinalizedEvent.OutputObject + >; + + "ExecuteUpgrade(tuple)": TypedContractEvent< + ExecuteUpgradeEvent.InputTuple, + ExecuteUpgradeEvent.OutputTuple, + ExecuteUpgradeEvent.OutputObject + >; + ExecuteUpgrade: TypedContractEvent< + ExecuteUpgradeEvent.InputTuple, + ExecuteUpgradeEvent.OutputTuple, + ExecuteUpgradeEvent.OutputObject + >; + + "Freeze()": TypedContractEvent< + FreezeEvent.InputTuple, + FreezeEvent.OutputTuple, + FreezeEvent.OutputObject + >; + Freeze: TypedContractEvent< + FreezeEvent.InputTuple, + FreezeEvent.OutputTuple, + FreezeEvent.OutputObject + >; + + "IsPorterAvailableStatusUpdate(bool)": TypedContractEvent< + IsPorterAvailableStatusUpdateEvent.InputTuple, + IsPorterAvailableStatusUpdateEvent.OutputTuple, + IsPorterAvailableStatusUpdateEvent.OutputObject + >; + IsPorterAvailableStatusUpdate: TypedContractEvent< + IsPorterAvailableStatusUpdateEvent.InputTuple, + IsPorterAvailableStatusUpdateEvent.OutputTuple, + IsPorterAvailableStatusUpdateEvent.OutputObject + >; + + "NewAdmin(address,address)": TypedContractEvent< + NewAdminEvent.InputTuple, + NewAdminEvent.OutputTuple, + NewAdminEvent.OutputObject + >; + NewAdmin: TypedContractEvent< + NewAdminEvent.InputTuple, + NewAdminEvent.OutputTuple, + NewAdminEvent.OutputObject + >; + + "NewBaseTokenMultiplier(uint128,uint128,uint128,uint128)": TypedContractEvent< + NewBaseTokenMultiplierEvent.InputTuple, + NewBaseTokenMultiplierEvent.OutputTuple, + NewBaseTokenMultiplierEvent.OutputObject + >; + NewBaseTokenMultiplier: TypedContractEvent< + NewBaseTokenMultiplierEvent.InputTuple, + NewBaseTokenMultiplierEvent.OutputTuple, + NewBaseTokenMultiplierEvent.OutputObject + >; + + "NewFeeParams(tuple,tuple)": TypedContractEvent< + NewFeeParamsEvent.InputTuple, + NewFeeParamsEvent.OutputTuple, + NewFeeParamsEvent.OutputObject + >; + NewFeeParams: TypedContractEvent< + NewFeeParamsEvent.InputTuple, + NewFeeParamsEvent.OutputTuple, + NewFeeParamsEvent.OutputObject + >; + + "NewPendingAdmin(address,address)": TypedContractEvent< + NewPendingAdminEvent.InputTuple, + NewPendingAdminEvent.OutputTuple, + NewPendingAdminEvent.OutputObject + >; + NewPendingAdmin: TypedContractEvent< + NewPendingAdminEvent.InputTuple, + NewPendingAdminEvent.OutputTuple, + NewPendingAdminEvent.OutputObject + >; + + "NewPriorityRequest(uint256,bytes32,uint64,tuple,bytes[])": TypedContractEvent< + NewPriorityRequestEvent.InputTuple, + NewPriorityRequestEvent.OutputTuple, + NewPriorityRequestEvent.OutputObject + >; + NewPriorityRequest: TypedContractEvent< + NewPriorityRequestEvent.InputTuple, + NewPriorityRequestEvent.OutputTuple, + NewPriorityRequestEvent.OutputObject + >; + + "NewPriorityTxMaxGasLimit(uint256,uint256)": TypedContractEvent< + NewPriorityTxMaxGasLimitEvent.InputTuple, + NewPriorityTxMaxGasLimitEvent.OutputTuple, + NewPriorityTxMaxGasLimitEvent.OutputObject + >; + NewPriorityTxMaxGasLimit: TypedContractEvent< + NewPriorityTxMaxGasLimitEvent.InputTuple, + NewPriorityTxMaxGasLimitEvent.OutputTuple, + NewPriorityTxMaxGasLimitEvent.OutputObject + >; + + "NewTransactionFilterer(address,address)": TypedContractEvent< + NewTransactionFiltererEvent.InputTuple, + NewTransactionFiltererEvent.OutputTuple, + NewTransactionFiltererEvent.OutputObject + >; + NewTransactionFilterer: TypedContractEvent< + NewTransactionFiltererEvent.InputTuple, + NewTransactionFiltererEvent.OutputTuple, + NewTransactionFiltererEvent.OutputObject + >; + + "ProposeTransparentUpgrade(tuple,uint256,bytes32)": TypedContractEvent< + ProposeTransparentUpgradeEvent.InputTuple, + ProposeTransparentUpgradeEvent.OutputTuple, + ProposeTransparentUpgradeEvent.OutputObject + >; + ProposeTransparentUpgrade: TypedContractEvent< + ProposeTransparentUpgradeEvent.InputTuple, + ProposeTransparentUpgradeEvent.OutputTuple, + ProposeTransparentUpgradeEvent.OutputObject + >; + + "Unfreeze()": TypedContractEvent< + UnfreezeEvent.InputTuple, + UnfreezeEvent.OutputTuple, + UnfreezeEvent.OutputObject + >; + Unfreeze: TypedContractEvent< + UnfreezeEvent.InputTuple, + UnfreezeEvent.OutputTuple, + UnfreezeEvent.OutputObject + >; + + "ValidatorStatusUpdate(address,bool)": TypedContractEvent< + ValidatorStatusUpdateEvent.InputTuple, + ValidatorStatusUpdateEvent.OutputTuple, + ValidatorStatusUpdateEvent.OutputObject + >; + ValidatorStatusUpdate: TypedContractEvent< + ValidatorStatusUpdateEvent.InputTuple, + ValidatorStatusUpdateEvent.OutputTuple, + ValidatorStatusUpdateEvent.OutputObject + >; + + "ValidiumModeStatusUpdate(uint8)": TypedContractEvent< + ValidiumModeStatusUpdateEvent.InputTuple, + ValidiumModeStatusUpdateEvent.OutputTuple, + ValidiumModeStatusUpdateEvent.OutputObject + >; + ValidiumModeStatusUpdate: TypedContractEvent< + ValidiumModeStatusUpdateEvent.InputTuple, + ValidiumModeStatusUpdateEvent.OutputTuple, + ValidiumModeStatusUpdateEvent.OutputObject + >; + }; +} diff --git a/src/typechain/factories/IBridgehub__factory.ts b/src/typechain/factories/IBridgehub__factory.ts new file mode 100644 index 00000000..5857bf79 --- /dev/null +++ b/src/typechain/factories/IBridgehub__factory.ts @@ -0,0 +1,648 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ + +import { Contract, Interface, type ContractRunner } from "ethers"; +import type { IBridgehub, IBridgehubInterface } from "../IBridgehub"; + +const _abi = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "oldAdmin", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "newAdmin", + type: "address", + }, + ], + name: "NewAdmin", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "uint256", + name: "chainId", + type: "uint256", + }, + { + indexed: false, + internalType: "address", + name: "stateTransitionManager", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "chainGovernance", + type: "address", + }, + ], + name: "NewChain", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "oldPendingAdmin", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "newPendingAdmin", + type: "address", + }, + ], + name: "NewPendingAdmin", + type: "event", + }, + { + inputs: [], + name: "acceptAdmin", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_stateTransitionManager", + type: "address", + }, + ], + name: "addStateTransitionManager", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_token", + type: "address", + }, + ], + name: "addToken", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + ], + name: "baseToken", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "address", + name: "_stateTransitionManager", + type: "address", + }, + { + internalType: "address", + name: "_baseToken", + type: "address", + }, + { + internalType: "uint256", + name: "_salt", + type: "uint256", + }, + { + internalType: "address", + name: "_admin", + type: "address", + }, + { + internalType: "bytes", + name: "_initData", + type: "bytes", + }, + ], + name: "createNewChain", + outputs: [ + { + internalType: "uint256", + name: "chainId", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + ], + name: "getStateTransition", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "uint256", + name: "_gasPrice", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2GasLimit", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2GasPerPubdataByteLimit", + type: "uint256", + }, + ], + name: "l2TransactionBaseCost", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "bytes32", + name: "_l2TxHash", + type: "bytes32", + }, + { + internalType: "uint256", + name: "_l2BatchNumber", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2MessageIndex", + type: "uint256", + }, + { + internalType: "uint16", + name: "_l2TxNumberInBatch", + type: "uint16", + }, + { + internalType: "bytes32[]", + name: "_merkleProof", + type: "bytes32[]", + }, + { + internalType: "enum TxStatus", + name: "_status", + type: "uint8", + }, + ], + name: "proveL1ToL2TransactionStatus", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "uint256", + name: "_batchNumber", + type: "uint256", + }, + { + internalType: "uint256", + name: "_index", + type: "uint256", + }, + { + components: [ + { + internalType: "uint8", + name: "l2ShardId", + type: "uint8", + }, + { + internalType: "bool", + name: "isService", + type: "bool", + }, + { + internalType: "uint16", + name: "txNumberInBatch", + type: "uint16", + }, + { + internalType: "address", + name: "sender", + type: "address", + }, + { + internalType: "bytes32", + name: "key", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "value", + type: "bytes32", + }, + ], + internalType: "struct L2Log", + name: "_log", + type: "tuple", + }, + { + internalType: "bytes32[]", + name: "_proof", + type: "bytes32[]", + }, + ], + name: "proveL2LogInclusion", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "uint256", + name: "_batchNumber", + type: "uint256", + }, + { + internalType: "uint256", + name: "_index", + type: "uint256", + }, + { + components: [ + { + internalType: "uint16", + name: "txNumberInBatch", + type: "uint16", + }, + { + internalType: "address", + name: "sender", + type: "address", + }, + { + internalType: "bytes", + name: "data", + type: "bytes", + }, + ], + internalType: "struct L2Message", + name: "_message", + type: "tuple", + }, + { + internalType: "bytes32[]", + name: "_proof", + type: "bytes32[]", + }, + ], + name: "proveL2MessageInclusion", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_stateTransitionManager", + type: "address", + }, + ], + name: "removeStateTransitionManager", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "uint256", + name: "chainId", + type: "uint256", + }, + { + internalType: "uint256", + name: "mintValue", + type: "uint256", + }, + { + internalType: "address", + name: "l2Contract", + type: "address", + }, + { + internalType: "uint256", + name: "l2Value", + type: "uint256", + }, + { + internalType: "bytes", + name: "l2Calldata", + type: "bytes", + }, + { + internalType: "uint256", + name: "l2GasLimit", + type: "uint256", + }, + { + internalType: "uint256", + name: "l2GasPerPubdataByteLimit", + type: "uint256", + }, + { + internalType: "bytes[]", + name: "factoryDeps", + type: "bytes[]", + }, + { + internalType: "address", + name: "refundRecipient", + type: "address", + }, + ], + internalType: "struct L2TransactionRequestDirect", + name: "_request", + type: "tuple", + }, + ], + name: "requestL2TransactionDirect", + outputs: [ + { + internalType: "bytes32", + name: "canonicalTxHash", + type: "bytes32", + }, + ], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "uint256", + name: "chainId", + type: "uint256", + }, + { + internalType: "uint256", + name: "mintValue", + type: "uint256", + }, + { + internalType: "uint256", + name: "l2Value", + type: "uint256", + }, + { + internalType: "uint256", + name: "l2GasLimit", + type: "uint256", + }, + { + internalType: "uint256", + name: "l2GasPerPubdataByteLimit", + type: "uint256", + }, + { + internalType: "address", + name: "refundRecipient", + type: "address", + }, + { + internalType: "address", + name: "secondBridgeAddress", + type: "address", + }, + { + internalType: "uint256", + name: "secondBridgeValue", + type: "uint256", + }, + { + internalType: "bytes", + name: "secondBridgeCalldata", + type: "bytes", + }, + ], + internalType: "struct L2TransactionRequestTwoBridgesOuter", + name: "_request", + type: "tuple", + }, + ], + name: "requestL2TransactionTwoBridges", + outputs: [ + { + internalType: "bytes32", + name: "canonicalTxHash", + type: "bytes32", + }, + ], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_newPendingAdmin", + type: "address", + }, + ], + name: "setPendingAdmin", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_sharedBridge", + type: "address", + }, + ], + name: "setSharedBridge", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "sharedBridge", + outputs: [ + { + internalType: "contract IL1SharedBridge", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + ], + name: "stateTransitionManager", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_stateTransitionManager", + type: "address", + }, + ], + name: "stateTransitionManagerIsRegistered", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_baseToken", + type: "address", + }, + ], + name: "tokenIsRegistered", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, +] as const; + +export class IBridgehub__factory { + static readonly abi = _abi; + static createInterface(): IBridgehubInterface { + return new Interface(_abi) as IBridgehubInterface; + } + static connect(address: string, runner?: ContractRunner | null): IBridgehub { + return new Contract(address, _abi, runner) as unknown as IBridgehub; + } +} diff --git a/src/typechain/factories/IContractDeployer__factory.ts b/src/typechain/factories/IContractDeployer__factory.ts index 52ce9945..111bb9cf 100644 --- a/src/typechain/factories/IContractDeployer__factory.ts +++ b/src/typechain/factories/IContractDeployer__factory.ts @@ -94,7 +94,7 @@ const _abi = [ outputs: [ { internalType: "address", - name: "newAddress", + name: "", type: "address", }, ], @@ -123,7 +123,7 @@ const _abi = [ outputs: [ { internalType: "address", - name: "newAddress", + name: "", type: "address", }, ], @@ -157,7 +157,7 @@ const _abi = [ outputs: [ { internalType: "address", - name: "newAddress", + name: "", type: "address", }, ], @@ -168,7 +168,7 @@ const _abi = [ inputs: [ { internalType: "bytes32", - name: "_salt", + name: "", type: "bytes32", }, { @@ -191,10 +191,114 @@ const _abi = [ outputs: [ { internalType: "address", - name: "newAddress", + name: "", + type: "address", + }, + ], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_address", + type: "address", + }, + ], + name: "extendedAccountVersion", + outputs: [ + { + internalType: "enum IContractDeployer.AccountAbstractionVersion", + name: "", + type: "uint8", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes32", + name: "bytecodeHash", + type: "bytes32", + }, + { + internalType: "address", + name: "newAddress", + type: "address", + }, + { + internalType: "bool", + name: "callConstructor", + type: "bool", + }, + { + internalType: "uint256", + name: "value", + type: "uint256", + }, + { + internalType: "bytes", + name: "input", + type: "bytes", + }, + ], + internalType: "struct ContractDeployer.ForceDeployment", + name: "_deployment", + type: "tuple", + }, + { + internalType: "address", + name: "_sender", type: "address", }, ], + name: "forceDeployOnAddress", + outputs: [], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes32", + name: "bytecodeHash", + type: "bytes32", + }, + { + internalType: "address", + name: "newAddress", + type: "address", + }, + { + internalType: "bool", + name: "callConstructor", + type: "bool", + }, + { + internalType: "uint256", + name: "value", + type: "uint256", + }, + { + internalType: "bytes", + name: "input", + type: "bytes", + }, + ], + internalType: "struct ContractDeployer.ForceDeployment[]", + name: "_deployments", + type: "tuple[]", + }, + ], + name: "forceDeployOnAddresses", + outputs: [], stateMutability: "payable", type: "function", }, diff --git a/src/typechain/factories/IL1Bridge__factory.ts b/src/typechain/factories/IL1Bridge__factory.ts index 64491451..d8eddb96 100644 --- a/src/typechain/factories/IL1Bridge__factory.ts +++ b/src/typechain/factories/IL1Bridge__factory.ts @@ -9,6 +9,80 @@ const _abi = [ { anonymous: false, inputs: [ + { + indexed: true, + internalType: "uint256", + name: "chainId", + type: "uint256", + }, + { + indexed: true, + internalType: "bytes32", + name: "txDataHash", + type: "bytes32", + }, + { + indexed: true, + internalType: "bytes32", + name: "l2DepositTxHash", + type: "bytes32", + }, + ], + name: "BridgehubDepositFinalized", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "uint256", + name: "chainId", + type: "uint256", + }, + { + indexed: true, + internalType: "bytes32", + name: "txDataHash", + type: "bytes32", + }, + { + indexed: true, + internalType: "address", + name: "from", + type: "address", + }, + { + indexed: false, + internalType: "address", + name: "to", + type: "address", + }, + { + indexed: false, + internalType: "address", + name: "l1Token", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "BridgehubDepositInitiatedSharedBridge", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "uint256", + name: "chainId", + type: "uint256", + }, { indexed: true, internalType: "address", @@ -28,12 +102,18 @@ const _abi = [ type: "uint256", }, ], - name: "ClaimedFailedDeposit", + name: "ClaimedFailedDepositSharedBridge", type: "event", }, { anonymous: false, inputs: [ + { + indexed: true, + internalType: "uint256", + name: "chainId", + type: "uint256", + }, { indexed: true, internalType: "bytes32", @@ -47,7 +127,7 @@ const _abi = [ type: "address", }, { - indexed: true, + indexed: false, internalType: "address", name: "to", type: "address", @@ -65,12 +145,18 @@ const _abi = [ type: "uint256", }, ], - name: "DepositInitiated", + name: "DepositInitiatedSharedBridge", type: "event", }, { anonymous: false, inputs: [ + { + indexed: true, + internalType: "uint256", + name: "chainId", + type: "uint256", + }, { indexed: true, internalType: "address", @@ -90,11 +176,136 @@ const _abi = [ type: "uint256", }, ], - name: "WithdrawalFinalized", + name: "WithdrawalFinalizedSharedBridge", type: "event", }, + { + inputs: [], + name: "bridgehub", + outputs: [ + { + internalType: "contract IBridgehub", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "bytes32", + name: "_txDataHash", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "_txHash", + type: "bytes32", + }, + ], + name: "bridgehubConfirmL2Transaction", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "address", + name: "_prevMsgSender", + type: "address", + }, + { + internalType: "bytes", + name: "_data", + type: "bytes", + }, + ], + name: "bridgehubDeposit", + outputs: [ + { + components: [ + { + internalType: "bytes32", + name: "magicValue", + type: "bytes32", + }, + { + internalType: "address", + name: "l2Contract", + type: "address", + }, + { + internalType: "bytes", + name: "l2Calldata", + type: "bytes", + }, + { + internalType: "bytes[]", + name: "factoryDeps", + type: "bytes[]", + }, + { + internalType: "bytes32", + name: "txDataHash", + type: "bytes32", + }, + ], + internalType: "struct L2TransactionRequestTwoBridgesInner", + name: "request", + type: "tuple", + }, + ], + stateMutability: "payable", + type: "function", + }, { inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "address", + name: "_prevMsgSender", + type: "address", + }, + { + internalType: "address", + name: "_l1Token", + type: "address", + }, + { + internalType: "uint256", + name: "_amount", + type: "uint256", + }, + ], + name: "bridgehubDepositBaseToken", + outputs: [], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, { internalType: "address", name: "_depositSender", @@ -105,6 +316,11 @@ const _abi = [ name: "_l1Token", type: "address", }, + { + internalType: "uint256", + name: "_amount", + type: "uint256", + }, { internalType: "bytes32", name: "_l2TxHash", @@ -138,6 +354,11 @@ const _abi = [ }, { inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, { internalType: "address", name: "_l2Receiver", @@ -148,6 +369,11 @@ const _abi = [ name: "_l1Token", type: "address", }, + { + internalType: "uint256", + name: "_mintValue", + type: "uint256", + }, { internalType: "uint256", name: "_amount", @@ -182,6 +408,35 @@ const _abi = [ }, { inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "bytes32", + name: "_l2TxHash", + type: "bytes32", + }, + ], + name: "depositHappened", + outputs: [ + { + internalType: "bytes32", + name: "", + type: "bytes32", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, { internalType: "uint256", name: "_l2BatchNumber", @@ -215,6 +470,11 @@ const _abi = [ }, { inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, { internalType: "uint256", name: "_l2BatchNumber", @@ -226,7 +486,7 @@ const _abi = [ type: "uint256", }, ], - name: "isWithdrawalFinalized", + name: "isWithdrawalFinalizedShared", outputs: [ { internalType: "bool", @@ -237,28 +497,15 @@ const _abi = [ stateMutability: "view", type: "function", }, - { - inputs: [], - name: "l2Bridge", - outputs: [ - { - internalType: "address", - name: "", - type: "address", - }, - ], - stateMutability: "view", - type: "function", - }, { inputs: [ { - internalType: "address", - name: "_l1Token", - type: "address", + internalType: "uint256", + name: "_chainId", + type: "uint256", }, ], - name: "l2TokenAddress", + name: "l2BridgeAddress", outputs: [ { internalType: "address", diff --git a/src/typechain/factories/IL1ERC20Bridge__factory.ts b/src/typechain/factories/IL1ERC20Bridge__factory.ts new file mode 100644 index 00000000..2a6557cd --- /dev/null +++ b/src/typechain/factories/IL1ERC20Bridge__factory.ts @@ -0,0 +1,400 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ + +import { Contract, Interface, type ContractRunner } from "ethers"; +import type { + IL1ERC20Bridge, + IL1ERC20BridgeInterface, +} from "../IL1ERC20Bridge"; + +const _abi = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "to", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "l1Token", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "ClaimedFailedDeposit", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "l2DepositTxHash", + type: "bytes32", + }, + { + indexed: true, + internalType: "address", + name: "from", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "to", + type: "address", + }, + { + indexed: false, + internalType: "address", + name: "l1Token", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "DepositInitiated", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "to", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "l1Token", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "WithdrawalFinalized", + type: "event", + }, + { + inputs: [ + { + internalType: "address", + name: "_depositSender", + type: "address", + }, + { + internalType: "address", + name: "_l1Token", + type: "address", + }, + { + internalType: "bytes32", + name: "_l2TxHash", + type: "bytes32", + }, + { + internalType: "uint256", + name: "_l2BatchNumber", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2MessageIndex", + type: "uint256", + }, + { + internalType: "uint16", + name: "_l2TxNumberInBatch", + type: "uint16", + }, + { + internalType: "bytes32[]", + name: "_merkleProof", + type: "bytes32[]", + }, + ], + name: "claimFailedDeposit", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_l2Receiver", + type: "address", + }, + { + internalType: "address", + name: "_l1Token", + type: "address", + }, + { + internalType: "uint256", + name: "_amount", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2TxGasLimit", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2TxGasPerPubdataByte", + type: "uint256", + }, + ], + name: "deposit", + outputs: [ + { + internalType: "bytes32", + name: "txHash", + type: "bytes32", + }, + ], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_l2Receiver", + type: "address", + }, + { + internalType: "address", + name: "_l1Token", + type: "address", + }, + { + internalType: "uint256", + name: "_amount", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2TxGasLimit", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2TxGasPerPubdataByte", + type: "uint256", + }, + { + internalType: "address", + name: "_refundRecipient", + type: "address", + }, + ], + name: "deposit", + outputs: [ + { + internalType: "bytes32", + name: "txHash", + type: "bytes32", + }, + ], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_account", + type: "address", + }, + { + internalType: "address", + name: "_l1Token", + type: "address", + }, + { + internalType: "bytes32", + name: "_depositL2TxHash", + type: "bytes32", + }, + ], + name: "depositAmount", + outputs: [ + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_l2BatchNumber", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2MessageIndex", + type: "uint256", + }, + { + internalType: "uint16", + name: "_l2TxNumberInBatch", + type: "uint16", + }, + { + internalType: "bytes", + name: "_message", + type: "bytes", + }, + { + internalType: "bytes32[]", + name: "_merkleProof", + type: "bytes32[]", + }, + ], + name: "finalizeWithdrawal", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_l2BatchNumber", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2MessageIndex", + type: "uint256", + }, + ], + name: "isWithdrawalFinalized", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "l2Bridge", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_l1Token", + type: "address", + }, + ], + name: "l2TokenAddress", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "l2TokenBeacon", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "sharedBridge", + outputs: [ + { + internalType: "contract IL1SharedBridge", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_token", + type: "address", + }, + { + internalType: "uint256", + name: "_amount", + type: "uint256", + }, + ], + name: "transferTokenToSharedBridge", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, +] as const; + +export class IL1ERC20Bridge__factory { + static readonly abi = _abi; + static createInterface(): IL1ERC20BridgeInterface { + return new Interface(_abi) as IL1ERC20BridgeInterface; + } + static connect( + address: string, + runner?: ContractRunner | null + ): IL1ERC20Bridge { + return new Contract(address, _abi, runner) as unknown as IL1ERC20Bridge; + } +} diff --git a/src/typechain/factories/IL1SharedBridge__factory.ts b/src/typechain/factories/IL1SharedBridge__factory.ts new file mode 100644 index 00000000..d34709f9 --- /dev/null +++ b/src/typechain/factories/IL1SharedBridge__factory.ts @@ -0,0 +1,715 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ + +import { Contract, Interface, type ContractRunner } from "ethers"; +import type { + IL1SharedBridge, + IL1SharedBridgeInterface, +} from "../IL1SharedBridge"; + +const _abi = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "uint256", + name: "chainId", + type: "uint256", + }, + { + indexed: true, + internalType: "address", + name: "from", + type: "address", + }, + { + indexed: false, + internalType: "address", + name: "l1Token", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "BridgehubDepositBaseTokenInitiated", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "uint256", + name: "chainId", + type: "uint256", + }, + { + indexed: true, + internalType: "bytes32", + name: "txDataHash", + type: "bytes32", + }, + { + indexed: true, + internalType: "bytes32", + name: "l2DepositTxHash", + type: "bytes32", + }, + ], + name: "BridgehubDepositFinalized", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "uint256", + name: "chainId", + type: "uint256", + }, + { + indexed: true, + internalType: "bytes32", + name: "txDataHash", + type: "bytes32", + }, + { + indexed: true, + internalType: "address", + name: "from", + type: "address", + }, + { + indexed: false, + internalType: "address", + name: "to", + type: "address", + }, + { + indexed: false, + internalType: "address", + name: "l1Token", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "BridgehubDepositInitiated", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "uint256", + name: "chainId", + type: "uint256", + }, + { + indexed: true, + internalType: "address", + name: "to", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "l1Token", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "ClaimedFailedDepositSharedBridge", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "uint256", + name: "chainId", + type: "uint256", + }, + { + indexed: true, + internalType: "bytes32", + name: "l2DepositTxHash", + type: "bytes32", + }, + { + indexed: true, + internalType: "address", + name: "from", + type: "address", + }, + { + indexed: false, + internalType: "address", + name: "to", + type: "address", + }, + { + indexed: false, + internalType: "address", + name: "l1Token", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "LegacyDepositInitiated", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "uint256", + name: "chainId", + type: "uint256", + }, + { + indexed: true, + internalType: "address", + name: "to", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "l1Token", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "WithdrawalFinalizedSharedBridge", + type: "event", + }, + { + inputs: [], + name: "bridgehub", + outputs: [ + { + internalType: "contract IBridgehub", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "bytes32", + name: "_txDataHash", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "_txHash", + type: "bytes32", + }, + ], + name: "bridgehubConfirmL2Transaction", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "address", + name: "_prevMsgSender", + type: "address", + }, + { + internalType: "uint256", + name: "_l2Value", + type: "uint256", + }, + { + internalType: "bytes", + name: "_data", + type: "bytes", + }, + ], + name: "bridgehubDeposit", + outputs: [ + { + components: [ + { + internalType: "bytes32", + name: "magicValue", + type: "bytes32", + }, + { + internalType: "address", + name: "l2Contract", + type: "address", + }, + { + internalType: "bytes", + name: "l2Calldata", + type: "bytes", + }, + { + internalType: "bytes[]", + name: "factoryDeps", + type: "bytes[]", + }, + { + internalType: "bytes32", + name: "txDataHash", + type: "bytes32", + }, + ], + internalType: "struct L2TransactionRequestTwoBridgesInner", + name: "request", + type: "tuple", + }, + ], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "address", + name: "_prevMsgSender", + type: "address", + }, + { + internalType: "address", + name: "_l1Token", + type: "address", + }, + { + internalType: "uint256", + name: "_amount", + type: "uint256", + }, + ], + name: "bridgehubDepositBaseToken", + outputs: [], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "address", + name: "_depositSender", + type: "address", + }, + { + internalType: "address", + name: "_l1Token", + type: "address", + }, + { + internalType: "uint256", + name: "_amount", + type: "uint256", + }, + { + internalType: "bytes32", + name: "_l2TxHash", + type: "bytes32", + }, + { + internalType: "uint256", + name: "_l2BatchNumber", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2MessageIndex", + type: "uint256", + }, + { + internalType: "uint16", + name: "_l2TxNumberInBatch", + type: "uint16", + }, + { + internalType: "bytes32[]", + name: "_merkleProof", + type: "bytes32[]", + }, + ], + name: "claimFailedDeposit", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_depositSender", + type: "address", + }, + { + internalType: "address", + name: "_l1Token", + type: "address", + }, + { + internalType: "uint256", + name: "_amount", + type: "uint256", + }, + { + internalType: "bytes32", + name: "_l2TxHash", + type: "bytes32", + }, + { + internalType: "uint256", + name: "_l2BatchNumber", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2MessageIndex", + type: "uint256", + }, + { + internalType: "uint16", + name: "_l2TxNumberInBatch", + type: "uint16", + }, + { + internalType: "bytes32[]", + name: "_merkleProof", + type: "bytes32[]", + }, + ], + name: "claimFailedDepositLegacyErc20Bridge", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "bytes32", + name: "_l2TxHash", + type: "bytes32", + }, + ], + name: "depositHappened", + outputs: [ + { + internalType: "bytes32", + name: "", + type: "bytes32", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_msgSender", + type: "address", + }, + { + internalType: "address", + name: "_l2Receiver", + type: "address", + }, + { + internalType: "address", + name: "_l1Token", + type: "address", + }, + { + internalType: "uint256", + name: "_amount", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2TxGasLimit", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2TxGasPerPubdataByte", + type: "uint256", + }, + { + internalType: "address", + name: "_refundRecipient", + type: "address", + }, + ], + name: "depositLegacyErc20Bridge", + outputs: [ + { + internalType: "bytes32", + name: "txHash", + type: "bytes32", + }, + ], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2BatchNumber", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2MessageIndex", + type: "uint256", + }, + { + internalType: "uint16", + name: "_l2TxNumberInBatch", + type: "uint16", + }, + { + internalType: "bytes", + name: "_message", + type: "bytes", + }, + { + internalType: "bytes32[]", + name: "_merkleProof", + type: "bytes32[]", + }, + ], + name: "finalizeWithdrawal", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_l2BatchNumber", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2MessageIndex", + type: "uint256", + }, + { + internalType: "uint16", + name: "_l2TxNumberInBatch", + type: "uint16", + }, + { + internalType: "bytes", + name: "_message", + type: "bytes", + }, + { + internalType: "bytes32[]", + name: "_merkleProof", + type: "bytes32[]", + }, + ], + name: "finalizeWithdrawalLegacyErc20Bridge", + outputs: [ + { + internalType: "address", + name: "l1Receiver", + type: "address", + }, + { + internalType: "address", + name: "l1Token", + type: "address", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2BatchNumber", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2MessageIndex", + type: "uint256", + }, + ], + name: "isWithdrawalFinalized", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "l1WethAddress", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + ], + name: "l2BridgeAddress", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "legacyBridge", + outputs: [ + { + internalType: "contract IL1ERC20Bridge", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + ], + name: "receiveEth", + outputs: [], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_eraFirstPostUpgradeBatch", + type: "uint256", + }, + ], + name: "setEraFirstPostUpgradeBatch", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, +] as const; + +export class IL1SharedBridge__factory { + static readonly abi = _abi; + static createInterface(): IL1SharedBridgeInterface { + return new Interface(_abi) as IL1SharedBridgeInterface; + } + static connect( + address: string, + runner?: ContractRunner | null + ): IL1SharedBridge { + return new Contract(address, _abi, runner) as unknown as IL1SharedBridge; + } +} diff --git a/src/typechain/factories/ITestnetERC20Token__factory.ts b/src/typechain/factories/ITestnetERC20Token__factory.ts new file mode 100644 index 00000000..15d1a2ea --- /dev/null +++ b/src/typechain/factories/ITestnetERC20Token__factory.ts @@ -0,0 +1,62 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ + +import { Contract, Interface, type ContractRunner } from "ethers"; +import type { + ITestnetERC20Token, + ITestnetERC20TokenInterface, +} from "../ITestnetERC20Token"; + +const _abi = [ + { + inputs: [], + name: "decimals", + outputs: [ + { + internalType: "uint8", + name: "", + type: "uint8", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_to", + type: "address", + }, + { + internalType: "uint256", + name: "_amount", + type: "uint256", + }, + ], + name: "mint", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, +] as const; + +export class ITestnetERC20Token__factory { + static readonly abi = _abi; + static createInterface(): ITestnetERC20TokenInterface { + return new Interface(_abi) as ITestnetERC20TokenInterface; + } + static connect( + address: string, + runner?: ContractRunner | null + ): ITestnetERC20Token { + return new Contract(address, _abi, runner) as unknown as ITestnetERC20Token; + } +} diff --git a/src/typechain/factories/IZkSyncStateTransition__factory.ts b/src/typechain/factories/IZkSyncStateTransition__factory.ts new file mode 100644 index 00000000..e8478c54 --- /dev/null +++ b/src/typechain/factories/IZkSyncStateTransition__factory.ts @@ -0,0 +1,2430 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ + +import { Contract, Interface, type ContractRunner } from "ethers"; +import type { + IZkSyncStateTransition, + IZkSyncStateTransitionInterface, +} from "../IZkSyncStateTransition"; + +const _abi = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "uint256", + name: "batchNumber", + type: "uint256", + }, + { + indexed: true, + internalType: "bytes32", + name: "batchHash", + type: "bytes32", + }, + { + indexed: true, + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + name: "BlockCommit", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "uint256", + name: "batchNumber", + type: "uint256", + }, + { + indexed: true, + internalType: "bytes32", + name: "batchHash", + type: "bytes32", + }, + { + indexed: true, + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + name: "BlockExecution", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint256", + name: "totalBatchesCommitted", + type: "uint256", + }, + { + indexed: false, + internalType: "uint256", + name: "totalBatchesVerified", + type: "uint256", + }, + { + indexed: false, + internalType: "uint256", + name: "totalBatchesExecuted", + type: "uint256", + }, + ], + name: "BlocksRevert", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "uint256", + name: "previousLastVerifiedBatch", + type: "uint256", + }, + { + indexed: true, + internalType: "uint256", + name: "currentLastVerifiedBatch", + type: "uint256", + }, + ], + name: "BlocksVerification", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "to", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "EthWithdrawalFinalized", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + components: [ + { + components: [ + { + internalType: "address", + name: "facet", + type: "address", + }, + { + internalType: "enum Diamond.Action", + name: "action", + type: "uint8", + }, + { + internalType: "bool", + name: "isFreezable", + type: "bool", + }, + { + internalType: "bytes4[]", + name: "selectors", + type: "bytes4[]", + }, + ], + internalType: "struct Diamond.FacetCut[]", + name: "facetCuts", + type: "tuple[]", + }, + { + internalType: "address", + name: "initAddress", + type: "address", + }, + { + internalType: "bytes", + name: "initCalldata", + type: "bytes", + }, + ], + indexed: false, + internalType: "struct Diamond.DiamondCutData", + name: "diamondCut", + type: "tuple", + }, + ], + name: "ExecuteUpgrade", + type: "event", + }, + { + anonymous: false, + inputs: [], + name: "Freeze", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "bool", + name: "isPorterAvailable", + type: "bool", + }, + ], + name: "IsPorterAvailableStatusUpdate", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "oldAdmin", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "newAdmin", + type: "address", + }, + ], + name: "NewAdmin", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint128", + name: "oldNominator", + type: "uint128", + }, + { + indexed: false, + internalType: "uint128", + name: "oldDenominator", + type: "uint128", + }, + { + indexed: false, + internalType: "uint128", + name: "newNominator", + type: "uint128", + }, + { + indexed: false, + internalType: "uint128", + name: "newDenominator", + type: "uint128", + }, + ], + name: "NewBaseTokenMultiplier", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + components: [ + { + internalType: "enum PubdataPricingMode", + name: "pubdataPricingMode", + type: "uint8", + }, + { + internalType: "uint32", + name: "batchOverheadL1Gas", + type: "uint32", + }, + { + internalType: "uint32", + name: "maxPubdataPerBatch", + type: "uint32", + }, + { + internalType: "uint32", + name: "maxL2GasPerBatch", + type: "uint32", + }, + { + internalType: "uint32", + name: "priorityTxMaxPubdata", + type: "uint32", + }, + { + internalType: "uint64", + name: "minimalL2GasPrice", + type: "uint64", + }, + ], + indexed: false, + internalType: "struct FeeParams", + name: "oldFeeParams", + type: "tuple", + }, + { + components: [ + { + internalType: "enum PubdataPricingMode", + name: "pubdataPricingMode", + type: "uint8", + }, + { + internalType: "uint32", + name: "batchOverheadL1Gas", + type: "uint32", + }, + { + internalType: "uint32", + name: "maxPubdataPerBatch", + type: "uint32", + }, + { + internalType: "uint32", + name: "maxL2GasPerBatch", + type: "uint32", + }, + { + internalType: "uint32", + name: "priorityTxMaxPubdata", + type: "uint32", + }, + { + internalType: "uint64", + name: "minimalL2GasPrice", + type: "uint64", + }, + ], + indexed: false, + internalType: "struct FeeParams", + name: "newFeeParams", + type: "tuple", + }, + ], + name: "NewFeeParams", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "oldPendingAdmin", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "newPendingAdmin", + type: "address", + }, + ], + name: "NewPendingAdmin", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint256", + name: "txId", + type: "uint256", + }, + { + indexed: false, + internalType: "bytes32", + name: "txHash", + type: "bytes32", + }, + { + indexed: false, + internalType: "uint64", + name: "expirationTimestamp", + type: "uint64", + }, + { + components: [ + { + internalType: "uint256", + name: "txType", + type: "uint256", + }, + { + internalType: "uint256", + name: "from", + type: "uint256", + }, + { + internalType: "uint256", + name: "to", + type: "uint256", + }, + { + internalType: "uint256", + name: "gasLimit", + type: "uint256", + }, + { + internalType: "uint256", + name: "gasPerPubdataByteLimit", + type: "uint256", + }, + { + internalType: "uint256", + name: "maxFeePerGas", + type: "uint256", + }, + { + internalType: "uint256", + name: "maxPriorityFeePerGas", + type: "uint256", + }, + { + internalType: "uint256", + name: "paymaster", + type: "uint256", + }, + { + internalType: "uint256", + name: "nonce", + type: "uint256", + }, + { + internalType: "uint256", + name: "value", + type: "uint256", + }, + { + internalType: "uint256[4]", + name: "reserved", + type: "uint256[4]", + }, + { + internalType: "bytes", + name: "data", + type: "bytes", + }, + { + internalType: "bytes", + name: "signature", + type: "bytes", + }, + { + internalType: "uint256[]", + name: "factoryDeps", + type: "uint256[]", + }, + { + internalType: "bytes", + name: "paymasterInput", + type: "bytes", + }, + { + internalType: "bytes", + name: "reservedDynamic", + type: "bytes", + }, + ], + indexed: false, + internalType: "struct L2CanonicalTransaction", + name: "transaction", + type: "tuple", + }, + { + indexed: false, + internalType: "bytes[]", + name: "factoryDeps", + type: "bytes[]", + }, + ], + name: "NewPriorityRequest", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint256", + name: "oldPriorityTxMaxGasLimit", + type: "uint256", + }, + { + indexed: false, + internalType: "uint256", + name: "newPriorityTxMaxGasLimit", + type: "uint256", + }, + ], + name: "NewPriorityTxMaxGasLimit", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "oldTransactionFilterer", + type: "address", + }, + { + indexed: false, + internalType: "address", + name: "newTransactionFilterer", + type: "address", + }, + ], + name: "NewTransactionFilterer", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + components: [ + { + components: [ + { + internalType: "address", + name: "facet", + type: "address", + }, + { + internalType: "enum Diamond.Action", + name: "action", + type: "uint8", + }, + { + internalType: "bool", + name: "isFreezable", + type: "bool", + }, + { + internalType: "bytes4[]", + name: "selectors", + type: "bytes4[]", + }, + ], + internalType: "struct Diamond.FacetCut[]", + name: "facetCuts", + type: "tuple[]", + }, + { + internalType: "address", + name: "initAddress", + type: "address", + }, + { + internalType: "bytes", + name: "initCalldata", + type: "bytes", + }, + ], + indexed: false, + internalType: "struct Diamond.DiamondCutData", + name: "diamondCut", + type: "tuple", + }, + { + indexed: true, + internalType: "uint256", + name: "proposalId", + type: "uint256", + }, + { + indexed: false, + internalType: "bytes32", + name: "proposalSalt", + type: "bytes32", + }, + ], + name: "ProposeTransparentUpgrade", + type: "event", + }, + { + anonymous: false, + inputs: [], + name: "Unfreeze", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "validatorAddress", + type: "address", + }, + { + indexed: false, + internalType: "bool", + name: "isActive", + type: "bool", + }, + ], + name: "ValidatorStatusUpdate", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "enum PubdataPricingMode", + name: "validiumMode", + type: "uint8", + }, + ], + name: "ValidiumModeStatusUpdate", + type: "event", + }, + { + inputs: [], + name: "acceptAdmin", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "baseTokenGasPriceMultiplierDenominator", + outputs: [ + { + internalType: "uint128", + name: "", + type: "uint128", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "baseTokenGasPriceMultiplierNominator", + outputs: [ + { + internalType: "uint128", + name: "", + type: "uint128", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "address", + name: "sender", + type: "address", + }, + { + internalType: "address", + name: "contractL2", + type: "address", + }, + { + internalType: "uint256", + name: "mintValue", + type: "uint256", + }, + { + internalType: "uint256", + name: "l2Value", + type: "uint256", + }, + { + internalType: "bytes", + name: "l2Calldata", + type: "bytes", + }, + { + internalType: "uint256", + name: "l2GasLimit", + type: "uint256", + }, + { + internalType: "uint256", + name: "l2GasPerPubdataByteLimit", + type: "uint256", + }, + { + internalType: "bytes[]", + name: "factoryDeps", + type: "bytes[]", + }, + { + internalType: "address", + name: "refundRecipient", + type: "address", + }, + ], + internalType: "struct BridgehubL2TransactionRequest", + name: "_request", + type: "tuple", + }, + ], + name: "bridgehubRequestL2Transaction", + outputs: [ + { + internalType: "bytes32", + name: "canonicalTxHash", + type: "bytes32", + }, + ], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "enum PubdataPricingMode", + name: "pubdataPricingMode", + type: "uint8", + }, + { + internalType: "uint32", + name: "batchOverheadL1Gas", + type: "uint32", + }, + { + internalType: "uint32", + name: "maxPubdataPerBatch", + type: "uint32", + }, + { + internalType: "uint32", + name: "maxL2GasPerBatch", + type: "uint32", + }, + { + internalType: "uint32", + name: "priorityTxMaxPubdata", + type: "uint32", + }, + { + internalType: "uint64", + name: "minimalL2GasPrice", + type: "uint64", + }, + ], + internalType: "struct FeeParams", + name: "_newFeeParams", + type: "tuple", + }, + ], + name: "changeFeeParams", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "uint64", + name: "batchNumber", + type: "uint64", + }, + { + internalType: "bytes32", + name: "batchHash", + type: "bytes32", + }, + { + internalType: "uint64", + name: "indexRepeatedStorageChanges", + type: "uint64", + }, + { + internalType: "uint256", + name: "numberOfLayer1Txs", + type: "uint256", + }, + { + internalType: "bytes32", + name: "priorityOperationsHash", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "l2LogsTreeRoot", + type: "bytes32", + }, + { + internalType: "uint256", + name: "timestamp", + type: "uint256", + }, + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + internalType: "struct IExecutor.StoredBatchInfo", + name: "_lastCommittedBatchData", + type: "tuple", + }, + { + components: [ + { + internalType: "uint64", + name: "batchNumber", + type: "uint64", + }, + { + internalType: "uint64", + name: "timestamp", + type: "uint64", + }, + { + internalType: "uint64", + name: "indexRepeatedStorageChanges", + type: "uint64", + }, + { + internalType: "bytes32", + name: "newStateRoot", + type: "bytes32", + }, + { + internalType: "uint256", + name: "numberOfLayer1Txs", + type: "uint256", + }, + { + internalType: "bytes32", + name: "priorityOperationsHash", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "bootloaderHeapInitialContentsHash", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "eventsQueueStateHash", + type: "bytes32", + }, + { + internalType: "bytes", + name: "systemLogs", + type: "bytes", + }, + { + internalType: "bytes", + name: "pubdataCommitments", + type: "bytes", + }, + ], + internalType: "struct IExecutor.CommitBatchInfo[]", + name: "_newBatchesData", + type: "tuple[]", + }, + ], + name: "commitBatches", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + components: [ + { + internalType: "uint64", + name: "batchNumber", + type: "uint64", + }, + { + internalType: "bytes32", + name: "batchHash", + type: "bytes32", + }, + { + internalType: "uint64", + name: "indexRepeatedStorageChanges", + type: "uint64", + }, + { + internalType: "uint256", + name: "numberOfLayer1Txs", + type: "uint256", + }, + { + internalType: "bytes32", + name: "priorityOperationsHash", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "l2LogsTreeRoot", + type: "bytes32", + }, + { + internalType: "uint256", + name: "timestamp", + type: "uint256", + }, + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + internalType: "struct IExecutor.StoredBatchInfo", + name: "_lastCommittedBatchData", + type: "tuple", + }, + { + components: [ + { + internalType: "uint64", + name: "batchNumber", + type: "uint64", + }, + { + internalType: "uint64", + name: "timestamp", + type: "uint64", + }, + { + internalType: "uint64", + name: "indexRepeatedStorageChanges", + type: "uint64", + }, + { + internalType: "bytes32", + name: "newStateRoot", + type: "bytes32", + }, + { + internalType: "uint256", + name: "numberOfLayer1Txs", + type: "uint256", + }, + { + internalType: "bytes32", + name: "priorityOperationsHash", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "bootloaderHeapInitialContentsHash", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "eventsQueueStateHash", + type: "bytes32", + }, + { + internalType: "bytes", + name: "systemLogs", + type: "bytes", + }, + { + internalType: "bytes", + name: "pubdataCommitments", + type: "bytes", + }, + ], + internalType: "struct IExecutor.CommitBatchInfo[]", + name: "_newBatchesData", + type: "tuple[]", + }, + ], + name: "commitBatchesSharedBridge", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "uint64", + name: "batchNumber", + type: "uint64", + }, + { + internalType: "bytes32", + name: "batchHash", + type: "bytes32", + }, + { + internalType: "uint64", + name: "indexRepeatedStorageChanges", + type: "uint64", + }, + { + internalType: "uint256", + name: "numberOfLayer1Txs", + type: "uint256", + }, + { + internalType: "bytes32", + name: "priorityOperationsHash", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "l2LogsTreeRoot", + type: "bytes32", + }, + { + internalType: "uint256", + name: "timestamp", + type: "uint256", + }, + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + internalType: "struct IExecutor.StoredBatchInfo[]", + name: "_batchesData", + type: "tuple[]", + }, + ], + name: "executeBatches", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + components: [ + { + internalType: "uint64", + name: "batchNumber", + type: "uint64", + }, + { + internalType: "bytes32", + name: "batchHash", + type: "bytes32", + }, + { + internalType: "uint64", + name: "indexRepeatedStorageChanges", + type: "uint64", + }, + { + internalType: "uint256", + name: "numberOfLayer1Txs", + type: "uint256", + }, + { + internalType: "bytes32", + name: "priorityOperationsHash", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "l2LogsTreeRoot", + type: "bytes32", + }, + { + internalType: "uint256", + name: "timestamp", + type: "uint256", + }, + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + internalType: "struct IExecutor.StoredBatchInfo[]", + name: "_batchesData", + type: "tuple[]", + }, + ], + name: "executeBatchesSharedBridge", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { + internalType: "address", + name: "facet", + type: "address", + }, + { + internalType: "enum Diamond.Action", + name: "action", + type: "uint8", + }, + { + internalType: "bool", + name: "isFreezable", + type: "bool", + }, + { + internalType: "bytes4[]", + name: "selectors", + type: "bytes4[]", + }, + ], + internalType: "struct Diamond.FacetCut[]", + name: "facetCuts", + type: "tuple[]", + }, + { + internalType: "address", + name: "initAddress", + type: "address", + }, + { + internalType: "bytes", + name: "initCalldata", + type: "bytes", + }, + ], + internalType: "struct Diamond.DiamondCutData", + name: "_diamondCut", + type: "tuple", + }, + ], + name: "executeUpgrade", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes4", + name: "_selector", + type: "bytes4", + }, + ], + name: "facetAddress", + outputs: [ + { + internalType: "address", + name: "facet", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "facetAddresses", + outputs: [ + { + internalType: "address[]", + name: "facets", + type: "address[]", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_facet", + type: "address", + }, + ], + name: "facetFunctionSelectors", + outputs: [ + { + internalType: "bytes4[]", + name: "", + type: "bytes4[]", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "facets", + outputs: [ + { + components: [ + { + internalType: "address", + name: "addr", + type: "address", + }, + { + internalType: "bytes4[]", + name: "selectors", + type: "bytes4[]", + }, + ], + internalType: "struct IGetters.Facet[]", + name: "", + type: "tuple[]", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_l2BatchNumber", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2MessageIndex", + type: "uint256", + }, + { + internalType: "uint16", + name: "_l2TxNumberInBatch", + type: "uint16", + }, + { + internalType: "bytes", + name: "_message", + type: "bytes", + }, + { + internalType: "bytes32[]", + name: "_merkleProof", + type: "bytes32[]", + }, + ], + name: "finalizeEthWithdrawal", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "freezeDiamond", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "getAdmin", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getBaseToken", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getBaseTokenBridge", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getBridgehub", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getFirstUnprocessedPriorityTx", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getL2BootloaderBytecodeHash", + outputs: [ + { + internalType: "bytes32", + name: "", + type: "bytes32", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getL2DefaultAccountBytecodeHash", + outputs: [ + { + internalType: "bytes32", + name: "", + type: "bytes32", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getL2SystemContractsUpgradeBatchNumber", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getL2SystemContractsUpgradeTxHash", + outputs: [ + { + internalType: "bytes32", + name: "", + type: "bytes32", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getName", + outputs: [ + { + internalType: "string", + name: "", + type: "string", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getPendingAdmin", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getPriorityQueueSize", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getPriorityTxMaxGasLimit", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getProtocolVersion", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getPubdataPricingMode", + outputs: [ + { + internalType: "enum PubdataPricingMode", + name: "", + type: "uint8", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getStateTransitionManager", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getTotalBatchesCommitted", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getTotalBatchesExecuted", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getTotalBatchesVerified", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getTotalPriorityTxs", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getVerifier", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getVerifierParams", + outputs: [ + { + components: [ + { + internalType: "bytes32", + name: "recursionNodeLevelVkHash", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "recursionLeafLevelVkHash", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "recursionCircuitsSetVksHash", + type: "bytes32", + }, + ], + internalType: "struct VerifierParams", + name: "", + type: "tuple", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "isDiamondStorageFrozen", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_l2BatchNumber", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2MessageIndex", + type: "uint256", + }, + ], + name: "isEthWithdrawalFinalized", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_facet", + type: "address", + }, + ], + name: "isFacetFreezable", + outputs: [ + { + internalType: "bool", + name: "isFreezable", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes4", + name: "_selector", + type: "bytes4", + }, + ], + name: "isFunctionFreezable", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_address", + type: "address", + }, + ], + name: "isValidator", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_batchNumber", + type: "uint256", + }, + ], + name: "l2LogsRootHash", + outputs: [ + { + internalType: "bytes32", + name: "merkleRoot", + type: "bytes32", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_gasPrice", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2GasLimit", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2GasPerPubdataByteLimit", + type: "uint256", + }, + ], + name: "l2TransactionBaseCost", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "priorityQueueFrontOperation", + outputs: [ + { + components: [ + { + internalType: "bytes32", + name: "canonicalTxHash", + type: "bytes32", + }, + { + internalType: "uint64", + name: "expirationTimestamp", + type: "uint64", + }, + { + internalType: "uint192", + name: "layer2Tip", + type: "uint192", + }, + ], + internalType: "struct PriorityOperation", + name: "", + type: "tuple", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "uint64", + name: "batchNumber", + type: "uint64", + }, + { + internalType: "bytes32", + name: "batchHash", + type: "bytes32", + }, + { + internalType: "uint64", + name: "indexRepeatedStorageChanges", + type: "uint64", + }, + { + internalType: "uint256", + name: "numberOfLayer1Txs", + type: "uint256", + }, + { + internalType: "bytes32", + name: "priorityOperationsHash", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "l2LogsTreeRoot", + type: "bytes32", + }, + { + internalType: "uint256", + name: "timestamp", + type: "uint256", + }, + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + internalType: "struct IExecutor.StoredBatchInfo", + name: "_prevBatch", + type: "tuple", + }, + { + components: [ + { + internalType: "uint64", + name: "batchNumber", + type: "uint64", + }, + { + internalType: "bytes32", + name: "batchHash", + type: "bytes32", + }, + { + internalType: "uint64", + name: "indexRepeatedStorageChanges", + type: "uint64", + }, + { + internalType: "uint256", + name: "numberOfLayer1Txs", + type: "uint256", + }, + { + internalType: "bytes32", + name: "priorityOperationsHash", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "l2LogsTreeRoot", + type: "bytes32", + }, + { + internalType: "uint256", + name: "timestamp", + type: "uint256", + }, + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + internalType: "struct IExecutor.StoredBatchInfo[]", + name: "_committedBatches", + type: "tuple[]", + }, + { + components: [ + { + internalType: "uint256[]", + name: "recursiveAggregationInput", + type: "uint256[]", + }, + { + internalType: "uint256[]", + name: "serializedProof", + type: "uint256[]", + }, + ], + internalType: "struct IExecutor.ProofInput", + name: "_proof", + type: "tuple", + }, + ], + name: "proveBatches", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + components: [ + { + internalType: "uint64", + name: "batchNumber", + type: "uint64", + }, + { + internalType: "bytes32", + name: "batchHash", + type: "bytes32", + }, + { + internalType: "uint64", + name: "indexRepeatedStorageChanges", + type: "uint64", + }, + { + internalType: "uint256", + name: "numberOfLayer1Txs", + type: "uint256", + }, + { + internalType: "bytes32", + name: "priorityOperationsHash", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "l2LogsTreeRoot", + type: "bytes32", + }, + { + internalType: "uint256", + name: "timestamp", + type: "uint256", + }, + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + internalType: "struct IExecutor.StoredBatchInfo", + name: "_prevBatch", + type: "tuple", + }, + { + components: [ + { + internalType: "uint64", + name: "batchNumber", + type: "uint64", + }, + { + internalType: "bytes32", + name: "batchHash", + type: "bytes32", + }, + { + internalType: "uint64", + name: "indexRepeatedStorageChanges", + type: "uint64", + }, + { + internalType: "uint256", + name: "numberOfLayer1Txs", + type: "uint256", + }, + { + internalType: "bytes32", + name: "priorityOperationsHash", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "l2LogsTreeRoot", + type: "bytes32", + }, + { + internalType: "uint256", + name: "timestamp", + type: "uint256", + }, + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + internalType: "struct IExecutor.StoredBatchInfo[]", + name: "_committedBatches", + type: "tuple[]", + }, + { + components: [ + { + internalType: "uint256[]", + name: "recursiveAggregationInput", + type: "uint256[]", + }, + { + internalType: "uint256[]", + name: "serializedProof", + type: "uint256[]", + }, + ], + internalType: "struct IExecutor.ProofInput", + name: "_proof", + type: "tuple", + }, + ], + name: "proveBatchesSharedBridge", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "_l2TxHash", + type: "bytes32", + }, + { + internalType: "uint256", + name: "_l2BatchNumber", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2MessageIndex", + type: "uint256", + }, + { + internalType: "uint16", + name: "_l2TxNumberInBatch", + type: "uint16", + }, + { + internalType: "bytes32[]", + name: "_merkleProof", + type: "bytes32[]", + }, + { + internalType: "enum TxStatus", + name: "_status", + type: "uint8", + }, + ], + name: "proveL1ToL2TransactionStatus", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_batchNumber", + type: "uint256", + }, + { + internalType: "uint256", + name: "_index", + type: "uint256", + }, + { + components: [ + { + internalType: "uint8", + name: "l2ShardId", + type: "uint8", + }, + { + internalType: "bool", + name: "isService", + type: "bool", + }, + { + internalType: "uint16", + name: "txNumberInBatch", + type: "uint16", + }, + { + internalType: "address", + name: "sender", + type: "address", + }, + { + internalType: "bytes32", + name: "key", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "value", + type: "bytes32", + }, + ], + internalType: "struct L2Log", + name: "_log", + type: "tuple", + }, + { + internalType: "bytes32[]", + name: "_proof", + type: "bytes32[]", + }, + ], + name: "proveL2LogInclusion", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_batchNumber", + type: "uint256", + }, + { + internalType: "uint256", + name: "_index", + type: "uint256", + }, + { + components: [ + { + internalType: "uint16", + name: "txNumberInBatch", + type: "uint16", + }, + { + internalType: "address", + name: "sender", + type: "address", + }, + { + internalType: "bytes", + name: "data", + type: "bytes", + }, + ], + internalType: "struct L2Message", + name: "_message", + type: "tuple", + }, + { + internalType: "bytes32[]", + name: "_proof", + type: "bytes32[]", + }, + ], + name: "proveL2MessageInclusion", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_contractL2", + type: "address", + }, + { + internalType: "uint256", + name: "_l2Value", + type: "uint256", + }, + { + internalType: "bytes", + name: "_calldata", + type: "bytes", + }, + { + internalType: "uint256", + name: "_l2GasLimit", + type: "uint256", + }, + { + internalType: "uint256", + name: "_l2GasPerPubdataByteLimit", + type: "uint256", + }, + { + internalType: "bytes[]", + name: "_factoryDeps", + type: "bytes[]", + }, + { + internalType: "address", + name: "_refundRecipient", + type: "address", + }, + ], + name: "requestL2Transaction", + outputs: [ + { + internalType: "bytes32", + name: "canonicalTxHash", + type: "bytes32", + }, + ], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_newLastBatch", + type: "uint256", + }, + ], + name: "revertBatches", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_chainId", + type: "uint256", + }, + { + internalType: "uint256", + name: "_newLastBatch", + type: "uint256", + }, + ], + name: "revertBatchesSharedBridge", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_newPendingAdmin", + type: "address", + }, + ], + name: "setPendingAdmin", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "bool", + name: "_zkPorterIsAvailable", + type: "bool", + }, + ], + name: "setPorterAvailability", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_newPriorityTxMaxGasLimit", + type: "uint256", + }, + ], + name: "setPriorityTxMaxGasLimit", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint128", + name: "_nominator", + type: "uint128", + }, + { + internalType: "uint128", + name: "_denominator", + type: "uint128", + }, + ], + name: "setTokenMultiplier", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_transactionFilterer", + type: "address", + }, + ], + name: "setTransactionFilterer", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_validator", + type: "address", + }, + { + internalType: "bool", + name: "_active", + type: "bool", + }, + ], + name: "setValidator", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "enum PubdataPricingMode", + name: "_validiumMode", + type: "uint8", + }, + ], + name: "setValidiumMode", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_batchNumber", + type: "uint256", + }, + ], + name: "storedBatchHash", + outputs: [ + { + internalType: "bytes32", + name: "", + type: "bytes32", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "transferEthToSharedBridge", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "unfreezeDiamond", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_protocolVersion", + type: "uint256", + }, + { + components: [ + { + components: [ + { + internalType: "address", + name: "facet", + type: "address", + }, + { + internalType: "enum Diamond.Action", + name: "action", + type: "uint8", + }, + { + internalType: "bool", + name: "isFreezable", + type: "bool", + }, + { + internalType: "bytes4[]", + name: "selectors", + type: "bytes4[]", + }, + ], + internalType: "struct Diamond.FacetCut[]", + name: "facetCuts", + type: "tuple[]", + }, + { + internalType: "address", + name: "initAddress", + type: "address", + }, + { + internalType: "bytes", + name: "initCalldata", + type: "bytes", + }, + ], + internalType: "struct Diamond.DiamondCutData", + name: "_cutData", + type: "tuple", + }, + ], + name: "upgradeChainFromVersion", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, +] as const; + +export class IZkSyncStateTransition__factory { + static readonly abi = _abi; + static createInterface(): IZkSyncStateTransitionInterface { + return new Interface(_abi) as IZkSyncStateTransitionInterface; + } + static connect( + address: string, + runner?: ContractRunner | null + ): IZkSyncStateTransition { + return new Contract( + address, + _abi, + runner + ) as unknown as IZkSyncStateTransition; + } +} diff --git a/src/typechain/factories/index.ts b/src/typechain/factories/index.ts index 84f0ad81..5d3bb145 100644 --- a/src/typechain/factories/index.ts +++ b/src/typechain/factories/index.ts @@ -1,13 +1,18 @@ /* Autogenerated file. Do not edit manually. */ /* tslint:disable */ /* eslint-disable */ +export { IBridgehub__factory } from "./IBridgehub__factory"; export { IContractDeployer__factory } from "./IContractDeployer__factory"; export { IERC1271__factory } from "./IERC1271__factory"; export { IERC20__factory } from "./IERC20__factory"; export { IEthToken__factory } from "./IEthToken__factory"; export { IL1Bridge__factory } from "./IL1Bridge__factory"; +export { IL1ERC20Bridge__factory } from "./IL1ERC20Bridge__factory"; export { IL1Messenger__factory } from "./IL1Messenger__factory"; +export { IL1SharedBridge__factory } from "./IL1SharedBridge__factory"; export { IL2Bridge__factory } from "./IL2Bridge__factory"; export { INonceHolder__factory } from "./INonceHolder__factory"; export { IPaymasterFlow__factory } from "./IPaymasterFlow__factory"; +export { ITestnetERC20Token__factory } from "./ITestnetERC20Token__factory"; export { IZkSync__factory } from "./IZkSync__factory"; +export { IZkSyncStateTransition__factory } from "./IZkSyncStateTransition__factory"; diff --git a/src/typechain/index.ts b/src/typechain/index.ts index 61222d25..92e4f624 100644 --- a/src/typechain/index.ts +++ b/src/typechain/index.ts @@ -1,24 +1,34 @@ /* Autogenerated file. Do not edit manually. */ /* tslint:disable */ /* eslint-disable */ +export type { IBridgehub } from "./IBridgehub"; export type { IContractDeployer } from "./IContractDeployer"; export type { IERC1271 } from "./IERC1271"; export type { IERC20 } from "./IERC20"; export type { IEthToken } from "./IEthToken"; export type { IL1Bridge } from "./IL1Bridge"; +export type { IL1ERC20Bridge } from "./IL1ERC20Bridge"; export type { IL1Messenger } from "./IL1Messenger"; +export type { IL1SharedBridge } from "./IL1SharedBridge"; export type { IL2Bridge } from "./IL2Bridge"; export type { INonceHolder } from "./INonceHolder"; export type { IPaymasterFlow } from "./IPaymasterFlow"; +export type { ITestnetERC20Token } from "./ITestnetERC20Token"; export type { IZkSync } from "./IZkSync"; +export type { IZkSyncStateTransition } from "./IZkSyncStateTransition"; export * as factories from "./factories"; +export { IBridgehub__factory } from "./factories/IBridgehub__factory"; export { IContractDeployer__factory } from "./factories/IContractDeployer__factory"; export { IERC1271__factory } from "./factories/IERC1271__factory"; export { IERC20__factory } from "./factories/IERC20__factory"; export { IEthToken__factory } from "./factories/IEthToken__factory"; export { IL1Bridge__factory } from "./factories/IL1Bridge__factory"; +export { IL1ERC20Bridge__factory } from "./factories/IL1ERC20Bridge__factory"; export { IL1Messenger__factory } from "./factories/IL1Messenger__factory"; +export { IL1SharedBridge__factory } from "./factories/IL1SharedBridge__factory"; export { IL2Bridge__factory } from "./factories/IL2Bridge__factory"; export { INonceHolder__factory } from "./factories/INonceHolder__factory"; export { IPaymasterFlow__factory } from "./factories/IPaymasterFlow__factory"; +export { ITestnetERC20Token__factory } from "./factories/ITestnetERC20Token__factory"; export { IZkSync__factory } from "./factories/IZkSync__factory"; +export { IZkSyncStateTransition__factory } from "./factories/IZkSyncStateTransition__factory"; diff --git a/src/types.ts b/src/types.ts index 55b98c55..7b95f48c 100644 --- a/src/types.ts +++ b/src/types.ts @@ -12,6 +12,7 @@ import { serializeEip712, sleep, eip712TxHash, + isAddressEq, } from './utils'; import {Provider} from './provider'; @@ -401,7 +402,7 @@ export class Transaction extends ethers.Transaction { tx ); assertArgument( - result.from.toLowerCase() === tx.from.toLowerCase(), + isAddressEq(result.from, tx.from), 'from mismatch', 'tx', tx diff --git a/src/utils.ts b/src/utils.ts index c5d5a0dd..aee746a7 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -13,13 +13,14 @@ import { } from './types'; import {Provider} from './provider'; import {EIP712Signer} from './signer'; -import {IERC20__factory, IL1Bridge__factory} from './typechain'; -import IZkSyncABI from '../abi/IZkSync.json'; +import {IERC20__factory} from './typechain'; +import IZkSyncABI from '../abi/IZkSyncStateTransition.json'; +import IBridgehubABI from '../abi/IBridgehub.json'; import IContractDeployerABI from '../abi/IContractDeployer.json'; import IL1MessengerABI from '../abi/IL1Messenger.json'; import IERC20ABI from '../abi/IERC20.json'; import IERC1271ABI from '../abi/IERC1271.json'; -import IL1BridgeABI from '../abi/IL1Bridge.json'; +import IL1BridgeABI from '../abi/IL1ERC20Bridge.json'; import IL2BridgeABI from '../abi/IL2Bridge.json'; import INonceHolderABI from '../abi/INonceHolder.json'; @@ -33,6 +34,12 @@ export {EIP712_TYPES} from './signer'; */ export const ZKSYNC_MAIN_ABI = new ethers.Interface(IZkSyncABI); +/** + * The ABI of the `Bridgehub` interface. + * @constant + */ +export const BRIDGEHUB_ABI = new ethers.Interface(IBridgehubABI); + /** * The ABI for the `IContractDeployer` interface, which is utilized for deploying smart contracts. * @constant @@ -82,6 +89,17 @@ export const NONCE_HOLDER_ABI = new ethers.Interface(INonceHolderABI); export const ETH_ADDRESS: Address = '0x0000000000000000000000000000000000000000'; +/** + * The address of the L1 `ETH` token. + * @constant + */ +export const LEGACY_ETH_ADDRESS: Address = + '0x0000000000000000000000000000000000000000'; + +// in the contracts the zero address can not be used, use one instead +export const ETH_ADDRESS_IN_CONTRACTS: Address = + '0x0000000000000000000000000000000000000001'; + /** * The formal address for the `Bootloader`. * @constant @@ -106,10 +124,18 @@ export const L1_MESSENGER_ADDRESS: Address = /** * The address of the L2 `ETH` token. * @constant + * @deprecated In favor of {@link L2_BASE_TOKEN_ADDRESS}. */ export const L2_ETH_TOKEN_ADDRESS: Address = '0x000000000000000000000000000000000000800a'; +/** + * The address of the base token. + * @constant + */ +export const L2_BASE_TOKEN_ADDRESS = + '0x000000000000000000000000000000000000800a'; + /** * The address of the Nonce holder. * @constant @@ -215,12 +241,13 @@ export const REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT = 800; * @example * * const isL1ETH = utils.isETH(utils.ETH_ADDRESS); // true - * const isL2ETH = utils.isETH(utils.L2_ETH_TOKEN_ADDRESS); // true + * const isL2ETH = utils.isETH(utils.ETH_ADDRESS_IN_CONTRACTS); // true */ -export function isETH(token: Address): boolean { +export function isETH(token: Address) { return ( - token.toLowerCase() === ETH_ADDRESS || - token.toLowerCase() === L2_ETH_TOKEN_ADDRESS + isAddressEq(token, LEGACY_ETH_ADDRESS) || + isAddressEq(token, L2_BASE_TOKEN_ADDRESS) || + isAddressEq(token, ETH_ADDRESS_IN_CONTRACTS) ); } @@ -300,7 +327,7 @@ export function getDeployedContracts( log => log.topics[0] === ethers.id('ContractDeployed(address,bytes32,address)') && - log.address === CONTRACT_DEPLOYER_ADDRESS + isAddressEq(log.address, CONTRACT_DEPLOYER_ADDRESS) ) // Take the last topic (deployed contract address as U256) and extract address from it (U160). .map(log => { @@ -749,7 +776,7 @@ export function getL2HashFromPriorityOp( ): string { let txHash: string | null = null; for (const log of txReceipt.logs) { - if (log.address.toLowerCase() !== zkSyncAddress.toLowerCase()) { + if (!isAddressEq(log.address, zkSyncAddress)) { continue; } @@ -838,11 +865,20 @@ export async function getERC20DefaultBridgeData( l1TokenAddress: string, provider: ethers.Provider ): Promise { + if (isAddressEq(l1TokenAddress, LEGACY_ETH_ADDRESS)) { + l1TokenAddress = ETH_ADDRESS_IN_CONTRACTS; + } const token = IERC20__factory.connect(l1TokenAddress, provider); - const name = await token.name(); - const symbol = await token.symbol(); - const decimals = await token.decimals(); + const name = isAddressEq(l1TokenAddress, ETH_ADDRESS_IN_CONTRACTS) + ? 'Ether' + : await token.name(); + const symbol = isAddressEq(l1TokenAddress, ETH_ADDRESS_IN_CONTRACTS) + ? 'ETH' + : await token.symbol(); + const decimals = isAddressEq(l1TokenAddress, ETH_ADDRESS_IN_CONTRACTS) + ? 18 + : await token.decimals(); const coder = new AbiCoder(); @@ -917,7 +953,7 @@ function isECDSASignatureCorrect( signature: SignatureLike ): boolean { try { - return address === ethers.recoverAddress(msgHash, signature); + return isAddressEq(address, ethers.recoverAddress(msgHash, signature)); } catch { // In case ECDSA signature verification has thrown an error, // we simply consider the signature as incorrect. @@ -1106,8 +1142,7 @@ export async function estimateDefaultBridgeDepositL2Gas( // due to storage slot aggregation, the gas estimation will depend on the address // and so estimation for the zero address may be smaller than for the sender. from ??= ethers.Wallet.createRandom().address; - - if (token === ETH_ADDRESS) { + if (await providerL2.isBaseToken(token)) { return await providerL2.estimateL1ToL2Execute({ contractAddress: to, gasPerPubdataByte: gasPerPubdataByte, @@ -1116,36 +1151,18 @@ export async function estimateDefaultBridgeDepositL2Gas( l2Value: amount, }); } else { - let value, l1BridgeAddress, l2BridgeAddress, bridgeData; const bridgeAddresses = await providerL2.getDefaultBridgeAddresses(); - const l1WethBridge = IL1Bridge__factory.connect( - bridgeAddresses.wethL1!, - providerL1 - ); - let l2WethToken = ethers.ZeroAddress; - try { - l2WethToken = await l1WethBridge.l2TokenAddress(token); - } catch (e) { - // skip - } - if (l2WethToken !== ethers.ZeroAddress) { - value = amount; - l1BridgeAddress = bridgeAddresses.wethL1; - l2BridgeAddress = bridgeAddresses.wethL2; - bridgeData = '0x'; - } else { - value = 0; - l1BridgeAddress = bridgeAddresses.erc20L1; - l2BridgeAddress = bridgeAddresses.erc20L2; - bridgeData = await getERC20DefaultBridgeData(token, providerL1); - } + const value = 0; + const l1BridgeAddress = bridgeAddresses.sharedL1; + const l2BridgeAddress = bridgeAddresses.sharedL2; + const bridgeData = await getERC20DefaultBridgeData(token, providerL1); return await estimateCustomBridgeDepositL2Gas( providerL2, - l1BridgeAddress!, - l2BridgeAddress!, - token, + l1BridgeAddress, + l2BridgeAddress, + isAddressEq(token, LEGACY_ETH_ADDRESS) ? ETH_ADDRESS_IN_CONTRACTS : token, amount, to, bridgeData, @@ -1233,7 +1250,7 @@ export async function estimateCustomBridgeDepositL2Gas( export function toJSON(object: any): string { return JSON.stringify( object, - (key, value) => { + (_, value) => { if (typeof value === 'bigint') { return value.toString(); // Convert BigInt to string } @@ -1242,3 +1259,15 @@ export function toJSON(object: any): string { 2 ); } + +/** + * Compares stringified addresses, taking into account the fact that + * addresses might be represented in different casing. + * + * @param a - The first address to compare. + * @param b - The second address to compare. + * @returns A boolean indicating whether the addresses are equal. + */ +export function isAddressEq(a: Address, b: Address): boolean { + return a.toLowerCase() === b.toLowerCase(); +} diff --git a/src/wallet.ts b/src/wallet.ts index bce25f1d..b0ac8eea 100644 --- a/src/wallet.ts +++ b/src/wallet.ts @@ -22,7 +22,13 @@ import { TransactionResponse, } from './types'; import {AdapterL1, AdapterL2} from './adapters'; -import {IL1Bridge, IL2Bridge, IZkSync} from './typechain'; +import { + IBridgehub, + IL1ERC20Bridge, + IL1SharedBridge, + IL2Bridge, + IZkSyncStateTransition, +} from './typechain'; /** * A `Wallet` is an extension of {@link ethers.Wallet} with additional features for interacting with zkSync Era. @@ -36,7 +42,9 @@ export class Wallet extends AdapterL2(AdapterL1(ethers.Wallet)) { override _providerL1(): ethers.Provider { if (!this.providerL1) { - throw new Error('L1 provider missing: use `connectToL1` to specify!'); + throw new Error( + 'L1 provider is missing! Specify an L1 provider using `Wallet.connectToL1()`.' + ); } return this.providerL1; } @@ -67,12 +75,32 @@ export class Wallet extends AdapterL2(AdapterL1(ethers.Wallet)) { * const ethProvider = ethers.getDefaultProvider("sepolia"); * const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); * - * console.log(`Main contract: ${await wallet.getMainContract()}`); + * const mainContract = await wallet.getMainContract(); */ - override async getMainContract(): Promise { + override async getMainContract(): Promise { return super.getMainContract(); } + /** + * @inheritDoc + * + * @example + * + * import { Wallet, Provider, utils } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const PRIVATE_KEY = ""; + * + * const provider = Provider.getDefaultProvider(types.Network.Sepolia); + * const ethProvider = ethers.getDefaultProvider("sepolia"); + * const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); + * + * const bridgehub = await wallet.getBridgehubContract(); + */ + override async getBridgehubContract(): Promise { + return super.getBridgehubContract(); + } + /** * @inheritDoc * @@ -90,8 +118,9 @@ export class Wallet extends AdapterL2(AdapterL1(ethers.Wallet)) { * const l1BridgeContracts = await wallet.getL1BridgeContracts(); */ override async getL1BridgeContracts(): Promise<{ - erc20: IL1Bridge; - weth: IL1Bridge; + erc20: IL1ERC20Bridge; + weth: IL1ERC20Bridge; + shared: IL1SharedBridge; }> { return super.getL1BridgeContracts(); } @@ -224,7 +253,135 @@ export class Wallet extends AdapterL2(AdapterL1(ethers.Wallet)) { /** * @inheritDoc * - * @example Deposit ETH. + * @example + * + * import { Wallet, Provider, types, utils } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const PRIVATE_KEY = ""; + * + * const provider = Provider.getDefaultProvider(types.Network.Sepolia); + * const ethProvider = ethers.getDefaultProvider("sepolia"); + * const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); + * + * console.log(`Base token: ${await wallet.getBaseToken()}`); + */ + override async getBaseToken(): Promise { + return super.getBaseToken(); + } + + /** + * @inheritDoc + * + * @example + * + * import { Wallet, Provider, types, utils } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const PRIVATE_KEY = ""; + * + * const provider = Provider.getDefaultProvider(types.Network.Sepolia); + * const ethProvider = ethers.getDefaultProvider("sepolia"); + * const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); + * + * console.log(`Is ETH-based chain: ${await wallet.isETHBasedChain()}`); + */ + override async isETHBasedChain(): Promise { + return super.isETHBasedChain(); + } + + /** + * @inheritDoc + * + * @example Get allowance parameters for depositing ETH on non-ETH-based chain. + * + * import { Wallet, Provider, types, utils } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const PRIVATE_KEY = ""; + * + * const provider = Provider.getDefaultProvider(types.Network.Sepolia); + * const ethProvider = ethers.getDefaultProvider("sepolia"); + * const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); + * + * const token = utils.LEGACY_ETH_ADDRESS; + * const amount = 5; + * const approveParams = await wallet.getDepositAllowanceParams(token, amount); + * + * await ( + * await wallet.approveERC20( + * approveParams[0].token, + * approveParams[0].allowance + * ) + * ).wait(); + * + * @example Get allowance parameters for depositing base token on non-ETH-based chain. + * + * import { Wallet, Provider, types, utils } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const PRIVATE_KEY = ""; + * + * const provider = Provider.getDefaultProvider(types.Network.Sepolia); + * const ethProvider = ethers.getDefaultProvider("sepolia"); + * const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); + * + * const token = await wallet.getBaseToken(); + * const amount = 5; + * const approveParams = await wallet.getDepositAllowanceParams(token, amount); + * + * await ( + * await wallet.approveERC20( + * approveParams[0].token, + * approveParams[0].allowance + * ) + * ).wait(); + * + * @example Get allowance parameters for depositing non-base token on non-ETH-based chain. + * + * import { Wallet, Provider, types, utils } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const PRIVATE_KEY = ""; + * + * const provider = Provider.getDefaultProvider(types.Network.Sepolia); + * const ethProvider = ethers.getDefaultProvider("sepolia"); + * const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); + * + * const token = ""; + * const amount = 5; + * const approveParams = await wallet.getDepositAllowanceParams(token, amount); + * + * await ( + * await wallet.approveERC20( + * approveParams[0].token, + * approveParams[0].allowance + * ) + * ).wait(); + * + * await ( + * await wallet.approveERC20( + * approveParams[1].token, + * approveParams[1].allowance + * ) + * ).wait(); + */ + override async getDepositAllowanceParams( + token: Address, + amount: BigNumberish + ): Promise< + { + token: Address; + allowance: BigNumberish; + }[] + > { + return super.getDepositAllowanceParams(token, amount); + } + + /** + * @inheritDoc + * + * @example Deposit ETH on ETH-based chain. * * import { Wallet, Provider, types, utils } from "zksync-ethers"; * import { ethers } from "ethers"; @@ -244,7 +401,7 @@ export class Wallet extends AdapterL2(AdapterL1(ethers.Wallet)) { * // we can use `await depositTx.waitL1Commit()` * await depositTx.wait(); * - * @example Deposit token. + * @example Deposit token on ETH-based chain. * * import { Wallet, Provider, types, utils } from "zksync-ethers"; * import { ethers } from "ethers"; @@ -265,6 +422,71 @@ export class Wallet extends AdapterL2(AdapterL1(ethers.Wallet)) { * // processed by zkSync. If we want to wait only for the transaction to be processed on L1, * // we can use `await depositTx.waitL1Commit()` * await depositTx.wait(); + * + * @example Deposit ETH on non-ETH-based chain. + * + * import { Wallet, Provider, types, utils } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const PRIVATE_KEY = ""; + * + * const provider = Provider.getDefaultProvider(types.Network.Sepolia); + * const ethProvider = ethers.getDefaultProvider("sepolia"); + * const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); + * + * const depositTx = await wallet.deposit({ + * token: utils.ETH_ADDRESS, + * amount: 10_000_000n, + * approveBaseERC20: true, + * }); + * // Note that we wait not only for the L1 transaction to complete but also for it to be + * // processed by zkSync. If we want to wait only for the transaction to be processed on L1, + * // we can use `await depositTx.waitL1Commit()` + * await depositTx.wait(); + * + * @example Deposit base token on non-ETH-based chain. + * + * import { Wallet, Provider, types, utils } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const PRIVATE_KEY = ""; + * + * const provider = Provider.getDefaultProvider(types.Network.Sepolia); + * const ethProvider = ethers.getDefaultProvider("sepolia"); + * const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); + * + * const depositTx = await wallet.deposit({ + * token: await wallet.getBaseToken(), + * amount: 10_000_000n, + * approveERC20: true, // or approveBaseERC20: true + * }); + * // Note that we wait not only for the L1 transaction to complete but also for it to be + * // processed by zkSync. If we want to wait only for the transaction to be processed on L1, + * // we can use `await depositTx.waitL1Commit()` + * await depositTx.wait(); + * + * @example Deposit non-base token on non-ETH-based chain. + * + * import { Wallet, Provider, types, utils } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const PRIVATE_KEY = ""; + * + * const provider = Provider.getDefaultProvider(types.Network.Sepolia); + * const ethProvider = ethers.getDefaultProvider("sepolia"); + * const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); + * + * const tokenL1 = "0x56E69Fa1BB0d1402c89E3A4E3417882DeA6B14Be"; + * const depositTx = await wallet.deposit({ + * token: tokenL1, + * amount: 10_000_000n, + * approveERC20: true, + * approveBaseERC20: true, + * }); + * // Note that we wait not only for the L1 transaction to complete but also for it to be + * // processed by zkSync. If we want to wait only for the transaction to be processed on L1, + * // we can use `await depositTx.waitL1Commit()` + * await depositTx.wait(); */ override async deposit(transaction: { token: Address; @@ -273,11 +495,13 @@ export class Wallet extends AdapterL2(AdapterL1(ethers.Wallet)) { operatorTip?: BigNumberish; bridgeAddress?: Address; approveERC20?: boolean; + approveBaseERC20?: boolean; l2GasLimit?: BigNumberish; gasPerPubdataByte?: BigNumberish; refundRecipient?: Address; overrides?: Overrides; approveOverrides?: Overrides; + approveBaseOverrides?: Overrides; customBridgeData?: BytesLike; }): Promise { return super.deposit(transaction); @@ -483,6 +707,48 @@ export class Wallet extends AdapterL2(AdapterL1(ethers.Wallet)) { return super.claimFailedDeposit(depositHash, overrides); } + /** + * @inheritDoc + * + * @example + * + * import { Wallet, Provider, utils } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const PRIVATE_KEY = ""; + * + * const provider = Provider.getDefaultProvider(types.Network.Sepolia); + * const ethProvider = ethers.getDefaultProvider("sepolia"); + * const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); + * + * const tx = { + * contractAddress: await wallet.getAddress(), + * calldata: '0x', + * l2Value: 7_000_000_000, + * }; + * + * const approveParams = await wallet.getRequestExecuteAllowanceParams(tx); + * await ( + * await wallet.approveERC20( + * approveParams.token, + * approveParams.allowance + * ) + * ).wait(); + */ + override async getRequestExecuteAllowanceParams(transaction: { + contractAddress: Address; + calldata: string; + l2GasLimit?: BigNumberish; + l2Value?: BigNumberish; + factoryDeps?: BytesLike[]; + operatorTip?: BigNumberish; + gasPerPubdataByte?: BigNumberish; + refundRecipient?: Address; + overrides?: Overrides; + }): Promise<{token: Address; allowance: BigNumberish}> { + return super.getRequestExecuteAllowanceParams(transaction); + } + /** * @inheritDoc * @@ -508,7 +774,8 @@ export class Wallet extends AdapterL2(AdapterL1(ethers.Wallet)) { override async requestExecute(transaction: { contractAddress: Address; calldata: string; - l2GasLimit: BigNumberish; + l2GasLimit?: BigNumberish; + mintValue?: BigNumberish; l2Value?: BigNumberish; factoryDeps?: BytesLike[]; operatorTip?: BigNumberish; @@ -545,6 +812,7 @@ export class Wallet extends AdapterL2(AdapterL1(ethers.Wallet)) { contractAddress: Address; calldata: string; l2GasLimit?: BigNumberish; + mintValue?: BigNumberish; l2Value?: BigNumberish; factoryDeps?: BytesLike[]; operatorTip?: BigNumberish; @@ -580,6 +848,7 @@ export class Wallet extends AdapterL2(AdapterL1(ethers.Wallet)) { contractAddress: Address; calldata: string; l2GasLimit?: BigNumberish; + mintValue?: BigNumberish; l2Value?: BigNumberish; factoryDeps?: BytesLike[]; operatorTip?: BigNumberish; @@ -687,6 +956,7 @@ export class Wallet extends AdapterL2(AdapterL1(ethers.Wallet)) { override async getL2BridgeContracts(): Promise<{ erc20: IL2Bridge; weth: IL2Bridge; + shared: IL2Bridge; }> { return super.getL2BridgeContracts(); } @@ -887,6 +1157,36 @@ export class Wallet extends AdapterL2(AdapterL1(ethers.Wallet)) { return super.transfer(transaction); } + /** + * @inheritDoc + * + * @example + * + * import { Wallet, Provider, utils } from "zksync-ethers"; + * import { ethers } from "ethers"; + * + * const PRIVATE_KEY = ""; + * + * const provider = Provider.getDefaultProvider(types.Network.Sepolia); + * const wallet = new Wallet(PRIVATE_KEY, provider); + * + * // Any L2 -> L1 transaction can be used. + * // In this case, withdrawal transaction is used. + * const tx = "0x2a1c6c74b184965c0cb015aae9ea134fd96215d2e4f4979cfec12563295f610e"; + * console.log(`Confirmation data: ${utils.toJSON(await wallet.getPriorityOpConfirmation(tx, 0))}`); + */ + override async getPriorityOpConfirmation( + txHash: string, + index = 0 + ): Promise<{ + l1BatchNumber: number; + l2MessageIndex: number; + l2TxNumberInBlock: number | null; + proof: string[]; + }> { + return super.getPriorityOpConfirmation(txHash, index); + } + /** * Returns `ethers.Wallet` object with the same private key. * diff --git a/tests/custom-matchers.ts b/tests/custom-matchers.ts index c3c5fb15..5748bc0b 100644 --- a/tests/custom-matchers.ts +++ b/tests/custom-matchers.ts @@ -1,4 +1,7 @@ import * as chai from 'chai'; +import {types} from '../src'; + +const {expect} = chai; declare global { // eslint-disable-next-line @typescript-eslint/no-namespace @@ -24,3 +27,47 @@ chai.Assertion.addMethod( } } ); + +// Custom assertion function for BigNumber values with a percentage tolerance +export function expectBigNumberCloseTo( + actual: bigint, + expected: bigint, + tolerancePercentage: number +) { + const actualPercentageDiff = ((actual - expected) * 100n) / expected; + const abs = + actualPercentageDiff < 0n ? -actualPercentageDiff : actualPercentageDiff; + expect(abs < tolerancePercentage).to.be.true; +} + +export function expectFeeDataCloseToExpected( + result: types.FullDepositFee, + expected: types.FullDepositFee, + tolerancePercentage: number +) { + expectBigNumberCloseTo( + result.baseCost.valueOf(), + expected.baseCost.valueOf(), + tolerancePercentage + ); + expectBigNumberCloseTo( + result.l1GasLimit.valueOf(), + expected.l1GasLimit.valueOf(), + tolerancePercentage + ); + expectBigNumberCloseTo( + result.l2GasLimit.valueOf(), + expected.l2GasLimit.valueOf(), + tolerancePercentage + ); + expectBigNumberCloseTo( + result.maxFeePerGas!.valueOf(), + expected.maxFeePerGas!.valueOf(), + tolerancePercentage + ); + expectBigNumberCloseTo( + result.maxPriorityFeePerGas!.valueOf(), + expected.maxPriorityFeePerGas!.valueOf(), + tolerancePercentage + ); +} diff --git a/tests/integration/account-abstraction.test.ts b/tests/integration/account-abstraction.test.ts index dd6b7c63..7df63989 100644 --- a/tests/integration/account-abstraction.test.ts +++ b/tests/integration/account-abstraction.test.ts @@ -3,6 +3,7 @@ import '../custom-matchers'; import {Provider, types, utils, Wallet, ContractFactory} from '../../src'; import {Contract, ethers, Typed} from 'ethers'; import {ECDSASmartAccount, MultisigECDSASmartAccount} from '../../src'; +import {ADDRESS1, PRIVATE_KEY1, APPROVAL_TOKEN, PAYMASTER} from '../utils'; const {expect} = chai; @@ -12,15 +13,8 @@ import Storage from '../files/Storage.json'; import MultisigAccount from '../files/TwoUserMultisig.json'; describe('Account Abstraction', () => { - const ADDRESS = '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049'; - const PRIVATE_KEY = - '0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110'; - const provider = Provider.getDefaultProvider(types.Network.Localhost); - const wallet = new Wallet(PRIVATE_KEY, provider); - - const TOKEN = '0x841c43Fa5d8fFfdB9efE3358906f7578d8700Dd4'; - const PAYMASTER = '0xa222f0c183AFA73a8Bc1AFb48D34C88c9Bf7A174'; + const wallet = new Wallet(PRIVATE_KEY1, provider); it('use the ERC20 token for paying transaction fee', async () => { const InitMintAmount = 10n; @@ -112,7 +106,7 @@ describe('Account Abstraction', () => { it('use multisig account', async () => { const storageValue = 500n; - const account = ECDSASmartAccount.create(ADDRESS, PRIVATE_KEY, provider); + const account = ECDSASmartAccount.create(ADDRESS1, PRIVATE_KEY1, provider); const multisigAccountAbi = MultisigAccount.abi; const multisigAccountBytecode: string = MultisigAccount.bytecode; @@ -140,11 +134,11 @@ describe('Account Abstraction', () => { // send paymaster approval token to multisig account const sendApprovalTokenTx = await new Wallet( - PRIVATE_KEY, + PRIVATE_KEY1, provider ).transfer({ to: multisigAddress, - token: TOKEN, + token: APPROVAL_TOKEN, amount: 5, }); await sendApprovalTokenTx.wait(); @@ -182,7 +176,7 @@ describe('Account Abstraction', () => { const minimalAllowance = 1n; const storageValue = 700n; - const account = ECDSASmartAccount.create(ADDRESS, PRIVATE_KEY, provider); + const account = ECDSASmartAccount.create(ADDRESS1, PRIVATE_KEY1, provider); const storageAbi = Storage.contracts['Storage.sol:Storage'].abi; const storageBytecode: string = @@ -195,13 +189,14 @@ describe('Account Abstraction', () => { const storage = (await storageFactory.deploy()) as Contract; const accountBalanceBeforeTx = await account.getBalance(); - const accountApprovalTokenBalanceBeforeTx = await account.getBalance(TOKEN); + const accountApprovalTokenBalanceBeforeTx = + await account.getBalance(APPROVAL_TOKEN); const paymasterSetTx = await storage.set(storageValue, { customData: { paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: minimalAllowance, innerInput: new Uint8Array(), }), @@ -210,7 +205,8 @@ describe('Account Abstraction', () => { await paymasterSetTx.wait(); const accountBalanceAfterTx = await account.getBalance(); - const accountApprovalTokenBalanceAfterTx = await account.getBalance(TOKEN); + const accountApprovalTokenBalanceAfterTx = + await account.getBalance(APPROVAL_TOKEN); expect(accountBalanceBeforeTx === accountBalanceAfterTx).to.be.true; expect( diff --git a/tests/integration/contract.test.ts b/tests/integration/contract.test.ts index d9724a47..160f20e0 100644 --- a/tests/integration/contract.test.ts +++ b/tests/integration/contract.test.ts @@ -2,23 +2,18 @@ import * as chai from 'chai'; import '../custom-matchers'; import {ContractFactory, Provider, types, Wallet, Contract} from '../../src'; import {ethers} from 'ethers'; +import {PRIVATE_KEY1, DAI_L1} from '../utils'; const {expect} = chai; -import TokensL1 from '../files/tokens.json'; import Token from '../files/Token.json'; import Paymaster from '../files/Paymaster.json'; import Storage from '../files/Storage.json'; import Demo from '../files/Demo.json'; describe('ContractFactory', () => { - const PRIVATE_KEY = - '0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110'; - const provider = Provider.getDefaultProvider(types.Network.Localhost); - const wallet = new Wallet(PRIVATE_KEY, provider); - - const DAI_L1 = TokensL1[0].address; + const wallet = new Wallet(PRIVATE_KEY1, provider); describe('#constructor()', () => { it('`ContractFactory(abi, bytecode, runner)` should return a `ContractFactory` with `create` deployment', async () => { diff --git a/tests/integration/provider.test.ts b/tests/integration/provider.test.ts index 694852da..a79cd6c8 100644 --- a/tests/integration/provider.test.ts +++ b/tests/integration/provider.test.ts @@ -2,30 +2,30 @@ import {expect} from 'chai'; import '../custom-matchers'; import {Provider, types, utils, Wallet} from '../../src'; import {ethers} from 'ethers'; - -import TokensL1 from '../files/tokens.json'; +import { + IS_ETH_BASED, + ADDRESS1, + PRIVATE_KEY1, + ADDRESS2, + DAI_L1, + APPROVAL_TOKEN, + PAYMASTER, +} from '../utils'; describe('Provider', () => { - const ADDRESS = '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049'; - const PRIVATE_KEY = - '0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110'; - const RECEIVER = '0xa61464658AfeAf65CccaaFD3a512b69A83B77618'; - const provider = Provider.getDefaultProvider(types.Network.Localhost); - const wallet = new Wallet(PRIVATE_KEY, provider); - - const DAI_L1 = TokensL1[0].address; - - const TOKEN = '0x841c43Fa5d8fFfdB9efE3358906f7578d8700Dd4'; - const PAYMASTER = '0xa222f0c183AFA73a8Bc1AFb48D34C88c9Bf7A174'; + const wallet = new Wallet(PRIVATE_KEY1, provider); let receipt: types.TransactionReceipt; + let baseToken: string; before('setup', async function () { this.timeout(25_000); + + baseToken = await provider.getBaseTokenContractAddress(); const tx = await wallet.transfer({ - token: utils.ETH_ADDRESS, - to: RECEIVER, + token: utils.LEGACY_ETH_ADDRESS, + to: ADDRESS2, amount: 1_000_000, }); receipt = await tx.wait(); @@ -72,11 +72,17 @@ describe('Provider', () => { }); }); + describe('#getBridgehubContractAddress()', () => { + it('should return the address of main contract', async () => { + const result = await provider.getBridgehubContractAddress(); + expect(result).not.to.be.null; + }); + }); + describe('#getTestnetPaymasterAddress()', () => { it('should return the address of testnet paymaster', async () => { - const TESTNET_PAYMASTER = '0x2d348ebb27d2624178c6a8a358d1ea064e67fd47'; const result = await provider.getTestnetPaymasterAddress(); - expect(result).to.be.equal(TESTNET_PAYMASTER); + expect(result).not.to.be.null; }); }); @@ -97,9 +103,8 @@ describe('Provider', () => { describe('#getGasPrice()', () => { it('should return a gas price', async () => { - const GAS_PRICE = 100_000_000n; const result = await provider.getGasPrice(); - expect(result).to.be.equal(GAS_PRICE); + expect(result > 0n).to.be.true; }); }); @@ -112,25 +117,26 @@ describe('Provider', () => { describe('#getBalance()', () => { it('should return an ETH balance of the account at `address`', async () => { - const result = await provider.getBalance(ADDRESS); - expect(result > 0).to.be.true; - }); + const result = await provider.getBalance(ADDRESS1); + expect(result > 0n).to.be.true; + }).timeout(5_000); it('should return a DAI balance of the account at `address`', async () => { const result = await provider.getBalance( - ADDRESS, + ADDRESS1, 'latest', await provider.l2TokenAddress(DAI_L1) ); - expect(result > 0).to.be.true; - }); + expect(result > 0n).to.be.true; + }).timeout(5_000); }); describe('#getAllAccountBalances()', () => { it('should return the all balances of the account at `address`', async () => { - const result = await provider.getAllAccountBalances(ADDRESS); - expect(Object.keys(result)).to.have.lengthOf(2); // ETH, DAI - }); + const result = await provider.getAllAccountBalances(ADDRESS1); + const expected = IS_ETH_BASED ? 2 : 3; + expect(Object.keys(result)).to.have.lengthOf(expected); + }).timeout(5_000); }); describe('#getBlockDetails()', () => { @@ -154,7 +160,7 @@ describe('Provider', () => { ); const testnetPaymasterBytecodeHash = ethers.hexlify( utils.hashBytecode(testnetPaymasterBytecode) - ); // "0x010000d590477725d953dc54a472de0943121b913d97843dc3e49e4f8519f34d" + ); const result = await provider.getBytecodeByHash( testnetPaymasterBytecodeHash ); @@ -162,7 +168,7 @@ describe('Provider', () => { Array.from(ethers.getBytes(testnetPaymasterBytecode)) ); }); - }); + }).timeout(10_000); describe('#getRawBlockTransactions()', () => { it('should return a raw transactions', async () => { @@ -258,7 +264,7 @@ describe('Provider', () => { const result = await provider.newFilter({ fromBlock: 0, toBlock: 5, - address: utils.L2_ETH_TOKEN_ADDRESS, + address: utils.L2_BASE_TOKEN_ADDRESS, }); expect(result).not.to.be.null; }); @@ -273,9 +279,16 @@ describe('Provider', () => { }); describe('#l2TokenAddress()', () => { + it('should return the L2 base address', async () => { + const result = await provider.l2TokenAddress(baseToken); + expect(result).to.be.equal(utils.L2_BASE_TOKEN_ADDRESS); + }); + it('should return the L2 ETH address', async () => { - const result = await provider.l2TokenAddress(utils.ETH_ADDRESS); - expect(result).to.be.equal(utils.ETH_ADDRESS); + if (!IS_ETH_BASED) { + const result = await provider.l2TokenAddress(utils.LEGACY_ETH_ADDRESS); + expect(result).not.to.be.null; + } }); it('should return the L2 DAI address', async () => { @@ -285,9 +298,9 @@ describe('Provider', () => { }); describe('#l1TokenAddress()', () => { - it('should return the L1 ETH address', async () => { - const result = await provider.l1TokenAddress(utils.ETH_ADDRESS); - expect(result).to.be.equal(utils.ETH_ADDRESS); + it('should return L1 token address', async () => { + const result = await provider.l1TokenAddress(utils.LEGACY_ETH_ADDRESS); + expect(result).to.be.equal(utils.LEGACY_ETH_ADDRESS); }); it('should return the L1 DAI address', async () => { @@ -363,7 +376,7 @@ describe('Provider', () => { const result = await provider.getLogs({ fromBlock: 0, toBlock: 5, - address: utils.L2_ETH_TOKEN_ADDRESS, + address: utils.L2_BASE_TOKEN_ADDRESS, }); expect(result).not.to.be.null; }); @@ -372,25 +385,25 @@ describe('Provider', () => { describe('#getWithdrawTx()', () => { it('should return an ETH withdraw transaction', async () => { const tx = { - from: ADDRESS, + from: ADDRESS1, value: 7_000_000_000n, - to: '0x000000000000000000000000000000000000800a', + to: utils.L2_BASE_TOKEN_ADDRESS, data: '0x51cff8d900000000000000000000000036615cf349d7f6344891b1e7ca7c72883f5dc049', }; const result = await provider.getWithdrawTx({ - token: utils.ETH_ADDRESS, + token: utils.LEGACY_ETH_ADDRESS, amount: 7_000_000_000, - to: ADDRESS, - from: ADDRESS, + to: ADDRESS1, + from: ADDRESS1, }); expect(result).to.be.deep.equal(tx); }); - it('should return an ETH withdraw transaction with paymaster parameters', async () => { + it('should return a withdraw transaction of the base token with paymaster parameters', async () => { const tx = { - from: ADDRESS, + from: ADDRESS1, value: 7_000_000_000n, - to: '0x000000000000000000000000000000000000800a', + to: utils.L2_BASE_TOKEN_ADDRESS, data: '0x51cff8d900000000000000000000000036615cf349d7f6344891b1e7ca7c72883f5dc049', customData: { paymasterParams: { @@ -401,13 +414,13 @@ describe('Provider', () => { }, }; const result = await provider.getWithdrawTx({ - token: utils.ETH_ADDRESS, + token: utils.LEGACY_ETH_ADDRESS, amount: 7_000_000_000, - to: ADDRESS, - from: ADDRESS, + to: ADDRESS1, + from: ADDRESS1, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: 1, innerInput: new Uint8Array(), }), @@ -417,23 +430,23 @@ describe('Provider', () => { it('should return a DAI withdraw transaction', async () => { const tx = { - from: ADDRESS, - to: (await provider.getDefaultBridgeAddresses()).erc20L2, + from: ADDRESS1, + to: (await provider.getDefaultBridgeAddresses()).sharedL2, data: '0xd9caed1200000000000000000000000036615cf349d7f6344891b1e7ca7c72883f5dc04900000000000000000000000082b5ea13260346f4251c0940067a9117a6cf13840000000000000000000000000000000000000000000000000000000000000005', }; const result = await provider.getWithdrawTx({ token: await provider.l2TokenAddress(DAI_L1), amount: 5, - to: ADDRESS, - from: ADDRESS, + to: ADDRESS1, + from: ADDRESS1, }); expect(result).to.be.deepEqualExcluding(tx, ['data']); }); it('should return a DAI withdraw transaction with paymaster parameters', async () => { const tx = { - from: ADDRESS, - to: (await provider.getDefaultBridgeAddresses()).erc20L2, + from: ADDRESS1, + to: (await provider.getDefaultBridgeAddresses()).sharedL2, data: '0xd9caed1200000000000000000000000036615cf349d7f6344891b1e7ca7c72883f5dc04900000000000000000000000082b5ea13260346f4251c0940067a9117a6cf13840000000000000000000000000000000000000000000000000000000000000005', customData: { paymasterParams: { @@ -446,11 +459,11 @@ describe('Provider', () => { const result = await provider.getWithdrawTx({ token: await provider.l2TokenAddress(DAI_L1), amount: 5, - to: ADDRESS, - from: ADDRESS, + to: ADDRESS1, + from: ADDRESS1, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: 1, innerInput: new Uint8Array(), }), @@ -460,15 +473,15 @@ describe('Provider', () => { it('should return a withdraw transaction with `tx.from==tx.to` when `tx.to` is not provided', async () => { const tx = { - from: ADDRESS, + from: ADDRESS1, value: 7_000_000_000n, - to: '0x000000000000000000000000000000000000800a', + to: utils.L2_BASE_TOKEN_ADDRESS, data: '0x51cff8d900000000000000000000000036615cf349d7f6344891b1e7ca7c72883f5dc049', }; const result = await provider.getWithdrawTx({ - token: utils.ETH_ADDRESS, + token: utils.LEGACY_ETH_ADDRESS, amount: 7_000_000_000, - from: ADDRESS, + from: ADDRESS1, }); expect(result).to.be.deep.equal(tx); }); @@ -476,7 +489,7 @@ describe('Provider', () => { it('should throw an error when `tx.to` and `tx.from` are not provided`', async () => { try { await provider.getWithdrawTx({ - token: utils.ETH_ADDRESS, + token: utils.LEGACY_ETH_ADDRESS, amount: 5, }); } catch (e) { @@ -487,10 +500,10 @@ describe('Provider', () => { it('should throw an error when `tx.amount!=tx.overrides.value', async () => { try { await provider.getWithdrawTx({ - token: utils.ETH_ADDRESS, + token: utils.LEGACY_ETH_ADDRESS, amount: 5, - to: ADDRESS, - from: ADDRESS, + to: ADDRESS1, + from: ADDRESS1, overrides: {value: 7}, }); } catch (e) { @@ -504,15 +517,15 @@ describe('Provider', () => { describe('#getTransferTx()', () => { it('should return an ETH transfer transaction', async () => { const tx = { - from: ADDRESS, - to: RECEIVER, + from: ADDRESS1, + to: ADDRESS2, value: 7_000_000_000, }; const result = await provider.getTransferTx({ - token: utils.ETH_ADDRESS, + token: utils.LEGACY_ETH_ADDRESS, amount: 7_000_000_000, - to: RECEIVER, - from: ADDRESS, + to: ADDRESS2, + from: ADDRESS1, }); expect(result).to.be.deep.equal(tx); }); @@ -520,8 +533,8 @@ describe('Provider', () => { it('should return an ETH transfer transaction with paymaster parameters', async () => { const tx = { type: utils.EIP712_TX_TYPE, - from: ADDRESS, - to: RECEIVER, + from: ADDRESS1, + to: ADDRESS2, value: 7_000_000_000, customData: { paymasterParams: { @@ -532,13 +545,13 @@ describe('Provider', () => { }, }; const result = await provider.getTransferTx({ - token: utils.ETH_ADDRESS, + token: utils.LEGACY_ETH_ADDRESS, amount: 7_000_000_000, - to: RECEIVER, - from: ADDRESS, + to: ADDRESS2, + from: ADDRESS1, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: 1, innerInput: new Uint8Array(), }), @@ -548,22 +561,22 @@ describe('Provider', () => { it('should return a DAI transfer transaction', async () => { const tx = { - from: ADDRESS, + from: ADDRESS1, to: await provider.l2TokenAddress(DAI_L1), data: '0xa9059cbb000000000000000000000000a61464658afeaf65cccaafd3a512b69a83b776180000000000000000000000000000000000000000000000000000000000000005', }; const result = await provider.getTransferTx({ token: await provider.l2TokenAddress(DAI_L1), amount: 5, - to: RECEIVER, - from: ADDRESS, + to: ADDRESS2, + from: ADDRESS1, }); expect(result).to.be.deep.equal(tx); }); it('should return a DAI transfer transaction with paymaster parameters', async () => { const tx = { - from: ADDRESS, + from: ADDRESS1, to: await provider.l2TokenAddress(DAI_L1), data: '0xa9059cbb000000000000000000000000a61464658afeaf65cccaafd3a512b69a83b776180000000000000000000000000000000000000000000000000000000000000005', customData: { @@ -577,11 +590,11 @@ describe('Provider', () => { const result = await provider.getTransferTx({ token: await provider.l2TokenAddress(DAI_L1), amount: 5, - to: RECEIVER, - from: ADDRESS, + to: ADDRESS2, + from: ADDRESS1, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: 1, innerInput: new Uint8Array(), }), @@ -593,90 +606,93 @@ describe('Provider', () => { describe('#estimateGasWithdraw()', () => { it('should return a gas estimation of the withdraw transaction', async () => { const result = await provider.estimateGasWithdraw({ - token: utils.ETH_ADDRESS, + token: utils.LEGACY_ETH_ADDRESS, amount: 7_000_000_000, - to: ADDRESS, - from: ADDRESS, + to: ADDRESS1, + from: ADDRESS1, }); - expect(result > 0).to.be.true; + expect(result > 0n).to.be.true; }); it('should return a gas estimation of the withdraw transaction with paymaster', async () => { + const token = IS_ETH_BASED + ? utils.ETH_ADDRESS_IN_CONTRACTS + : await wallet.l2TokenAddress(utils.ETH_ADDRESS_IN_CONTRACTS); const result = await provider.estimateGasWithdraw({ - token: utils.ETH_ADDRESS, + token: token, amount: 7_000_000_000, - to: ADDRESS, - from: ADDRESS, + to: ADDRESS1, + from: ADDRESS1, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: 1, innerInput: new Uint8Array(), }), }); - expect(result > 0).to.be.true; + expect(result > 0n).to.be.true; }); }); describe('#estimateGasTransfer()', () => { it('should return a gas estimation of the transfer transaction', async () => { const result = await provider.estimateGasTransfer({ - token: utils.ETH_ADDRESS, + token: utils.LEGACY_ETH_ADDRESS, amount: 7_000_000_000, - to: RECEIVER, - from: ADDRESS, + to: ADDRESS2, + from: ADDRESS1, }); - expect(result > 0).to.be.be.true; + expect(result > 0n).to.be.be.true; }); it('should return a gas estimation of the transfer transaction with paymaster', async () => { const result = await provider.estimateGasTransfer({ - token: utils.ETH_ADDRESS, + token: utils.LEGACY_ETH_ADDRESS, amount: 7_000_000_000, - to: RECEIVER, - from: ADDRESS, + to: ADDRESS2, + from: ADDRESS1, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: 1, innerInput: new Uint8Array(), }), }); - expect(result > 0).to.be.be.true; + expect(result > 0n).to.be.be.true; }); }); describe('#estimateGasL1()', () => { it('should return a gas estimation of the L1 transaction', async () => { const result = await provider.estimateGasL1({ - from: ADDRESS, - to: await provider.getMainContractAddress(), + from: ADDRESS1, + to: await provider.getBridgehubContractAddress(), value: 7_000_000_000, customData: { gasPerPubdata: 800, }, }); - expect(result > 0).to.be.true; + expect(result > 0n).to.be.true; }); }); describe('#estimateL1ToL2Execute()', () => { it('should return a gas estimation of the L1 to L2 transaction', async () => { const result = await provider.estimateL1ToL2Execute({ - contractAddress: await provider.getMainContractAddress(), + contractAddress: await provider.getBridgehubContractAddress(), calldata: '0x', - caller: ADDRESS, + caller: ADDRESS1, l2Value: 7_000_000_000, }); - expect(result > 0).to.be.true; + expect(result > 0n).to.be.true; }); }); describe('#estimateFee()', () => { it('should return a gas estimation of the transaction', async () => { const result = await provider.estimateFee({ - from: ADDRESS, - to: RECEIVER, + from: ADDRESS1, + to: ADDRESS2, value: `0x${7_000_000_000n.toString(16)}`, }); expect(result).not.to.be.null; @@ -686,34 +702,34 @@ describe('Provider', () => { describe('#estimateGas()', () => { it('should return a gas estimation of the transaction', async () => { const result = await provider.estimateGas({ - from: ADDRESS, + from: ADDRESS1, to: await provider.l2TokenAddress(DAI_L1), - data: utils.IERC20.encodeFunctionData('approve', [RECEIVER, 1]), + data: utils.IERC20.encodeFunctionData('approve', [ADDRESS2, 1]), }); - expect(result > 0).to.be.true; + expect(result > 0n).to.be.true; }); it('should return a gas estimation of the EIP712 transaction', async () => { const result = await provider.estimateGas({ - from: ADDRESS, + from: ADDRESS1, to: await provider.l2TokenAddress(DAI_L1), - data: utils.IERC20.encodeFunctionData('approve', [RECEIVER, 1]), + data: utils.IERC20.encodeFunctionData('approve', [ADDRESS2, 1]), customData: { gasPerPubdata: utils.DEFAULT_GAS_PER_PUBDATA_LIMIT, }, }); - expect(result > 0).to.be.true; + expect(result > 0n).to.be.true; }); }); describe('#getFilterChanges()', () => { it('should return the filtered logs', async () => { const filter = await provider.newFilter({ - address: utils.L2_ETH_TOKEN_ADDRESS, + address: utils.L2_BASE_TOKEN_ADDRESS, topics: [ethers.id('Transfer(address,address,uint256)')], }); const result = await provider.getFilterChanges(filter); expect(result).not.to.be.null; - }); + }).timeout(10_000); }); }); diff --git a/tests/integration/signer.test.ts b/tests/integration/signer.test.ts index 9a165f10..fdbfac80 100644 --- a/tests/integration/signer.test.ts +++ b/tests/integration/signer.test.ts @@ -2,30 +2,35 @@ import * as chai from 'chai'; import '../custom-matchers'; import {Provider, utils, Wallet, L2VoidSigner, L1VoidSigner} from '../../src'; import {ethers} from 'ethers'; +import {IS_ETH_BASED, ADDRESS1, PRIVATE_KEY1, ADDRESS2, DAI_L1} from '../utils'; const {expect} = chai; -import TokensL1 from '../files/tokens.json'; +import {ITestnetERC20Token__factory} from '../../src/typechain'; describe('L2VoidSigner', () => { - const ADDRESS = '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049'; - const RECEIVER = '0xa61464658AfeAf65CccaaFD3a512b69A83B77618'; - const provider = Provider.getDefaultProvider(); - const signer = new L2VoidSigner(ADDRESS, provider); + const signer = new L2VoidSigner(ADDRESS1, provider); + + let baseToken: string; + + before('setup', async function () { + this.timeout(25_000); + baseToken = await provider.getBaseTokenContractAddress(); + }); describe('#constructor()', () => { it('`L2VoidSigner(address, provider)` should return a `L2VoidSigner` with L2 provider', async () => { - const signer = new L2VoidSigner(ADDRESS, provider); + const signer = new L2VoidSigner(ADDRESS1, provider); - expect(signer.address).to.be.equal(ADDRESS); + expect(signer.address).to.be.equal(ADDRESS1); expect(signer.provider).to.be.equal(provider); }); it('`L2VoidSigner(address)` should return a `L2VoidSigner` without L2 provider', async () => { - const signer = new L2VoidSigner(ADDRESS); + const signer = new L2VoidSigner(ADDRESS1); - expect(signer.address).to.be.equal(ADDRESS); + expect(signer.address).to.be.equal(ADDRESS1); expect(signer.provider).to.be.null; }); }); @@ -33,14 +38,15 @@ describe('L2VoidSigner', () => { describe('#getBalance()', () => { it('should return the `L2VoidSigner` balance', async () => { const result = await signer.getBalance(); - expect(result > 0).to.be.true; + expect(result > 0n).to.be.true; }); }); describe('#getAllBalances()', () => { it('should return all balances', async () => { const result = await signer.getAllBalances(); - expect(Object.keys(result)).to.have.lengthOf(2); + const expected = IS_ETH_BASED ? 2 : 3; + expect(Object.keys(result)).to.have.lengthOf(expected); }); }); @@ -54,16 +60,16 @@ describe('L2VoidSigner', () => { describe('#getAddress()', () => { it('should return a `L2VoidSigner` address', async () => { const result = await signer.getAddress(); - expect(result).to.be.equal(ADDRESS); + expect(result).to.be.equal(ADDRESS1); }); }); describe('#connect()', () => { it('should return a `L2VoidSigner` with provided `provider` as L2 provider', async () => { - let signer = new L2VoidSigner(ADDRESS); + let signer = new L2VoidSigner(ADDRESS1); signer = signer.connect(provider); - expect(signer.address).to.be.equal(ADDRESS); + expect(signer.address).to.be.equal(ADDRESS1); expect(signer.provider).to.be.equal(provider); }); }); @@ -78,28 +84,35 @@ describe('L2VoidSigner', () => { describe('#populateTransaction()', () => { it('should return populated transaction with default values if are omitted', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 2, - from: ADDRESS, + from: ADDRESS1, nonce: await signer.getNonce('pending'), chainId: 270n, maxFeePerGas: 1_200_000_000n, maxPriorityFeePerGas: 1_000_000_000n, }; const result = await signer.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, }); - expect(result).to.be.deepEqualExcluding(tx, ['gasLimit']); + expect(result).to.be.deepEqualExcluding(tx, [ + 'gasLimit', + 'maxFeePerGas', + 'maxPriorityFeePerGas', + ]); + expect(BigInt(result.gasLimit!) > 0n).to.be.true; + expect(BigInt(result.maxFeePerGas!) > 0n).to.be.true; + expect(BigInt(result.maxPriorityFeePerGas!) > 0n).to.be.true; }); it('should return populated transaction when `maxFeePerGas` and `maxPriorityFeePerGas` and `customData` are provided', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 113, - from: ADDRESS, + from: ADDRESS1, nonce: await signer.getNonce('pending'), data: '0x', chainId: 270n, @@ -111,7 +124,7 @@ describe('L2VoidSigner', () => { }, }; const result = await signer.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 2_000_000_000n, @@ -121,14 +134,15 @@ describe('L2VoidSigner', () => { }, }); expect(result).to.be.deepEqualExcluding(tx, ['gasLimit']); + expect(BigInt(result.gasLimit!) > 0n).to.be.true; }); it('should return populated transaction when `maxPriorityFeePerGas` and `customData` are provided', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 113, - from: ADDRESS, + from: ADDRESS1, nonce: await signer.getNonce('pending'), data: '0x', chainId: 270n, @@ -139,7 +153,7 @@ describe('L2VoidSigner', () => { }, }; const result = await signer.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, maxPriorityFeePerGas: 2_000_000_000n, customData: { @@ -147,14 +161,15 @@ describe('L2VoidSigner', () => { }, }); expect(result).to.be.deepEqualExcluding(tx, ['gasLimit']); + expect(BigInt(result.gasLimit!) > 0n).to.be.true; }); it('should return populated transaction when `maxFeePerGas` and `customData` are provided', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 113, - from: ADDRESS, + from: ADDRESS1, nonce: await signer.getNonce('pending'), data: '0x', chainId: 270n, @@ -165,7 +180,7 @@ describe('L2VoidSigner', () => { }, }; const result = await signer.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, maxFeePerGas: 3_500_000_000n, customData: { @@ -173,63 +188,67 @@ describe('L2VoidSigner', () => { }, }); expect(result).to.be.deepEqualExcluding(tx, ['gasLimit']); + expect(BigInt(result.gasLimit!) > 0n).to.be.true; }); it('should return populated EIP1559 transaction when `maxFeePerGas` and `maxPriorityFeePerGas` are provided', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 2, - from: ADDRESS, + from: ADDRESS1, nonce: await signer.getNonce('pending'), chainId: 270n, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 2_000_000_000n, }; const result = await signer.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 2_000_000_000n, }); expect(result).to.be.deepEqualExcluding(tx, ['gasLimit']); + expect(BigInt(result.gasLimit!) > 0n).to.be.true; }); it('should return populated EIP1559 transaction with `maxFeePerGas` and `maxPriorityFeePerGas` same as provided `gasPrice`', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 2, - from: ADDRESS, + from: ADDRESS1, nonce: await signer.getNonce('pending'), chainId: 270n, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 3_500_000_000n, }; const result = await signer.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, gasPrice: 3_500_000_000n, }); expect(result).to.be.deepEqualExcluding(tx, ['gasLimit']); + expect(BigInt(result.gasLimit!) > 0n).to.be.true; }); it('should return populated legacy transaction when `type = 0`', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 0, - from: ADDRESS, + from: ADDRESS1, nonce: await signer.getNonce('pending'), chainId: 270n, gasPrice: 100_000_000n, }; const result = await signer.populateTransaction({ type: 0, - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, }); expect(result).to.be.deepEqualExcluding(tx, ['gasLimit']); + expect(BigInt(result.gasLimit!) > 0n).to.be.true; }); }); @@ -237,7 +256,7 @@ describe('L2VoidSigner', () => { it('should throw an error when trying to send transaction', async () => { try { await signer.sendTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 2_000_000_000n, @@ -254,7 +273,7 @@ describe('L2VoidSigner', () => { it('should throw an error when tyring to withdraw assets', async () => { try { await signer.withdraw({ - token: utils.ETH_ADDRESS, + token: utils.LEGACY_ETH_ADDRESS, to: await signer.getAddress(), amount: 7_000_000_000, }); @@ -270,8 +289,8 @@ describe('L2VoidSigner', () => { it('should throw an error when tyring to transfer assets', async () => { try { await signer.transfer({ - token: utils.ETH_ADDRESS, - to: RECEIVER, + token: baseToken, + to: ADDRESS2, amount: 7_000_000_000, }); } catch (e) { @@ -287,7 +306,7 @@ describe('L2VoidSigner', () => { try { await signer.signTransaction({ type: 2, - to: RECEIVER, + to: ADDRESS2, value: 7_000_000_000n, }); } catch (e) { @@ -299,37 +318,39 @@ describe('L2VoidSigner', () => { }); }); -describe('L1VoidSigner', () => { - const ADDRESS = '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049'; - const RECEIVER = '0xa61464658AfeAf65CccaaFD3a512b69A83B77618'; - +describe('L1VoidSigner', async () => { const provider = Provider.getDefaultProvider(); const ethProvider = ethers.getDefaultProvider('http://localhost:8545'); - const signer = new L1VoidSigner(ADDRESS, ethProvider, provider); + const signer = new L1VoidSigner(ADDRESS1, ethProvider, provider); - const DAI_L1 = TokensL1[0].address; + let baseToken: string; + + before('setup', async function () { + baseToken = await provider.getBaseTokenContractAddress(); + this.timeout(25_000); + }); describe('#constructor()', () => { it('`L1VoidSigner(privateKey, providerL1, providerL2)` should return a `L1VoidSigner` with L1 and L2 provider', async () => { - const signer = new L1VoidSigner(ADDRESS, ethProvider, provider); + const signer = new L1VoidSigner(ADDRESS1, ethProvider, provider); - expect(signer.address).to.be.equal(ADDRESS); + expect(signer.address).to.be.equal(ADDRESS1); expect(signer.provider).to.be.equal(ethProvider); expect(signer.providerL2).to.be.equal(provider); }); it('`L1VoidSigner(privateKey, providerL1)` should return a `L1VoidSigner` with L1 provider', async () => { - const signer = new L1VoidSigner(ADDRESS, ethProvider); + const signer = new L1VoidSigner(ADDRESS1, ethProvider); - expect(signer.address).to.be.equal(ADDRESS); + expect(signer.address).to.be.equal(ADDRESS1); expect(signer.provider).to.be.equal(ethProvider); expect(signer.providerL2).to.be.undefined; }); it('`L1VoidSigner(privateKey)` should return a `L1VoidSigner` without providers', async () => { - const signer = new L1VoidSigner(ADDRESS); + const signer = new L1VoidSigner(ADDRESS1); - expect(signer.address).to.be.equal(ADDRESS); + expect(signer.address).to.be.equal(ADDRESS1); expect(signer.provider).to.be.null; expect(signer.providerL2).to.be.undefined; }); @@ -352,7 +373,7 @@ describe('L1VoidSigner', () => { describe('#getBalanceL1()', () => { it('should return a L1 balance', async () => { const result = await signer.getBalanceL1(); - expect(result > 0).to.be.true; + expect(result > 0n).to.be.true; }); }); @@ -365,20 +386,27 @@ describe('L1VoidSigner', () => { describe('#l2TokenAddress()', () => { it('should return the L2 ETH address', async () => { - const result = await signer.l2TokenAddress(utils.ETH_ADDRESS); - expect(result).to.be.equal(utils.ETH_ADDRESS); + const result = await signer.l2TokenAddress(baseToken); + expect(result).to.be.equal(utils.L2_BASE_TOKEN_ADDRESS); }); it('should return the L2 DAI address', async () => { const result = await signer.l2TokenAddress(DAI_L1); expect(result).not.to.be.null; }); + + if (!IS_ETH_BASED) { + it('should return the L2 ETH address', async () => { + const result = await signer.l2TokenAddress(utils.LEGACY_ETH_ADDRESS); + expect(result).not.to.be.null; + }); + } }); describe('#approveERC20()', () => { it('should throw an error when approving token', async () => { try { - await signer.approveERC20(utils.ETH_ADDRESS, 5); + await signer.approveERC20(utils.LEGACY_ETH_ADDRESS, 5); } catch (e) { expect((e as Error).message).to.be.equal( "ETH token can't be approved! The address of the token does not exist on L1." @@ -404,24 +432,24 @@ describe('L1VoidSigner', () => { describe('#getAddress()', () => { it('should return a `L1VoidSigner` address', async () => { const result = await signer.getAddress(); - expect(result).to.be.equal(ADDRESS); + expect(result).to.be.equal(ADDRESS1); }); }); describe('#connect()', () => { it('should return a `L1VoidSigner` with provided `provider` as L1 provider', async () => { - let singer = new L1VoidSigner(ADDRESS); + let singer = new L1VoidSigner(ADDRESS1); singer = singer.connect(ethProvider); - expect(singer.address).to.be.equal(ADDRESS); + expect(singer.address).to.be.equal(ADDRESS1); expect(singer.provider).to.be.equal(ethProvider); }); }); describe('#connectL2()', () => { it('should return a `L1VoidSigner` with provided `provider` as L2 provider', async () => { - let singer = new L1VoidSigner(ADDRESS); + let singer = new L1VoidSigner(ADDRESS1); singer = singer.connectToL2(provider); - expect(singer.address).to.be.equal(ADDRESS); + expect(singer.address).to.be.equal(ADDRESS1); expect(singer.providerL2).to.be.equal(provider); }); }); @@ -429,77 +457,88 @@ describe('L1VoidSigner', () => { describe('#populateTransaction()', () => { it('should return populated transaction with default values if are omitted', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 2, - from: ADDRESS, + from: ADDRESS1, nonce: await signer.getNonce('pending'), chainId: 9n, maxFeePerGas: 1_000_000_002n, maxPriorityFeePerGas: 1_000_000_000n, }; const result = await signer.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, }); - expect(result).to.be.deepEqualExcluding(tx, ['gasLimit']); + expect(result).to.be.deepEqualExcluding(tx, [ + 'gasLimit', + 'maxPriorityFeePerGas', + 'maxFeePerGas', + ]); + expect(BigInt(result.gasLimit!) > 0n).to.be.true; + expect(BigInt(result.maxPriorityFeePerGas!) > 0n).to.be.true; + expect(BigInt(result.maxFeePerGas!) > 0n).to.be.true; }); it('should return populated EIP1559 transaction when `maxFeePerGas` and `maxPriorityFeePerGas` are provided', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 2, - from: ADDRESS, + from: ADDRESS1, nonce: await signer.getNonce('pending'), chainId: 9n, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 2_000_000_000n, }; const result = await signer.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 2_000_000_000n, }); expect(result).to.be.deepEqualExcluding(tx, ['gasLimit']); + expect(BigInt(result.gasLimit!) > 0n).to.be.true; }); it('should return populated EIP1559 transaction with `maxFeePerGas` and `maxPriorityFeePerGas` same as provided `gasPrice`', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 2, - from: ADDRESS, + from: ADDRESS1, nonce: await signer.getNonce('pending'), chainId: 9n, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 3_500_000_000n, }; const result = await signer.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, gasPrice: 3_500_000_000n, }); expect(result).to.be.deepEqualExcluding(tx, ['gasLimit']); + expect(BigInt(result.gasLimit!) > 0n).to.be.true; }); it('should return populated legacy transaction when `type = 0`', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 0, - from: ADDRESS, + from: ADDRESS1, nonce: await signer.getNonce('pending'), chainId: 9n, gasPrice: 1_000_000_001n, }; const result = await signer.populateTransaction({ type: 0, - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, }); - expect(result).to.be.deepEqualExcluding(tx, ['gasLimit']); + expect(result).to.be.deepEqualExcluding(tx, ['gasLimit', 'gasPrice']); + expect(BigInt(result.gasLimit!) > 0n).to.be.true; + expect(BigInt(result.gasPrice!) > 0n).to.be.true; }); }); @@ -507,7 +546,7 @@ describe('L1VoidSigner', () => { it('should throw an error when trying to send transaction', async () => { try { await signer.sendTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 2_000_000_000n, @@ -521,114 +560,318 @@ describe('L1VoidSigner', () => { }); describe('#getDepositTx()', () => { - it('should return ETH deposit transaction', async () => { - const tx = { - contractAddress: ADDRESS, - calldata: '0x', - l2Value: 7_000_000, - l2GasLimit: '0x56d78', - token: '0x0000000000000000000000000000000000000000', - to: ADDRESS, - amount: 7_000_000, - refundRecipient: ADDRESS, - operatorTip: 0, - overrides: { - from: ADDRESS, + if (IS_ETH_BASED) { + it('should return ETH deposit transaction', async () => { + const tx = { + contractAddress: ADDRESS1, + calldata: '0x', + l2Value: 7_000_000, + l2GasLimit: '0x56d78', + mintValue: 93_372_307_000_000n, + token: utils.ETH_ADDRESS_IN_CONTRACTS, + to: ADDRESS1, + amount: 7_000_000, + refundRecipient: ADDRESS1, + operatorTip: 0, + overrides: { + from: ADDRESS1, + maxFeePerGas: 1_000_000_001n, + maxPriorityFeePerGas: 1_000_000_000n, + value: 93_372_307_000_000n, + }, + gasPerPubdataByte: 800, + }; + const result = await signer.getDepositTx({ + token: utils.LEGACY_ETH_ADDRESS, + to: await signer.getAddress(), + amount: 7_000_000, + refundRecipient: await signer.getAddress(), + }); + expect(result).to.be.deepEqualExcluding(tx, [ + 'l2GasLimit', + 'mintValue', + 'overrides', + ]); + expect(result.l2GasLimit > 0n).to.be.true; + expect(BigInt(result.mintValue) > 0n).to.be.true; + expect(utils.isAddressEq(result.overrides.from, ADDRESS1)).to.be.true; + expect(result.overrides.maxFeePerGas > 0n).to.be.true; + expect(result.overrides.maxPriorityFeePerGas > 0n).to.be.true; + expect(result.overrides.value > 0n).to.be.true; + }); + + it('should return a deposit transaction with `tx.to == Wallet.getAddress()` when `tx.to` is not specified', async () => { + const tx = { + contractAddress: ADDRESS1, + calldata: '0x', + l2Value: 7_000_000, + l2GasLimit: '0x56d78', + mintValue: 93_372_307_000_000n, + token: utils.ETH_ADDRESS_IN_CONTRACTS, + to: ADDRESS1, + amount: 7_000_000, + refundRecipient: ADDRESS1, + operatorTip: 0, + overrides: { + from: ADDRESS1, + maxFeePerGas: 1_000_000_001n, + maxPriorityFeePerGas: 1_000_000_000n, + value: 93_372_307_000_000n, + }, + gasPerPubdataByte: 800, + }; + const result = await signer.getDepositTx({ + token: utils.LEGACY_ETH_ADDRESS, + amount: 7_000_000, + refundRecipient: await signer.getAddress(), + }); + expect(result).to.be.deepEqualExcluding(tx, [ + 'l2GasLimit', + 'mintValue', + 'overrides', + ]); + expect(result.l2GasLimit > 0n).to.be.true; + expect(BigInt(result.mintValue) > 0n).to.be.true; + expect(utils.isAddressEq(result.overrides.from, ADDRESS1)).to.be.true; + expect(result.overrides.maxFeePerGas > 0n).to.be.true; + expect(result.overrides.maxPriorityFeePerGas > 0n).to.be.true; + expect(result.overrides.value > 0n).to.be.true; + }); + + it('should return DAI deposit transaction', async () => { + const tx = { maxFeePerGas: 1_000_000_001n, maxPriorityFeePerGas: 1_000_000_000n, - value: 93_372_307_000_000n, - }, - gasPerPubdataByte: 800, - }; - const result = await signer.getDepositTx({ - token: utils.ETH_ADDRESS, - to: await signer.getAddress(), - amount: 7_000_000, - refundRecipient: await signer.getAddress(), + value: 105_100_275_000_000n, + from: ADDRESS1, + to: await provider.getBridgehubContractAddress(), + }; + const result = await signer.getDepositTx({ + token: DAI_L1, + to: await signer.getAddress(), + amount: 5, + refundRecipient: await signer.getAddress(), + }); + result.to = result.to.toLowerCase(); + expect(result).to.be.deepEqualExcluding(tx, [ + 'data', + 'maxFeePerGas', + 'maxPriorityFeePerGas', + 'value', + ]); + expect(BigInt(result.value) > 0n).to.be.true; + expect(BigInt(result.maxPriorityFeePerGas) > 0n).to.be.true; + expect(BigInt(result.maxFeePerGas) > 0n).to.be.true; }); - expect(result).to.be.deep.equal(tx); - }); - - it('should return a deposit transaction with `tx.to == L1VoidSigner.getAddress()` when `tx.to` is not specified', async () => { - const tx = { - contractAddress: ADDRESS, - calldata: '0x', - l2Value: 7_000_000, - l2GasLimit: '0x56d78', - token: '0x0000000000000000000000000000000000000000', - to: ADDRESS, - amount: 7_000_000, - refundRecipient: ADDRESS, - operatorTip: 0, - overrides: { - from: ADDRESS, + } else { + it('should return ETH deposit transaction', async () => { + const tx = { + from: ADDRESS1, + to: (await provider.getBridgehubContractAddress()).toLowerCase(), + value: 7_000_000n, + data: '0x24fd57fb0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000010e0000000000000000000000000000000000000000000000000000bf1aaa17ee7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000062e3d000000000000000000000000000000000000000000000000000000000000032000000000000000000000000036615cf349d7f6344891b1e7ca7c72883f5dc049000000000000000000000000842deab39809094bf5e4b77a7f97ae308adc5e5500000000000000000000000000000000000000000000000000000000006acfc0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036615cf349d7f6344891b1e7ca7c72883f5dc049', maxFeePerGas: 1_000_000_001n, maxPriorityFeePerGas: 1_000_000_000n, - value: 93_372_307_000_000n, - }, - gasPerPubdataByte: 800, - }; - const result = await signer.getDepositTx({ - token: utils.ETH_ADDRESS, - amount: 7_000_000, - refundRecipient: await signer.getAddress(), + }; + const result = await signer.getDepositTx({ + token: utils.LEGACY_ETH_ADDRESS, + to: await signer.getAddress(), + amount: 7_000_000, + refundRecipient: await signer.getAddress(), + }); + result.to = result.to.toLowerCase(); + expect(result).to.be.deepEqualExcluding(tx, [ + 'data', + 'maxFeePerGas', + 'maxPriorityFeePerGas', + 'value', + ]); + expect(BigInt(result.value) > 0n).to.be.true; + expect(BigInt(result.maxPriorityFeePerGas) > 0n).to.be.true; + expect(BigInt(result.maxFeePerGas) > 0n).to.be.true; }); - expect(result).to.be.deep.equal(tx); - }); - it('should return DAI deposit transaction', async () => { - const tx = { - maxFeePerGas: 1_000_000_001n, - maxPriorityFeePerGas: 1_000_000_000n, - value: 105_100_275_000_000n, - from: ADDRESS, - to: await (await signer.getL1BridgeContracts()).erc20.getAddress(), - }; - const result = await signer.getDepositTx({ - token: DAI_L1, - to: await signer.getAddress(), - amount: 5, - refundRecipient: await signer.getAddress(), + it('should return a deposit transaction with `tx.to == Wallet.getAddress()` when `tx.to` is not specified', async () => { + const tx = { + from: ADDRESS1, + to: (await provider.getBridgehubContractAddress()).toLowerCase(), + value: 7_000_000n, + maxFeePerGas: 1_000_000_001n, + maxPriorityFeePerGas: 1000_000_000n, + }; + const result = await signer.getDepositTx({ + token: utils.LEGACY_ETH_ADDRESS, + amount: 7_000_000, + refundRecipient: await signer.getAddress(), + }); + result.to = result.to.toLowerCase(); + expect(result).to.be.deepEqualExcluding(tx, [ + 'data', + 'maxFeePerGas', + 'maxPriorityFeePerGas', + 'value', + ]); + expect(BigInt(result.value) > 0n).to.be.true; + expect(BigInt(result.maxPriorityFeePerGas) > 0n).to.be.true; + expect(BigInt(result.maxFeePerGas) > 0n).to.be.true; }); - expect(result).to.be.deepEqualExcluding(tx, ['data']); - }); + + it('should return DAI deposit transaction', async () => { + const tx = { + maxFeePerGas: 1_000_000_001n, + maxPriorityFeePerGas: 1_000_000_000n, + value: 0n, + from: ADDRESS1, + to: (await provider.getBridgehubContractAddress()).toLowerCase(), + }; + const result = await signer.getDepositTx({ + token: DAI_L1, + to: await signer.getAddress(), + amount: 5, + refundRecipient: await signer.getAddress(), + }); + result.to = result.to.toLowerCase(); + expect(result).to.be.deepEqualExcluding(tx, [ + 'data', + 'maxFeePerGas', + 'maxPriorityFeePerGas', + 'value', + ]); + expect(BigInt(result.maxPriorityFeePerGas) > 0n).to.be.true; + expect(BigInt(result.maxFeePerGas) > 0n).to.be.true; + }); + } }); describe('#estimateGasDeposit()', () => { - it('should return gas estimation for ETH deposit transaction', async () => { - const result = await signer.estimateGasDeposit({ - token: utils.ETH_ADDRESS, - to: await signer.getAddress(), - amount: 5, - refundRecipient: await signer.getAddress(), + if (IS_ETH_BASED) { + it('should return gas estimation for ETH deposit transaction', async () => { + const result = await signer.estimateGasDeposit({ + token: utils.LEGACY_ETH_ADDRESS, + to: await signer.getAddress(), + amount: 5, + refundRecipient: await signer.getAddress(), + }); + expect(result > 0n).to.be.true; }); - expect(result > 0n).to.be.true; - }); - it('should return gas estimation for DAI deposit transaction', async () => { - const wallet = new Wallet( - '0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110', - provider, - ethProvider - ); - const tx = await wallet.approveERC20(DAI_L1, 5); - await tx.wait(); - - const result = await signer.estimateGasDeposit({ - token: DAI_L1, - to: await signer.getAddress(), - amount: 5, - refundRecipient: await signer.getAddress(), - }); - expect(result > 0n).to.be.true; - }).timeout(10_000); + it('should return gas estimation for DAI deposit transaction', async () => { + const wallet = new Wallet(PRIVATE_KEY1, provider, ethProvider); + await (await wallet.approveERC20(DAI_L1, 5)).wait(); + + const result = await signer.estimateGasDeposit({ + token: DAI_L1, + to: await signer.getAddress(), + amount: 5, + refundRecipient: await signer.getAddress(), + }); + expect(result > 0n).to.be.true; + }).timeout(10_000); + } else { + it('should throw an error for insufficient allowance when estimating gas for ETH deposit transaction', async () => { + try { + await signer.estimateGasDeposit({ + token: utils.LEGACY_ETH_ADDRESS, + to: await signer.getAddress(), + amount: 5, + refundRecipient: await signer.getAddress(), + }); + } catch (e) { + expect((e as any).reason).to.include('ERC20: insufficient allowance'); + } + }).timeout(10_000); + + it('should return gas estimation for ETH deposit transaction', async () => { + const wallet = new Wallet(PRIVATE_KEY1, provider, ethProvider); + + const token = utils.LEGACY_ETH_ADDRESS; + const amount = 5; + const approveParams = await signer.getDepositAllowanceParams( + token, + amount + ); + + await ( + await wallet.approveERC20( + approveParams[0].token, + approveParams[0].allowance + ) + ).wait(); + + const result = await signer.estimateGasDeposit({ + token: token, + to: await signer.getAddress(), + amount: amount, + refundRecipient: await signer.getAddress(), + }); + expect(result > 0n).to.be.true; + }).timeout(10_000); + + it('should return gas estimation for base token deposit transaction', async () => { + const wallet = new Wallet(PRIVATE_KEY1, provider, ethProvider); + + const token = await signer.getBaseToken(); + const amount = 5; + const approveParams = await signer.getDepositAllowanceParams( + token, + amount + ); + + await ( + await wallet.approveERC20( + approveParams[0].token, + approveParams[0].allowance + ) + ).wait(); + + const result = await signer.estimateGasDeposit({ + token: token, + to: await signer.getAddress(), + amount: amount, + refundRecipient: await signer.getAddress(), + }); + expect(result > 0n).to.be.true; + }).timeout(10_000); + + it('should return gas estimation for DAI deposit transaction', async () => { + const wallet = new Wallet(PRIVATE_KEY1, provider, ethProvider); + + const token = DAI_L1; + const amount = 5; + const approveParams = await signer.getDepositAllowanceParams( + token, + amount + ); + + await ( + await wallet.approveERC20( + approveParams[0].token, + approveParams[0].allowance + ) + ).wait(); + await ( + await wallet.approveERC20( + approveParams[1].token, + approveParams[1].allowance + ) + ).wait(); + + const result = await signer.estimateGasDeposit({ + token: token, + to: await signer.getAddress(), + amount: amount, + refundRecipient: await signer.getAddress(), + }); + expect(result > 0n).to.be.true; + }).timeout(10_000); + } }); describe('#deposit()', () => { it('should throw an error when trying to deposit assets', async () => { try { await signer.deposit({ - token: utils.ETH_ADDRESS, + token: utils.LEGACY_ETH_ADDRESS, to: await signer.getAddress(), amount: 7_000_000_000, refundRecipient: await signer.getAddress(), @@ -645,7 +888,7 @@ describe('L1VoidSigner', () => { it('should throw an error when trying to claim successful deposit', async () => { try { const response = await signer.deposit({ - token: utils.ETH_ADDRESS, + token: utils.LEGACY_ETH_ADDRESS, to: await signer.getAddress(), amount: 7_000_000_000, refundRecipient: await signer.getAddress(), @@ -662,107 +905,327 @@ describe('L1VoidSigner', () => { }); describe('#getFullRequiredDepositFee()', () => { - it('should return fee for ETH token deposit', async () => { - const result = await signer.getFullRequiredDepositFee({ - token: utils.ETH_ADDRESS, - to: await signer.getAddress(), - }); - expect((result.baseCost as bigint) > 0n).to.be.true; - expect((result.l1GasLimit as bigint) > 0n).to.be.true; - expect((result.l2GasLimit as bigint) > 0n).to.be.true; - expect((result.maxPriorityFeePerGas as bigint) > 0n).to.be.true; - expect((result.maxFeePerGas as bigint) > 0n).to.be.true; - }); - - it('should throw an error when there is not enough allowance to cover the deposit', async () => { - try { - await signer.getFullRequiredDepositFee({ - token: DAI_L1, + if (IS_ETH_BASED) { + it('should return fee for ETH token deposit', async () => { + const result = await signer.getFullRequiredDepositFee({ + token: utils.LEGACY_ETH_ADDRESS, to: await signer.getAddress(), }); - } catch (e) { - expect((e as Error).message).to.be.equal( - 'Not enough allowance to cover the deposit!' - ); - } - }).timeout(10_000); - - it('should return fee for DAI token deposit', async () => { - const result = await signer.getFullRequiredDepositFee({ - token: DAI_L1, - to: await signer.getAddress(), - }); - expect((result.baseCost as bigint) > BigInt(0)).to.be.true; - expect((result.l1GasLimit as bigint) > BigInt(0)).to.be.true; - expect((result.l2GasLimit as bigint) > BigInt(0)).to.be.true; - expect((result.maxFeePerGas as bigint) > BigInt(0)).to.be.true; - expect((result.maxPriorityFeePerGas as bigint) > BigInt(0)).to.be.true; - }).timeout(10_000); - - it('should throw an error when there is not enough balance for the deposit', async () => { - try { + expect(result.baseCost.valueOf() > 0n).to.be.true; + expect(result.l1GasLimit.valueOf() > 0n).to.be.true; + expect(result.l2GasLimit.valueOf() > 0n).to.be.true; + expect(result.maxPriorityFeePerGas!.valueOf() > 0n).to.be.true; + expect(result.maxFeePerGas!.valueOf() > 0n).to.be.true; + }).timeout(10_000); + + it('should throw an error when there is not enough allowance to cover the deposit', async () => { const randomSigner = new L1VoidSigner( - ethers.Wallet.createRandom().address, + Wallet.createRandom().address, ethProvider, provider ); - await randomSigner.getFullRequiredDepositFee({ - token: DAI_L1, + // transfer ETH to random signer so to avoid error: not enough balance + const transferTx = await new ethers.Wallet( + PRIVATE_KEY1, + ethProvider + ).sendTransaction({ to: await randomSigner.getAddress(), + value: ethers.parseEther('0.1'), }); - } catch (e) { - expect((e as Error).message).to.include( - 'Not enough balance for deposit!' + await transferTx.wait(); + + try { + await randomSigner.getFullRequiredDepositFee({ + token: DAI_L1, + to: await signer.getAddress(), + }); + } catch (e) { + expect((e as Error).message).to.be.equal( + 'Not enough allowance to cover the deposit!' + ); + } + }).timeout(10_000); + + it('should return fee for DAI token deposit', async () => { + const wallet = new Wallet(PRIVATE_KEY1, provider, ethProvider); + const tx = await wallet.approveERC20(DAI_L1, 5); + await tx.wait(); + + const result = await signer.getFullRequiredDepositFee({ + token: DAI_L1, + to: await signer.getAddress(), + }); + expect(result.baseCost.valueOf() > 0n).to.be.true; + expect(result.l1GasLimit.valueOf() > 0n).to.be.true; + expect(result.l2GasLimit.valueOf() > 0n).to.be.true; + expect(result.maxPriorityFeePerGas!.valueOf() > 0n).to.be.true; + expect(result.maxFeePerGas!.valueOf() > 0n).to.be.true; + }).timeout(10_000); + + it('should throw an error when there is not enough balance for the deposit', async () => { + try { + await new L1VoidSigner( + ethers.Wallet.createRandom().address, + ethProvider, + provider + ).getFullRequiredDepositFee({ + token: DAI_L1, + to: await signer.getAddress(), + }); + } catch (e) { + expect((e as Error).message).to.include( + 'Not enough balance for deposit!' + ); + } + }).timeout(10_000); + } else { + it('should throw an error when there is not enough base token allowance to cover the deposit', async () => { + try { + await new L1VoidSigner( + ethers.Wallet.createRandom().address, + ethProvider, + provider + ).getFullRequiredDepositFee({ + token: utils.LEGACY_ETH_ADDRESS, + to: await signer.getAddress(), + }); + } catch (e) { + expect((e as Error).message).to.be.equal( + 'Not enough base token allowance to cover the deposit!' + ); + } + }).timeout(10_000); + + it('should return fee for ETH token deposit', async () => { + const wallet = new Wallet(PRIVATE_KEY1, provider, ethProvider); + const token = utils.LEGACY_ETH_ADDRESS; + const approveParams = await signer.getDepositAllowanceParams(token, 1); + + await ( + await wallet.approveERC20( + approveParams[0].token, + approveParams[0].allowance + ) + ).wait(); + + const result = await signer.getFullRequiredDepositFee({ + token: token, + to: await signer.getAddress(), + }); + expect(result.baseCost.valueOf() > 0n).to.be.true; + expect(result.l1GasLimit.valueOf() > 0n).to.be.true; + expect(result.l2GasLimit.valueOf() > 0n).to.be.true; + expect(result.maxPriorityFeePerGas!.valueOf() > 0n).to.be.true; + expect(result.maxFeePerGas!.valueOf() > 0n).to.be.true; + }).timeout(10_000); + + it('should return fee for base token deposit', async () => { + const wallet = new Wallet(PRIVATE_KEY1, provider, ethProvider); + const token = await signer.getBaseToken(); + const approveParams = await signer.getDepositAllowanceParams(token, 1); + + await ( + await wallet.approveERC20( + approveParams[0].token, + approveParams[0].allowance + ) + ).wait(); + + const result = await signer.getFullRequiredDepositFee({ + token: token, + to: await signer.getAddress(), + }); + expect(result).not.to.be.null; + }).timeout(10_000); + + it('should return fee for DAI token deposit', async () => { + const wallet = new Wallet(PRIVATE_KEY1, provider, ethProvider); + const token = DAI_L1; + const approveParams = await signer.getDepositAllowanceParams(token, 1); + + await ( + await wallet.approveERC20( + approveParams[0].token, + approveParams[0].allowance + ) + ).wait(); + await ( + await wallet.approveERC20( + approveParams[1].token, + approveParams[1].allowance + ) + ).wait(); + + const result = await signer.getFullRequiredDepositFee({ + token: token, + to: await signer.getAddress(), + }); + expect(result.baseCost.valueOf() > 0n).to.be.true; + expect(result.l1GasLimit.valueOf() > 0n).to.be.true; + expect(result.l2GasLimit.valueOf() > 0n).to.be.true; + expect(result.maxPriorityFeePerGas!.valueOf() > 0n).to.be.true; + expect(result.maxFeePerGas!.valueOf() > 0n).to.be.true; + }).timeout(10_000); + + it('should throw an error when there is not enough token allowance to cover the deposit', async () => { + const wallet = new Wallet(PRIVATE_KEY1, provider, ethProvider); + + const token = DAI_L1; + const randomWallet = new Wallet( + Wallet.createRandom().signingKey, + provider, + ethProvider ); - } - }).timeout(10_000); + + // mint base token to random wallet + const baseToken = ITestnetERC20Token__factory.connect( + await wallet.getBaseToken(), + wallet._signerL1() + ); + const baseTokenMintTx = await baseToken.mint( + await randomWallet.getAddress(), + ethers.parseEther('0.5') + ); + await baseTokenMintTx.wait(); + + // transfer ETH to random wallet so that base token approval tx can be performed + const transferTx = await new ethers.Wallet( + PRIVATE_KEY1, + ethProvider + ).sendTransaction({ + to: await randomWallet.getAddress(), + value: ethers.parseEther('0.1'), + }); + await transferTx.wait(); + + const approveParams = await randomWallet.getDepositAllowanceParams( + token, + 1 + ); + // only approve base token + await ( + await randomWallet.approveERC20( + approveParams[0].token, + approveParams[0].allowance + ) + ).wait(); + + try { + await new L1VoidSigner( + randomWallet.address, + ethProvider, + provider + ).getFullRequiredDepositFee({ + token: token, + to: await wallet.getAddress(), + }); + } catch (e) { + expect((e as Error).message).to.be.equal( + 'Not enough token allowance to cover the deposit!' + ); + } + }).timeout(20_000); + } }); describe('#getRequestExecuteTx()', () => { - it('should return request execute transaction', async () => { - const result = await signer.getRequestExecuteTx({ - contractAddress: await provider.getMainContractAddress(), - calldata: '0x', - l2Value: 7_000_000_000, + const amount = 7_000_000_000; + if (IS_ETH_BASED) { + it('should return request execute transaction', async () => { + const result = await signer.getRequestExecuteTx({ + contractAddress: await provider.getBridgehubContractAddress(), + calldata: '0x', + l2Value: amount, + }); + expect(result).not.to.be.null; }); - expect(result).not.to.be.null; - }); + } else { + it('should return request execute transaction', async () => { + const result = await signer.getRequestExecuteTx({ + contractAddress: await signer.getAddress(), + calldata: '0x', + l2Value: amount, + overrides: {nonce: 0}, + }); + expect(result).not.to.be.null; + }); + } }); describe('#estimateGasRequestExecute()', () => { it('should return gas estimation for request execute transaction', async () => { const result = await signer.estimateGasRequestExecute({ - contractAddress: await provider.getMainContractAddress(), + contractAddress: await provider.getBridgehubContractAddress(), calldata: '0x', l2Value: 7_000_000_000, }); - expect(result >= 0n).to.be.true; + expect(result > 0n).to.be.true; }); }); describe('#requestExecute()', () => { - it('should request transaction execution on L2 network', async () => { - try { - await signer.requestExecute({ - contractAddress: await provider.getMainContractAddress(), + if (IS_ETH_BASED) { + it('should request transaction execution on L2 network', async () => { + try { + await signer.requestExecute({ + contractAddress: await provider.getBridgehubContractAddress(), + calldata: '0x', + l2Value: 7_000_000_000, + l2GasLimit: 900_000, + }); + } catch (e) { + expect((e as Error).message).to.contain( + 'VoidSigner cannot sign transactions' + ); + } + }).timeout(10_000); + } else { + it('should request transaction execution on L2 network', async () => { + const wallet = new Wallet(PRIVATE_KEY1, provider, ethProvider); + + const amount = 7_000_000_000; + const request = { + contractAddress: await signer.getAddress(), calldata: '0x', - l2Value: 7_000_000_000, - l2GasLimit: 900_000, - }); - } catch (e) { - expect((e as Error).message).to.contain( - 'VoidSigner cannot sign transactions' - ); - } - }).timeout(10_000); + l2Value: amount, + l2GasLimit: 1_319_957n, + operatorTip: 0, + gasPerPubdataByte: 800, + refundRecipient: await signer.getAddress(), + overrides: { + maxFeePerGas: 1_000_000_010n, + maxPriorityFeePerGas: 1_000_000_000n, + gasLimit: 238_654n, + value: 0, + }, + }; + + const approveParams = + await signer.getRequestExecuteAllowanceParams(request); + await ( + await wallet.approveERC20( + approveParams.token, + approveParams.allowance + ) + ).wait(); + + try { + await signer.requestExecute(request); + } catch (e) { + expect((e as Error).message).to.contain( + 'VoidSigner cannot sign transactions' + ); + } + }).timeout(10_000); + } }); describe('#signTransaction()', () => { it('should throw an error when trying to send transaction', async () => { try { await signer.sendTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 2_000_000_000n, diff --git a/tests/integration/smart-account.test.ts b/tests/integration/smart-account.test.ts index fe2afa3a..a37efb8a 100644 --- a/tests/integration/smart-account.test.ts +++ b/tests/integration/smart-account.test.ts @@ -8,56 +8,58 @@ import { Wallet, ContractFactory, } from '../../src'; -import {ethers, toBigInt} from 'ethers'; +import {ethers} from 'ethers'; import {ECDSASmartAccount, MultisigECDSASmartAccount} from '../../src'; +import { + IS_ETH_BASED, + ADDRESS1, + PRIVATE_KEY1, + ADDRESS2, + PRIVATE_KEY2, + DAI_L1, + APPROVAL_TOKEN, + PAYMASTER, +} from '../utils'; const {expect} = chai; -import TokensL1 from '../files/tokens.json'; import MultisigAccount from '../files/TwoUserMultisig.json'; describe('SmartAccount', async () => { - const ADDRESS = '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049'; - const PRIVATE_KEY = - '0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110'; - const RECEIVER = '0xa61464658AfeAf65CccaaFD3a512b69A83B77618'; - const provider = Provider.getDefaultProvider(types.Network.Localhost); const ethProvider = ethers.getDefaultProvider('http://localhost:8545'); - const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); + const wallet = new Wallet(PRIVATE_KEY1, provider, ethProvider); const account = new SmartAccount( - {address: ADDRESS, secret: PRIVATE_KEY}, + {address: ADDRESS1, secret: PRIVATE_KEY1}, provider ); - const DAI_L1 = TokensL1[0].address; - - const TOKEN = '0x841c43Fa5d8fFfdB9efE3358906f7578d8700Dd4'; - const PAYMASTER = '0xa222f0c183AFA73a8Bc1AFb48D34C88c9Bf7A174'; - describe('#constructor()', () => { it('`SmartAccount(address, {address, secret}, provider)` should return a `SmartAccount` with signer and provider', () => { const account = new SmartAccount( - {address: ADDRESS, secret: PRIVATE_KEY}, + {address: ADDRESS1, secret: PRIVATE_KEY1}, provider ); - expect(account.address).to.be.equal(ADDRESS); - expect(account.secret).to.be.equal(PRIVATE_KEY); + expect(account.address).to.be.equal(ADDRESS1); + expect(account.secret).to.be.equal(PRIVATE_KEY1); expect(account.provider).to.be.equal(provider); }); it('`SmartAccount(address, {address, secret})` should return a `SmartAccount` with signer', () => { - const account = new SmartAccount({address: ADDRESS, secret: PRIVATE_KEY}); - expect(account.address).to.be.equal(ADDRESS); - expect(account.secret).to.be.equal(PRIVATE_KEY); + const account = new SmartAccount({ + address: ADDRESS1, + secret: PRIVATE_KEY1, + }); + expect(account.address).to.be.equal(ADDRESS1); + expect(account.secret).to.be.equal(PRIVATE_KEY1); expect(account.provider).to.be.null; }); it('`SmartWallet(address, {address, secret, payloadSigner, transactionBuilder}, provider)` should return a `SmartAccount` with custom payload signing method', async () => { const account = new SmartAccount( { - address: ADDRESS, - secret: PRIVATE_KEY, + address: ADDRESS1, + secret: PRIVATE_KEY1, payloadSigner: async () => { return '0x'; }, @@ -68,8 +70,8 @@ describe('SmartAccount', async () => { provider ); - expect(account.address).to.be.equal(ADDRESS); - expect(account.secret).to.be.equal(PRIVATE_KEY); + expect(account.address).to.be.equal(ADDRESS1); + expect(account.secret).to.be.equal(PRIVATE_KEY1); expect(account.provider).to.be.equal(provider); }); }); @@ -78,23 +80,23 @@ describe('SmartAccount', async () => { it('should return a `SmartAccount` with provided `provider` as a provider', async () => { const newProvider = Provider.getDefaultProvider(types.Network.Localhost); let account = new SmartAccount( - {address: ADDRESS, secret: PRIVATE_KEY}, + {address: ADDRESS1, secret: PRIVATE_KEY1}, provider ); account = account.connect(newProvider); - expect(account.address).to.be.equal(ADDRESS); - expect(account.secret).to.be.equal(PRIVATE_KEY); + expect(account.address).to.be.equal(ADDRESS1); + expect(account.secret).to.be.equal(PRIVATE_KEY1); expect(account.provider).to.be.equal(newProvider); }); it('should return a `SmartAccount` with no `provider` when `null` is used', async () => { let account = new SmartAccount( - {address: ADDRESS, secret: PRIVATE_KEY}, + {address: ADDRESS1, secret: PRIVATE_KEY1}, provider ); account = account.connect(null); - expect(account.address).to.be.equal(ADDRESS); - expect(account.secret).to.be.equal(PRIVATE_KEY); + expect(account.address).to.be.equal(ADDRESS1); + expect(account.secret).to.be.equal(PRIVATE_KEY1); expect(account.provider).to.be.equal(null); }); }); @@ -102,25 +104,26 @@ describe('SmartAccount', async () => { describe('#getAddress()', () => { it('should return the `SmartAccount` address', async () => { const account = new SmartAccount( - {address: ADDRESS, secret: PRIVATE_KEY}, + {address: ADDRESS1, secret: PRIVATE_KEY1}, provider ); const result = await account.getAddress(); - expect(result).to.be.equal(ADDRESS); + expect(result).to.be.equal(ADDRESS1); }); }); describe('#getBalance()', () => { it('should return a `SmartAccount` balance', async () => { const result = await account.getBalance(); - expect(result > 0).to.be.true; + expect(result > 0n).to.be.true; }); }); describe('#getAllBalances()', () => { it('should return all balances', async () => { const result = await account.getAllBalances(); - expect(Object.keys(result)).to.have.lengthOf(2); + const expected = IS_ETH_BASED ? 2 : 3; + expect(Object.keys(result)).to.have.lengthOf(expected); }); }); @@ -134,35 +137,34 @@ describe('SmartAccount', async () => { describe('#populateTransaction()', () => { it('should return a populated transaction', async () => { const tx = { - to: '0xa61464658AfeAf65CccaaFD3a512b69A83B77618', + to: ADDRESS2, value: 7_000_000_000n, type: utils.EIP712_TX_TYPE, - from: '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049', + from: ADDRESS1, nonce: await account.getNonce('pending'), - gasLimit: 154_379n, + gasLimit: 156_726n, chainId: 270n, data: '0x', customData: {gasPerPubdata: 50_000, factoryDeps: []}, - gasPrice: 250_000_000n, + gasPrice: 100_000_000n, }; const result = await account.populateTransaction({ type: utils.EIP712_TX_TYPE, - to: RECEIVER, + to: ADDRESS2, value: 7_000_000_000, }); - expect(result).to.be.deepEqualExcluding(tx, ['gasLimit', 'gasPrice']); - result.gasPrice; - expect(toBigInt(result.gasLimit!) > 0n).to.be.true; - expect(toBigInt(result.gasPrice!) > 0n).to.be.true; + expect(result).to.be.deepEqualExcluding(tx, ['gasLimit']); + expect(BigInt(result.gasLimit!) > 0n).to.be.true; + expect(BigInt(result.gasPrice!) > 0n).to.be.true; }).timeout(25_000); it('should return a populated transaction with default values if are omitted', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: utils.EIP712_TX_TYPE, - from: '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049', + from: ADDRESS1, nonce: await account.getNonce('pending'), chainId: 270n, gasPrice: 100_000_000n, @@ -170,17 +172,18 @@ describe('SmartAccount', async () => { customData: {gasPerPubdata: 50_000, factoryDeps: []}, }; const result = await account.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, }); expect(result).to.be.deepEqualExcluding(tx, ['gasLimit']); + expect(BigInt(result.gasLimit!) > 0n).to.be.true; }); }); describe('#signTransaction()', () => { it('should return a signed EIP712 transaction', async () => { const result = await account.signTransaction({ - to: RECEIVER, + to: ADDRESS2, value: ethers.parseEther('1'), }); expect(result).not.to.be.null; @@ -217,14 +220,14 @@ describe('SmartAccount', async () => { describe('#transfer()', () => { it('should transfer ETH', async () => { const amount = 7_000_000_000n; - const balanceBeforeTransfer = await provider.getBalance(RECEIVER); + const balanceBeforeTransfer = await provider.getBalance(ADDRESS2); const tx = await account.transfer({ token: utils.ETH_ADDRESS, - to: RECEIVER, + to: ADDRESS2, amount: amount, }); const result = await tx.wait(); - const balanceAfterTransfer = await provider.getBalance(RECEIVER); + const balanceAfterTransfer = await provider.getBalance(ADDRESS2); expect(result).not.to.be.null; expect(balanceAfterTransfer - balanceBeforeTransfer).to.be.equal(amount); }).timeout(25_000); @@ -238,20 +241,20 @@ describe('SmartAccount', async () => { const paymasterTokenBalanceBeforeTransfer = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const senderBalanceBeforeTransfer = await account.getBalance(); const senderApprovalTokenBalanceBeforeTransfer = - await account.getBalance(TOKEN); - const receiverBalanceBeforeTransfer = await provider.getBalance(RECEIVER); + await account.getBalance(APPROVAL_TOKEN); + const receiverBalanceBeforeTransfer = await provider.getBalance(ADDRESS2); const tx = await account.transfer({ token: utils.ETH_ADDRESS, - to: RECEIVER, + to: ADDRESS2, amount: amount, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: minimalAllowance, innerInput: new Uint8Array(), }), @@ -263,12 +266,12 @@ describe('SmartAccount', async () => { const paymasterTokenBalanceAfterTransfer = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const senderBalanceAfterTransfer = await account.getBalance(); const senderApprovalTokenBalanceAfterTransfer = - await account.getBalance(TOKEN); - const receiverBalanceAfterTransfer = await provider.getBalance(RECEIVER); + await account.getBalance(APPROVAL_TOKEN); + const receiverBalanceAfterTransfer = await provider.getBalance(ADDRESS2); expect( paymasterBalanceBeforeTransfer - paymasterBalanceAfterTransfer >= 0n @@ -295,18 +298,18 @@ describe('SmartAccount', async () => { const amount = 5n; const l2DAI = await provider.l2TokenAddress(DAI_L1); const balanceBeforeTransfer = await provider.getBalance( - RECEIVER, + ADDRESS2, 'latest', l2DAI ); const tx = await account.transfer({ token: l2DAI, - to: RECEIVER, + to: ADDRESS2, amount: amount, }); const result = await tx.wait(); const balanceAfterTransfer = await provider.getBalance( - RECEIVER, + ADDRESS2, 'latest', l2DAI ); @@ -324,24 +327,24 @@ describe('SmartAccount', async () => { const paymasterTokenBalanceBeforeTransfer = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const senderBalanceBeforeTransfer = await account.getBalance(l2DAI); const senderApprovalTokenBalanceBeforeTransfer = - await account.getBalance(TOKEN); + await account.getBalance(APPROVAL_TOKEN); const receiverBalanceBeforeTransfer = await provider.getBalance( - RECEIVER, + ADDRESS2, 'latest', l2DAI ); const tx = await account.transfer({ token: l2DAI, - to: RECEIVER, + to: ADDRESS2, amount: amount, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: minimalAllowance, innerInput: new Uint8Array(), }), @@ -353,13 +356,13 @@ describe('SmartAccount', async () => { const paymasterTokenBalanceAfterTransfer = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const senderBalanceAfterTransfer = await account.getBalance(l2DAI); const senderApprovalTokenBalanceAfterTransfer = - await account.getBalance(TOKEN); + await account.getBalance(APPROVAL_TOKEN); const receiverBalanceAfterTransfer = await provider.getBalance( - RECEIVER, + ADDRESS2, 'latest', l2DAI ); @@ -417,11 +420,11 @@ describe('SmartAccount', async () => { const paymasterTokenBalanceBeforeWithdrawal = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const l2BalanceBeforeWithdrawal = await account.getBalance(); const l2ApprovalTokenBalanceBeforeWithdrawal = - await account.getBalance(TOKEN); + await account.getBalance(APPROVAL_TOKEN); const withdrawTx = await account.withdraw({ token: utils.ETH_ADDRESS, @@ -429,7 +432,7 @@ describe('SmartAccount', async () => { amount: amount, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: minimalAllowance, innerInput: new Uint8Array(), }), @@ -447,11 +450,11 @@ describe('SmartAccount', async () => { const paymasterTokenBalanceAfterWithdrawal = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const l2BalanceAfterWithdrawal = await account.getBalance(); const l2ApprovalTokenBalanceAfterWithdrawal = - await account.getBalance(TOKEN); + await account.getBalance(APPROVAL_TOKEN); expect( paymasterBalanceBeforeWithdrawal - paymasterBalanceAfterWithdrawal >= 0n @@ -512,12 +515,12 @@ describe('SmartAccount', async () => { const paymasterTokenBalanceBeforeWithdrawal = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const l2BalanceBeforeWithdrawal = await account.getBalance(l2DAI); const l1BalanceBeforeWithdrawal = await wallet.getBalanceL1(DAI_L1); const l2ApprovalTokenBalanceBeforeWithdrawal = - await account.getBalance(TOKEN); + await account.getBalance(APPROVAL_TOKEN); const withdrawTx = await account.withdraw({ token: l2DAI, @@ -525,7 +528,7 @@ describe('SmartAccount', async () => { amount: amount, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: minimalAllowance, innerInput: new Uint8Array(), }), @@ -543,12 +546,12 @@ describe('SmartAccount', async () => { const paymasterTokenBalanceAfterWithdrawal = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const l2BalanceAfterWithdrawal = await account.getBalance(l2DAI); const l1BalanceAfterWithdrawal = await wallet.getBalanceL1(DAI_L1); const l2ApprovalTokenBalanceAfterWithdrawal = - await account.getBalance(TOKEN); + await account.getBalance(APPROVAL_TOKEN); expect( paymasterBalanceBeforeWithdrawal - paymasterBalanceAfterWithdrawal >= 0n @@ -574,23 +577,11 @@ describe('SmartAccount', async () => { }); describe('MultisigECDSASmartAccount', async () => { - const ADDRESS1 = '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049'; - const PRIVATE_KEY1 = - '0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110'; - const ADDRESS2 = '0xa61464658AfeAf65CccaaFD3a512b69A83B77618'; - const PRIVATE_KEY2 = - '0xac1e735be8536c6534bb4f17f06f6afc73b2b5ba84ac2cfb12f7461b20c0bbe3'; - const provider = Provider.getDefaultProvider(types.Network.Localhost); const ethProvider = ethers.getDefaultProvider('http://localhost:8545'); const wallet = new Wallet(PRIVATE_KEY1, provider, ethProvider); let account: SmartAccount; - const DAI_L1 = TokensL1[0].address; - - const TOKEN = '0x841c43Fa5d8fFfdB9efE3358906f7578d8700Dd4'; - const PAYMASTER = '0xa222f0c183AFA73a8Bc1AFb48D34C88c9Bf7A174'; - before('setup', async function () { this.timeout(25_000); @@ -623,7 +614,7 @@ describe('MultisigECDSASmartAccount', async () => { // send paymaster approval token to multisig account const sendApprovalTokenTx = await deployer.transfer({ to: multisigAddress, - token: TOKEN, + token: APPROVAL_TOKEN, amount: 5, }); await sendApprovalTokenTx.wait(); @@ -667,11 +658,11 @@ describe('MultisigECDSASmartAccount', async () => { const paymasterTokenBalanceBeforeTransfer = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const senderBalanceBeforeTransfer = await account.getBalance(); const senderApprovalTokenBalanceBeforeTransfer = - await account.getBalance(TOKEN); + await account.getBalance(APPROVAL_TOKEN); const receiverBalanceBeforeTransfer = await provider.getBalance(ADDRESS2); const tx = await account.transfer({ @@ -680,7 +671,7 @@ describe('MultisigECDSASmartAccount', async () => { amount: amount, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: minimalAllowance, innerInput: new Uint8Array(), }), @@ -692,11 +683,11 @@ describe('MultisigECDSASmartAccount', async () => { const paymasterTokenBalanceAfterTransfer = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const senderBalanceAfterTransfer = await account.getBalance(); const senderApprovalTokenBalanceAfterTransfer = - await account.getBalance(TOKEN); + await account.getBalance(APPROVAL_TOKEN); const receiverBalanceAfterTransfer = await provider.getBalance(ADDRESS2); expect( @@ -753,11 +744,11 @@ describe('MultisigECDSASmartAccount', async () => { const paymasterTokenBalanceBeforeTransfer = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const senderBalanceBeforeTransfer = await account.getBalance(l2DAI); const senderApprovalTokenBalanceBeforeTransfer = - await account.getBalance(TOKEN); + await account.getBalance(APPROVAL_TOKEN); const receiverBalanceBeforeTransfer = await provider.getBalance( ADDRESS2, 'latest', @@ -770,7 +761,7 @@ describe('MultisigECDSASmartAccount', async () => { amount: amount, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: minimalAllowance, innerInput: new Uint8Array(), }), @@ -782,11 +773,11 @@ describe('MultisigECDSASmartAccount', async () => { const paymasterTokenBalanceAfterTransfer = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const senderBalanceAfterTransfer = await account.getBalance(l2DAI); const senderApprovalTokenBalanceAfterTransfer = - await account.getBalance(TOKEN); + await account.getBalance(APPROVAL_TOKEN); const receiverBalanceAfterTransfer = await provider.getBalance( ADDRESS2, 'latest', @@ -846,11 +837,11 @@ describe('MultisigECDSASmartAccount', async () => { const paymasterTokenBalanceBeforeWithdrawal = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const l2BalanceBeforeWithdrawal = await account.getBalance(); const l2ApprovalTokenBalanceBeforeWithdrawal = - await account.getBalance(TOKEN); + await account.getBalance(APPROVAL_TOKEN); const withdrawTx = await account.withdraw({ token: utils.ETH_ADDRESS, @@ -858,7 +849,7 @@ describe('MultisigECDSASmartAccount', async () => { amount: amount, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: minimalAllowance, innerInput: new Uint8Array(), }), @@ -876,11 +867,11 @@ describe('MultisigECDSASmartAccount', async () => { const paymasterTokenBalanceAfterWithdrawal = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const l2BalanceAfterWithdrawal = await account.getBalance(); const l2ApprovalTokenBalanceAfterWithdrawal = - await account.getBalance(TOKEN); + await account.getBalance(APPROVAL_TOKEN); expect( paymasterBalanceBeforeWithdrawal - paymasterBalanceAfterWithdrawal >= 0 @@ -942,12 +933,12 @@ describe('MultisigECDSASmartAccount', async () => { const paymasterTokenBalanceBeforeWithdrawal = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const l2BalanceBeforeWithdrawal = await account.getBalance(l2DAI); const l1BalanceBeforeWithdrawal = await wallet.getBalanceL1(DAI_L1); const l2ApprovalTokenBalanceBeforeWithdrawal = - await account.getBalance(TOKEN); + await account.getBalance(APPROVAL_TOKEN); const withdrawTx = await account.withdraw({ token: l2DAI, @@ -955,7 +946,7 @@ describe('MultisigECDSASmartAccount', async () => { amount: amount, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: minimalAllowance, innerInput: new Uint8Array(), }), @@ -973,12 +964,12 @@ describe('MultisigECDSASmartAccount', async () => { const paymasterTokenBalanceAfterWithdrawal = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const l2BalanceAfterWithdrawal = await account.getBalance(l2DAI); const l1BalanceAfterWithdrawal = await wallet.getBalanceL1(DAI_L1); const l2ApprovalTokenBalanceAfterWithdrawal = - await account.getBalance(TOKEN); + await account.getBalance(APPROVAL_TOKEN); expect( paymasterBalanceBeforeWithdrawal - paymasterBalanceAfterWithdrawal >= 0n diff --git a/tests/integration/types.test.ts b/tests/integration/types.test.ts index 202ad9eb..65db057a 100644 --- a/tests/integration/types.test.ts +++ b/tests/integration/types.test.ts @@ -1,14 +1,11 @@ import {expect} from 'chai'; import '../custom-matchers'; import {Provider, types, utils, Wallet} from '../../src'; +import {ADDRESS2, PRIVATE_KEY1} from '../utils'; describe('types', () => { - const PRIVATE_KEY = - '0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110'; - const RECEIVER = '0xa61464658AfeAf65CccaaFD3a512b69A83B77618'; - const provider = Provider.getDefaultProvider(types.Network.Localhost); - const wallet = new Wallet(PRIVATE_KEY, provider); + const wallet = new Wallet(PRIVATE_KEY1, provider); describe('TransactionResponse', () => { let tx: types.TransactionResponse; @@ -17,7 +14,7 @@ describe('types', () => { this.timeout(25_000); tx = await wallet.transfer({ token: utils.ETH_ADDRESS, - to: RECEIVER, + to: ADDRESS2, amount: 1_000_000, }); await tx.wait(); @@ -52,7 +49,7 @@ describe('types', () => { this.timeout(25_000); const tx = await wallet.transfer({ token: utils.ETH_ADDRESS, - to: RECEIVER, + to: ADDRESS2, amount: 1_000_000, }); await tx.wait(); @@ -88,7 +85,7 @@ describe('types', () => { this.timeout(25_000); const tx = await wallet.transfer({ token: utils.ETH_ADDRESS, - to: RECEIVER, + to: ADDRESS2, amount: 1_000_000, }); await tx.wait(); @@ -132,7 +129,7 @@ describe('types', () => { this.timeout(25_000); const tx = await wallet.transfer({ token: utils.ETH_ADDRESS, - to: RECEIVER, + to: ADDRESS2, amount: 1_000_000, }); await tx.wait(); @@ -144,7 +141,7 @@ describe('types', () => { transactionHash: receipt.hash, transactionIndex: receipt.index, data: '0x', - address: utils.L2_ETH_TOKEN_ADDRESS, + address: utils.L2_BASE_TOKEN_ADDRESS, index: 0, removed: false, topics: [], @@ -191,14 +188,14 @@ describe('types', () => { this.timeout(25_000); const signedEip712Tx = await wallet.signTransaction({ type: utils.EIP712_TX_TYPE, - to: RECEIVER, + to: ADDRESS2, value: 1_000_000, nonce: 1, }); eip712Tx = types.Transaction.from(signedEip712Tx); const signedLegacyTx = await wallet.signTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 1_000_000, nonce: 1, }); @@ -207,33 +204,25 @@ describe('types', () => { describe('#serialized()', () => { it('should return the serialized EIP1559 transaction', async () => { - const tx = - '0x02f87082010e01843b9aca008447868c0083026e1f94a61464658afeaf65cccaafd3a512b69a83b77618830f424080c001a0b0131078e3635ea6366cba74053b7df981e317ec5f05fc5107a31c2b5769435aa03ecbe41ddc7a5b2a6814c9d93222d339951848b678d66333ff1416ac3f16b7ff'; const result = eip1559Tx.serialized; - expect(result).to.be.equal(tx); + expect(result).not.to.be.null; }); it('should return the serialized EIP712 transaction', async () => { - const tx = - '0x71f88e018405f5e1008405f5e1008302658a94a61464658afeaf65cccaafd3a512b69a83b77618830f42408082010e808082010e9436615cf349d7f6344891b1e7ca7c72883f5dc04982c350c0b8412058c9984aa8b1ff410286b17c6be2e8039058c75cf13edea577f6ee7d1b3b7943e579477c497eaa7d857654b73eea5d12d51a347ee8707389c811f3acf322851cc0'; const result = eip712Tx.serialized; - expect(result).to.be.equal(tx); + expect(result).not.to.be.null; }); }); describe('#unsignedSerialized()', () => { it('should return the unsigned serialized EIP1559 transaction', async () => { - const tx = - '0x02ed82010e01843b9aca008447868c0083026e1f94a61464658afeaf65cccaafd3a512b69a83b77618830f424080c0'; const result = eip1559Tx.unsignedSerialized; - expect(result).to.be.equal(tx); + expect(result).not.to.be.null; }); it('should return the unsigned serialized EIP712 transaction', async () => { - const tx = - '0x71f88e018405f5e1008405f5e1008302658a94a61464658afeaf65cccaafd3a512b69a83b77618830f42408082010e808082010e9436615cf349d7f6344891b1e7ca7c72883f5dc04982c350c0b8412058c9984aa8b1ff410286b17c6be2e8039058c75cf13edea577f6ee7d1b3b7943e579477c497eaa7d857654b73eea5d12d51a347ee8707389c811f3acf322851cc0'; const result = eip712Tx.unsignedSerialized; - expect(result).to.be.equal(tx); + expect(result).not.to.be.null; }); }); diff --git a/tests/integration/utils.test.ts b/tests/integration/utils.test.ts index 7391f34a..bf47acbb 100644 --- a/tests/integration/utils.test.ts +++ b/tests/integration/utils.test.ts @@ -2,26 +2,24 @@ import * as chai from 'chai'; import '../custom-matchers'; import {Provider, types, utils, EIP712Signer} from '../../src'; import {ethers} from 'ethers'; +import {PRIVATE_KEY1, ADDRESS1, IS_ETH_BASED, ADDRESS2, DAI_L1} from '../utils'; const {expect} = chai; describe('utils', () => { - const ADDRESS = '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049'; - const PRIVATE_KEY = - '0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110'; - const provider = Provider.getDefaultProvider(types.Network.Localhost); + const ethProvider = ethers.getDefaultProvider('http://localhost:8545'); describe('#isMessageSignatureCorrect()', () => { it('should return true for a valid message signature', async () => { const message = 'Hello, world!'; - const signature = await new ethers.Wallet(PRIVATE_KEY).signMessage( + const signature = await new ethers.Wallet(PRIVATE_KEY1).signMessage( message ); const result = await utils.isMessageSignatureCorrect( provider, - ADDRESS, + ADDRESS1, message, signature ); @@ -35,7 +33,7 @@ describe('utils', () => { const result = await utils.isMessageSignatureCorrect( provider, - ADDRESS, + ADDRESS1, message, invalidSignature ); @@ -48,13 +46,13 @@ describe('utils', () => { const tx: types.TransactionRequest = { type: 113, chainId: 270, - from: ADDRESS, + from: ADDRESS1, to: '0xa61464658AfeAf65CccaaFD3a512b69A83B77618', value: 7_000_000n, }; const eip712Signer = new EIP712Signer( - new ethers.Wallet(PRIVATE_KEY), + new ethers.Wallet(PRIVATE_KEY1), Number((await provider.getNetwork()).chainId) ); @@ -62,7 +60,7 @@ describe('utils', () => { const result = await utils.isTypedDataSignatureCorrect( provider, - ADDRESS, + ADDRESS1, await eip712Signer.getDomain(), utils.EIP712_TYPES, EIP712Signer.getSignInput(tx), @@ -79,19 +77,19 @@ describe('utils', () => { const tx: types.TransactionRequest = { type: 113, chainId: 270, - from: ADDRESS, + from: ADDRESS1, to: '0xa61464658AfeAf65CccaaFD3a512b69A83B77618', value: 1_000_000n, }; const eip712Signer = new EIP712Signer( - new ethers.Wallet(PRIVATE_KEY), + new ethers.Wallet(PRIVATE_KEY1), Number((await provider.getNetwork()).chainId) ); const result = await utils.isTypedDataSignatureCorrect( provider, - ADDRESS, + ADDRESS1, await eip712Signer.getDomain(), utils.EIP712_TYPES, EIP712Signer.getSignInput(tx), @@ -100,4 +98,68 @@ describe('utils', () => { expect(result).to.be.false; }); }); + + describe('#estimateDefaultBridgeDepositL2Gas()', () => { + if (IS_ETH_BASED) { + it('should return estimation for ETH token', async () => { + const result = await utils.estimateDefaultBridgeDepositL2Gas( + ethProvider, + provider, + utils.LEGACY_ETH_ADDRESS, + ethers.parseEther('1'), + ADDRESS2, + ADDRESS1 + ); + expect(result > 0n).to.be.true; + }); + + it('should return estimation for DAI token', async () => { + const result = await utils.estimateDefaultBridgeDepositL2Gas( + ethProvider, + provider, + DAI_L1, + 5, + ADDRESS2, + ADDRESS1 + ); + expect(result > 0n).to.be.true; + }); + } else { + it('should return estimation for ETH token', async () => { + const result = await utils.estimateDefaultBridgeDepositL2Gas( + ethProvider, + provider, + utils.LEGACY_ETH_ADDRESS, + ethers.parseEther('1'), + ADDRESS2, + ADDRESS1 + ); + expect(result > 0n).to.be.true; + }); + + it('should return estimation for base token', async () => { + const result = await utils.estimateDefaultBridgeDepositL2Gas( + ethProvider, + provider, + await provider.getBaseTokenContractAddress(), + ethers.parseEther('1'), + ADDRESS2, + ADDRESS1 + ); + expect(result > 0n).to.be.true; + }); + + it('should return estimation for DAI token', async () => { + const result = await utils.estimateDefaultBridgeDepositL2Gas( + ethProvider, + provider, + DAI_L1, + 5, + ADDRESS2, + ADDRESS1 + ); + expect(result > 0n).to.be.true; + }); + } + }); }); diff --git a/tests/integration/wallet.test.ts b/tests/integration/wallet.test.ts index ae3ca852..b15dae3d 100644 --- a/tests/integration/wallet.test.ts +++ b/tests/integration/wallet.test.ts @@ -3,40 +3,37 @@ import '../custom-matchers'; import {Provider, types, utils, Wallet} from '../../src'; import {ethers} from 'ethers'; import * as fs from 'fs'; +import {ITestnetERC20Token__factory} from '../../src/typechain'; +import { + IS_ETH_BASED, + ADDRESS1, + PRIVATE_KEY1, + MNEMONIC1, + ADDRESS2, + DAI_L1, + APPROVAL_TOKEN, + PAYMASTER, +} from '../utils'; const {expect} = chai; -import TokensL1 from '../files/tokens.json'; - describe('Wallet', () => { - const ADDRESS = '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049'; - const PRIVATE_KEY = - '0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110'; - const MNEMONIC = - 'stuff slice staff easily soup parent arm payment cotton trade scatter struggle'; - const RECEIVER = '0xa61464658AfeAf65CccaaFD3a512b69A83B77618'; - const provider = Provider.getDefaultProvider(types.Network.Localhost); const ethProvider = ethers.getDefaultProvider('http://localhost:8545'); - const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); - - const DAI_L1 = TokensL1[0].address; - - const TOKEN = '0x841c43Fa5d8fFfdB9efE3358906f7578d8700Dd4'; - const PAYMASTER = '0xa222f0c183AFA73a8Bc1AFb48D34C88c9Bf7A174'; + const wallet = new Wallet(PRIVATE_KEY1, provider, ethProvider); describe('#constructor()', () => { it('`Wallet(privateKey, provider)` should return a `Wallet` with L2 provider', async () => { - const wallet = new Wallet(PRIVATE_KEY, provider); + const wallet = new Wallet(PRIVATE_KEY1, provider); - expect(wallet.signingKey.privateKey).to.be.equal(PRIVATE_KEY); + expect(wallet.signingKey.privateKey).to.be.equal(PRIVATE_KEY1); expect(wallet.provider).to.be.equal(provider); }); it('`Wallet(privateKey, provider, ethProvider)` should return a `Wallet` with L1 and L2 provider', async () => { - const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); + const wallet = new Wallet(PRIVATE_KEY1, provider, ethProvider); - expect(wallet.signingKey.privateKey).to.be.equal(PRIVATE_KEY); + expect(wallet.signingKey.privateKey).to.be.equal(PRIVATE_KEY1); expect(wallet.provider).to.be.equal(provider); expect(wallet.providerL1).to.be.equal(ethProvider); }); @@ -49,6 +46,13 @@ describe('Wallet', () => { }); }); + describe('#getBridgehubContract()', () => { + it('should return the bridgehub contract', async () => { + const result = await wallet.getBridgehubContract(); + expect(result).not.to.be.null; + }); + }); + describe('#getL1BridgeContracts()', () => { it('should return the L1 bridge contracts', async () => { const result = await wallet.getL1BridgeContracts(); @@ -56,24 +60,48 @@ describe('Wallet', () => { }); }); + describe('#isETHBasedChain()', () => { + it('should return whether the chain is ETH-based or not', async () => { + const result = await wallet.isETHBasedChain(); + expect(result).to.be.equal(IS_ETH_BASED); + }); + }); + + describe('#getBaseToken()', () => { + it('should return base token', async () => { + const result = await wallet.getBaseToken(); + IS_ETH_BASED + ? expect(result).to.be.equal(utils.ETH_ADDRESS_IN_CONTRACTS) + : expect(result).not.to.be.null; + }); + }); + describe('#getBalanceL1()', () => { it('should return a L1 balance', async () => { const result = await wallet.getBalanceL1(); - expect(result > 0).to.be.true; + expect(result > 0n).to.be.true; }); }); describe('#getAllowanceL1()', () => { it('should return an allowance of L1 token', async () => { const result = await wallet.getAllowanceL1(DAI_L1); - expect(result >= 0).to.be.true; + expect(result >= 0n).to.be.true; }); }); describe('#l2TokenAddress()', () => { + it('should return the L2 base address', async () => { + const baseToken = await provider.getBaseTokenContractAddress(); + const result = await wallet.l2TokenAddress(baseToken); + expect(result).to.be.equal(utils.L2_BASE_TOKEN_ADDRESS); + }); + it('should return the L2 ETH address', async () => { - const result = await wallet.l2TokenAddress(utils.ETH_ADDRESS); - expect(result).to.be.equal(utils.ETH_ADDRESS); + if (!IS_ETH_BASED) { + const result = await wallet.l2TokenAddress(utils.LEGACY_ETH_ADDRESS); + expect(result).not.to.be.null; + } }); it('should return the L2 DAI address', async () => { @@ -91,7 +119,7 @@ describe('Wallet', () => { it('should throw an error when approving ETH token', async () => { try { - await wallet.approveERC20(utils.ETH_ADDRESS, 5); + await wallet.approveERC20(utils.LEGACY_ETH_ADDRESS, 5); } catch (e) { expect((e as Error).message).to.be.equal( "ETH token can't be approved! The address of the token does not exist on L1." @@ -110,14 +138,15 @@ describe('Wallet', () => { describe('#getBalance()', () => { it('should return a `Wallet` balance', async () => { const result = await wallet.getBalance(); - expect(result > 0).to.be.true; + expect(result > 0n).to.be.true; }); }); describe('#getAllBalances()', () => { it('should return the all balances', async () => { const result = await wallet.getAllBalances(); - expect(Object.keys(result)).to.have.lengthOf(2); + const expected = IS_ETH_BASED ? 2 : 3; + expect(Object.keys(result)).to.have.lengthOf(expected); }); }); @@ -131,25 +160,25 @@ describe('Wallet', () => { describe('#getAddress()', () => { it('should return the `Wallet` address', async () => { const result = await wallet.getAddress(); - expect(result).to.be.equal(ADDRESS); + expect(result).to.be.equal(ADDRESS1); }); }); describe('#ethWallet()', () => { it('should return a L1 `Wallet`', async () => { - const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); + const wallet = new Wallet(PRIVATE_KEY1, provider, ethProvider); const ethWallet = wallet.ethWallet(); - expect(ethWallet.signingKey.privateKey).to.be.equal(PRIVATE_KEY); + expect(ethWallet.signingKey.privateKey).to.be.equal(PRIVATE_KEY1); expect(ethWallet.provider).to.be.equal(ethProvider); }); it('should throw an error when L1 `Provider` is not specified in constructor', async () => { - const wallet = new Wallet(PRIVATE_KEY, provider); + const wallet = new Wallet(PRIVATE_KEY1, provider); try { wallet.ethWallet(); } catch (e) { expect((e as Error).message).to.be.equal( - 'L1 provider missing: use `connectToL1` to specify!' + 'L1 provider is missing! Specify an L1 provider using `Wallet.connectToL1()`.' ); } }); @@ -157,18 +186,18 @@ describe('Wallet', () => { describe('#connect()', () => { it('should return a `Wallet` with provided `provider` as L2 provider', async () => { - let wallet = new Wallet(PRIVATE_KEY); + let wallet = new Wallet(PRIVATE_KEY1); wallet = wallet.connect(provider); - expect(wallet.signingKey.privateKey).to.be.equal(PRIVATE_KEY); + expect(wallet.signingKey.privateKey).to.be.equal(PRIVATE_KEY1); expect(wallet.provider).to.be.equal(provider); }); }); describe('#connectL1()', () => { it('should return a `Wallet` with provided `provider` as L1 provider', async () => { - let wallet = new Wallet(PRIVATE_KEY); + let wallet = new Wallet(PRIVATE_KEY1); wallet = wallet.connectToL1(ethProvider); - expect(wallet.signingKey.privateKey).to.be.equal(PRIVATE_KEY); + expect(wallet.signingKey.privateKey).to.be.equal(PRIVATE_KEY1); expect(wallet.providerL1).to.be.equal(ethProvider); }); }); @@ -183,10 +212,10 @@ describe('Wallet', () => { describe('#populateTransaction()', () => { it('should return a populated transaction', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000_000n, type: utils.EIP712_TX_TYPE, - from: ADDRESS, + from: ADDRESS1, nonce: await wallet.getNonce('pending'), gasLimit: 154_379n, chainId: 270n, @@ -197,38 +226,50 @@ describe('Wallet', () => { const result = await wallet.populateTransaction({ type: utils.EIP712_TX_TYPE, - to: RECEIVER, + to: ADDRESS2, value: 7_000_000_000, }); - expect(result).to.be.deepEqualExcluding(tx, ['gasLimit', 'gasPrice']); - expect((result.gasLimit as bigint) > 0n).to.be.true; - expect((result.gasPrice as bigint) > 0n).to.be.true; + expect(result).to.be.deepEqualExcluding(tx, [ + 'gasLimit', + 'chainId', + 'gasPrice', + ]); + expect(BigInt(result.gasLimit!) > 0n).to.be.true; + expect(BigInt(result.gasPrice!) > 0n).to.be.true; }).timeout(25_000); it('should return a populated transaction with default values if are omitted', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 2, - from: ADDRESS, + from: ADDRESS1, nonce: await wallet.getNonce('pending'), chainId: 270n, maxFeePerGas: 1_200_000_000n, maxPriorityFeePerGas: 1_000_000_000n, }; const result = await wallet.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, }); - expect(result).to.be.deepEqualExcluding(tx, ['gasLimit']); + expect(result).to.be.deepEqualExcluding(tx, [ + 'gasLimit', + 'chainId', + 'maxFeePerGas', + 'maxPriorityFeePerGas', + ]); + expect(BigInt(result.gasLimit!) > 0n).to.be.true; + expect(BigInt(result.maxFeePerGas!) > 0n).to.be.true; + expect(BigInt(result.maxPriorityFeePerGas!) > 0n).to.be.true; }); it('should return populated transaction when `maxFeePerGas` and `maxPriorityFeePerGas` and `customData` are provided', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 113, - from: ADDRESS, + from: ADDRESS1, nonce: await wallet.getNonce('pending'), data: '0x', chainId: 270n, @@ -240,7 +281,7 @@ describe('Wallet', () => { }, }; const result = await wallet.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 2_000_000_000n, @@ -250,14 +291,15 @@ describe('Wallet', () => { }, }); expect(result).to.be.deepEqualExcluding(tx, ['gasLimit']); + expect(BigInt(result.gasLimit!) > 0n).to.be.true; }); it('should return populated transaction when `maxPriorityFeePerGas` and `customData` are provided', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 113, - from: ADDRESS, + from: ADDRESS1, nonce: await wallet.getNonce('pending'), data: '0x', chainId: 270n, @@ -268,7 +310,7 @@ describe('Wallet', () => { }, }; const result = await wallet.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, maxPriorityFeePerGas: 2_000_000_000n, customData: { @@ -276,14 +318,15 @@ describe('Wallet', () => { }, }); expect(result).to.be.deepEqualExcluding(tx, ['gasLimit']); + expect(BigInt(result.gasLimit!) > 0n).to.be.true; }); it('should return populated transaction when `maxFeePerGas` and `customData` are provided', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 113, - from: ADDRESS, + from: ADDRESS1, nonce: await wallet.getNonce('pending'), data: '0x', chainId: 270n, @@ -294,7 +337,7 @@ describe('Wallet', () => { }, }; const result = await wallet.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, maxFeePerGas: 3_500_000_000n, customData: { @@ -302,70 +345,75 @@ describe('Wallet', () => { }, }); expect(result).to.be.deepEqualExcluding(tx, ['gasLimit']); + expect(BigInt(result.gasLimit!) > 0n).to.be.true; }); it('should return populated EIP1559 transaction when `maxFeePerGas` and `maxPriorityFeePerGas` are provided', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 2, - from: ADDRESS, + from: ADDRESS1, nonce: await wallet.getNonce('pending'), chainId: 270n, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 2_000_000_000n, }; const result = await wallet.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 2_000_000_000n, }); expect(result).to.be.deepEqualExcluding(tx, ['gasLimit']); + expect(BigInt(result.gasLimit!) > 0n).to.be.true; }); it('should return populated EIP1559 transaction with `maxFeePerGas` and `maxPriorityFeePerGas` same as provided `gasPrice`', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 2, - from: ADDRESS, + from: ADDRESS1, nonce: await wallet.getNonce('pending'), chainId: 270n, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 3_500_000_000n, }; const result = await wallet.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, gasPrice: 3_500_000_000n, }); expect(result).to.be.deepEqualExcluding(tx, ['gasLimit']); + expect(BigInt(result.gasLimit!) > 0n).to.be.true; }); it('should return populated legacy transaction when `type = 0`', async () => { const tx = { - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, type: 0, - from: ADDRESS, + from: ADDRESS1, nonce: await wallet.getNonce('pending'), chainId: 270n, gasPrice: 100_000_000n, }; const result = await wallet.populateTransaction({ type: 0, - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, }); - expect(result).to.be.deepEqualExcluding(tx, ['gasLimit']); + expect(result).to.be.deepEqualExcluding(tx, ['gasLimit', 'gasPrice']); + expect(BigInt(result.gasLimit!) > 0n).to.be.true; + expect(BigInt(result.gasPrice!) > 0n).to.be.true; }); }); describe('#sendTransaction()', () => { it('should send already populated transaction with provided `maxFeePerGas` and `maxPriorityFeePerGas` and `customData` fields', async () => { const populatedTx = await wallet.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 2_000_000_000n, @@ -380,7 +428,7 @@ describe('Wallet', () => { it('should send EIP1559 transaction when `maxFeePerGas` and `maxPriorityFeePerGas` are provided', async () => { const tx = await wallet.sendTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 2_000_000_000n, @@ -390,9 +438,9 @@ describe('Wallet', () => { expect(result.type).to.be.equal(2); }).timeout(10_000); - it('should return already populated EIP1559 transaction with `maxFeePerGas` and `maxPriorityFeePerGas`', async () => { + it('should send already populated EIP1559 transaction with `maxFeePerGas` and `maxPriorityFeePerGas`', async () => { const populatedTx = await wallet.populateTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, maxFeePerGas: 3_500_000_000n, maxPriorityFeePerGas: 2_000_000_000n, @@ -406,7 +454,7 @@ describe('Wallet', () => { it('should send EIP1559 transaction with `maxFeePerGas` and `maxPriorityFeePerGas` same as provided `gasPrice`', async () => { const tx = await wallet.sendTransaction({ - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, gasPrice: 3_500_000_000n, }); @@ -418,7 +466,7 @@ describe('Wallet', () => { it('should send legacy transaction when `type = 0`', async () => { const tx = await wallet.sendTransaction({ type: 0, - to: RECEIVER, + to: ADDRESS2, value: 7_000_000, }); const result = await tx.wait(); @@ -429,8 +477,8 @@ describe('Wallet', () => { describe('#fromMnemonic()', () => { it('should return a `Wallet` with the `provider` as L1 provider and a private key that is built from the `mnemonic` passphrase', async () => { - const wallet = Wallet.fromMnemonic(MNEMONIC, ethProvider); - expect(wallet.signingKey.privateKey).to.be.equal(PRIVATE_KEY); + const wallet = Wallet.fromMnemonic(MNEMONIC1, ethProvider); + expect(wallet.signingKey.privateKey).to.be.equal(PRIVATE_KEY1); expect(wallet.providerL1).to.be.equal(ethProvider); }); }); @@ -441,7 +489,7 @@ describe('Wallet', () => { fs.readFileSync('tests/files/wallet.json', 'utf8'), 'password' ); - expect(wallet.signingKey.privateKey).to.be.equal(PRIVATE_KEY); + expect(wallet.signingKey.privateKey).to.be.equal(PRIVATE_KEY1); }).timeout(5_000); }); @@ -451,7 +499,7 @@ describe('Wallet', () => { fs.readFileSync('tests/files/wallet.json', 'utf8'), 'password' ); - expect(wallet.signingKey.privateKey).to.be.equal(PRIVATE_KEY); + expect(wallet.signingKey.privateKey).to.be.equal(PRIVATE_KEY1); }).timeout(5_000); }); @@ -464,278 +512,715 @@ describe('Wallet', () => { }); describe('#getDepositTx()', () => { - it('should return an ETH deposit transaction', async () => { - const tx = { - contractAddress: ADDRESS, - calldata: '0x', - l2Value: 7_000_000, - l2GasLimit: '0x8cbaa', - token: '0x0000000000000000000000000000000000000000', - to: ADDRESS, - amount: 7_000_000, - refundRecipient: ADDRESS, - operatorTip: 0, - overrides: { - from: ADDRESS, - maxFeePerGas: 1_500_000_010n, - maxPriorityFeePerGas: 1_500_000_000n, - value: 288_213_007_000_000n, - }, - gasPerPubdataByte: 800, - }; - const result = await wallet.getDepositTx({ - token: utils.ETH_ADDRESS, - to: await wallet.getAddress(), - amount: 7_000_000, - refundRecipient: await wallet.getAddress(), + if (IS_ETH_BASED) { + it('should return ETH deposit transaction', async () => { + const tx = { + contractAddress: ADDRESS1, + calldata: '0x', + l2Value: 7_000_000, + l2GasLimit: 415_035n, + mintValue: 111_540_663_250_000n, + token: utils.ETH_ADDRESS_IN_CONTRACTS, + to: ADDRESS1, + amount: 7_000_000, + refundRecipient: ADDRESS1, + operatorTip: 0, + overrides: { + from: ADDRESS1, + maxFeePerGas: 1_000_000_001n, + maxPriorityFeePerGas: 1_000_000_000n, + value: 111_540_663_250_000n, + }, + gasPerPubdataByte: 800, + }; + const result = await wallet.getDepositTx({ + token: utils.LEGACY_ETH_ADDRESS, + to: await wallet.getAddress(), + amount: 7_000_000, + refundRecipient: await wallet.getAddress(), + }); + expect(result).to.be.deepEqualExcluding(tx, [ + 'l2GasLimit', + 'mintValue', + 'overrides', + ]); + expect(result.l2GasLimit > 0n).to.be.true; + expect(result.mintValue > 0n).to.be.true; + expect(utils.isAddressEq(result.overrides.from, ADDRESS1)).to.be.true; + expect(result.overrides.maxFeePerGas > 0n).to.be.true; + expect(result.overrides.maxPriorityFeePerGas > 0n).to.be.true; + expect(result.overrides.value > 0n).to.be.true; }); - expect(result).to.be.deepEqualExcluding(tx, ['l2GasLimit', 'overrides']); - expect(result.l2GasLimit > 0n).to.be.true; - expect(result.overrides.from === ADDRESS).to.be.true; - expect(result.overrides.maxFeePerGas > 0n).to.be.true; - expect(result.overrides.maxPriorityFeePerGas > 0n).to.be.true; - expect(result.overrides.value > 0n).to.be.true; - }); - it('should return a deposit transaction with `tx.to == Wallet.getAddress()` when `tx.to` is not specified', async () => { - const tx = { - contractAddress: ADDRESS, - calldata: '0x', - l2Value: 7_000_000, - l2GasLimit: '0x8cbaa', - token: '0x0000000000000000000000000000000000000000', - to: ADDRESS, - amount: 7_000_000, - refundRecipient: ADDRESS, - operatorTip: 0, - overrides: { - from: ADDRESS, - maxFeePerGas: 1_500_000_010n, - maxPriorityFeePerGas: 1_500_000_000n, - value: 288_213_007_000_000n, - }, - gasPerPubdataByte: 800, - }; - const result = await wallet.getDepositTx({ - token: utils.ETH_ADDRESS, - amount: 7_000_000, - refundRecipient: await wallet.getAddress(), + it('should return a deposit transaction with `tx.to == Wallet.getAddress()` when `tx.to` is not specified', async () => { + const tx = { + contractAddress: ADDRESS1, + calldata: '0x', + l2Value: 7_000_000, + l2GasLimit: 415_035n, + mintValue: 111_540_663_250_000n, + token: utils.ETH_ADDRESS_IN_CONTRACTS, + to: ADDRESS1, + amount: 7_000_000, + refundRecipient: ADDRESS1, + operatorTip: 0, + overrides: { + from: ADDRESS1, + maxFeePerGas: 1_000_000_001n, + maxPriorityFeePerGas: 1_000_000_000n, + value: 111_540_663_250_000n, + }, + gasPerPubdataByte: 800, + }; + const result = await wallet.getDepositTx({ + token: utils.LEGACY_ETH_ADDRESS, + amount: 7_000_000, + refundRecipient: await wallet.getAddress(), + }); + expect(result).to.be.deepEqualExcluding(tx, [ + 'l2GasLimit', + 'mintValue', + 'overrides', + ]); + expect(result.l2GasLimit > 0n).to.be.true; + expect(result.mintValue > 0n).to.be.true; + expect(utils.isAddressEq(result.overrides.from, ADDRESS1)).to.be.true; + expect(result.overrides.maxFeePerGas > 0n).to.be.true; + expect(result.overrides.maxPriorityFeePerGas > 0n).to.be.true; + expect(result.overrides.value > 0n).to.be.true; }); - expect(result).to.be.deepEqualExcluding(tx, ['l2GasLimit', 'overrides']); - expect(result.overrides.from === ADDRESS).to.be.true; - expect(result.l2GasLimit > 0n).to.be.true; - expect(result.overrides.maxFeePerGas > 0n).to.be.true; - expect(result.overrides.maxPriorityFeePerGas > 0n).to.be.true; - expect(result.overrides.value > 0n).to.be.true; - }); - it('should return a DAI deposit transaction', async () => { - const tx = { - maxFeePerGas: 1_000_000_001n, - maxPriorityFeePerGas: 1_000_000_000n, - value: 105_100_275_000_000n, - from: ADDRESS, - to: await (await wallet.getL1BridgeContracts()).erc20.getAddress(), - }; - const result = await wallet.getDepositTx({ - token: DAI_L1, - to: await wallet.getAddress(), - amount: 5, - refundRecipient: await wallet.getAddress(), + it('should return DAI deposit transaction', async () => { + const transaction = { + maxFeePerGas: 1_000_000_001n, + maxPriorityFeePerGas: 1_000_000_000n, + value: 105_100_275_000_000n, + from: ADDRESS1, + to: await provider.getBridgehubContractAddress(), + }; + const result = await wallet.getDepositTx({ + token: DAI_L1, + to: await wallet.getAddress(), + amount: 5, + refundRecipient: await wallet.getAddress(), + }); + result.to = result.to.toLowerCase(); + expect(result).to.be.deepEqualExcluding(transaction, [ + 'data', + 'maxFeePerGas', + 'maxPriorityFeePerGas', + 'value', + ]); + expect(result.maxFeePerGas > 0n).to.be.true; + expect(result.maxPriorityFeePerGas > 0n).to.be.true; + expect(result.value > 0n).to.be.true; + }); + } else { + it('should return ETH deposit transaction', async () => { + const tx = { + from: ADDRESS1, + to: (await provider.getBridgehubContractAddress()).toLowerCase(), + value: 7_000_000n, + data: '0x24fd57fb0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000010e0000000000000000000000000000000000000000000000000000bf1aaa17ee7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000062e3d000000000000000000000000000000000000000000000000000000000000032000000000000000000000000036615cf349d7f6344891b1e7ca7c72883f5dc049000000000000000000000000842deab39809094bf5e4b77a7f97ae308adc5e5500000000000000000000000000000000000000000000000000000000006acfc0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036615cf349d7f6344891b1e7ca7c72883f5dc049', + maxFeePerGas: 1_000_000_001n, + maxPriorityFeePerGas: 1_000_000_000n, + }; + const result = await wallet.getDepositTx({ + token: utils.LEGACY_ETH_ADDRESS, + to: await wallet.getAddress(), + amount: 7_000_000, + refundRecipient: await wallet.getAddress(), + }); + result.to = result.to.toLowerCase(); + expect(result).to.be.deepEqualExcluding(tx, [ + 'data', + 'maxFeePerGas', + 'maxPriorityFeePerGas', + ]); + expect(BigInt(result.maxPriorityFeePerGas) > 0n).to.be.true; + expect(BigInt(result.maxFeePerGas) > 0n).to.be.true; }); - expect(result).to.be.deepEqualExcluding(tx, ['data']); - }); - }); - describe('#estimateGasDeposit()', () => { - it('should return a gas estimation for the ETH deposit transaction', async () => { - const result = await wallet.estimateGasDeposit({ - token: utils.ETH_ADDRESS, - to: await wallet.getAddress(), - amount: 5, - refundRecipient: await wallet.getAddress(), + it('should return a deposit transaction with `tx.to == Wallet.getAddress()` when `tx.to` is not specified', async () => { + const tx = { + from: ADDRESS1, + to: (await provider.getBridgehubContractAddress()).toLowerCase(), + value: 7_000_000n, + maxFeePerGas: 1_000_000_001n, + maxPriorityFeePerGas: 1000_000_000n, + }; + const result = await wallet.getDepositTx({ + token: utils.LEGACY_ETH_ADDRESS, + amount: 7_000_000, + refundRecipient: await wallet.getAddress(), + }); + result.to = result.to.toLowerCase(); + expect(result).to.be.deepEqualExcluding(tx, [ + 'data', + 'maxFeePerGas', + 'maxPriorityFeePerGas', + ]); + expect(BigInt(result.maxPriorityFeePerGas) > 0n).to.be.true; + expect(BigInt(result.maxFeePerGas) > 0n).to.be.true; }); - expect(result > 0n).to.be.true; - }); - it('should return a gas estimation for the DAI deposit transaction', async () => { - const result = await wallet.estimateGasDeposit({ - token: DAI_L1, - to: await wallet.getAddress(), - amount: 5, - refundRecipient: await wallet.getAddress(), + it('should return DAI deposit transaction', async () => { + const tx = { + maxFeePerGas: 1_000_000_001n, + maxPriorityFeePerGas: 1_000_000_000n, + value: 0n, + from: ADDRESS1, + to: (await provider.getBridgehubContractAddress()).toLowerCase(), + }; + const result = await wallet.getDepositTx({ + token: DAI_L1, + to: await wallet.getAddress(), + amount: 5, + refundRecipient: await wallet.getAddress(), + }); + result.to = result.to.toLowerCase(); + expect(result).to.be.deepEqualExcluding(tx, [ + 'data', + 'maxFeePerGas', + 'maxPriorityFeePerGas', + ]); + expect(BigInt(result.maxPriorityFeePerGas) > 0n).to.be.true; + expect(BigInt(result.maxFeePerGas) > 0n).to.be.true; }); - expect(result > 0n).to.be.true; - }); + } }); - describe('#deposit()', () => { - it('should deposit ETH to the L2 network', async () => { - const amount = 7_000_000_000n; - const l2BalanceBeforeDeposit = await wallet.getBalance(); - const l1BalanceBeforeDeposit = await wallet.getBalanceL1(); - const tx = await wallet.deposit({ - token: utils.ETH_ADDRESS, - to: await wallet.getAddress(), - amount: amount, - refundRecipient: await wallet.getAddress(), + describe('#estimateGasDeposit()', () => { + if (IS_ETH_BASED) { + it('should return a gas estimation for the ETH deposit transaction', async () => { + const result = await wallet.estimateGasDeposit({ + token: utils.LEGACY_ETH_ADDRESS, + to: await wallet.getAddress(), + amount: 5, + refundRecipient: await wallet.getAddress(), + }); + expect(result > 0n).to.be.true; }); - const result = await tx.wait(); - const l2BalanceAfterDeposit = await wallet.getBalance(); - const l1BalanceAfterDeposit = await wallet.getBalanceL1(); - expect(result).not.to.be.null; - expect(l2BalanceAfterDeposit - l2BalanceBeforeDeposit >= amount).to.be - .true; - expect(l1BalanceBeforeDeposit - l1BalanceAfterDeposit >= amount).to.be - .true; - }).timeout(20_000); - it('should deposit DAI to the L2 network', async () => { - const amount = 5n; - const l2DAI = await provider.l2TokenAddress(DAI_L1); - const l2BalanceBeforeDeposit = await wallet.getBalance(l2DAI); - const l1BalanceBeforeDeposit = await wallet.getBalanceL1(DAI_L1); - const tx = await wallet.deposit({ - token: DAI_L1, - to: await wallet.getAddress(), - amount: amount, - approveERC20: true, - refundRecipient: await wallet.getAddress(), - }); - const result = await tx.wait(); - const l2BalanceAfterDeposit = await wallet.getBalance(l2DAI); - const l1BalanceAfterDeposit = await wallet.getBalanceL1(DAI_L1); - expect(result).not.to.be.null; - expect(l2BalanceAfterDeposit - l2BalanceBeforeDeposit === amount).to.be - .true; - expect(l1BalanceBeforeDeposit - l1BalanceAfterDeposit === amount).to.be - .true; - }).timeout(20_000); - - it('should deposit DAI to the L2 network with approve transaction for allowance', async () => { - const amount = 7n; - const l2DAI = await provider.l2TokenAddress(DAI_L1); - const l2BalanceBeforeDeposit = await wallet.getBalance(l2DAI); - const l1BalanceBeforeDeposit = await wallet.getBalanceL1(DAI_L1); - const tx = await wallet.deposit({ - token: DAI_L1, - to: await wallet.getAddress(), - amount: amount, - approveERC20: true, - refundRecipient: await wallet.getAddress(), + it('should return a gas estimation for the DAI deposit transaction', async () => { + const result = await wallet.estimateGasDeposit({ + token: DAI_L1, + to: await wallet.getAddress(), + amount: 5, + refundRecipient: await wallet.getAddress(), + }); + expect(result > 0n).to.be.true; }); - const result = await tx.wait(); - await tx.waitFinalize(); - const l2BalanceAfterDeposit = await wallet.getBalance(l2DAI); - const l1BalanceAfterDeposit = await wallet.getBalanceL1(DAI_L1); - expect(result).not.to.be.null; - expect(l2BalanceAfterDeposit - l2BalanceBeforeDeposit === amount).to.be - .true; - expect(l1BalanceBeforeDeposit - l1BalanceAfterDeposit === amount).to.be - .true; - }).timeout(30_000); - }); + } else { + it('should throw an error for insufficient allowance when estimating gas for ETH deposit transaction', async () => { + try { + await wallet.estimateGasDeposit({ + token: utils.LEGACY_ETH_ADDRESS, + to: await wallet.getAddress(), + amount: 5, + refundRecipient: await wallet.getAddress(), + }); + } catch (e: any) { + expect(e.reason).to.include('ERC20: insufficient allowance'); + } + }).timeout(10_000); + + it('should return gas estimation for ETH deposit transaction', async () => { + const token = utils.LEGACY_ETH_ADDRESS; + const amount = 5; + const approveParams = await wallet.getDepositAllowanceParams( + token, + amount + ); - describe('#claimFailedDeposit()', () => { - // it("should claim failed deposit", async () => { - // const response = await wallet.deposit({ - // token: utils.ETH_ADDRESS, - // to: await wallet.getAddress(), - // amount: 7_000_000_000, - // refundRecipient: await wallet.getAddress(), - // gasPerPubdataByte: 500 // make it fail because of low gas - // }); - // - // const tx = await response.waitFinalize(); // fails, sames goes with response.wait() - // const result = await wallet.claimFailedDeposit(tx.hash); - // - // }).timeout(30_000); - - it('should throw an error when trying to claim successful deposit', async () => { - const response = await wallet.deposit({ - token: utils.ETH_ADDRESS, - to: await wallet.getAddress(), - amount: 7_000_000_000, - refundRecipient: await wallet.getAddress(), - }); + await ( + await wallet.approveERC20( + approveParams[0].token, + approveParams[0].allowance + ) + ).wait(); - const tx = await response.waitFinalize(); - try { - await wallet.claimFailedDeposit(tx.hash); - } catch (e) { - expect((e as Error).message).to.be.equal( - 'Cannot claim successful deposit!' + const result = await wallet.estimateGasDeposit({ + token: token, + to: await wallet.getAddress(), + amount: amount, + refundRecipient: await wallet.getAddress(), + }); + expect(result > 0n).to.be.true; + }).timeout(10_000); + + it('should return gas estimation for base token deposit transaction', async () => { + const token = await wallet.getBaseToken(); + const amount = 5; + const approveParams = await wallet.getDepositAllowanceParams( + token, + amount ); - } - }).timeout(30_000); - }); - describe('#getFullRequiredDepositFee()', () => { - it('should return a fee for ETH token deposit', async () => { - const result = await wallet.getFullRequiredDepositFee({ - token: utils.ETH_ADDRESS, - to: await wallet.getAddress(), - }); - expect(result.baseCost.valueOf() > 0n).to.be.true; - expect(result.l1GasLimit.valueOf() > 0n).to.be.true; - expect(result.l2GasLimit.valueOf() > 0n).to.be.true; - expect(result.maxPriorityFeePerGas!.valueOf() > 0n).to.be.true; - expect(result.maxFeePerGas!.valueOf() > 0n).to.be.true; - }); + await ( + await wallet.approveERC20( + approveParams[0].token, + approveParams[0].allowance + ) + ).wait(); - it('should throw an error when there is not enough allowance to cover the deposit', async () => { - try { - await wallet.getFullRequiredDepositFee({ - token: DAI_L1, + const result = await wallet.estimateGasDeposit({ + token: token, to: await wallet.getAddress(), + amount: amount, + refundRecipient: await wallet.getAddress(), }); - } catch (e) { - expect((e as Error).message).to.be.equal( - 'Not enough allowance to cover the deposit!' + expect(result > 0n).to.be.true; + }).timeout(10_000); + + it('should return gas estimation for DAI deposit transaction', async () => { + const token = DAI_L1; + const amount = 5; + const approveParams = await wallet.getDepositAllowanceParams( + token, + amount ); - } - }).timeout(10_000); - it('should return a fee for DAI token deposit', async () => { - const tx = await wallet.approveERC20(DAI_L1, 5); - await tx.wait(); + await ( + await wallet.approveERC20( + approveParams[0].token, + approveParams[0].allowance + ) + ).wait(); + await ( + await wallet.approveERC20( + approveParams[1].token, + approveParams[1].allowance + ) + ).wait(); + + const result = await wallet.estimateGasDeposit({ + token: token, + to: await wallet.getAddress(), + amount: amount, + refundRecipient: await wallet.getAddress(), + }); + expect(result > 0n).to.be.true; + }).timeout(10_000); + } + }); - const result = await wallet.getFullRequiredDepositFee({ - token: DAI_L1, - to: await wallet.getAddress(), + describe('#deposit()', () => { + if (IS_ETH_BASED) { + it('should deposit ETH to L2 network', async () => { + const amount = 7_000_000_000; + const l2BalanceBeforeDeposit = await wallet.getBalance(); + const l1BalanceBeforeDeposit = await wallet.getBalanceL1(); + const tx = await wallet.deposit({ + token: utils.LEGACY_ETH_ADDRESS, + to: await wallet.getAddress(), + amount: amount, + refundRecipient: await wallet.getAddress(), + }); + const result = await tx.wait(); + const l2BalanceAfterDeposit = await wallet.getBalance(); + const l1BalanceAfterDeposit = await wallet.getBalanceL1(); + expect(result).not.to.be.null; + expect(l2BalanceAfterDeposit - l2BalanceBeforeDeposit >= amount).to.be + .true; + expect(l1BalanceBeforeDeposit - l1BalanceAfterDeposit >= amount).to.be + .true; + }).timeout(10_000); + + it('should deposit DAI to L2 network', async () => { + const amount = 5; + const l2DAI = await provider.l2TokenAddress(DAI_L1); + const l2BalanceBeforeDeposit = await wallet.getBalance(l2DAI); + const l1BalanceBeforeDeposit = await wallet.getBalanceL1(DAI_L1); + const tx = await wallet.deposit({ + token: DAI_L1, + to: await wallet.getAddress(), + amount: amount, + approveERC20: true, + refundRecipient: await wallet.getAddress(), + }); + const result = await tx.wait(); + const l2BalanceAfterDeposit = await wallet.getBalance(l2DAI); + const l1BalanceAfterDeposit = await wallet.getBalanceL1(DAI_L1); + expect(result).not.to.be.null; + expect(l2BalanceAfterDeposit - l2BalanceBeforeDeposit >= amount).to.be + .true; + expect(l1BalanceBeforeDeposit - l1BalanceAfterDeposit >= amount).to.be + .true; + }).timeout(10_000); + + it('should deposit DAI to the L2 network with approve transaction for allowance', async () => { + const amount = 7; + const l2DAI = await provider.l2TokenAddress(DAI_L1); + const l2BalanceBeforeDeposit = await wallet.getBalance(l2DAI); + const l1BalanceBeforeDeposit = await wallet.getBalanceL1(DAI_L1); + const tx = await wallet.deposit({ + token: DAI_L1, + to: await wallet.getAddress(), + amount: amount, + approveERC20: true, + refundRecipient: await wallet.getAddress(), + }); + const result = await tx.wait(); + await tx.waitFinalize(); + const l2BalanceAfterDeposit = await wallet.getBalance(l2DAI); + const l1BalanceAfterDeposit = await wallet.getBalanceL1(DAI_L1); + expect(result).not.to.be.null; + expect(l2BalanceAfterDeposit - l2BalanceBeforeDeposit >= amount).to.be + .true; + expect(l1BalanceBeforeDeposit - l1BalanceAfterDeposit >= amount).to.be + .true; + }).timeout(30_000); + } else { + it('should deposit ETH to L2 network', async () => { + const amount = 7_000_000_000; + const l2BalanceBeforeDeposit = await wallet.getBalance(); + const l1BalanceBeforeDeposit = await wallet.getBalanceL1(); + const tx = await wallet.deposit({ + token: utils.ETH_ADDRESS, + to: await wallet.getAddress(), + amount: amount, + approveBaseERC20: true, + refundRecipient: await wallet.getAddress(), + }); + const result = await tx.wait(); + const l2BalanceAfterDeposit = await wallet.getBalance(); + const l1BalanceAfterDeposit = await wallet.getBalanceL1(); + expect(result).not.to.be.null; + expect(l2BalanceAfterDeposit - l2BalanceBeforeDeposit >= amount).to.be + .true; + expect(l1BalanceBeforeDeposit - l1BalanceAfterDeposit >= amount).to.be + .true; + }).timeout(20_000); + + it('should deposit base token to L2 network', async () => { + const amount = 5; + const baseTokenL1 = await wallet.getBaseToken(); + const l2BalanceBeforeDeposit = await wallet.getBalance(); + const l1BalanceBeforeDeposit = await wallet.getBalanceL1(baseTokenL1); + const tx = await wallet.deposit({ + token: baseTokenL1, + to: await wallet.getAddress(), + amount: amount, + approveERC20: true, + refundRecipient: await wallet.getAddress(), + }); + const result = await tx.wait(); + const l2BalanceAfterDeposit = await wallet.getBalance(); + const l1BalanceAfterDeposit = await wallet.getBalanceL1(baseTokenL1); + expect(result).not.to.be.null; + expect(l2BalanceAfterDeposit - l2BalanceBeforeDeposit >= amount).to.be + .true; + expect(l1BalanceBeforeDeposit - l1BalanceAfterDeposit >= 0n).to.be.true; + }).timeout(20_000); + + it('should deposit DAI to L2 network', async () => { + const amount = 5; + const l2DAI = await provider.l2TokenAddress(DAI_L1); + const l2BalanceBeforeDeposit = await wallet.getBalance(l2DAI); + const l1BalanceBeforeDeposit = await wallet.getBalanceL1(DAI_L1); + const tx = await wallet.deposit({ + token: DAI_L1, + to: await wallet.getAddress(), + amount: amount, + approveERC20: true, + approveBaseERC20: true, + refundRecipient: await wallet.getAddress(), + }); + const result = await tx.wait(); + const l2BalanceAfterDeposit = await wallet.getBalance(l2DAI); + const l1BalanceAfterDeposit = await wallet.getBalanceL1(DAI_L1); + expect(result).not.to.be.null; + expect(l2BalanceAfterDeposit - l2BalanceBeforeDeposit >= amount).to.be + .true; + expect(l1BalanceBeforeDeposit - l1BalanceAfterDeposit >= amount).to.be + .true; + }).timeout(20_000); + } + }); + + describe('#claimFailedDeposit()', () => { + if (IS_ETH_BASED) { + it('should claim failed deposit', async () => { + const response = await wallet.deposit({ + token: DAI_L1, + to: await wallet.getAddress(), + amount: 5, + approveERC20: true, + refundRecipient: await wallet.getAddress(), + l2GasLimit: 300_000, // make it fail because of low gas + }); + try { + await response.waitFinalize(); + } catch (error) { + const blockNumber = ( + await wallet + ._providerL2() + .getTransaction((error as any).receipt.hash) + ).blockNumber!; + // Now wait for block number to be executed. + let blockDetails: types.BlockDetails; + do { + // still not executed. + await utils.sleep(500); + blockDetails = await wallet + ._providerL2() + .getBlockDetails(blockNumber); + } while (!blockDetails || !blockDetails.executeTxHash); + const tx = await wallet.claimFailedDeposit( + (error as any).receipt.hash + ); + const result = await tx.wait(); + expect(result?.blockHash).to.be.not.null; + } + }).timeout(40_000); + + it('should throw an error when trying to claim successful deposit', async () => { + const response = await wallet.deposit({ + token: utils.LEGACY_ETH_ADDRESS, + to: await wallet.getAddress(), + amount: 7_000_000_000, + refundRecipient: await wallet.getAddress(), + }); + const tx = await response.waitFinalize(); + try { + await wallet.claimFailedDeposit(tx.hash); + } catch (e) { + expect((e as Error).message).to.be.equal( + 'Cannot claim successful deposit!' + ); + } + }).timeout(30_000); + } else { + it('should throw an error when trying to claim successful deposit', async () => { + const response = await wallet.deposit({ + token: await wallet.getBaseToken(), + to: await wallet.getAddress(), + amount: 5, + approveERC20: true, + refundRecipient: await wallet.getAddress(), + }); + const tx = await response.waitFinalize(); + try { + await wallet.claimFailedDeposit(tx.hash); + } catch (e) { + expect((e as Error).message).to.be.equal( + 'Cannot claim successful deposit!' + ); + } + }).timeout(30_000); + } + }); + + describe('#getFullRequiredDepositFee()', () => { + if (IS_ETH_BASED) { + it('should return a fee for ETH token deposit', async () => { + const result = await wallet.getFullRequiredDepositFee({ + token: utils.LEGACY_ETH_ADDRESS, + to: await wallet.getAddress(), + }); + expect(result.baseCost.valueOf() > 0n).to.be.true; + expect(result.l1GasLimit.valueOf() > 0n).to.be.true; + expect(result.l2GasLimit.valueOf() > 0n).to.be.true; + expect(result.maxPriorityFeePerGas!.valueOf() > 0n).to.be.true; + expect(result.maxFeePerGas!.valueOf() > 0n).to.be.true; }); - expect(result.baseCost.valueOf() > 0n).to.be.true; - expect(result.l1GasLimit.valueOf() > 0n).to.be.true; - expect(result.l2GasLimit.valueOf() > 0n).to.be.true; - expect(result.maxPriorityFeePerGas!.valueOf() > 0n).to.be.true; - expect(result.maxFeePerGas!.valueOf() > 0n).to.be.true; - }).timeout(10_000); - it('should throw an error when there is not enough balance for the deposit', async () => { - try { + it('should throw an error when there is not enough allowance to cover the deposit', async () => { + try { + await wallet.getFullRequiredDepositFee({ + token: DAI_L1, + to: await wallet.getAddress(), + }); + } catch (e) { + expect((e as Error).message).to.be.equal( + 'Not enough allowance to cover the deposit!' + ); + } + }).timeout(10_000); + + it('should return a fee for DAI token deposit', async () => { + const tx = await wallet.approveERC20(DAI_L1, 5); + await tx.wait(); + + const result = await wallet.getFullRequiredDepositFee({ + token: DAI_L1, + to: await wallet.getAddress(), + }); + expect(result.baseCost.valueOf() > 0n).to.be.true; + expect(result.l1GasLimit.valueOf() > 0n).to.be.true; + expect(result.l2GasLimit.valueOf() > 0n).to.be.true; + expect(result.maxPriorityFeePerGas!.valueOf() > 0n).to.be.true; + expect(result.maxFeePerGas!.valueOf() > 0n).to.be.true; + }).timeout(10_000); + + it('should throw an error when there is not enough balance for the deposit', async () => { + try { + const randomWallet = new Wallet( + ethers.Wallet.createRandom().privateKey, + provider, + ethProvider + ); + await randomWallet.getFullRequiredDepositFee({ + token: DAI_L1, + to: await wallet.getAddress(), + }); + } catch (e) { + expect((e as Error).message).to.include( + 'Not enough balance for deposit!' + ); + } + }).timeout(10_000); + } else { + it('should throw an error when there is not enough base token allowance to cover the deposit', async () => { + try { + await new Wallet( + ethers.Wallet.createRandom().privateKey, + provider, + ethProvider + ).getFullRequiredDepositFee({ + token: utils.LEGACY_ETH_ADDRESS, + to: await wallet.getAddress(), + }); + } catch (e) { + expect((e as Error).message).to.be.equal( + 'Not enough base token allowance to cover the deposit!' + ); + } + }).timeout(10_000); + + it('should return fee for ETH token deposit', async () => { + const token = utils.LEGACY_ETH_ADDRESS; + const approveParams = await wallet.getDepositAllowanceParams(token, 1); + + await ( + await wallet.approveERC20( + approveParams[0].token, + approveParams[0].allowance + ) + ).wait(); + + const result = await wallet.getFullRequiredDepositFee({ + token: token, + to: await wallet.getAddress(), + }); + expect(result.baseCost.valueOf() > 0n).to.be.true; + expect(result.l1GasLimit.valueOf() > 0n).to.be.true; + expect(result.l2GasLimit.valueOf() > 0n).to.be.true; + expect(result.maxPriorityFeePerGas!.valueOf() > 0n).to.be.true; + expect(result.maxFeePerGas!.valueOf() > 0n).to.be.true; + }).timeout(10_000); + + it('should return fee for base token deposit', async () => { + const token = await wallet.getBaseToken(); + const approveParams = await wallet.getDepositAllowanceParams(token, 1); + + await ( + await wallet.approveERC20( + approveParams[0].token, + approveParams[0].allowance + ) + ).wait(); + + const result = await wallet.getFullRequiredDepositFee({ + token: token, + to: await wallet.getAddress(), + }); + expect(result).not.to.be.null; + }).timeout(10_000); + + it('should return fee for DAI token deposit', async () => { + const token = DAI_L1; + const approveParams = await wallet.getDepositAllowanceParams(token, 1); + + await ( + await wallet.approveERC20( + approveParams[0].token, + approveParams[0].allowance + ) + ).wait(); + await ( + await wallet.approveERC20( + approveParams[1].token, + approveParams[1].allowance + ) + ).wait(); + + const result = await wallet.getFullRequiredDepositFee({ + token: token, + to: await wallet.getAddress(), + }); + expect(result.baseCost.valueOf() > 0n).to.be.true; + expect(result.l1GasLimit.valueOf() > 0n).to.be.true; + expect(result.l2GasLimit.valueOf() > 0n).to.be.true; + expect(result.maxPriorityFeePerGas!.valueOf() > 0n).to.be.true; + expect(result.maxFeePerGas!.valueOf() > 0n).to.be.true; + }).timeout(10_000); + + it('should throw an error when there is not enough token allowance to cover the deposit', async () => { + const token = DAI_L1; const randomWallet = new Wallet( ethers.Wallet.createRandom().privateKey, provider, ethProvider ); - await randomWallet.getFullRequiredDepositFee({ - token: DAI_L1, - to: await wallet.getAddress(), + + // mint base token to random wallet + const baseToken = ITestnetERC20Token__factory.connect( + await wallet.getBaseToken(), + wallet._signerL1() + ); + const baseTokenMintTx = await baseToken.mint( + await randomWallet.getAddress(), + ethers.parseEther('0.5') + ); + await baseTokenMintTx.wait(); + + // transfer ETH to random wallet so that base token approval tx can be performed + const transferTx = await new ethers.Wallet( + PRIVATE_KEY1, + ethProvider + ).sendTransaction({ + to: await randomWallet.getAddress(), + value: ethers.parseEther('0.1'), }); - } catch (e) { - expect((e as Error).message).to.include( - 'Not enough balance for deposit!' + await transferTx.wait(); + + const approveParams = await randomWallet.getDepositAllowanceParams( + token, + 1 ); - } - }).timeout(10_000); + // only approve base token + await ( + await randomWallet.approveERC20( + approveParams[0].token, + approveParams[0].allowance + ) + ).wait(); + + try { + await randomWallet.getFullRequiredDepositFee({ + token: token, + to: await wallet.getAddress(), + }); + } catch (e) { + expect((e as Error).message).to.be.equal( + 'Not enough token allowance to cover the deposit!' + ); + } + }).timeout(20_000); + } }); describe('#withdraw()', () => { it('should withdraw ETH to the L1 network', async () => { const amount = 7_000_000_000n; const l2BalanceBeforeWithdrawal = await wallet.getBalance(); + const token = IS_ETH_BASED + ? utils.ETH_ADDRESS_IN_CONTRACTS + : await wallet.l2TokenAddress(utils.ETH_ADDRESS_IN_CONTRACTS); const withdrawTx = await wallet.withdraw({ - token: utils.ETH_ADDRESS, + token: token, to: await wallet.getAddress(), amount: amount, }); @@ -761,19 +1246,19 @@ describe('Wallet', () => { const paymasterTokenBalanceBeforeWithdrawal = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const l2BalanceBeforeWithdrawal = await wallet.getBalance(); const l2ApprovalTokenBalanceBeforeWithdrawal = - await wallet.getBalance(TOKEN); + await wallet.getBalance(APPROVAL_TOKEN); const withdrawTx = await wallet.withdraw({ - token: utils.ETH_ADDRESS, + token: utils.LEGACY_ETH_ADDRESS, to: await wallet.getAddress(), amount: amount, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: minimalAllowance, innerInput: new Uint8Array(), }), @@ -791,11 +1276,11 @@ describe('Wallet', () => { const paymasterTokenBalanceAfterWithdrawal = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const l2BalanceAfterWithdrawal = await wallet.getBalance(); const l2ApprovalTokenBalanceAfterWithdrawal = - await wallet.getBalance(TOKEN); + await wallet.getBalance(APPROVAL_TOKEN); expect( paymasterBalanceBeforeWithdrawal - paymasterBalanceAfterWithdrawal >= 0n @@ -856,12 +1341,12 @@ describe('Wallet', () => { const paymasterTokenBalanceBeforeWithdrawal = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const l2BalanceBeforeWithdrawal = await wallet.getBalance(l2DAI); const l1BalanceBeforeWithdrawal = await wallet.getBalanceL1(DAI_L1); const l2ApprovalTokenBalanceBeforeWithdrawal = - await wallet.getBalance(TOKEN); + await wallet.getBalance(APPROVAL_TOKEN); const withdrawTx = await wallet.withdraw({ token: l2DAI, @@ -869,7 +1354,7 @@ describe('Wallet', () => { amount: amount, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: minimalAllowance, innerInput: new Uint8Array(), }), @@ -887,12 +1372,12 @@ describe('Wallet', () => { const paymasterTokenBalanceAfterWithdrawal = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const l2BalanceAfterWithdrawal = await wallet.getBalance(l2DAI); const l1BalanceAfterWithdrawal = await wallet.getBalanceL1(DAI_L1); const l2ApprovalTokenBalanceAfterWithdrawal = - await wallet.getBalance(TOKEN); + await wallet.getBalance(APPROVAL_TOKEN); expect( paymasterBalanceBeforeWithdrawal - paymasterBalanceAfterWithdrawal >= 0n @@ -917,60 +1402,138 @@ describe('Wallet', () => { }); describe('#getRequestExecuteTx()', () => { - it('should return a request execute transaction', async () => { - const result = await wallet.getRequestExecuteTx({ - contractAddress: await provider.getMainContractAddress(), - calldata: '0x', - l2Value: 7_000_000_000, + const amount = 7_000_000_000; + if (IS_ETH_BASED) { + it('should return request execute transaction', async () => { + const result = await wallet.getRequestExecuteTx({ + contractAddress: await provider.getBridgehubContractAddress(), + calldata: '0x', + l2Value: amount, + }); + expect(result).not.to.be.null; }); - expect(result).not.to.be.null; - }); + } else { + it('should return request execute transaction', async () => { + const result = await wallet.getRequestExecuteTx({ + contractAddress: await wallet.getAddress(), + calldata: '0x', + l2Value: amount, + overrides: {nonce: 0}, + }); + expect(result).not.to.be.null; + }); + } }); describe('#estimateGasRequestExecute()', () => { - it('should return a gas estimation for the request execute transaction', async () => { - const result = await wallet.estimateGasRequestExecute({ - contractAddress: await provider.getMainContractAddress(), - calldata: '0x', - l2Value: 7_000_000_000, + if (IS_ETH_BASED) { + it('should return gas estimation for request execute transaction', async () => { + const result = await wallet.estimateGasRequestExecute({ + contractAddress: await provider.getBridgehubContractAddress(), + calldata: '0x', + l2Value: 7_000_000_000, + }); + expect(result > 0n).to.be.true; }); - expect(result > 0n).to.be.true; - }); + } else { + it('should return gas estimation for request execute transaction', async () => { + const tx = { + contractAddress: await wallet.getAddress(), + calldata: '0x', + l2Value: 7_000_000_000, + overrides: {value: 0}, + }; + + const approveParams = await wallet.getRequestExecuteAllowanceParams(tx); + await ( + await wallet.approveERC20( + approveParams.token, + approveParams.allowance + ) + ).wait(); + + const result = await wallet.estimateGasRequestExecute(tx); + expect(result > 0n).to.be.true; + }).timeout(10_000); + } }); describe('#requestExecute()', () => { - it('should request transaction execution on the L2 network', async () => { - const amount = 7_000_000_000n; - const l2BalanceBeforeExecution = await wallet.getBalance(); - const l1BalanceBeforeExecution = await wallet.getBalanceL1(); - const tx = await wallet.requestExecute({ - contractAddress: await provider.getMainContractAddress(), - calldata: '0x', - l2Value: amount, - l2GasLimit: 900_000, - }); - const result = await tx.wait(); - const l2BalanceAfterExecution = await wallet.getBalance(); - const l1BalanceAfterExecution = await wallet.getBalanceL1(); - expect(result).not.to.be.null; - expect(l2BalanceAfterExecution - l2BalanceBeforeExecution >= amount).to.be - .true; - expect(l1BalanceBeforeExecution - l1BalanceAfterExecution >= amount).to.be - .true; - }).timeout(10_000); + if (IS_ETH_BASED) { + it('should request transaction execution on L2 network', async () => { + const amount = 7_000_000_000; + const l2BalanceBeforeExecution = await wallet.getBalance(); + const l1BalanceBeforeExecution = await wallet.getBalanceL1(); + const tx = await wallet.requestExecute({ + contractAddress: await provider.getBridgehubContractAddress(), + calldata: '0x', + l2Value: amount, + l2GasLimit: 900_000, + }); + const result = await tx.wait(); + const l2BalanceAfterExecution = await wallet.getBalance(); + const l1BalanceAfterExecution = await wallet.getBalanceL1(); + expect(result).not.to.be.null; + expect(l2BalanceAfterExecution - l2BalanceBeforeExecution >= amount).to + .be.true; + expect(l1BalanceBeforeExecution - l1BalanceAfterExecution >= amount).to + .be.true; + }).timeout(10_000); + } else { + it('should request transaction execution on L2 network', async () => { + const amount = 7_000_000_000; + const request = { + contractAddress: await wallet.getAddress(), + calldata: '0x', + l2Value: amount, + l2GasLimit: 1_319_957n, + operatorTip: 0, + gasPerPubdataByte: 800, + refundRecipient: await wallet.getAddress(), + overrides: { + maxFeePerGas: 1_000_000_010n, + maxPriorityFeePerGas: 1_000_000_000n, + gasLimit: 238_654n, + value: 0, + }, + }; + + const approveParams = + await wallet.getRequestExecuteAllowanceParams(request); + await ( + await wallet.approveERC20( + approveParams.token, + approveParams.allowance + ) + ).wait(); + + const l2BalanceBeforeExecution = await wallet.getBalance(); + const l1BalanceBeforeExecution = await wallet.getBalanceL1(); + + const tx = await wallet.requestExecute(request); + const result = await tx.wait(); + const l2BalanceAfterExecution = await wallet.getBalance(); + const l1BalanceAfterExecution = await wallet.getBalanceL1(); + expect(result).not.to.be.null; + expect(l2BalanceAfterExecution - l2BalanceBeforeExecution >= amount).to + .be.true; + expect(l1BalanceBeforeExecution - l1BalanceAfterExecution >= amount).to + .be.true; + }).timeout(10_000); + } }); describe('#transfer()', () => { it('should transfer ETH', async () => { const amount = 7_000_000_000n; - const balanceBeforeTransfer = await provider.getBalance(RECEIVER); + const balanceBeforeTransfer = await provider.getBalance(ADDRESS2); const tx = await wallet.transfer({ - token: utils.ETH_ADDRESS, - to: RECEIVER, + token: utils.LEGACY_ETH_ADDRESS, + to: ADDRESS2, amount: amount, }); const result = await tx.wait(); - const balanceAfterTransfer = await provider.getBalance(RECEIVER); + const balanceAfterTransfer = await provider.getBalance(ADDRESS2); expect(result).not.to.be.null; expect(balanceAfterTransfer - balanceBeforeTransfer).to.be.equal(amount); }).timeout(25_000); @@ -984,20 +1547,20 @@ describe('Wallet', () => { const paymasterTokenBalanceBeforeTransfer = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const senderBalanceBeforeTransfer = await wallet.getBalance(); const senderApprovalTokenBalanceBeforeTransfer = - await wallet.getBalance(TOKEN); - const receiverBalanceBeforeTransfer = await provider.getBalance(RECEIVER); + await wallet.getBalance(APPROVAL_TOKEN); + const receiverBalanceBeforeTransfer = await provider.getBalance(ADDRESS2); const tx = await wallet.transfer({ - token: utils.ETH_ADDRESS, - to: RECEIVER, + token: utils.LEGACY_ETH_ADDRESS, + to: ADDRESS2, amount: amount, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: minimalAllowance, innerInput: new Uint8Array(), }), @@ -1009,12 +1572,12 @@ describe('Wallet', () => { const paymasterTokenBalanceAfterTransfer = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const senderBalanceAfterTransfer = await wallet.getBalance(); const senderApprovalTokenBalanceAfterTransfer = - await wallet.getBalance(TOKEN); - const receiverBalanceAfterTransfer = await provider.getBalance(RECEIVER); + await wallet.getBalance(APPROVAL_TOKEN); + const receiverBalanceAfterTransfer = await provider.getBalance(ADDRESS2); expect( paymasterBalanceBeforeTransfer - paymasterBalanceAfterTransfer >= 0n @@ -1041,18 +1604,18 @@ describe('Wallet', () => { const amount = 5n; const l2DAI = await provider.l2TokenAddress(DAI_L1); const balanceBeforeTransfer = await provider.getBalance( - RECEIVER, + ADDRESS2, 'latest', l2DAI ); const tx = await wallet.transfer({ token: l2DAI, - to: RECEIVER, + to: ADDRESS2, amount: amount, }); const result = await tx.wait(); const balanceAfterTransfer = await provider.getBalance( - RECEIVER, + ADDRESS2, 'latest', l2DAI ); @@ -1070,24 +1633,24 @@ describe('Wallet', () => { const paymasterTokenBalanceBeforeTransfer = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const senderBalanceBeforeTransfer = await wallet.getBalance(l2DAI); const senderApprovalTokenBalanceBeforeTransfer = - await wallet.getBalance(TOKEN); + await wallet.getBalance(APPROVAL_TOKEN); const receiverBalanceBeforeTransfer = await provider.getBalance( - RECEIVER, + ADDRESS2, 'latest', l2DAI ); const tx = await wallet.transfer({ token: l2DAI, - to: RECEIVER, + to: ADDRESS2, amount: amount, paymasterParams: utils.getPaymasterParams(PAYMASTER, { type: 'ApprovalBased', - token: TOKEN, + token: APPROVAL_TOKEN, minimalAllowance: minimalAllowance, innerInput: new Uint8Array(), }), @@ -1099,13 +1662,13 @@ describe('Wallet', () => { const paymasterTokenBalanceAfterTransfer = await provider.getBalance( PAYMASTER, 'latest', - TOKEN + APPROVAL_TOKEN ); const senderBalanceAfterTransfer = await wallet.getBalance(l2DAI); const senderApprovalTokenBalanceAfterTransfer = - await wallet.getBalance(TOKEN); + await wallet.getBalance(APPROVAL_TOKEN); const receiverBalanceAfterTransfer = await provider.getBalance( - RECEIVER, + ADDRESS2, 'latest', l2DAI ); @@ -1130,13 +1693,31 @@ describe('Wallet', () => { receiverBalanceAfterTransfer - receiverBalanceBeforeTransfer ).to.be.equal(amount); }).timeout(25_000); + + if (!IS_ETH_BASED) { + it('should transfer base token', async () => { + const amount = 7_000_000_000n; + const balanceBeforeTransfer = await provider.getBalance(ADDRESS2); + const tx = await wallet.transfer({ + token: await wallet.getBaseToken(), + to: ADDRESS2, + amount: amount, + }); + const result = await tx.wait(); + const balanceAfterTransfer = await provider.getBalance(ADDRESS2); + expect(result).not.to.be.null; + expect(balanceAfterTransfer - balanceBeforeTransfer).to.be.equal( + amount + ); + }).timeout(25_000); + } }); describe('#signTransaction()', () => { it('should return a signed type EIP1559 transaction', async () => { const result = await wallet.signTransaction({ type: 2, - to: RECEIVER, + to: ADDRESS2, value: 7_000_000_000n, }); expect(result).not.to.be.null; @@ -1145,7 +1726,7 @@ describe('Wallet', () => { it('should return a signed EIP712 transaction', async () => { const result = await wallet.signTransaction({ type: utils.EIP712_TX_TYPE, - to: RECEIVER, + to: ADDRESS2, value: ethers.parseEther('1'), }); expect(result).not.to.be.null; @@ -1155,8 +1736,8 @@ describe('Wallet', () => { try { await wallet.signTransaction({ type: utils.EIP712_TX_TYPE, - from: RECEIVER, - to: RECEIVER, + from: ADDRESS2, + to: ADDRESS2, value: 7_000_000_000, }); } catch (e) { diff --git a/tests/setup.ts b/tests/setup.ts index bfcb6389..aacfe553 100644 --- a/tests/setup.ts +++ b/tests/setup.ts @@ -7,8 +7,8 @@ import { utils, } from '../src'; import {ethers, Typed} from 'ethers'; +import {ITestnetERC20Token__factory} from '../src/typechain'; -import TokensL1 from './files/tokens.json'; import Token from './files/Token.json'; import Paymaster from './files/Paymaster.json'; @@ -20,6 +20,8 @@ const ethProvider = ethers.getDefaultProvider('http://127.0.0.1:8545'); const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); +const DAI_L1 = '0x70a0F165d6f8054d0d0CF8dFd4DD2005f0AF6B55'; + const SALT = '0x293328ad84b118194c65a0dc0defdb6483740d3163fd99b260907e15f2e2f642'; const TOKEN = '0x841c43Fa5d8fFfdB9efE3358906f7578d8700Dd4'; // deployed by using create2 and SALT @@ -80,27 +82,93 @@ async function deployPaymasterAndToken(): Promise<{ return {token: tokenAddress, paymaster: paymasterAddress}; } -// Creates token on L2 by depositing -async function createTokenL2(l1TokenAddress: string): Promise { +/* +Mints tokens on L1 in case L2 is non-ETH based chain. +It mints based token, provided alternative tokens (different from base token) and wETH. +*/ +async function mintTokensOnL1(l1Token: string) { + if (l1Token !== utils.ETH_ADDRESS_IN_CONTRACTS) { + const token = ITestnetERC20Token__factory.connect( + l1Token, + wallet._signerL1() + ); + const mintTx = await token.mint( + await wallet.getAddress(), + ethers.parseEther('20000') + ); + await mintTx.wait(); + } +} + +/* +Send base token to L2 in case L2 in non-ETH base chain. +*/ +async function sendTokenToL2(l1TokenAddress: string) { const priorityOpResponse = await wallet.deposit({ token: l1TokenAddress, to: await wallet.getAddress(), - amount: 100, + amount: ethers.parseEther('10000'), approveERC20: true, + approveBaseERC20: true, refundRecipient: await wallet.getAddress(), }); - await priorityOpResponse.waitFinalize(); - return await wallet.l2TokenAddress(l1TokenAddress); + const receipt = await priorityOpResponse.waitFinalize(); + console.log(`Send funds tx: ${receipt.hash}`); } -/* -Deploy token to the L2 network through deposit transaction. -Deploy approval token and it's paymaster. - */ async function main() { - console.log('===== Depositing DAI to L2 ====='); - const l2DAI = await createTokenL2(TokensL1[0].address); - console.log(`L2 DAI address: ${l2DAI}`); + const baseToken = await wallet.getBaseToken(); + console.log(`Wallet address: ${await wallet.getAddress()}`); + console.log(`Base token L1: ${baseToken}`); + + console.log( + `L1 base token balance before: ${await wallet.getBalanceL1(baseToken)}` + ); + console.log(`L2 base token balance before: ${await wallet.getBalance()}`); + + await mintTokensOnL1(baseToken); + await sendTokenToL2(baseToken); + + console.log( + `L1 base token balance after: ${await wallet.getBalanceL1(baseToken)}` + ); + console.log(`L2 base token balance after: ${await wallet.getBalance()} \n`); + + if (baseToken !== utils.ETH_ADDRESS_IN_CONTRACTS) { + const l2EthAddress = await wallet.l2TokenAddress( + utils.ETH_ADDRESS_IN_CONTRACTS + ); + console.log(`ETH L1: ${utils.ETH_ADDRESS_IN_CONTRACTS}`); + console.log(`ETH L2: ${l2EthAddress}`); + + console.log(`L1 ETH balance before: ${await wallet.getBalanceL1()}`); + console.log( + `L2 ETH balance before: ${await wallet.getBalance(l2EthAddress)}` + ); + + await mintTokensOnL1(utils.ETH_ADDRESS_IN_CONTRACTS); + await sendTokenToL2(utils.ETH_ADDRESS_IN_CONTRACTS); + + console.log(`L1 ETH balance after: ${await wallet.getBalanceL1()}`); + console.log( + `L2 ETH balance after: ${await wallet.getBalance(l2EthAddress)}\n` + ); + } + + const l2DAIAddress = await wallet.l2TokenAddress(DAI_L1); + console.log(`DAI L1: ${DAI_L1}`); + console.log(`DAI L2: ${l2DAIAddress}`); + + console.log(`L1 DAI balance before: ${await wallet.getBalanceL1(DAI_L1)}`); + console.log( + `L2 DAI balance before: ${await wallet.getBalance(l2DAIAddress)}` + ); + + await mintTokensOnL1(DAI_L1); + await sendTokenToL2(DAI_L1); + + console.log(`L1 DAI balance after: ${await wallet.getBalanceL1(DAI_L1)}`); + console.log(`L2 DAI balance after: ${await wallet.getBalance(l2DAIAddress)}`); console.log('===== Deploying token and paymaster ====='); const {token, paymaster} = await deployPaymasterAndToken(); diff --git a/tests/unit/signer.test.ts b/tests/unit/signer.test.ts index e925984f..c7350849 100644 --- a/tests/unit/signer.test.ts +++ b/tests/unit/signer.test.ts @@ -2,19 +2,17 @@ import * as chai from 'chai'; import '../custom-matchers'; import {utils, EIP712Signer} from '../../src'; import {ethers} from 'ethers'; +import {ADDRESS1, ADDRESS2} from '../utils'; const {expect} = chai; describe('EIP712Signer', () => { - const ADDRESS = '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049'; - const RECEIVER = '0xa61464658AfeAf65CccaaFD3a512b69A83B77618'; - describe('#getSignInput()', () => { it('should return a populated transaction', async () => { const tx = { txType: utils.EIP712_TX_TYPE, - from: ADDRESS, - to: RECEIVER, + from: ADDRESS1, + to: ADDRESS2, gasLimit: 21_000n, gasPerPubdataByteLimit: utils.DEFAULT_GAS_PER_PUBDATA_LIMIT, maxFeePerGas: 250_000_000n, @@ -29,9 +27,9 @@ describe('EIP712Signer', () => { const result = EIP712Signer.getSignInput({ type: utils.EIP712_TX_TYPE, - to: RECEIVER, + to: ADDRESS2, value: 7_000_000n, - from: ADDRESS, + from: ADDRESS1, nonce: 0, chainId: 270n, gasPrice: 250_000_000n, @@ -44,8 +42,8 @@ describe('EIP712Signer', () => { it('should return a populated transaction with default values', async () => { const tx = { txType: utils.EIP712_TX_TYPE, - from: ADDRESS, - to: RECEIVER, + from: ADDRESS1, + to: ADDRESS2, gasLimit: 0n, gasPerPubdataByteLimit: utils.DEFAULT_GAS_PER_PUBDATA_LIMIT, maxFeePerGas: 0n, @@ -60,8 +58,8 @@ describe('EIP712Signer', () => { const result = EIP712Signer.getSignInput({ type: utils.EIP712_TX_TYPE, - to: RECEIVER, - from: ADDRESS, + to: ADDRESS2, + from: ADDRESS1, }); expect(result).to.be.deep.equal(tx); }); diff --git a/tests/unit/smart-account.test.ts b/tests/unit/smart-account.test.ts index 280a2b63..7fbdbf7f 100644 --- a/tests/unit/smart-account.test.ts +++ b/tests/unit/smart-account.test.ts @@ -9,26 +9,22 @@ import { signPayloadWithMultipleECDSA, } from '../../src/smart-account-utils'; import {TypedDataEncoder, hashMessage} from 'ethers'; +import {ADDRESS1, PRIVATE_KEY1, ADDRESS2} from '../utils'; const {expect} = chai; describe('signPayloadWithECDSA()', () => { - const ADDRESS = '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049'; - const PRIVATE_KEY = - '0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110'; - const RECEIVER = '0xa61464658AfeAf65CccaaFD3a512b69A83B77618'; - it('should return signature by signing EIP712 transaction hash', async () => { const tx: TransactionRequest = { chainId: 270, - from: ADDRESS, - to: RECEIVER, + from: ADDRESS1, + to: ADDRESS2, value: 7_000_000_000, }; const txHash = EIP712Signer.getSignedDigest(tx); - const result = await signPayloadWithECDSA(txHash, PRIVATE_KEY); + const result = await signPayloadWithECDSA(txHash, PRIVATE_KEY1); expect(result).to.be.equal( '0x89905d36a3cdde117445d6c58627061a53f09cf0535d73719d82d4d96fe332541167e2e3d38ce3cb2751a0203eff2a71f55ad45dc91623587f5480ec1883281b1b' ); @@ -38,7 +34,7 @@ describe('signPayloadWithECDSA()', () => { const message = 'Hello World!'; const messageHash = hashMessage(message); - const result = await signPayloadWithECDSA(messageHash, PRIVATE_KEY); + const result = await signPayloadWithECDSA(messageHash, PRIVATE_KEY1); expect(result).to.be.equal( '0x7c15eb760c394b0ca49496e71d841378d8bfd4f9fb67e930eb5531485329ab7c67068d1f8ef4b480ec327214ee6ed203687e3fbe74b92367b259281e340d16fd1c' ); @@ -55,7 +51,7 @@ describe('signPayloadWithECDSA()', () => { }, {name: 'John', age: 30} ); - const result = await signPayloadWithECDSA(typedDataHash, PRIVATE_KEY); + const result = await signPayloadWithECDSA(typedDataHash, PRIVATE_KEY1); expect(result).to.be.equal( '0xbcaf0673c0c2b0e120165d207d42281d0c6e85f0a7f6b8044b0578a91cf5bda66b4aeb62aca4ae17012a38d71c9943e27285792fa7d788d848f849e3ea2e614b1b' ); @@ -124,11 +120,6 @@ describe('signPayloadWithMultipleECDSA()', () => { }); describe('populateTransaction()', () => { - const ADDRESS = '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049'; - const PRIVATE_KEY = - '0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110'; - const RECEIVER = '0xa61464658AfeAf65CccaaFD3a512b69A83B77618'; - const provider = Provider.getDefaultProvider(types.Network.Localhost); it('should populate `tx.from` to address derived from private key if it not set', async () => { @@ -139,7 +130,7 @@ describe('populateTransaction()', () => { type: 113, data: '0x', gasPrice: 100_000_000n, - gasLimit: 157_459n, + gasLimit: 156_726n, customData: { gasPerPubdata: 50_000, factoryDeps: [], @@ -150,10 +141,10 @@ describe('populateTransaction()', () => { const result = await populateTransactionECDSA( { chainId: 270, - to: RECEIVER, + to: ADDRESS2, value: 7_000_000_000, }, - PRIVATE_KEY, + PRIVATE_KEY1, provider ); expect(result).to.be.deepEqualExcluding(tx, ['nonce']); @@ -162,13 +153,13 @@ describe('populateTransaction()', () => { it('should throw an error when provider is not set', async () => { const tx: TransactionRequest = { chainId: 270, - from: ADDRESS, - to: RECEIVER, + from: ADDRESS1, + to: ADDRESS2, value: 7_000_000_000, }; try { - await populateTransactionECDSA(tx, PRIVATE_KEY); + await populateTransactionECDSA(tx, PRIVATE_KEY1); } catch (error) { expect((error as Error).message).to.be.equal( 'Provider is required but is not provided!' @@ -178,21 +169,16 @@ describe('populateTransaction()', () => { }); describe('populateTransactionMultisig()', () => { - const ADDRESS = '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049'; - const PRIVATE_KEY = - '0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110'; - const RECEIVER = '0xa61464658AfeAf65CccaaFD3a512b69A83B77618'; - it('should throw an error when multiple keys are not provided', async () => { const tx: TransactionRequest = { chainId: 270, - from: ADDRESS, - to: RECEIVER, + from: ADDRESS1, + to: ADDRESS2, value: 7_000_000_000, }; try { - await populateTransactionMultisigECDSA(tx, PRIVATE_KEY); + await populateTransactionMultisigECDSA(tx, PRIVATE_KEY1); } catch (error) { expect((error as Error).message).to.be.equal( 'Multiple keys are required to build the transaction!' diff --git a/tests/unit/utils.test.ts b/tests/unit/utils.test.ts index a88aeda9..17f74760 100644 --- a/tests/unit/utils.test.ts +++ b/tests/unit/utils.test.ts @@ -1,37 +1,40 @@ import {expect} from 'chai'; import {types, utils} from '../../src'; import {ethers} from 'ethers'; +import {ADDRESS1, ADDRESS2} from '../utils'; describe('utils', () => { - const ADDRESS = '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049'; - const RECEIVER = '0xa61464658AfeAf65CccaaFD3a512b69A83B77618'; - describe('#getHashedL2ToL1Msg()', () => { it('should return a hashed L2 to L1 message', async () => { const withdrawETHMessage = '0x6c0960f936615cf349d7f6344891b1e7ca7c72883f5dc04900000000000000000000000000000000000000000000000000000001a13b8600'; const withdrawETHMessageHash = '0x521bd25904766c83fe868d6a29cbffa011afd8a1754f6c9a52b053b693e42f18'; - const result = utils.getHashedL2ToL1Msg(ADDRESS, withdrawETHMessage, 0); + const result = utils.getHashedL2ToL1Msg(ADDRESS1, withdrawETHMessage, 0); expect(result).to.be.equal(withdrawETHMessageHash); }); }); describe('#isETH()', () => { + it('should return true for legacy L1 ETH address', async () => { + const result = utils.isETH(utils.LEGACY_ETH_ADDRESS); + expect(result).to.be.true; + }); + it('should return true for L1 ETH address', async () => { - const result = utils.isETH(utils.ETH_ADDRESS); + const result = utils.isETH(utils.ETH_ADDRESS_IN_CONTRACTS); expect(result).to.be.true; }); it('should return true for L2 ETH address', async () => { - const result = utils.isETH(utils.L2_ETH_TOKEN_ADDRESS); + const result = utils.isETH(utils.L2_BASE_TOKEN_ADDRESS); expect(result).to.be.true; }); }); describe('#createAddress()', () => { it('should return a correct address', async () => { - const address = utils.createAddress(ADDRESS, 1); + const address = utils.createAddress(ADDRESS1, 1); expect(address).to.be.equal('0x4B5DF730c2e6b28E17013A1485E5d9BC41Efe021'); }); }); @@ -39,7 +42,7 @@ describe('utils', () => { describe('#create2Address()', () => { it('should return a correct address', async () => { const address = utils.create2Address( - ADDRESS, + ADDRESS1, '0x010001cb6a6e8d5f6829522f19fa9568660e0a9cd53b2e8be4deb0a679452e41', '0x01', '0x01' @@ -132,7 +135,7 @@ describe('utils', () => { try { utils.serializeEip712({ chainId: 270, - from: ADDRESS, + from: ADDRESS1, customData: { customSignature: '', }, @@ -149,7 +152,7 @@ describe('utils', () => { '0x71ea8080808080808082010e808082010e9436615cf349d7f6344891b1e7ca7c72883f5dc04982c350c080c0'; const result = utils.serializeEip712({ chainId: 270, - from: ADDRESS, + from: ADDRESS1, }); expect(result).to.be.equal(tx); }); @@ -163,8 +166,8 @@ describe('utils', () => { const result = utils.serializeEip712( { chainId: 270, - from: ADDRESS, - to: RECEIVER, + from: ADDRESS1, + to: ADDRESS2, value: 1_000_000, }, signature @@ -236,11 +239,11 @@ describe('utils', () => { maxPriorityFeePerGas: 0n, maxFeePerGas: 0n, gasLimit: 0n, - to: RECEIVER, + to: ADDRESS2, value: 1_000_000n, data: '0x', chainId: 270n, - from: ADDRESS, + from: ADDRESS1, customData: { gasPerPubdata: 50_000n, factoryDeps: [], @@ -263,11 +266,11 @@ describe('utils', () => { maxPriorityFeePerGas: 0n, maxFeePerGas: 0n, gasLimit: 0n, - to: RECEIVER, + to: ADDRESS2, value: 0n, data: '0x', chainId: 270n, - from: ADDRESS, + from: ADDRESS1, customData: { gasPerPubdata: 50_000n, factoryDeps: [], diff --git a/tests/utils.ts b/tests/utils.ts new file mode 100644 index 00000000..0a72a7d3 --- /dev/null +++ b/tests/utils.ts @@ -0,0 +1,13 @@ +export const ADDRESS1 = '0x36615Cf349d7F6344891B1e7CA7C72883F5dc049'; +export const PRIVATE_KEY1 = + '0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110'; +export const MNEMONIC1 = + 'stuff slice staff easily soup parent arm payment cotton trade scatter struggle'; +export const ADDRESS2 = '0xa61464658AfeAf65CccaaFD3a512b69A83B77618'; +export const PRIVATE_KEY2 = + '0xac1e735be8536c6534bb4f17f06f6afc73b2b5ba84ac2cfb12f7461b20c0bbe3'; +export const DAI_L1 = '0x70a0F165d6f8054d0d0CF8dFd4DD2005f0AF6B55'; +export const APPROVAL_TOKEN = '0x841c43Fa5d8fFfdB9efE3358906f7578d8700Dd4'; // Crown token +export const PAYMASTER = '0xa222f0c183AFA73a8Bc1AFb48D34C88c9Bf7A174'; // Crown token paymaster + +export const IS_ETH_BASED = true;