@imtbl/sdk 0.4.1-alpha → 0.4.2-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,7 +4,7 @@ import $7v2Z6$metamaskdetectprovider from '@metamask/detect-provider';
4
4
  import { Token, TradeType, CurrencyAmount, Percent } from '@uniswap/sdk-core';
5
5
  import assert from 'assert';
6
6
  import { BigNumber as BigNumber$1 } from '@ethersproject/bignumber';
7
- import { FeeAmount, Route, SwapQuoter, Pool, Trade } from '@uniswap/v3-sdk';
7
+ import { FeeAmount, Route, SwapQuoter, Pool, Trade, toHex as toHex$1, encodeRouteToPath } from '@uniswap/v3-sdk';
8
8
  import JSBI from 'jsbi';
9
9
  import { keccak256 as keccak256$1 } from '@ethersproject/solidity';
10
10
  import { SwapRouter } from '@uniswap/router-sdk';
@@ -6034,6 +6034,13 @@ function arrayifyInteger(value) {
6034
6034
  }
6035
6035
  return result;
6036
6036
  }
6037
+ function unarrayifyInteger(data, offset, length) {
6038
+ let result = 0;
6039
+ for (let i = 0; i < length; i++) {
6040
+ result = (result * 256) + data[offset + i];
6041
+ }
6042
+ return result;
6043
+ }
6037
6044
  function _encode(object) {
6038
6045
  if (Array.isArray(object)) {
6039
6046
  let payload = [];
@@ -6066,6 +6073,72 @@ function _encode(object) {
6066
6073
  function encode(object) {
6067
6074
  return hexlify(_encode(object));
6068
6075
  }
6076
+ function _decodeChildren(data, offset, childOffset, length) {
6077
+ const result = [];
6078
+ while (childOffset < offset + 1 + length) {
6079
+ const decoded = _decode(data, childOffset);
6080
+ result.push(decoded.result);
6081
+ childOffset += decoded.consumed;
6082
+ if (childOffset > offset + 1 + length) {
6083
+ logger$9.throwError("child data too short", Logger.errors.BUFFER_OVERRUN, {});
6084
+ }
6085
+ }
6086
+ return { consumed: (1 + length), result: result };
6087
+ }
6088
+ // returns { consumed: number, result: Object }
6089
+ function _decode(data, offset) {
6090
+ if (data.length === 0) {
6091
+ logger$9.throwError("data too short", Logger.errors.BUFFER_OVERRUN, {});
6092
+ }
6093
+ // Array with extra length prefix
6094
+ if (data[offset] >= 0xf8) {
6095
+ const lengthLength = data[offset] - 0xf7;
6096
+ if (offset + 1 + lengthLength > data.length) {
6097
+ logger$9.throwError("data short segment too short", Logger.errors.BUFFER_OVERRUN, {});
6098
+ }
6099
+ const length = unarrayifyInteger(data, offset + 1, lengthLength);
6100
+ if (offset + 1 + lengthLength + length > data.length) {
6101
+ logger$9.throwError("data long segment too short", Logger.errors.BUFFER_OVERRUN, {});
6102
+ }
6103
+ return _decodeChildren(data, offset, offset + 1 + lengthLength, lengthLength + length);
6104
+ }
6105
+ else if (data[offset] >= 0xc0) {
6106
+ const length = data[offset] - 0xc0;
6107
+ if (offset + 1 + length > data.length) {
6108
+ logger$9.throwError("data array too short", Logger.errors.BUFFER_OVERRUN, {});
6109
+ }
6110
+ return _decodeChildren(data, offset, offset + 1, length);
6111
+ }
6112
+ else if (data[offset] >= 0xb8) {
6113
+ const lengthLength = data[offset] - 0xb7;
6114
+ if (offset + 1 + lengthLength > data.length) {
6115
+ logger$9.throwError("data array too short", Logger.errors.BUFFER_OVERRUN, {});
6116
+ }
6117
+ const length = unarrayifyInteger(data, offset + 1, lengthLength);
6118
+ if (offset + 1 + lengthLength + length > data.length) {
6119
+ logger$9.throwError("data array too short", Logger.errors.BUFFER_OVERRUN, {});
6120
+ }
6121
+ const result = hexlify(data.slice(offset + 1 + lengthLength, offset + 1 + lengthLength + length));
6122
+ return { consumed: (1 + lengthLength + length), result: result };
6123
+ }
6124
+ else if (data[offset] >= 0x80) {
6125
+ const length = data[offset] - 0x80;
6126
+ if (offset + 1 + length > data.length) {
6127
+ logger$9.throwError("data too short", Logger.errors.BUFFER_OVERRUN, {});
6128
+ }
6129
+ const result = hexlify(data.slice(offset + 1, offset + 1 + length));
6130
+ return { consumed: (1 + length), result: result };
6131
+ }
6132
+ return { consumed: 1, result: hexlify(data[offset]) };
6133
+ }
6134
+ function decode(data) {
6135
+ const bytes = arrayify(data);
6136
+ const decoded = _decode(bytes, 0);
6137
+ if (decoded.consumed !== bytes.length) {
6138
+ logger$9.throwArgumentError("invalid rlp data", "data", data);
6139
+ }
6140
+ return decoded.result;
6141
+ }
6069
6142
 
6070
6143
  const version$5 = "address/5.7.0";
6071
6144
 
@@ -8932,6 +9005,19 @@ const ROOT_ERC20_PREDICATE = [
8932
9005
  stateMutability: 'view',
8933
9006
  type: 'function',
8934
9007
  },
9008
+ {
9009
+ inputs: [],
9010
+ name: 'NATIVE_TOKEN',
9011
+ outputs: [
9012
+ {
9013
+ internalType: 'address',
9014
+ name: '',
9015
+ type: 'address',
9016
+ },
9017
+ ],
9018
+ stateMutability: 'view',
9019
+ type: 'function',
9020
+ },
8935
9021
  {
8936
9022
  inputs: [],
8937
9023
  name: 'WITHDRAW_SIG',
@@ -8989,6 +9075,19 @@ const ROOT_ERC20_PREDICATE = [
8989
9075
  stateMutability: 'nonpayable',
8990
9076
  type: 'function',
8991
9077
  },
9078
+ {
9079
+ inputs: [
9080
+ {
9081
+ internalType: 'address',
9082
+ name: 'receiver',
9083
+ type: 'address',
9084
+ },
9085
+ ],
9086
+ name: 'depositNativeTo',
9087
+ outputs: [],
9088
+ stateMutability: 'payable',
9089
+ type: 'function',
9090
+ },
8992
9091
  {
8993
9092
  inputs: [
8994
9093
  {
@@ -9067,7 +9166,13 @@ const ROOT_ERC20_PREDICATE = [
9067
9166
  },
9068
9167
  ],
9069
9168
  name: 'mapToken',
9070
- outputs: [],
9169
+ outputs: [
9170
+ {
9171
+ internalType: 'address',
9172
+ name: '',
9173
+ type: 'address',
9174
+ },
9175
+ ],
9071
9176
  stateMutability: 'nonpayable',
9072
9177
  type: 'function',
9073
9178
  },
@@ -9362,6 +9467,8 @@ var BridgeErrorType;
9362
9467
  BridgeErrorType["INTERNAL_ERROR"] = "INTERNAL_ERROR";
9363
9468
  BridgeErrorType["PROVIDER_ERROR"] = "PROVIDER_ERROR";
9364
9469
  BridgeErrorType["TRANSACTION_REVERTED"] = "TRANSACTION_REVERTED";
9470
+ BridgeErrorType["INVALID_TOKEN"] = "INVALID_TOKEN";
9471
+ BridgeErrorType["INVALID_TRANSACTION"] = "INVALID_TRANSACTION";
9365
9472
  })(BridgeErrorType || (BridgeErrorType = {}));
9366
9473
  /**
9367
9474
  * Represents a custom error for bridge operations.
@@ -9389,14 +9496,18 @@ class BridgeError extends Error {
9389
9496
  * @template T - The type of the value that the Promise resolves to.
9390
9497
  * @param {() => Promise<T>} fn - The function to wrap with error handling.
9391
9498
  * @param {BridgeErrorType} customErrorType - The custom error type to use for the error.
9499
+ * @param {string} [details] - Additional details to add to the error message.
9392
9500
  * @returns {Promise<T>} The result of the wrapped function or a rejected promise with a BridgeError.
9393
9501
  */
9394
- const withBridgeError = async (fn, customErrorType) => {
9502
+ const withBridgeError = async (fn, customErrorType, details) => {
9395
9503
  try {
9396
9504
  return await fn();
9397
9505
  }
9398
9506
  catch (error) {
9399
- const errorMessage = `${customErrorType}: ${error.message}` || 'UnknownError';
9507
+ let errorMessage = `${customErrorType}: ${error.message}` || 'UnknownError';
9508
+ if (details) {
9509
+ errorMessage = `${details}: ${errorMessage}`;
9510
+ }
9400
9511
  throw new BridgeError(errorMessage, customErrorType);
9401
9512
  }
9402
9513
  };
@@ -9911,234 +10022,1872 @@ async function getBlockNumberClosestToTimestamp(provider, targetTimestamp, block
9911
10022
  return lowerBlockNumber;
9912
10023
  }
9913
10024
 
9914
- /**
9915
- * Represents a token bridge, which manages asset transfers between two chains.
9916
- */
9917
- class TokenBridge {
9918
- /**
9919
- * @property {BridgeConfiguration} config - The bridge configuration object.
9920
- */
9921
- config;
9922
- /**
9923
- * Constructs a TokenBridge instance.
9924
- *
9925
- * @param {BridgeConfiguration} config - The bridge configuration object.
9926
- */
9927
- constructor(config) {
9928
- this.config = config;
9929
- }
9930
- /**
9931
- * Retrieves the bridge fee for a specific token.
9932
- *
9933
- * @param {BridgeFeeRequest} req - The fee request object containing the token address for which the fee is required.
9934
- * @returns {Promise<BridgeFeeResponse>} - A promise that resolves to an object containing the bridge fee for the specified token and a flag indicating if the token is bridgeable.
9935
- * @throws {BridgeError} - If an error occurs during the fee retrieval, a BridgeError will be thrown with a specific error type.
9936
- *
9937
- * Possible BridgeError types include:
9938
- * - INVALID_ADDRESS: The token address provided in the request is invalid.
9939
- *
9940
- * @example
9941
- * const feeRequest = {
9942
- * token: '0x123456...', // ERC20 token address
9943
- * };
9944
- *
9945
- * bridgeSdk.getFee(feeRequest)
9946
- * .then((feeResponse) => {
9947
- * console.log('Bridgeable:', feeResponse.bridgeable);
9948
- * console.log('Fee Amount:', feeResponse.feeAmount.toString());
9949
- * })
9950
- * .catch((error) => {
9951
- * console.error('Error:', error.message);
9952
- * });
9953
- */
9954
- async getFee(req) {
9955
- if (!isAddress(req.token)) {
9956
- throw new BridgeError(`token address ${req.token} is not a valid address`, BridgeErrorType.INVALID_ADDRESS);
9957
- }
9958
- return {
9959
- bridgeable: true,
9960
- feeAmount: await this.getFeeForToken(req.token),
9961
- };
9962
- }
9963
- /**
9964
- * Generates an unsigned deposit transaction for a user to sign and submit to the bridge.
9965
- *
9966
- * @param {BridgeDepositRequest} req - The deposit request object containing the required data for depositing tokens.
9967
- * @returns {Promise<BridgeDepositResponse>} - A promise that resolves to an object containing the unsigned transaction data.
9968
- * @throws {BridgeError} - If an error occurs during the generation of the unsigned transaction, a BridgeError will be thrown with a specific error type.
9969
- *
9970
- * Possible BridgeError types include:
9971
- * - UNSUPPORTED_ERROR: The operation is not supported. Currently thrown when attempting to deposit native tokens.
9972
- * - INVALID_ADDRESS: An Ethereum address provided in the request is invalid. This could be the depositor's, recipient's or the token's address.
9973
- * - INVALID_AMOUNT: The deposit amount provided in the request is invalid (less than or equal to 0).
9974
- * - INTERNAL_ERROR: An unexpected error occurred during the execution, likely due to the bridge SDK implementation.
9975
- *
9976
- * @example
9977
- * const depositRequest = {
9978
- * token: '0x123456...', // ERC20 token address
9979
- * depositorAddress: '0xabcdef...', // User's wallet address
9980
- * recipientAddress: '0x987654...', // Destination wallet address on the target chain
9981
- * depositAmount: ethers.utils.parseUnits('100', 18), // Deposit amount in wei
9982
- * };
9983
- *
9984
- * bridgeSdk.getUnsignedDepositTx(depositRequest)
9985
- * .then((depositResponse) => {
9986
- * console.log(depositResponse.unsignedTx);
9987
- * })
9988
- * .catch((error) => {
9989
- * console.error('Error:', error.message);
9990
- * });
9991
- */
9992
- async getUnsignedDepositTx(req) {
9993
- if (req.token === 'NATIVE') {
9994
- throw new BridgeError('native token deposit is not yet supported', BridgeErrorType.UNSUPPORTED_ERROR);
9995
- }
9996
- if (!isAddress(req.depositorAddress)) {
9997
- throw new BridgeError(`depositor address ${req.depositorAddress} is not a valid address`, BridgeErrorType.INVALID_ADDRESS);
9998
- }
9999
- if (!isAddress(req.recipientAddress)) {
10000
- throw new BridgeError(`recipient address ${req.recipientAddress} is not a valid address`, BridgeErrorType.INVALID_ADDRESS);
10001
- }
10002
- // If the token is ERC20, the address must be valid
10003
- if (req.token !== 'NATIVE' && !isAddress(req.token)) {
10004
- throw new BridgeError(`token address ${req.token} is not a valid address`, BridgeErrorType.INVALID_ADDRESS);
10005
- }
10006
- // The deposit amount cannot be <= 0
10007
- if (req.depositAmount.isNegative() || req.depositAmount.isZero()) {
10008
- throw new BridgeError(`deposit amount ${req.depositAmount.toString()} is invalid`, BridgeErrorType.INVALID_AMOUNT);
10009
- }
10010
- // Convert the addresses to correct format addresses (e.g. prepend 0x if not already)
10011
- const depositor = getAddress(req.depositorAddress);
10012
- const receipient = getAddress(req.recipientAddress);
10013
- const token = getAddress(req.token);
10014
- const rootERC20PredicateContract = await withBridgeError(async () => {
10015
- const contract = new Contract(this.config.bridgeContracts.rootChainERC20Predicate, ROOT_ERC20_PREDICATE);
10016
- return contract;
10017
- }, BridgeErrorType.INTERNAL_ERROR);
10018
- // Encode the function data into a payload
10019
- const data = await withBridgeError(async () => rootERC20PredicateContract.interface.encodeFunctionData('depositTo', [token, receipient, req.depositAmount]), BridgeErrorType.INTERNAL_ERROR);
10020
- return {
10021
- unsignedTx: {
10022
- data,
10023
- to: this.config.bridgeContracts.rootChainERC20Predicate,
10024
- value: 0,
10025
- from: depositor,
10025
+ const CHILD_ERC20_PREDICATE = [
10026
+ {
10027
+ inputs: [
10028
+ {
10029
+ internalType: 'string',
10030
+ name: 'only',
10031
+ type: 'string',
10026
10032
  },
10027
- };
10028
- }
10029
- /**
10030
- * Retrieves the unsigned approval transaction for a deposit to the bridge.
10031
- *
10032
- * @param {ApproveBridgeRequest} req - The approve bridge request object containing the depositor address, token address, and deposit amount.
10033
- * @returns {Promise<ApproveBridgeResponse>} - A promise that resolves to an object containing the unsigned approval transaction and a flag indicating if the approval is required.
10034
- * @throws {BridgeError} - If an error occurs during the transaction creation, a BridgeError will be thrown with a specific error type.
10035
- *
10036
- * Possible BridgeError types include:
10037
- * - UNSUPPORTED_ERROR: The operation is not supported. Currently thrown when attempting to deposit native tokens.
10038
- * - INVALID_ADDRESS: An Ethereum address provided in the request is invalid.
10039
- * - INVALID_AMOUNT: The deposit amount provided in the request is invalid (less than or equal to 0).
10040
- * - INTERNAL_ERROR: An unexpected error occurred during the execution, likely due to the bridge SDK implementation.
10041
- * - PROVIDER_ERROR: An error occurred while interacting with the Ethereum provider. This includes issues calling the ERC20 smart contract
10042
- *
10043
- * @example
10044
- * const approveRequest = {
10045
- * depositorAddress: '0x123456...', // Depositor's Ethereum address
10046
- * token: '0xabcdef...', // ERC20 token address
10047
- * depositAmount: ethers.utils.parseUnits('100', 18), // Deposit amount in token's smallest unit (e.g., wei for Ether)
10048
- * };
10049
- *
10050
- * bridgeSdk.getUnsignedApproveBridgeTx(approveRequest)
10051
- * .then((approveResponse) => {
10052
- * console.log('Approval Required:', approveResponse.required);
10053
- * console.log('Unsigned Approval Transaction:', approveResponse.unsignedTx);
10054
- * })
10055
- * .catch((error) => {
10056
- * console.error('Error:', error.message);
10057
- * });
10058
- */
10059
- async getUnsignedApproveBridgeTx(req) {
10060
- // If the token is NATIVE, no approval is required
10061
- if (req.token === 'NATIVE') {
10062
- // When native tokens are supported, change this to return required: false
10063
- throw new BridgeError('native token deposit is not yet supported', BridgeErrorType.UNSUPPORTED_ERROR);
10064
- }
10065
- if (!isAddress(req.depositorAddress)) {
10066
- throw new BridgeError(`depositor address ${req.depositorAddress} is not a valid address`, BridgeErrorType.INVALID_ADDRESS);
10067
- }
10068
- // If the token is ERC20, the address must be valid
10069
- if (req.token !== 'NATIVE' && !isAddress(req.token)) {
10070
- throw new BridgeError(`token address ${req.token} is not a valid address`, BridgeErrorType.INVALID_ADDRESS);
10071
- }
10072
- // The deposit amount cannot be <= 0
10073
- if (req.depositAmount.isNegative() || req.depositAmount.isZero()) {
10074
- throw new BridgeError(`deposit amount ${req.depositAmount.toString()} is invalid`, BridgeErrorType.INVALID_AMOUNT);
10075
- }
10076
- const erc20Contract = await withBridgeError(async () => new Contract(req.token, ERC20, this.config.rootProvider), BridgeErrorType.INTERNAL_ERROR);
10077
- // Get the current approved allowance of the RootERC20Predicate
10078
- const rootERC20PredicateAllowance = await withBridgeError(() => erc20Contract.allowance(req.depositorAddress, this.config.bridgeContracts.rootChainERC20Predicate), BridgeErrorType.PROVIDER_ERROR);
10079
- // If the allowance is greater than or equal to the deposit amount, no approval is required
10080
- if (rootERC20PredicateAllowance.gte(req.depositAmount)) {
10081
- return {
10082
- unsignedTx: null,
10083
- required: false,
10084
- };
10085
- }
10086
- // Calculate the amount of tokens that need to be approved for deposit
10087
- const approvalAmountRequired = req.depositAmount.sub(rootERC20PredicateAllowance);
10088
- // Encode the approve function call data for the ERC20 contract
10089
- const data = await withBridgeError(async () => erc20Contract.interface.encodeFunctionData('approve', [
10090
- this.config.bridgeContracts.rootChainERC20Predicate,
10091
- approvalAmountRequired,
10092
- ]), BridgeErrorType.INTERNAL_ERROR);
10093
- // Create the unsigned transaction for the approval
10094
- const unsignedTx = {
10095
- data,
10096
- to: req.token,
10097
- value: 0,
10098
- from: req.depositorAddress,
10099
- };
10100
- return {
10101
- unsignedTx,
10102
- required: true,
10103
- };
10104
- }
10105
- /**
10106
- * Waits for the deposit transaction to be confirmed and synced from the root chain to the child chain.
10107
- *
10108
- * @param {WaitForRequest} req - The wait for request object containing the transaction hash.
10109
- * @returns {Promise<WaitForResponse>} - A promise that resolves to an object containing the status of the deposit transaction.
10110
- * @throws {BridgeError} - If an error occurs during the transaction confirmation or state sync, a BridgeError will be thrown with a specific error type.
10111
- *
10112
- * Possible BridgeError types include:
10113
- * - PROVIDER_ERROR: An error occurred with the Ethereum provider during transaction confirmation or state synchronization.
10114
- * - TRANSACTION_REVERTED: The transaction on the root chain was reverted.
10115
- *
10116
- * @example
10117
- * const waitForRequest = {
10118
- * transactionHash: '0x123456...', // Deposit transaction hash on the root chain
10119
- * };
10120
- *
10121
- * bridgeSdk.waitForDeposit(waitForRequest)
10122
- * .then((waitForResponse) => {
10123
- * console.log('Deposit Transaction Status:', waitForResponse.status);
10124
- * })
10125
- * .catch((error) => {
10126
- * console.error('Error:', error.message);
10127
- * });
10128
- */
10129
- async waitForDeposit(req) {
10130
- const rootTxReceipt = await withBridgeError(async () => this.config.rootProvider.waitForTransaction(req.transactionHash, this.config.rootChainFinalityBlocks), BridgeErrorType.PROVIDER_ERROR);
10131
- // Throw an error if the transaction was reverted
10132
- if (rootTxReceipt.status !== 1) {
10133
- throw new BridgeError(`${rootTxReceipt.transactionHash} on rootchain was reverted`, BridgeErrorType.TRANSACTION_REVERTED);
10134
- }
10135
- // Get the state sync ID from the transaction receipt
10136
- const stateSyncID = await withBridgeError(async () => this.getRootStateSyncID(rootTxReceipt), BridgeErrorType.PROVIDER_ERROR);
10137
- // Get the block for the timestamp
10138
- const rootBlock = await this.config.rootProvider.getBlock(rootTxReceipt.blockNumber);
10139
- // Get the minimum block on childchain which corresponds with the timestamp on rootchain
10140
- const minBlockRange = await withBridgeError(async () => getBlockNumberClosestToTimestamp(this.config.childProvider, rootBlock.timestamp, this.config.blockTime, this.config.clockInaccuracy), BridgeErrorType.PROVIDER_ERROR);
10141
- // Get the upper bound for which we expect the StateSync event to occur
10033
+ ],
10034
+ name: 'Unauthorized',
10035
+ type: 'error',
10036
+ },
10037
+ {
10038
+ anonymous: false,
10039
+ inputs: [
10040
+ {
10041
+ indexed: false,
10042
+ internalType: 'uint8',
10043
+ name: 'version',
10044
+ type: 'uint8',
10045
+ },
10046
+ ],
10047
+ name: 'Initialized',
10048
+ type: 'event',
10049
+ },
10050
+ {
10051
+ anonymous: false,
10052
+ inputs: [
10053
+ {
10054
+ indexed: true,
10055
+ internalType: 'address',
10056
+ name: 'rootToken',
10057
+ type: 'address',
10058
+ },
10059
+ {
10060
+ indexed: true,
10061
+ internalType: 'address',
10062
+ name: 'childToken',
10063
+ type: 'address',
10064
+ },
10065
+ {
10066
+ indexed: false,
10067
+ internalType: 'address',
10068
+ name: 'sender',
10069
+ type: 'address',
10070
+ },
10071
+ {
10072
+ indexed: true,
10073
+ internalType: 'address',
10074
+ name: 'receiver',
10075
+ type: 'address',
10076
+ },
10077
+ {
10078
+ indexed: false,
10079
+ internalType: 'uint256',
10080
+ name: 'amount',
10081
+ type: 'uint256',
10082
+ },
10083
+ ],
10084
+ name: 'L2ERC20Deposit',
10085
+ type: 'event',
10086
+ },
10087
+ {
10088
+ anonymous: false,
10089
+ inputs: [
10090
+ {
10091
+ indexed: true,
10092
+ internalType: 'address',
10093
+ name: 'rootToken',
10094
+ type: 'address',
10095
+ },
10096
+ {
10097
+ indexed: true,
10098
+ internalType: 'address',
10099
+ name: 'childToken',
10100
+ type: 'address',
10101
+ },
10102
+ {
10103
+ indexed: false,
10104
+ internalType: 'address',
10105
+ name: 'sender',
10106
+ type: 'address',
10107
+ },
10108
+ {
10109
+ indexed: true,
10110
+ internalType: 'address',
10111
+ name: 'receiver',
10112
+ type: 'address',
10113
+ },
10114
+ {
10115
+ indexed: false,
10116
+ internalType: 'uint256',
10117
+ name: 'amount',
10118
+ type: 'uint256',
10119
+ },
10120
+ ],
10121
+ name: 'L2ERC20Withdraw',
10122
+ type: 'event',
10123
+ },
10124
+ {
10125
+ anonymous: false,
10126
+ inputs: [
10127
+ {
10128
+ indexed: true,
10129
+ internalType: 'address',
10130
+ name: 'rootToken',
10131
+ type: 'address',
10132
+ },
10133
+ {
10134
+ indexed: true,
10135
+ internalType: 'address',
10136
+ name: 'childToken',
10137
+ type: 'address',
10138
+ },
10139
+ ],
10140
+ name: 'L2TokenMapped',
10141
+ type: 'event',
10142
+ },
10143
+ {
10144
+ inputs: [],
10145
+ name: 'DEPOSIT_SIG',
10146
+ outputs: [
10147
+ {
10148
+ internalType: 'bytes32',
10149
+ name: '',
10150
+ type: 'bytes32',
10151
+ },
10152
+ ],
10153
+ stateMutability: 'view',
10154
+ type: 'function',
10155
+ },
10156
+ {
10157
+ inputs: [],
10158
+ name: 'MAP_TOKEN_SIG',
10159
+ outputs: [
10160
+ {
10161
+ internalType: 'bytes32',
10162
+ name: '',
10163
+ type: 'bytes32',
10164
+ },
10165
+ ],
10166
+ stateMutability: 'view',
10167
+ type: 'function',
10168
+ },
10169
+ {
10170
+ inputs: [],
10171
+ name: 'NATIVE_TOKEN_CONTRACT',
10172
+ outputs: [
10173
+ {
10174
+ internalType: 'address',
10175
+ name: '',
10176
+ type: 'address',
10177
+ },
10178
+ ],
10179
+ stateMutability: 'view',
10180
+ type: 'function',
10181
+ },
10182
+ {
10183
+ inputs: [],
10184
+ name: 'NATIVE_TRANSFER_PRECOMPILE',
10185
+ outputs: [
10186
+ {
10187
+ internalType: 'address',
10188
+ name: '',
10189
+ type: 'address',
10190
+ },
10191
+ ],
10192
+ stateMutability: 'view',
10193
+ type: 'function',
10194
+ },
10195
+ {
10196
+ inputs: [],
10197
+ name: 'NATIVE_TRANSFER_PRECOMPILE_GAS',
10198
+ outputs: [
10199
+ {
10200
+ internalType: 'uint256',
10201
+ name: '',
10202
+ type: 'uint256',
10203
+ },
10204
+ ],
10205
+ stateMutability: 'view',
10206
+ type: 'function',
10207
+ },
10208
+ {
10209
+ inputs: [],
10210
+ name: 'SYSTEM',
10211
+ outputs: [
10212
+ {
10213
+ internalType: 'address',
10214
+ name: '',
10215
+ type: 'address',
10216
+ },
10217
+ ],
10218
+ stateMutability: 'view',
10219
+ type: 'function',
10220
+ },
10221
+ {
10222
+ inputs: [],
10223
+ name: 'VALIDATOR_PKCHECK_PRECOMPILE',
10224
+ outputs: [
10225
+ {
10226
+ internalType: 'address',
10227
+ name: '',
10228
+ type: 'address',
10229
+ },
10230
+ ],
10231
+ stateMutability: 'view',
10232
+ type: 'function',
10233
+ },
10234
+ {
10235
+ inputs: [],
10236
+ name: 'VALIDATOR_PKCHECK_PRECOMPILE_GAS',
10237
+ outputs: [
10238
+ {
10239
+ internalType: 'uint256',
10240
+ name: '',
10241
+ type: 'uint256',
10242
+ },
10243
+ ],
10244
+ stateMutability: 'view',
10245
+ type: 'function',
10246
+ },
10247
+ {
10248
+ inputs: [],
10249
+ name: 'WITHDRAW_SIG',
10250
+ outputs: [
10251
+ {
10252
+ internalType: 'bytes32',
10253
+ name: '',
10254
+ type: 'bytes32',
10255
+ },
10256
+ ],
10257
+ stateMutability: 'view',
10258
+ type: 'function',
10259
+ },
10260
+ {
10261
+ inputs: [],
10262
+ name: 'childTokenTemplate',
10263
+ outputs: [
10264
+ {
10265
+ internalType: 'address',
10266
+ name: '',
10267
+ type: 'address',
10268
+ },
10269
+ ],
10270
+ stateMutability: 'view',
10271
+ type: 'function',
10272
+ },
10273
+ {
10274
+ inputs: [
10275
+ {
10276
+ internalType: 'address',
10277
+ name: 'newL2StateSender',
10278
+ type: 'address',
10279
+ },
10280
+ {
10281
+ internalType: 'address',
10282
+ name: 'newStateReceiver',
10283
+ type: 'address',
10284
+ },
10285
+ {
10286
+ internalType: 'address',
10287
+ name: 'newRootERC20Predicate',
10288
+ type: 'address',
10289
+ },
10290
+ {
10291
+ internalType: 'address',
10292
+ name: 'newChildTokenTemplate',
10293
+ type: 'address',
10294
+ },
10295
+ {
10296
+ internalType: 'address',
10297
+ name: 'newNativeTokenRootAddress',
10298
+ type: 'address',
10299
+ },
10300
+ ],
10301
+ name: 'initialize',
10302
+ outputs: [],
10303
+ stateMutability: 'nonpayable',
10304
+ type: 'function',
10305
+ },
10306
+ {
10307
+ inputs: [],
10308
+ name: 'l2StateSender',
10309
+ outputs: [
10310
+ {
10311
+ internalType: 'contract IStateSender',
10312
+ name: '',
10313
+ type: 'address',
10314
+ },
10315
+ ],
10316
+ stateMutability: 'view',
10317
+ type: 'function',
10318
+ },
10319
+ {
10320
+ inputs: [
10321
+ {
10322
+ internalType: 'uint256',
10323
+ name: '',
10324
+ type: 'uint256',
10325
+ },
10326
+ {
10327
+ internalType: 'address',
10328
+ name: 'sender',
10329
+ type: 'address',
10330
+ },
10331
+ {
10332
+ internalType: 'bytes',
10333
+ name: 'data',
10334
+ type: 'bytes',
10335
+ },
10336
+ ],
10337
+ name: 'onStateReceive',
10338
+ outputs: [],
10339
+ stateMutability: 'nonpayable',
10340
+ type: 'function',
10341
+ },
10342
+ {
10343
+ inputs: [],
10344
+ name: 'rootERC20Predicate',
10345
+ outputs: [
10346
+ {
10347
+ internalType: 'address',
10348
+ name: '',
10349
+ type: 'address',
10350
+ },
10351
+ ],
10352
+ stateMutability: 'view',
10353
+ type: 'function',
10354
+ },
10355
+ {
10356
+ inputs: [
10357
+ {
10358
+ internalType: 'address',
10359
+ name: '',
10360
+ type: 'address',
10361
+ },
10362
+ ],
10363
+ name: 'rootTokenToChildToken',
10364
+ outputs: [
10365
+ {
10366
+ internalType: 'address',
10367
+ name: '',
10368
+ type: 'address',
10369
+ },
10370
+ ],
10371
+ stateMutability: 'view',
10372
+ type: 'function',
10373
+ },
10374
+ {
10375
+ inputs: [],
10376
+ name: 'stateReceiver',
10377
+ outputs: [
10378
+ {
10379
+ internalType: 'address',
10380
+ name: '',
10381
+ type: 'address',
10382
+ },
10383
+ ],
10384
+ stateMutability: 'view',
10385
+ type: 'function',
10386
+ },
10387
+ {
10388
+ inputs: [
10389
+ {
10390
+ internalType: 'contract IChildERC20',
10391
+ name: 'childToken',
10392
+ type: 'address',
10393
+ },
10394
+ {
10395
+ internalType: 'uint256',
10396
+ name: 'amount',
10397
+ type: 'uint256',
10398
+ },
10399
+ ],
10400
+ name: 'withdraw',
10401
+ outputs: [],
10402
+ stateMutability: 'nonpayable',
10403
+ type: 'function',
10404
+ },
10405
+ {
10406
+ inputs: [
10407
+ {
10408
+ internalType: 'contract IChildERC20',
10409
+ name: 'childToken',
10410
+ type: 'address',
10411
+ },
10412
+ {
10413
+ internalType: 'address',
10414
+ name: 'receiver',
10415
+ type: 'address',
10416
+ },
10417
+ {
10418
+ internalType: 'uint256',
10419
+ name: 'amount',
10420
+ type: 'uint256',
10421
+ },
10422
+ ],
10423
+ name: 'withdrawTo',
10424
+ outputs: [],
10425
+ stateMutability: 'nonpayable',
10426
+ type: 'function',
10427
+ },
10428
+ ];
10429
+
10430
+ const CHECKPOINT_MANAGER = [
10431
+ {
10432
+ anonymous: false,
10433
+ inputs: [
10434
+ {
10435
+ indexed: false,
10436
+ internalType: 'uint8',
10437
+ name: 'version',
10438
+ type: 'uint8',
10439
+ },
10440
+ ],
10441
+ name: 'Initialized',
10442
+ type: 'event',
10443
+ },
10444
+ {
10445
+ inputs: [],
10446
+ name: 'DOMAIN',
10447
+ outputs: [
10448
+ {
10449
+ internalType: 'bytes32',
10450
+ name: '',
10451
+ type: 'bytes32',
10452
+ },
10453
+ ],
10454
+ stateMutability: 'view',
10455
+ type: 'function',
10456
+ },
10457
+ {
10458
+ inputs: [],
10459
+ name: 'bls',
10460
+ outputs: [
10461
+ {
10462
+ internalType: 'contract IBLS',
10463
+ name: '',
10464
+ type: 'address',
10465
+ },
10466
+ ],
10467
+ stateMutability: 'view',
10468
+ type: 'function',
10469
+ },
10470
+ {
10471
+ inputs: [],
10472
+ name: 'bn256G2',
10473
+ outputs: [
10474
+ {
10475
+ internalType: 'contract IBN256G2',
10476
+ name: '',
10477
+ type: 'address',
10478
+ },
10479
+ ],
10480
+ stateMutability: 'view',
10481
+ type: 'function',
10482
+ },
10483
+ {
10484
+ inputs: [],
10485
+ name: 'chainId',
10486
+ outputs: [
10487
+ {
10488
+ internalType: 'uint256',
10489
+ name: '',
10490
+ type: 'uint256',
10491
+ },
10492
+ ],
10493
+ stateMutability: 'view',
10494
+ type: 'function',
10495
+ },
10496
+ {
10497
+ inputs: [
10498
+ {
10499
+ internalType: 'uint256',
10500
+ name: '',
10501
+ type: 'uint256',
10502
+ },
10503
+ ],
10504
+ name: 'checkpointBlockNumbers',
10505
+ outputs: [
10506
+ {
10507
+ internalType: 'uint256',
10508
+ name: '',
10509
+ type: 'uint256',
10510
+ },
10511
+ ],
10512
+ stateMutability: 'view',
10513
+ type: 'function',
10514
+ },
10515
+ {
10516
+ inputs: [
10517
+ {
10518
+ internalType: 'uint256',
10519
+ name: '',
10520
+ type: 'uint256',
10521
+ },
10522
+ ],
10523
+ name: 'checkpoints',
10524
+ outputs: [
10525
+ {
10526
+ internalType: 'uint256',
10527
+ name: 'epoch',
10528
+ type: 'uint256',
10529
+ },
10530
+ {
10531
+ internalType: 'uint256',
10532
+ name: 'blockNumber',
10533
+ type: 'uint256',
10534
+ },
10535
+ {
10536
+ internalType: 'bytes32',
10537
+ name: 'eventRoot',
10538
+ type: 'bytes32',
10539
+ },
10540
+ ],
10541
+ stateMutability: 'view',
10542
+ type: 'function',
10543
+ },
10544
+ {
10545
+ inputs: [],
10546
+ name: 'currentCheckpointBlockNumber',
10547
+ outputs: [
10548
+ {
10549
+ internalType: 'uint256',
10550
+ name: '',
10551
+ type: 'uint256',
10552
+ },
10553
+ ],
10554
+ stateMutability: 'view',
10555
+ type: 'function',
10556
+ },
10557
+ {
10558
+ inputs: [],
10559
+ name: 'currentEpoch',
10560
+ outputs: [
10561
+ {
10562
+ internalType: 'uint256',
10563
+ name: '',
10564
+ type: 'uint256',
10565
+ },
10566
+ ],
10567
+ stateMutability: 'view',
10568
+ type: 'function',
10569
+ },
10570
+ {
10571
+ inputs: [
10572
+ {
10573
+ internalType: 'uint256',
10574
+ name: '',
10575
+ type: 'uint256',
10576
+ },
10577
+ ],
10578
+ name: 'currentValidatorSet',
10579
+ outputs: [
10580
+ {
10581
+ internalType: 'address',
10582
+ name: '_address',
10583
+ type: 'address',
10584
+ },
10585
+ {
10586
+ internalType: 'uint256',
10587
+ name: 'votingPower',
10588
+ type: 'uint256',
10589
+ },
10590
+ ],
10591
+ stateMutability: 'view',
10592
+ type: 'function',
10593
+ },
10594
+ {
10595
+ inputs: [],
10596
+ name: 'currentValidatorSetHash',
10597
+ outputs: [
10598
+ {
10599
+ internalType: 'bytes32',
10600
+ name: '',
10601
+ type: 'bytes32',
10602
+ },
10603
+ ],
10604
+ stateMutability: 'view',
10605
+ type: 'function',
10606
+ },
10607
+ {
10608
+ inputs: [],
10609
+ name: 'currentValidatorSetLength',
10610
+ outputs: [
10611
+ {
10612
+ internalType: 'uint256',
10613
+ name: '',
10614
+ type: 'uint256',
10615
+ },
10616
+ ],
10617
+ stateMutability: 'view',
10618
+ type: 'function',
10619
+ },
10620
+ {
10621
+ inputs: [
10622
+ {
10623
+ internalType: 'uint256',
10624
+ name: 'blockNumber',
10625
+ type: 'uint256',
10626
+ },
10627
+ ],
10628
+ name: 'getCheckpointBlock',
10629
+ outputs: [
10630
+ {
10631
+ internalType: 'bool',
10632
+ name: '',
10633
+ type: 'bool',
10634
+ },
10635
+ {
10636
+ internalType: 'uint256',
10637
+ name: '',
10638
+ type: 'uint256',
10639
+ },
10640
+ ],
10641
+ stateMutability: 'view',
10642
+ type: 'function',
10643
+ },
10644
+ {
10645
+ inputs: [
10646
+ {
10647
+ internalType: 'uint256',
10648
+ name: 'blockNumber',
10649
+ type: 'uint256',
10650
+ },
10651
+ {
10652
+ internalType: 'bytes32',
10653
+ name: 'leaf',
10654
+ type: 'bytes32',
10655
+ },
10656
+ {
10657
+ internalType: 'uint256',
10658
+ name: 'leafIndex',
10659
+ type: 'uint256',
10660
+ },
10661
+ {
10662
+ internalType: 'bytes32[]',
10663
+ name: 'proof',
10664
+ type: 'bytes32[]',
10665
+ },
10666
+ ],
10667
+ name: 'getEventMembershipByBlockNumber',
10668
+ outputs: [
10669
+ {
10670
+ internalType: 'bool',
10671
+ name: '',
10672
+ type: 'bool',
10673
+ },
10674
+ ],
10675
+ stateMutability: 'view',
10676
+ type: 'function',
10677
+ },
10678
+ {
10679
+ inputs: [
10680
+ {
10681
+ internalType: 'uint256',
10682
+ name: 'epoch',
10683
+ type: 'uint256',
10684
+ },
10685
+ {
10686
+ internalType: 'bytes32',
10687
+ name: 'leaf',
10688
+ type: 'bytes32',
10689
+ },
10690
+ {
10691
+ internalType: 'uint256',
10692
+ name: 'leafIndex',
10693
+ type: 'uint256',
10694
+ },
10695
+ {
10696
+ internalType: 'bytes32[]',
10697
+ name: 'proof',
10698
+ type: 'bytes32[]',
10699
+ },
10700
+ ],
10701
+ name: 'getEventMembershipByEpoch',
10702
+ outputs: [
10703
+ {
10704
+ internalType: 'bool',
10705
+ name: '',
10706
+ type: 'bool',
10707
+ },
10708
+ ],
10709
+ stateMutability: 'view',
10710
+ type: 'function',
10711
+ },
10712
+ {
10713
+ inputs: [
10714
+ {
10715
+ internalType: 'uint256',
10716
+ name: 'blockNumber',
10717
+ type: 'uint256',
10718
+ },
10719
+ ],
10720
+ name: 'getEventRootByBlock',
10721
+ outputs: [
10722
+ {
10723
+ internalType: 'bytes32',
10724
+ name: '',
10725
+ type: 'bytes32',
10726
+ },
10727
+ ],
10728
+ stateMutability: 'view',
10729
+ type: 'function',
10730
+ },
10731
+ {
10732
+ inputs: [
10733
+ {
10734
+ internalType: 'contract IBLS',
10735
+ name: 'newBls',
10736
+ type: 'address',
10737
+ },
10738
+ {
10739
+ internalType: 'contract IBN256G2',
10740
+ name: 'newBn256G2',
10741
+ type: 'address',
10742
+ },
10743
+ {
10744
+ internalType: 'uint256',
10745
+ name: 'chainId_',
10746
+ type: 'uint256',
10747
+ },
10748
+ {
10749
+ components: [
10750
+ {
10751
+ internalType: 'address',
10752
+ name: '_address',
10753
+ type: 'address',
10754
+ },
10755
+ {
10756
+ internalType: 'uint256[4]',
10757
+ name: 'blsKey',
10758
+ type: 'uint256[4]',
10759
+ },
10760
+ {
10761
+ internalType: 'uint256',
10762
+ name: 'votingPower',
10763
+ type: 'uint256',
10764
+ },
10765
+ ],
10766
+ internalType: 'struct ICheckpointManager.Validator[]',
10767
+ name: 'newValidatorSet',
10768
+ type: 'tuple[]',
10769
+ },
10770
+ ],
10771
+ name: 'initialize',
10772
+ outputs: [],
10773
+ stateMutability: 'nonpayable',
10774
+ type: 'function',
10775
+ },
10776
+ {
10777
+ inputs: [
10778
+ {
10779
+ components: [
10780
+ {
10781
+ internalType: 'bytes32',
10782
+ name: 'blockHash',
10783
+ type: 'bytes32',
10784
+ },
10785
+ {
10786
+ internalType: 'uint256',
10787
+ name: 'blockRound',
10788
+ type: 'uint256',
10789
+ },
10790
+ {
10791
+ internalType: 'bytes32',
10792
+ name: 'currentValidatorSetHash',
10793
+ type: 'bytes32',
10794
+ },
10795
+ ],
10796
+ internalType: 'struct ICheckpointManager.CheckpointMetadata',
10797
+ name: 'checkpointMetadata',
10798
+ type: 'tuple',
10799
+ },
10800
+ {
10801
+ components: [
10802
+ {
10803
+ internalType: 'uint256',
10804
+ name: 'epoch',
10805
+ type: 'uint256',
10806
+ },
10807
+ {
10808
+ internalType: 'uint256',
10809
+ name: 'blockNumber',
10810
+ type: 'uint256',
10811
+ },
10812
+ {
10813
+ internalType: 'bytes32',
10814
+ name: 'eventRoot',
10815
+ type: 'bytes32',
10816
+ },
10817
+ ],
10818
+ internalType: 'struct ICheckpointManager.Checkpoint',
10819
+ name: 'checkpoint',
10820
+ type: 'tuple',
10821
+ },
10822
+ {
10823
+ internalType: 'uint256[2]',
10824
+ name: 'signature',
10825
+ type: 'uint256[2]',
10826
+ },
10827
+ {
10828
+ components: [
10829
+ {
10830
+ internalType: 'address',
10831
+ name: '_address',
10832
+ type: 'address',
10833
+ },
10834
+ {
10835
+ internalType: 'uint256[4]',
10836
+ name: 'blsKey',
10837
+ type: 'uint256[4]',
10838
+ },
10839
+ {
10840
+ internalType: 'uint256',
10841
+ name: 'votingPower',
10842
+ type: 'uint256',
10843
+ },
10844
+ ],
10845
+ internalType: 'struct ICheckpointManager.Validator[]',
10846
+ name: 'newValidatorSet',
10847
+ type: 'tuple[]',
10848
+ },
10849
+ {
10850
+ internalType: 'bytes',
10851
+ name: 'bitmap',
10852
+ type: 'bytes',
10853
+ },
10854
+ ],
10855
+ name: 'submit',
10856
+ outputs: [],
10857
+ stateMutability: 'nonpayable',
10858
+ type: 'function',
10859
+ },
10860
+ {
10861
+ inputs: [],
10862
+ name: 'totalVotingPower',
10863
+ outputs: [
10864
+ {
10865
+ internalType: 'uint256',
10866
+ name: '',
10867
+ type: 'uint256',
10868
+ },
10869
+ ],
10870
+ stateMutability: 'view',
10871
+ type: 'function',
10872
+ },
10873
+ ];
10874
+
10875
+ function decodeExtraData(extraData) {
10876
+ const decoded = decode(`0x${extraData.substring(66)}`);
10877
+ const blockExtraData = {
10878
+ validators: decoded[0],
10879
+ parent: decoded[1],
10880
+ committed: decoded[2],
10881
+ checkpoint: {
10882
+ blockRound: decoded[3][0],
10883
+ epochNumber: parseInt(decoded[3][1], 16),
10884
+ currentValidatorHash: decoded[3][2],
10885
+ nextValidatorHash: decoded[3][3],
10886
+ eventRoot: decoded[3][4],
10887
+ },
10888
+ };
10889
+ return blockExtraData;
10890
+ }
10891
+
10892
+ /**
10893
+ * @constant {string} ETH_SEPOLIA_CHAIN_ID - The chain ID for the Ethereum Sepolia testnet (EIP-155 compatible format).
10894
+ */
10895
+ const ETH_SEPOLIA_CHAIN_ID = '11155111';
10896
+ /**
10897
+ * @constant {string} ETH_MAINNET_CHAIN_ID - The chain ID for the Ethereum mainnet (EIP-155 compatible format).
10898
+ */
10899
+ const ETH_MAINNET_CHAIN_ID = '1';
10900
+ /**
10901
+ * @constant {string} ZKEVM_DEVNET_CHAIN_ID - The chain ID for the zkEVM devnet (EIP-155 compatible format).
10902
+ */
10903
+ const ZKEVM_DEVNET_CHAIN_ID = '13433';
10904
+ /**
10905
+ /**
10906
+ * @constant {string} ZKEVM_TESTNET_CHAIN_ID - The chain ID for the zkEVM testnet (EIP-155 compatible format).
10907
+ */
10908
+ const ZKEVM_TESTNET_CHAIN_ID = '13372';
10909
+ /**
10910
+ * @constant {string} ZKEVM_MAINNET_CHAIN_ID - The chain ID for the zkEVM mainnet (EIP-155 compatible format).
10911
+ */
10912
+ const ZKEVM_MAINNET_CHAIN_ID = '13371';
10913
+ /**
10914
+ * @constant {string} L2_STATE_SENDER_ADDRESS - Address of bridge contract to the rootchain
10915
+ */
10916
+ const L2_STATE_SENDER_ADDRESS = '0x0000000000000000000000000000000000001002';
10917
+ /**
10918
+ * The constant value representing the native token in the token bridge context.
10919
+ * The key is used to indicate the native token of a blockchain network (like Ether in Ethereum) in methods that normally require a token address.
10920
+ * @constant {string}
10921
+ */
10922
+ const NATIVE_TOKEN_BRIDGE_KEY = '0x0000000000000000000000000000000000000001';
10923
+ /**
10924
+ * @constant {BridgeInstance} ETH_SEPOLIA_TO_ZKEVM_DEVNET - A bridge instance configuration for bridging between the Ethereum Sepolia testnet and the zkEVM devnet.
10925
+ */
10926
+ const ETH_SEPOLIA_TO_ZKEVM_DEVNET = {
10927
+ rootChainID: ETH_SEPOLIA_CHAIN_ID,
10928
+ childChainID: ZKEVM_DEVNET_CHAIN_ID,
10929
+ };
10930
+ /**
10931
+ * @constant {BridgeInstance} ETH_SEPOLIA_TO_ZKEVM_TESTNET - A bridge instance configuration for bridging between the Ethereum Sepolia testnet and the zkEVM testnet.
10932
+ */
10933
+ const ETH_SEPOLIA_TO_ZKEVM_TESTNET = {
10934
+ rootChainID: ETH_SEPOLIA_CHAIN_ID,
10935
+ childChainID: ZKEVM_TESTNET_CHAIN_ID,
10936
+ };
10937
+ /**
10938
+ * @constant {BridgeInstance} ETH_MAINNET_TO_ZKEVM_MAINNET - A bridge instance configuration for bridging between the Ethereum mainnet and the zkEVM mainnet.
10939
+ */
10940
+ const ETH_MAINNET_TO_ZKEVM_MAINNET = {
10941
+ rootChainID: ETH_MAINNET_CHAIN_ID,
10942
+ childChainID: ZKEVM_MAINNET_CHAIN_ID,
10943
+ };
10944
+
10945
+ const L2_STATE_SENDER = [
10946
+ {
10947
+ anonymous: false,
10948
+ inputs: [
10949
+ {
10950
+ indexed: true,
10951
+ internalType: 'uint256',
10952
+ name: 'id',
10953
+ type: 'uint256',
10954
+ },
10955
+ {
10956
+ indexed: true,
10957
+ internalType: 'address',
10958
+ name: 'sender',
10959
+ type: 'address',
10960
+ },
10961
+ {
10962
+ indexed: true,
10963
+ internalType: 'address',
10964
+ name: 'receiver',
10965
+ type: 'address',
10966
+ },
10967
+ {
10968
+ indexed: false,
10969
+ internalType: 'bytes',
10970
+ name: 'data',
10971
+ type: 'bytes',
10972
+ },
10973
+ ],
10974
+ name: 'L2StateSynced',
10975
+ type: 'event',
10976
+ },
10977
+ {
10978
+ inputs: [],
10979
+ name: 'MAX_LENGTH',
10980
+ outputs: [
10981
+ {
10982
+ internalType: 'uint256',
10983
+ name: '',
10984
+ type: 'uint256',
10985
+ },
10986
+ ],
10987
+ stateMutability: 'view',
10988
+ type: 'function',
10989
+ },
10990
+ {
10991
+ inputs: [],
10992
+ name: 'counter',
10993
+ outputs: [
10994
+ {
10995
+ internalType: 'uint256',
10996
+ name: '',
10997
+ type: 'uint256',
10998
+ },
10999
+ ],
11000
+ stateMutability: 'view',
11001
+ type: 'function',
11002
+ },
11003
+ {
11004
+ inputs: [
11005
+ {
11006
+ internalType: 'address',
11007
+ name: 'receiver',
11008
+ type: 'address',
11009
+ },
11010
+ {
11011
+ internalType: 'bytes',
11012
+ name: 'data',
11013
+ type: 'bytes',
11014
+ },
11015
+ ],
11016
+ name: 'syncState',
11017
+ outputs: [],
11018
+ stateMutability: 'nonpayable',
11019
+ type: 'function',
11020
+ },
11021
+ ];
11022
+
11023
+ const EXIT_HELPER = [
11024
+ {
11025
+ anonymous: false,
11026
+ inputs: [
11027
+ {
11028
+ indexed: true,
11029
+ internalType: 'uint256',
11030
+ name: 'id',
11031
+ type: 'uint256',
11032
+ },
11033
+ {
11034
+ indexed: true,
11035
+ internalType: 'bool',
11036
+ name: 'success',
11037
+ type: 'bool',
11038
+ },
11039
+ {
11040
+ indexed: false,
11041
+ internalType: 'bytes',
11042
+ name: 'returnData',
11043
+ type: 'bytes',
11044
+ },
11045
+ ],
11046
+ name: 'ExitProcessed',
11047
+ type: 'event',
11048
+ },
11049
+ {
11050
+ anonymous: false,
11051
+ inputs: [
11052
+ {
11053
+ indexed: false,
11054
+ internalType: 'uint8',
11055
+ name: 'version',
11056
+ type: 'uint8',
11057
+ },
11058
+ ],
11059
+ name: 'Initialized',
11060
+ type: 'event',
11061
+ },
11062
+ {
11063
+ inputs: [
11064
+ {
11065
+ components: [
11066
+ {
11067
+ internalType: 'uint256',
11068
+ name: 'blockNumber',
11069
+ type: 'uint256',
11070
+ },
11071
+ {
11072
+ internalType: 'uint256',
11073
+ name: 'leafIndex',
11074
+ type: 'uint256',
11075
+ },
11076
+ {
11077
+ internalType: 'bytes',
11078
+ name: 'unhashedLeaf',
11079
+ type: 'bytes',
11080
+ },
11081
+ {
11082
+ internalType: 'bytes32[]',
11083
+ name: 'proof',
11084
+ type: 'bytes32[]',
11085
+ },
11086
+ ],
11087
+ internalType: 'struct IExitHelper.BatchExitInput[]',
11088
+ name: 'inputs',
11089
+ type: 'tuple[]',
11090
+ },
11091
+ ],
11092
+ name: 'batchExit',
11093
+ outputs: [],
11094
+ stateMutability: 'nonpayable',
11095
+ type: 'function',
11096
+ },
11097
+ {
11098
+ inputs: [],
11099
+ name: 'checkpointManager',
11100
+ outputs: [
11101
+ {
11102
+ internalType: 'contract ICheckpointManager',
11103
+ name: '',
11104
+ type: 'address',
11105
+ },
11106
+ ],
11107
+ stateMutability: 'view',
11108
+ type: 'function',
11109
+ },
11110
+ {
11111
+ inputs: [
11112
+ {
11113
+ internalType: 'uint256',
11114
+ name: 'blockNumber',
11115
+ type: 'uint256',
11116
+ },
11117
+ {
11118
+ internalType: 'uint256',
11119
+ name: 'leafIndex',
11120
+ type: 'uint256',
11121
+ },
11122
+ {
11123
+ internalType: 'bytes',
11124
+ name: 'unhashedLeaf',
11125
+ type: 'bytes',
11126
+ },
11127
+ {
11128
+ internalType: 'bytes32[]',
11129
+ name: 'proof',
11130
+ type: 'bytes32[]',
11131
+ },
11132
+ ],
11133
+ name: 'exit',
11134
+ outputs: [],
11135
+ stateMutability: 'nonpayable',
11136
+ type: 'function',
11137
+ },
11138
+ {
11139
+ inputs: [
11140
+ {
11141
+ internalType: 'contract ICheckpointManager',
11142
+ name: 'newCheckpointManager',
11143
+ type: 'address',
11144
+ },
11145
+ ],
11146
+ name: 'initialize',
11147
+ outputs: [],
11148
+ stateMutability: 'nonpayable',
11149
+ type: 'function',
11150
+ },
11151
+ {
11152
+ inputs: [
11153
+ {
11154
+ internalType: 'uint256',
11155
+ name: '',
11156
+ type: 'uint256',
11157
+ },
11158
+ ],
11159
+ name: 'processedExits',
11160
+ outputs: [
11161
+ {
11162
+ internalType: 'bool',
11163
+ name: '',
11164
+ type: 'bool',
11165
+ },
11166
+ ],
11167
+ stateMutability: 'view',
11168
+ type: 'function',
11169
+ },
11170
+ ];
11171
+
11172
+ const CHILD_ERC20 = [
11173
+ {
11174
+ anonymous: false,
11175
+ inputs: [
11176
+ {
11177
+ indexed: true,
11178
+ internalType: 'address',
11179
+ name: 'owner',
11180
+ type: 'address',
11181
+ },
11182
+ {
11183
+ indexed: true,
11184
+ internalType: 'address',
11185
+ name: 'spender',
11186
+ type: 'address',
11187
+ },
11188
+ {
11189
+ indexed: false,
11190
+ internalType: 'uint256',
11191
+ name: 'value',
11192
+ type: 'uint256',
11193
+ },
11194
+ ],
11195
+ name: 'Approval',
11196
+ type: 'event',
11197
+ },
11198
+ {
11199
+ anonymous: false,
11200
+ inputs: [
11201
+ {
11202
+ indexed: false,
11203
+ internalType: 'uint8',
11204
+ name: 'version',
11205
+ type: 'uint8',
11206
+ },
11207
+ ],
11208
+ name: 'Initialized',
11209
+ type: 'event',
11210
+ },
11211
+ {
11212
+ anonymous: false,
11213
+ inputs: [
11214
+ {
11215
+ indexed: false,
11216
+ internalType: 'address',
11217
+ name: 'userAddress',
11218
+ type: 'address',
11219
+ },
11220
+ {
11221
+ indexed: false,
11222
+ internalType: 'address',
11223
+ name: 'relayerAddress',
11224
+ type: 'address',
11225
+ },
11226
+ {
11227
+ indexed: false,
11228
+ internalType: 'bytes',
11229
+ name: 'functionSignature',
11230
+ type: 'bytes',
11231
+ },
11232
+ ],
11233
+ name: 'MetaTransactionExecuted',
11234
+ type: 'event',
11235
+ },
11236
+ {
11237
+ anonymous: false,
11238
+ inputs: [
11239
+ {
11240
+ indexed: true,
11241
+ internalType: 'address',
11242
+ name: 'from',
11243
+ type: 'address',
11244
+ },
11245
+ {
11246
+ indexed: true,
11247
+ internalType: 'address',
11248
+ name: 'to',
11249
+ type: 'address',
11250
+ },
11251
+ {
11252
+ indexed: false,
11253
+ internalType: 'uint256',
11254
+ name: 'value',
11255
+ type: 'uint256',
11256
+ },
11257
+ ],
11258
+ name: 'Transfer',
11259
+ type: 'event',
11260
+ },
11261
+ {
11262
+ inputs: [
11263
+ {
11264
+ internalType: 'address',
11265
+ name: 'owner',
11266
+ type: 'address',
11267
+ },
11268
+ {
11269
+ internalType: 'address',
11270
+ name: 'spender',
11271
+ type: 'address',
11272
+ },
11273
+ ],
11274
+ name: 'allowance',
11275
+ outputs: [
11276
+ {
11277
+ internalType: 'uint256',
11278
+ name: '',
11279
+ type: 'uint256',
11280
+ },
11281
+ ],
11282
+ stateMutability: 'view',
11283
+ type: 'function',
11284
+ },
11285
+ {
11286
+ inputs: [
11287
+ {
11288
+ internalType: 'address',
11289
+ name: 'spender',
11290
+ type: 'address',
11291
+ },
11292
+ {
11293
+ internalType: 'uint256',
11294
+ name: 'amount',
11295
+ type: 'uint256',
11296
+ },
11297
+ ],
11298
+ name: 'approve',
11299
+ outputs: [
11300
+ {
11301
+ internalType: 'bool',
11302
+ name: '',
11303
+ type: 'bool',
11304
+ },
11305
+ ],
11306
+ stateMutability: 'nonpayable',
11307
+ type: 'function',
11308
+ },
11309
+ {
11310
+ inputs: [
11311
+ {
11312
+ internalType: 'address',
11313
+ name: 'account',
11314
+ type: 'address',
11315
+ },
11316
+ ],
11317
+ name: 'balanceOf',
11318
+ outputs: [
11319
+ {
11320
+ internalType: 'uint256',
11321
+ name: '',
11322
+ type: 'uint256',
11323
+ },
11324
+ ],
11325
+ stateMutability: 'view',
11326
+ type: 'function',
11327
+ },
11328
+ {
11329
+ inputs: [
11330
+ {
11331
+ internalType: 'address',
11332
+ name: 'account',
11333
+ type: 'address',
11334
+ },
11335
+ {
11336
+ internalType: 'uint256',
11337
+ name: 'amount',
11338
+ type: 'uint256',
11339
+ },
11340
+ ],
11341
+ name: 'burn',
11342
+ outputs: [
11343
+ {
11344
+ internalType: 'bool',
11345
+ name: '',
11346
+ type: 'bool',
11347
+ },
11348
+ ],
11349
+ stateMutability: 'nonpayable',
11350
+ type: 'function',
11351
+ },
11352
+ {
11353
+ inputs: [],
11354
+ name: 'decimals',
11355
+ outputs: [
11356
+ {
11357
+ internalType: 'uint8',
11358
+ name: '',
11359
+ type: 'uint8',
11360
+ },
11361
+ ],
11362
+ stateMutability: 'view',
11363
+ type: 'function',
11364
+ },
11365
+ {
11366
+ inputs: [
11367
+ {
11368
+ internalType: 'address',
11369
+ name: 'spender',
11370
+ type: 'address',
11371
+ },
11372
+ {
11373
+ internalType: 'uint256',
11374
+ name: 'subtractedValue',
11375
+ type: 'uint256',
11376
+ },
11377
+ ],
11378
+ name: 'decreaseAllowance',
11379
+ outputs: [
11380
+ {
11381
+ internalType: 'bool',
11382
+ name: '',
11383
+ type: 'bool',
11384
+ },
11385
+ ],
11386
+ stateMutability: 'nonpayable',
11387
+ type: 'function',
11388
+ },
11389
+ {
11390
+ inputs: [
11391
+ {
11392
+ internalType: 'address',
11393
+ name: 'userAddress',
11394
+ type: 'address',
11395
+ },
11396
+ {
11397
+ internalType: 'bytes',
11398
+ name: 'functionSignature',
11399
+ type: 'bytes',
11400
+ },
11401
+ {
11402
+ internalType: 'bytes32',
11403
+ name: 'sigR',
11404
+ type: 'bytes32',
11405
+ },
11406
+ {
11407
+ internalType: 'bytes32',
11408
+ name: 'sigS',
11409
+ type: 'bytes32',
11410
+ },
11411
+ {
11412
+ internalType: 'uint8',
11413
+ name: 'sigV',
11414
+ type: 'uint8',
11415
+ },
11416
+ ],
11417
+ name: 'executeMetaTransaction',
11418
+ outputs: [
11419
+ {
11420
+ internalType: 'bytes',
11421
+ name: '',
11422
+ type: 'bytes',
11423
+ },
11424
+ ],
11425
+ stateMutability: 'nonpayable',
11426
+ type: 'function',
11427
+ },
11428
+ {
11429
+ inputs: [
11430
+ {
11431
+ internalType: 'address',
11432
+ name: 'user',
11433
+ type: 'address',
11434
+ },
11435
+ ],
11436
+ name: 'getNonce',
11437
+ outputs: [
11438
+ {
11439
+ internalType: 'uint256',
11440
+ name: 'nonce',
11441
+ type: 'uint256',
11442
+ },
11443
+ ],
11444
+ stateMutability: 'view',
11445
+ type: 'function',
11446
+ },
11447
+ {
11448
+ inputs: [
11449
+ {
11450
+ internalType: 'address',
11451
+ name: 'spender',
11452
+ type: 'address',
11453
+ },
11454
+ {
11455
+ internalType: 'uint256',
11456
+ name: 'addedValue',
11457
+ type: 'uint256',
11458
+ },
11459
+ ],
11460
+ name: 'increaseAllowance',
11461
+ outputs: [
11462
+ {
11463
+ internalType: 'bool',
11464
+ name: '',
11465
+ type: 'bool',
11466
+ },
11467
+ ],
11468
+ stateMutability: 'nonpayable',
11469
+ type: 'function',
11470
+ },
11471
+ {
11472
+ inputs: [
11473
+ {
11474
+ internalType: 'address',
11475
+ name: 'rootToken_',
11476
+ type: 'address',
11477
+ },
11478
+ {
11479
+ internalType: 'string',
11480
+ name: 'name_',
11481
+ type: 'string',
11482
+ },
11483
+ {
11484
+ internalType: 'string',
11485
+ name: 'symbol_',
11486
+ type: 'string',
11487
+ },
11488
+ {
11489
+ internalType: 'uint8',
11490
+ name: 'decimals_',
11491
+ type: 'uint8',
11492
+ },
11493
+ ],
11494
+ name: 'initialize',
11495
+ outputs: [],
11496
+ stateMutability: 'nonpayable',
11497
+ type: 'function',
11498
+ },
11499
+ {
11500
+ inputs: [
11501
+ {
11502
+ internalType: 'uint256',
11503
+ name: 'offset',
11504
+ type: 'uint256',
11505
+ },
11506
+ ],
11507
+ name: 'invalidateNext',
11508
+ outputs: [],
11509
+ stateMutability: 'nonpayable',
11510
+ type: 'function',
11511
+ },
11512
+ {
11513
+ inputs: [
11514
+ {
11515
+ internalType: 'address',
11516
+ name: 'account',
11517
+ type: 'address',
11518
+ },
11519
+ {
11520
+ internalType: 'uint256',
11521
+ name: 'amount',
11522
+ type: 'uint256',
11523
+ },
11524
+ ],
11525
+ name: 'mint',
11526
+ outputs: [
11527
+ {
11528
+ internalType: 'bool',
11529
+ name: '',
11530
+ type: 'bool',
11531
+ },
11532
+ ],
11533
+ stateMutability: 'nonpayable',
11534
+ type: 'function',
11535
+ },
11536
+ {
11537
+ inputs: [],
11538
+ name: 'name',
11539
+ outputs: [
11540
+ {
11541
+ internalType: 'string',
11542
+ name: '',
11543
+ type: 'string',
11544
+ },
11545
+ ],
11546
+ stateMutability: 'view',
11547
+ type: 'function',
11548
+ },
11549
+ {
11550
+ inputs: [],
11551
+ name: 'predicate',
11552
+ outputs: [
11553
+ {
11554
+ internalType: 'address',
11555
+ name: '',
11556
+ type: 'address',
11557
+ },
11558
+ ],
11559
+ stateMutability: 'view',
11560
+ type: 'function',
11561
+ },
11562
+ {
11563
+ inputs: [],
11564
+ name: 'rootToken',
11565
+ outputs: [
11566
+ {
11567
+ internalType: 'address',
11568
+ name: '',
11569
+ type: 'address',
11570
+ },
11571
+ ],
11572
+ stateMutability: 'view',
11573
+ type: 'function',
11574
+ },
11575
+ {
11576
+ inputs: [],
11577
+ name: 'symbol',
11578
+ outputs: [
11579
+ {
11580
+ internalType: 'string',
11581
+ name: '',
11582
+ type: 'string',
11583
+ },
11584
+ ],
11585
+ stateMutability: 'view',
11586
+ type: 'function',
11587
+ },
11588
+ {
11589
+ inputs: [],
11590
+ name: 'totalSupply',
11591
+ outputs: [
11592
+ {
11593
+ internalType: 'uint256',
11594
+ name: '',
11595
+ type: 'uint256',
11596
+ },
11597
+ ],
11598
+ stateMutability: 'view',
11599
+ type: 'function',
11600
+ },
11601
+ {
11602
+ inputs: [
11603
+ {
11604
+ internalType: 'address',
11605
+ name: 'to',
11606
+ type: 'address',
11607
+ },
11608
+ {
11609
+ internalType: 'uint256',
11610
+ name: 'amount',
11611
+ type: 'uint256',
11612
+ },
11613
+ ],
11614
+ name: 'transfer',
11615
+ outputs: [
11616
+ {
11617
+ internalType: 'bool',
11618
+ name: '',
11619
+ type: 'bool',
11620
+ },
11621
+ ],
11622
+ stateMutability: 'nonpayable',
11623
+ type: 'function',
11624
+ },
11625
+ {
11626
+ inputs: [
11627
+ {
11628
+ internalType: 'address',
11629
+ name: 'from',
11630
+ type: 'address',
11631
+ },
11632
+ {
11633
+ internalType: 'address',
11634
+ name: 'to',
11635
+ type: 'address',
11636
+ },
11637
+ {
11638
+ internalType: 'uint256',
11639
+ name: 'amount',
11640
+ type: 'uint256',
11641
+ },
11642
+ ],
11643
+ name: 'transferFrom',
11644
+ outputs: [
11645
+ {
11646
+ internalType: 'bool',
11647
+ name: '',
11648
+ type: 'bool',
11649
+ },
11650
+ ],
11651
+ stateMutability: 'nonpayable',
11652
+ type: 'function',
11653
+ },
11654
+ ];
11655
+
11656
+ /**
11657
+ * Represents a token bridge, which manages asset transfers between two chains.
11658
+ */
11659
+ class TokenBridge {
11660
+ /**
11661
+ * @property {BridgeConfiguration} config - The bridge configuration object.
11662
+ */
11663
+ config;
11664
+ /**
11665
+ * Constructs a TokenBridge instance.
11666
+ *
11667
+ * @param {BridgeConfiguration} config - The bridge configuration object.
11668
+ */
11669
+ constructor(config) {
11670
+ this.config = config;
11671
+ }
11672
+ /**
11673
+ * Retrieves the bridge fee for depositing a specific token, used to reimburse the bridge-relayer.
11674
+ * It is clipped from the deposit amount.
11675
+ *
11676
+ * @param {BridgeFeeRequest} req - The fee request object containing the token address for which the fee is required.
11677
+ * @returns {Promise<BridgeFeeResponse>} - A promise that resolves to an object containing the bridge fee for the specified token and a flag indicating if the token is bridgeable.
11678
+ * @throws {BridgeError} - If an error occurs during the fee retrieval, a BridgeError will be thrown with a specific error type.
11679
+ *
11680
+ * Possible BridgeError types include:
11681
+ * - INVALID_ADDRESS: The token address provided in the request is invalid.
11682
+ *
11683
+ * @example
11684
+ * const feeRequest = {
11685
+ * token: '0x123456...', // token
11686
+ * };
11687
+ *
11688
+ * @example
11689
+ * const feeRequest = {
11690
+ * token: 'NATIVE', // token
11691
+ * };
11692
+ *
11693
+ * bridgeSdk.getFee(feeRequest)
11694
+ * .then((feeResponse) => {
11695
+ * console.log('Bridgeable:', feeResponse.bridgeable);
11696
+ * console.log('Fee Amount:', feeResponse.feeAmount.toString());
11697
+ * })
11698
+ * .catch((error) => {
11699
+ * console.error('Error:', error.message);
11700
+ * });
11701
+ */
11702
+ async getFee(req) {
11703
+ this.validateChainConfiguration();
11704
+ if (req.token !== 'NATIVE' && !isAddress(req.token)) {
11705
+ throw new BridgeError(`token address ${req.token} is not a valid address`, BridgeErrorType.INVALID_ADDRESS);
11706
+ }
11707
+ return {
11708
+ bridgeable: true,
11709
+ feeAmount: BigNumber.from(0),
11710
+ };
11711
+ }
11712
+ /**
11713
+ * Retrieves the unsigned approval transaction for a deposit to the bridge.
11714
+ * Approval is required before depositing tokens to the bridge using
11715
+ *
11716
+ * @param {ApproveBridgeRequest} req - The approve bridge request object containing the depositor address, token address, and deposit amount.
11717
+ * @returns {Promise<ApproveBridgeResponse>} - A promise that resolves to an object containing the unsigned approval transaction and a flag indicating if the approval is required.
11718
+ * @throws {BridgeError} - If an error occurs during the transaction creation, a BridgeError will be thrown with a specific error type.
11719
+ *
11720
+ * Possible BridgeError types include:
11721
+ * - UNSUPPORTED_ERROR: The operation is not supported. Currently thrown when attempting to deposit native tokens.
11722
+ * - INVALID_ADDRESS: An Ethereum address provided in the request is invalid.
11723
+ * - INVALID_AMOUNT: The deposit amount provided in the request is invalid (less than or equal to 0).
11724
+ * - INTERNAL_ERROR: An unexpected error occurred during the execution, likely due to the bridge SDK implementation.
11725
+ * - PROVIDER_ERROR: An error occurred while interacting with the Ethereum provider. This includes issues calling the ERC20 smart contract
11726
+ *
11727
+ * @example
11728
+ * const approveRequest = {
11729
+ * depositorAddress: '0x123456...', // Depositor's Ethereum address
11730
+ * token: '0xabcdef...', // ERC20 token address
11731
+ * depositAmount: ethers.utils.parseUnits('100', 18), // Deposit amount in token's smallest unit (e.g., wei for Ether)
11732
+ * };
11733
+ *
11734
+ * bridgeSdk.getUnsignedApproveDepositBridgeTx(approveRequest)
11735
+ * .then((approveResponse) => {
11736
+ * if (approveResponse.unsignedTx) {
11737
+ * // Send the unsigned approval transaction to the depositor to sign and send
11738
+ * } else {
11739
+ * // No approval is required
11740
+ * }
11741
+ * })
11742
+ * .catch((error) => {
11743
+ * console.error('Error:', error.message);
11744
+ * });
11745
+ */
11746
+ async getUnsignedApproveDepositBridgeTx(req) {
11747
+ this.validateChainConfiguration();
11748
+ TokenBridge.validateDepositArgs(req.depositorAddress, req.depositAmount, req.token);
11749
+ // If the token is NATIVE, no approval is required
11750
+ if (req.token === 'NATIVE') {
11751
+ return {
11752
+ unsignedTx: null,
11753
+ };
11754
+ }
11755
+ const erc20Contract = await withBridgeError(async () => new Contract(req.token, ERC20, this.config.rootProvider), BridgeErrorType.PROVIDER_ERROR);
11756
+ // Get the current approved allowance of the RootERC20Predicate
11757
+ const rootERC20PredicateAllowance = await withBridgeError(() => erc20Contract.allowance(req.depositorAddress, this.config.bridgeContracts.rootChainERC20Predicate), BridgeErrorType.PROVIDER_ERROR);
11758
+ // If the allowance is greater than or equal to the deposit amount, no approval is required
11759
+ if (rootERC20PredicateAllowance.gte(req.depositAmount)) {
11760
+ return {
11761
+ unsignedTx: null,
11762
+ };
11763
+ }
11764
+ // Calculate the amount of tokens that need to be approved for deposit
11765
+ const approvalAmountRequired = req.depositAmount.sub(rootERC20PredicateAllowance);
11766
+ // Encode the approve function call data for the ERC20 contract
11767
+ const data = await withBridgeError(async () => erc20Contract.interface.encodeFunctionData('approve', [
11768
+ this.config.bridgeContracts.rootChainERC20Predicate,
11769
+ approvalAmountRequired,
11770
+ ]), BridgeErrorType.INTERNAL_ERROR);
11771
+ // Create the unsigned transaction for the approval
11772
+ const unsignedTx = {
11773
+ data,
11774
+ to: req.token,
11775
+ value: 0,
11776
+ from: req.depositorAddress,
11777
+ };
11778
+ return {
11779
+ unsignedTx,
11780
+ };
11781
+ }
11782
+ /**
11783
+ * Generates an unsigned deposit transaction for a user to sign and submit to the bridge.
11784
+ * Must be called after bridgeSdk.getUnsignedApproveDepositBridgeTx to ensure user has approved sufficient tokens for deposit.
11785
+ *
11786
+ * @param {BridgeDepositRequest} req - The deposit request object containing the required data for depositing tokens.
11787
+ * @returns {Promise<BridgeDepositResponse>} - A promise that resolves to an object containing the unsigned transaction data.
11788
+ * @throws {BridgeError} - If an error occurs during the generation of the unsigned transaction, a BridgeError will be thrown with a specific error type.
11789
+ *
11790
+ * Possible BridgeError types include:
11791
+ * - UNSUPPORTED_ERROR: The operation is not supported. Currently thrown when attempting to deposit native tokens.
11792
+ * - INVALID_ADDRESS: An Ethereum address provided in the request is invalid. This could be the depositor's, recipient's or the token's address.
11793
+ * - INVALID_AMOUNT: The deposit amount provided in the request is invalid (less than or equal to 0).
11794
+ * - INTERNAL_ERROR: An unexpected error occurred during the execution, likely due to the bridge SDK implementation.
11795
+ *
11796
+ * @example
11797
+ * const depositERC20Request = {
11798
+ * token: '0x123456...', // ERC20 token address
11799
+ * depositorAddress: '0xabcdef...', // User's wallet address
11800
+ * recipientAddress: '0x987654...', // Destination wallet address on the target chain
11801
+ * depositAmount: ethers.utils.parseUnits('100', 18), // Deposit amount in wei
11802
+ * };
11803
+ *
11804
+ * @example
11805
+ * const depositEtherTokenRequest = {
11806
+ * token: 'NATIVE',
11807
+ * depositorAddress: '0xabcdef...', // User's wallet address
11808
+ * recipientAddress: '0x987654...', // Destination wallet address on the target chain
11809
+ * depositAmount: ethers.utils.parseUnits('100', 18), // Deposit amount in wei
11810
+ * };
11811
+ *
11812
+ * bridgeSdk.getUnsignedDepositTx(depositRequest)
11813
+ * .then((depositResponse) => {
11814
+ * console.log(depositResponse.unsignedTx);
11815
+ * })
11816
+ * .catch((error) => {
11817
+ * console.error('Error:', error.message);
11818
+ * });
11819
+ */
11820
+ async getUnsignedDepositTx(req) {
11821
+ this.validateChainConfiguration();
11822
+ TokenBridge.validateDepositArgs(req.recipientAddress, req.depositAmount, req.token);
11823
+ const rootERC20PredicateContract = await withBridgeError(async () => {
11824
+ const contract = new Contract(this.config.bridgeContracts.rootChainERC20Predicate, ROOT_ERC20_PREDICATE);
11825
+ return contract;
11826
+ }, BridgeErrorType.INTERNAL_ERROR);
11827
+ // Convert the addresses to correct format addresses (e.g. prepend 0x if not already)
11828
+ const receipient = getAddress(req.recipientAddress);
11829
+ // Handle return if it is a native token
11830
+ if (req.token === 'NATIVE') {
11831
+ // Encode the function data into a payload
11832
+ const data = await withBridgeError(async () => rootERC20PredicateContract.interface.encodeFunctionData('depositNativeTo', [receipient]), BridgeErrorType.INTERNAL_ERROR);
11833
+ return {
11834
+ unsignedTx: {
11835
+ data,
11836
+ to: this.config.bridgeContracts.rootChainERC20Predicate,
11837
+ value: req.depositAmount,
11838
+ },
11839
+ };
11840
+ }
11841
+ // Handle return for ERC20
11842
+ const token = getAddress(req.token);
11843
+ // Encode the function data into a payload
11844
+ const data = await withBridgeError(async () => rootERC20PredicateContract.interface.encodeFunctionData('depositTo', [token, receipient, req.depositAmount]), BridgeErrorType.INTERNAL_ERROR);
11845
+ return {
11846
+ unsignedTx: {
11847
+ data,
11848
+ to: this.config.bridgeContracts.rootChainERC20Predicate,
11849
+ value: 0,
11850
+ },
11851
+ };
11852
+ }
11853
+ /**
11854
+ * Waits for the deposit transaction to be confirmed and synced from the root chain to the child chain.
11855
+ *
11856
+ * @param {WaitForDepositRequest} req - The wait for request object containing the transaction hash.
11857
+ * @returns {Promise<WaitForDepositResponse>} - A promise that resolves to an object containing the status of the deposit transaction.
11858
+ * @throws {BridgeError} - If an error occurs during the transaction confirmation or state sync, a BridgeError will be thrown with a specific error type.
11859
+ *
11860
+ * Possible BridgeError types include:
11861
+ * - PROVIDER_ERROR: An error occurred with the Ethereum provider during transaction confirmation or state synchronization.
11862
+ * - TRANSACTION_REVERTED: The transaction on the root chain was reverted.
11863
+ *
11864
+ * @example
11865
+ * const waitForRequest = {
11866
+ * transactionHash: '0x123456...', // Deposit transaction hash on the root chain
11867
+ * };
11868
+ *
11869
+ * bridgeSdk.waitForDeposit(waitForRequest)
11870
+ * .then((waitForResponse) => {
11871
+ * console.log('Deposit Transaction Status:', waitForResponse.status);
11872
+ * })
11873
+ * .catch((error) => {
11874
+ * console.error('Error:', error.message);
11875
+ * });
11876
+ */
11877
+ async waitForDeposit(req) {
11878
+ this.validateChainConfiguration();
11879
+ const rootTxReceipt = await withBridgeError(async () => this.config.rootProvider.waitForTransaction(req.transactionHash, this.config.rootChainFinalityBlocks), BridgeErrorType.PROVIDER_ERROR);
11880
+ // Throw an error if the transaction was reverted
11881
+ if (rootTxReceipt.status !== 1) {
11882
+ throw new BridgeError(`${rootTxReceipt.transactionHash} on rootchain was reverted`, BridgeErrorType.TRANSACTION_REVERTED);
11883
+ }
11884
+ // Get the state sync ID from the transaction receipt
11885
+ const stateSyncID = await withBridgeError(async () => this.getRootStateSyncID(rootTxReceipt), BridgeErrorType.PROVIDER_ERROR);
11886
+ // Get the block for the timestamp
11887
+ const rootBlock = await withBridgeError(async () => await this.config.rootProvider.getBlock(rootTxReceipt.blockNumber), BridgeErrorType.PROVIDER_ERROR, `failed to query block ${rootTxReceipt.blockNumber} on rootchain`);
11888
+ // Get the minimum block on childchain which corresponds with the timestamp on rootchain
11889
+ const minBlockRange = await withBridgeError(async () => getBlockNumberClosestToTimestamp(this.config.childProvider, rootBlock.timestamp, this.config.blockTime, this.config.clockInaccuracy), BridgeErrorType.PROVIDER_ERROR);
11890
+ // Get the upper bound for which we expect the StateSync event to occur
10142
11891
  const maxBlockRange = minBlockRange + this.config.maxDepositBlockDelay;
10143
11892
  // Poll till event observed
10144
11893
  const result = await withBridgeError(async () => this.waitForChildStateSync(stateSyncID, this.config.pollInterval, minBlockRange, maxBlockRange), BridgeErrorType.PROVIDER_ERROR);
@@ -10146,6 +11895,271 @@ class TokenBridge {
10146
11895
  status: result,
10147
11896
  };
10148
11897
  }
11898
+ /**
11899
+ * Retrieves the corresponding child token address for a given root token address.
11900
+ * This function is used to map a root token to its child token in the context of a bridging system between chains.
11901
+ * If the token is native, a special key is used to represent it.
11902
+ *
11903
+ * @param {RootTokenToChildTokenRequest} req - The request object containing the root token address or the string 'NATIVE'.
11904
+ * @returns {Promise<RootTokenToChildTokenResponse>} - A promise that resolves to an object containing the child token address.
11905
+ * @throws {BridgeError} - If an error occurs during the query, a BridgeError will be thrown with a specific error type.
11906
+ *
11907
+ * Possible BridgeError types include:
11908
+ * - INVALID_ADDRESS: If the Ethereum address provided in the request is invalid.
11909
+ * - PROVIDER_ERROR: If there's an error in querying the rootTokenToChildToken mapping.
11910
+ * - INTERNAL_ERROR: An unexpected error occurred during the execution.
11911
+ *
11912
+ * @example
11913
+ * const request = {
11914
+ * rootToken: '0x123456...', // Root token address or 'NATIVE'
11915
+ * };
11916
+ *
11917
+ * bridgeSdk.rootTokenToChildToken(request)
11918
+ * .then((response) => {
11919
+ * console.log(response.childToken); // Child token address
11920
+ * })
11921
+ * .catch((error) => {
11922
+ * console.error('Error:', error.message);
11923
+ * });
11924
+ */
11925
+ async rootTokenToChildToken(req) {
11926
+ // Validate the chain configuration to ensure proper setup
11927
+ this.validateChainConfiguration();
11928
+ // If the root token is native, use the native token key; otherwise, use the provided root token address
11929
+ const reqTokenAddress = (req.rootToken === 'NATIVE') ? NATIVE_TOKEN_BRIDGE_KEY : req.rootToken;
11930
+ // Validate the request token address
11931
+ if (!isAddress(reqTokenAddress)) {
11932
+ throw new BridgeError(`recipient address ${reqTokenAddress} is not a valid address`, BridgeErrorType.INVALID_ADDRESS);
11933
+ }
11934
+ // Create an instance of the root ERC20 predicate contract
11935
+ const childTokenAddress = await withBridgeError(async () => {
11936
+ const rootERC20Predicate = new Contract(this.config.bridgeContracts.rootChainERC20Predicate, ROOT_ERC20_PREDICATE, this.config.rootProvider);
11937
+ return await rootERC20Predicate.rootTokenToChildToken(reqTokenAddress);
11938
+ }, BridgeErrorType.PROVIDER_ERROR, 'failed to query rootTokenToChildToken mapping');
11939
+ // Return the child token address
11940
+ return {
11941
+ childToken: childTokenAddress,
11942
+ };
11943
+ }
11944
+ /**
11945
+ * Retrieves the corresponding root token address for a given child token address.
11946
+ * This function is used to map a child token back to its root token in the context of a bridging system between chains.
11947
+ *
11948
+ * If the root token address matches the address designated for the native token, the method will return 'NATIVE'.
11949
+ *
11950
+ * @param {ChildTokenToRootTokenRequest} req - The request object containing the child token address.
11951
+ * @returns {Promise<ChildTokenToRootTokenResponse>} - A promise that resolves to an object containing the root token address.
11952
+ * @throws {BridgeError} - If an error occurs during the query, a BridgeError will be thrown with a specific error type.
11953
+ *
11954
+ * Possible BridgeError types include:
11955
+ * - PROVIDER_ERROR: If there's an error in querying the root token from the child token contract.
11956
+ * - INVALID_TOKEN: If the token being withdrawed is not a valid bridgeable token
11957
+ *
11958
+ * @example
11959
+ * const request = {
11960
+ * childToken: '0x123456...', // Child token address
11961
+ * };
11962
+ *
11963
+ * bridgeSdk.childTokenToRootToken(request)
11964
+ * .then((response) => {
11965
+ * console.log(response.rootToken); // Outputs: 'NATIVE' or Root token address
11966
+ * })
11967
+ * .catch((error) => {
11968
+ * console.error('Error:', error.message);
11969
+ * });
11970
+ */
11971
+ async childTokenToRootToken(req) {
11972
+ // Validate the chain configuration to ensure proper setup
11973
+ this.validateChainConfiguration();
11974
+ // Query the corresponding root token address using the child token contract
11975
+ const rootToken = await withBridgeError(async () => {
11976
+ // Create an instance of the child token contract using the given child token address
11977
+ const childToken = new Contract(req.childToken, CHILD_ERC20, this.config.childProvider);
11978
+ return await childToken.rootToken();
11979
+ }, BridgeErrorType.PROVIDER_ERROR, 'failed to query the root token from the child token contract');
11980
+ // Check if the rootToken address is the designated native token address. If it is, return 'NATIVE'. Else, return the root token address.
11981
+ return {
11982
+ rootToken: (rootToken === NATIVE_TOKEN_BRIDGE_KEY) ? 'NATIVE' : rootToken,
11983
+ };
11984
+ }
11985
+ /**
11986
+ * Generates an unsigned transaction that a user can use to initiate a token withdrawal from the bridge.
11987
+ * The user must sign and submit this transaction to execute the withdrawal.
11988
+ *
11989
+ * @param {BridgeWithdrawRequest} req - The withdrawal request object containing the necessary data for withdrawing tokens.
11990
+ * @returns {Promise<BridgeWithdrawResponse>} - A promise that resolves to an object containing the unsigned transaction data.
11991
+ *
11992
+ * @throws {BridgeError} - If an error occurs during the generation of the unsigned transaction, a BridgeError will be thrown with a specific error type.
11993
+ * Possible BridgeError types include:
11994
+ * - INVALID_ADDRESS: The Ethereum address provided in the request is invalid. This could be the user's address or the token's address.
11995
+ * - INVALID_AMOUNT: The withdrawal amount provided in the request is invalid (less than or equal to 0).
11996
+ * - PROVIDER_ERROR: An error occurred when interacting with the Ethereum provider, likely due to a network or connectivity issue.
11997
+ * - INTERNAL_ERROR: An unexpected error occurred during the execution, likely due to the bridge SDK implementation.
11998
+ *
11999
+ * @example
12000
+ * const withdrawRequest = {
12001
+ * token: '0x123456...', // ERC20 token address
12002
+ * recipientAddress: '0xabcdef...', // Address to receive the withdrawn tokens
12003
+ * withdrawAmount: ethers.utils.parseUnits('100', 18), // Withdraw amount in wei
12004
+ * };
12005
+ *
12006
+ * bridgeSdk.getUnsignedWithdrawTx(withdrawRequest)
12007
+ * .then((withdrawalResponse) => {
12008
+ * console.log(withdrawalResponse.unsignedTx);
12009
+ * })
12010
+ * .catch((error) => {
12011
+ * console.error('Error:', error.message);
12012
+ * });
12013
+ */
12014
+ async getUnsignedWithdrawTx(req) {
12015
+ // Ensure the configuration of chains is valid.
12016
+ this.validateChainConfiguration();
12017
+ // Validate the recipient address, withdrawal amount, and token.
12018
+ TokenBridge.validateWithdrawArgs(req.recipientAddress, req.withdrawAmount, req.token);
12019
+ // Create a contract instance for interacting with the ChildERC20Predicate
12020
+ const childERC20PredicateContract = await withBridgeError(async () => {
12021
+ const contract = new Contract(this.config.bridgeContracts.childChainERC20Predicate, CHILD_ERC20_PREDICATE);
12022
+ return contract;
12023
+ }, BridgeErrorType.INTERNAL_ERROR);
12024
+ // Encode the withdrawTo function call data for the ERC20 contract
12025
+ const data = await withBridgeError(async () => childERC20PredicateContract.interface.encodeFunctionData('withdrawTo', [
12026
+ req.token,
12027
+ req.recipientAddress,
12028
+ req.withdrawAmount,
12029
+ ]), BridgeErrorType.INTERNAL_ERROR);
12030
+ // Construct the unsigned transaction for the withdrawal
12031
+ return {
12032
+ unsignedTx: {
12033
+ data,
12034
+ to: this.config.bridgeContracts.childChainERC20Predicate,
12035
+ value: 0,
12036
+ },
12037
+ };
12038
+ }
12039
+ /**
12040
+ * Waits for the withdrawal transaction to be confirmed in the root chain by continuously polling until the transaction is included in a checkpoint.
12041
+ * This function is intended to be used after executing a withdrawal transaction.
12042
+ *
12043
+ * @param {WaitForWithdrawalRequest} req - The request object containing the transaction hash of the withdrawal transaction.
12044
+ * @returns {Promise<WaitForWithdrawalResponse>} - A promise that resolves to an empty object once the withdrawal transaction has been confirmed in the root chain.
12045
+ *
12046
+ * @throws {BridgeError} - If an error occurs during the waiting process, a BridgeError will be thrown with a specific error type.
12047
+ * Possible BridgeError types include:
12048
+ * - PROVIDER_ERROR: An error occurred when interacting with the Ethereum provider, likely due to a network or connectivity issue.
12049
+ *
12050
+ * @example
12051
+ * const waitForWithdrawalRequest = {
12052
+ * transactionHash: '0x123456...', // Transaction hash of the withdrawal transaction
12053
+ * };
12054
+ *
12055
+ * bridgeSdk.waitForWithdrawal(waitForWithdrawalRequest)
12056
+ * .then(() => {
12057
+ * console.log('Withdrawal transaction has been confirmed in the root chain.');
12058
+ * })
12059
+ * .catch((error) => {
12060
+ * console.error('Error:', error.message);
12061
+ * });
12062
+ */
12063
+ async waitForWithdrawal(req) {
12064
+ // Ensure the configuration of chains is valid.
12065
+ this.validateChainConfiguration();
12066
+ // Helper function to pause execution for a specified interval
12067
+ const pause = () => new Promise((resolve) => {
12068
+ setTimeout(resolve, this.config.pollInterval);
12069
+ });
12070
+ await withBridgeError(async () => {
12071
+ // Fetch the receipt of the withdrawal transaction
12072
+ const transactionReceipt = await this.config.childProvider.getTransactionReceipt(req.transactionHash);
12073
+ // Fetch the block in which the withdrawal transaction was included
12074
+ const block = await this.config.childProvider.getBlock(transactionReceipt.blockNumber);
12075
+ // Decode the extra data field from the block header
12076
+ const decodedExtraData = decodeExtraData(block.extraData);
12077
+ // Instantiate the checkpoint manager contract
12078
+ const checkpointManager = new Contract(this.config.bridgeContracts.rootChainCheckpointManager, CHECKPOINT_MANAGER, this.config.rootProvider);
12079
+ // Recursive function to keep checking for the child deposit event
12080
+ const waitForRootEpoch = async () => {
12081
+ // Fetch the current checkpoint epoch from the root chain
12082
+ const currentEpoch = await checkpointManager.currentEpoch();
12083
+ // If the current epoch is greater than or equal to the epoch number of the checkpoint in which the withdrawal transaction was included, the withdrawal has been confirmed in the root chain
12084
+ if (currentEpoch >= decodedExtraData.checkpoint.epochNumber) {
12085
+ return null;
12086
+ }
12087
+ // Pause execution for a specified interval before checking again
12088
+ await pause();
12089
+ // Recursive call
12090
+ return waitForRootEpoch();
12091
+ };
12092
+ // Start waiting for the withdrawal transaction to be confirmed in the root chain
12093
+ await waitForRootEpoch();
12094
+ }, BridgeErrorType.PROVIDER_ERROR);
12095
+ // Return an empty object once the withdrawal transaction has been confirmed in the root chain
12096
+ return {};
12097
+ }
12098
+ /**
12099
+ * Creates an unsigned exit transaction which, when executed, will exit the assets from the child chain to the root chain.
12100
+ * This function should be used after a withdraw transaction has been executed on the child chain.
12101
+ * It should only be executed after `waitForWithdrawal` has completed successfully.
12102
+ *
12103
+ * @param {ExitRequest} req - The request object containing the transaction hash of the withdraw transaction.
12104
+ * @returns {Promise<ExitResponse>} - A promise that resolves to an object containing the unsigned exit transaction.
12105
+ *
12106
+ * @throws {BridgeError} - If an error occurs during the exit transaction creation process, a BridgeError will be thrown with a specific error type.
12107
+ * Possible BridgeError types include:
12108
+ * - PROVIDER_ERROR: An error occurred when interacting with the Ethereum provider, likely due to a network or connectivity issue.
12109
+ * - INVALID_TRANSACTION: The deposit transaction is invalid or the L2StateSynced event log does not match the expected format.
12110
+ * - INTERNAL_ERROR: An internal error occurred during the function call encoding process.
12111
+ *
12112
+ * @example
12113
+ * const exitRequest = {
12114
+ * transactionHash: '0x123456...', // Transaction hash of the deposit transaction
12115
+ * };
12116
+ *
12117
+ * bridgeSdk.getUnsignedExitTx(exitRequest)
12118
+ * .then((response) => {
12119
+ * console.log('Unsigned exit transaction:', response.unsignedTx);
12120
+ * })
12121
+ * .catch((error) => {
12122
+ * console.error('Error:', error.message);
12123
+ * });
12124
+ */
12125
+ async getUnsignedExitTx(req) {
12126
+ // Ensure the configuration of chains is valid
12127
+ this.validateChainConfiguration();
12128
+ // Fetch the receipt of the deposit transaction
12129
+ const txReceipt = await withBridgeError(async () => await this.config.childProvider.getTransactionReceipt(req.transactionHash), BridgeErrorType.PROVIDER_ERROR);
12130
+ // Filter out the StateSynced event log from the transaction receipt
12131
+ const stateSenderLogs = txReceipt.logs.filter((log) => log.address.toLowerCase() === L2_STATE_SENDER_ADDRESS);
12132
+ if (stateSenderLogs.length !== 1) {
12133
+ throw new BridgeError(`expected 1 log in tx ${txReceipt.transactionHash} from address ${L2_STATE_SENDER_ADDRESS}`, BridgeErrorType.INVALID_TRANSACTION);
12134
+ }
12135
+ // Parse the StateSynced event log
12136
+ const l2StateSyncEvent = await withBridgeError(async () => {
12137
+ const l2StateSenderInterface = new Interface(L2_STATE_SENDER);
12138
+ const event = l2StateSenderInterface.parseLog(stateSenderLogs[0]);
12139
+ // Throw an error if the event log doesn't match the expected format
12140
+ if (event.signature !== 'L2StateSynced(uint256,address,address,bytes)') {
12141
+ throw new Error(`expected L2StateSynced event in tx ${txReceipt.transactionHash}`);
12142
+ }
12143
+ return event;
12144
+ }, BridgeErrorType.INVALID_TRANSACTION);
12145
+ // Instantiate the exit helper contract
12146
+ const exitHelper = await withBridgeError(async () => new Contract(this.config.bridgeContracts.rootChainExitHelper, EXIT_HELPER, this.config.rootProvider), BridgeErrorType.PROVIDER_ERROR);
12147
+ // Generate the exit proof
12148
+ const exitProof = await withBridgeError(async () => this.config.childProvider.send('bridge_generateExitProof', [l2StateSyncEvent.args.id.toHexString()]), BridgeErrorType.PROVIDER_ERROR);
12149
+ // Encode the exit function call data
12150
+ const encodedExitTx = await withBridgeError(async () => {
12151
+ const exitEventEncoded = defaultAbiCoder.encode(['uint256', 'address', 'address', 'bytes'], l2StateSyncEvent.args);
12152
+ return exitHelper.interface.encodeFunctionData('exit', [exitProof.Metadata.CheckpointBlock, exitProof.Metadata.LeafIndex, exitEventEncoded, exitProof.Data]);
12153
+ }, BridgeErrorType.INTERNAL_ERROR);
12154
+ // Create the unsigned exit transaction
12155
+ const unsignedTx = {
12156
+ data: encodedExitTx,
12157
+ to: this.config.bridgeContracts.rootChainExitHelper,
12158
+ value: 0,
12159
+ };
12160
+ // Return the unsigned exit transaction
12161
+ return { unsignedTx };
12162
+ }
10149
12163
  async waitForChildStateSync(stateSyncID, interval, minBlockRange, maxBlockRange) {
10150
12164
  const childStateReceiver = new Contract(this.config.bridgeContracts.childChainStateReceiver, CHILD_STATE_RECEIVER, this.config.childProvider);
10151
12165
  // Set up an event filter for the StateSyncResult event
@@ -10196,57 +12210,47 @@ class TokenBridge {
10196
12210
  const stateSyncID = parseInt(stateSyncEvent.args.id, 10);
10197
12211
  return stateSyncID;
10198
12212
  }
10199
- // TODO: please fix this
10200
- // eslint-disable-next-line class-methods-use-this
10201
- async getFeeForToken(
10202
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
10203
- token) {
10204
- return BigNumber.from(0);
10205
- }
10206
- }
10207
-
10208
- /**
10209
- * @constant {string} ETH_SEPOLIA_CHAIN_ID - The chain ID for the Ethereum Sepolia testnet (EIP-155 compatible format).
10210
- */
10211
- const ETH_SEPOLIA_CHAIN_ID = 'eip155:11155111';
10212
- /**
10213
- * @constant {string} ETH_MAINNET_CHAIN_ID - The chain ID for the Ethereum mainnet (EIP-155 compatible format).
10214
- */
10215
- const ETH_MAINNET_CHAIN_ID = 'eip155:1';
10216
- /**
10217
- * @constant {string} ZKEVM_DEVNET_CHAIN_ID - The chain ID for the zkEVM devnet (EIP-155 compatible format).
10218
- */
10219
- const ZKEVM_DEVNET_CHAIN_ID = 'eip155:13423';
10220
- /**
10221
- /**
10222
- * @constant {string} ZKEVM_TESTNET_CHAIN_ID - The chain ID for the zkEVM testnet (EIP-155 compatible format).
10223
- */
10224
- const ZKEVM_TESTNET_CHAIN_ID = 'eip155:13372';
10225
- /**
10226
- * @constant {string} ZKEVM_MAINNET_CHAIN_ID - The chain ID for the zkEVM mainnet (EIP-155 compatible format).
10227
- */
10228
- const ZKEVM_MAINNET_CHAIN_ID = 'eip155:13371';
10229
- /**
10230
- * @constant {BridgeInstance} ETH_SEPOLIA_TO_ZKEVM_DEVNET - A bridge instance configuration for bridging between the Ethereum Sepolia testnet and the zkEVM devnet.
10231
- */
10232
- const ETH_SEPOLIA_TO_ZKEVM_DEVNET = {
10233
- rootChainID: ETH_SEPOLIA_CHAIN_ID,
10234
- childChainID: ZKEVM_DEVNET_CHAIN_ID,
10235
- };
10236
- /**
10237
- * @constant {BridgeInstance} ETH_SEPOLIA_TO_ZKEVM_TESTNET - A bridge instance configuration for bridging between the Ethereum Sepolia testnet and the zkEVM testnet.
10238
- */
10239
- const ETH_SEPOLIA_TO_ZKEVM_TESTNET = {
10240
- rootChainID: ETH_SEPOLIA_CHAIN_ID,
10241
- childChainID: ZKEVM_TESTNET_CHAIN_ID,
10242
- };
10243
- /**
10244
- * @constant {BridgeInstance} ETH_MAINNET_TO_ZKEVM_MAINNET - A bridge instance configuration for bridging between the Ethereum mainnet and the zkEVM mainnet.
10245
- */
10246
- const ETH_MAINNET_TO_ZKEVM_MAINNET = {
10247
- rootChainID: ETH_MAINNET_CHAIN_ID,
10248
- childChainID: ZKEVM_MAINNET_CHAIN_ID,
10249
- };
12213
+ static validateDepositArgs(depositorOrRecipientAddress, depositAmount, token) {
12214
+ if (!isAddress(depositorOrRecipientAddress)) {
12215
+ throw new BridgeError(`address ${depositorOrRecipientAddress} is not a valid address`, BridgeErrorType.INVALID_ADDRESS);
12216
+ }
12217
+ // The deposit amount cannot be <= 0
12218
+ if (depositAmount.isNegative() || depositAmount.isZero()) {
12219
+ throw new BridgeError(`deposit amount ${depositAmount.toString()} is invalid`, BridgeErrorType.INVALID_AMOUNT);
12220
+ }
12221
+ // If the token is not native, it must be a valid address
12222
+ if (token !== 'NATIVE' && !isAddress(token)) {
12223
+ throw new BridgeError(`token address ${token} is not a valid address`, BridgeErrorType.INVALID_ADDRESS);
12224
+ }
12225
+ }
12226
+ static validateWithdrawArgs(withdrawerOrRecipientAddress, withdrawAmount, token) {
12227
+ // Validate the withdrawer address
12228
+ if (!isAddress(withdrawerOrRecipientAddress)) {
12229
+ throw new BridgeError(`withdrawer address ${withdrawerOrRecipientAddress} is not a valid address`, BridgeErrorType.INVALID_ADDRESS);
12230
+ }
12231
+ // Validate the withdrawal amount. It cannot be zero or negative.
12232
+ if (withdrawAmount.isNegative() || withdrawAmount.isZero()) {
12233
+ throw new BridgeError(`withdraw amount ${withdrawAmount.toString()} is invalid`, BridgeErrorType.INVALID_AMOUNT);
12234
+ }
12235
+ // Check if the ERC20 Token is a valid address
12236
+ if (!isAddress(token)) {
12237
+ throw new BridgeError(`token address ${token} is not a valid address`, BridgeErrorType.INVALID_ADDRESS);
12238
+ }
12239
+ }
12240
+ // Query the rootchain and childchain providers to ensure the chainID is as expected by the SDK.
12241
+ // This is to prevent the SDK from being used on the wrong chain, especially after a chain reset.
12242
+ async validateChainConfiguration() {
12243
+ const errMessage = 'Please upgrade to the latest version of the Bridge SDK or provide valid configuration';
12244
+ const rootNetwork = await withBridgeError(async () => this.config.rootProvider.getNetwork(), BridgeErrorType.PROVIDER_ERROR);
12245
+ if (rootNetwork.chainId.toString() !== this.config.bridgeInstance.rootChainID) {
12246
+ throw new BridgeError(`Rootchain provider chainID ${rootNetwork.chainId} does not match expected chainID ${this.config.bridgeInstance.rootChainID}. ${errMessage}`, BridgeErrorType.UNSUPPORTED_ERROR);
12247
+ }
12248
+ const childNetwork = await this.config.childProvider.getNetwork();
12249
+ if (childNetwork.chainId.toString() !== this.config.bridgeInstance.childChainID) {
12250
+ throw new BridgeError(`Childchain provider chainID ${childNetwork.chainId} does not match expected chainID ${this.config.bridgeInstance.childChainID}. ${errMessage}`, BridgeErrorType.UNSUPPORTED_ERROR);
12251
+ }
12252
+ }
12253
+ }
10250
12254
 
10251
12255
  var Environment;
10252
12256
  (function (Environment) {
@@ -10274,20 +12278,26 @@ const SUPPORTED_BRIDGES_FOR_ENVIRONMENT = {
10274
12278
  */
10275
12279
  const CONTRACTS_FOR_BRIDGE = new Map()
10276
12280
  .set(ETH_SEPOLIA_TO_ZKEVM_DEVNET, {
10277
- rootChainERC20Predicate: '0xf0b3435411A74F1aeCBD0fd6D53a90D5227fEeba',
10278
- rootChainStateSender: '0x868097dbAcfD431F441d09D0e4D3B5eD3182E597',
12281
+ rootChainERC20Predicate: '0xAC0f2096732D40096B3356AD76ba60a2f02366c8',
12282
+ rootChainStateSender: '0xeA76fcCdD791A9c231CAda787ae7535c8a5E55B5',
12283
+ rootChainCheckpointManager: '0x321A466aa78F5957C6E2375114915EcD14DAdE44',
12284
+ rootChainExitHelper: '0x55cA8C418bbB0aC87414F9ea6FFC6a33860Cf967',
10279
12285
  childChainERC20Predicate: '0x0000000000000000000000000000000000001004',
10280
12286
  childChainStateReceiver: '0x0000000000000000000000000000000000001001',
10281
12287
  })
10282
12288
  .set(ETH_SEPOLIA_TO_ZKEVM_TESTNET, {
10283
12289
  rootChainERC20Predicate: '0x0C15a8359865867CdCC44f98b2F3fd5DF098C7E0',
10284
12290
  rootChainStateSender: '0x4C80001188db53dbc2eaAb32d5ef825feEedECA5',
12291
+ rootChainCheckpointManager: '0x0F3157bc91f66C350f87172bBB28d9417167074F',
12292
+ rootChainExitHelper: '0xB057A6C4e951a315E9f2DAe6d28B83cD0480e873',
10285
12293
  childChainERC20Predicate: '0x0000000000000000000000000000000000001004',
10286
12294
  childChainStateReceiver: '0x0000000000000000000000000000000000001001',
10287
12295
  })
10288
12296
  .set(ETH_MAINNET_TO_ZKEVM_MAINNET, {
10289
12297
  rootChainERC20Predicate: '0x',
10290
12298
  rootChainStateSender: '0x',
12299
+ rootChainCheckpointManager: '0x',
12300
+ rootChainExitHelper: '0x',
10291
12301
  childChainERC20Predicate: '0x',
10292
12302
  childChainStateReceiver: '0x',
10293
12303
  });
@@ -10477,7 +12487,7 @@ const calculateGasFee = (gasPriceInWei, gasUsed) => gasUsed.mul(gasPriceInWei);
10477
12487
  /* Autogenerated file. Do not edit manually. */
10478
12488
  /* tslint:disable */
10479
12489
  /* eslint-disable */
10480
- const _abi$2 = [
12490
+ const _abi$3 = [
10481
12491
  {
10482
12492
  constant: true,
10483
12493
  inputs: [],
@@ -10700,12 +12710,12 @@ const _abi$2 = [
10700
12710
  },
10701
12711
  ];
10702
12712
  class ERC20__factory {
10703
- static abi = _abi$2;
12713
+ static abi = _abi$3;
10704
12714
  static createInterface() {
10705
- return new utils.Interface(_abi$2);
12715
+ return new utils.Interface(_abi$3);
10706
12716
  }
10707
12717
  static connect(address, signerOrProvider) {
10708
- return new Contract$1(address, _abi$2, signerOrProvider);
12718
+ return new Contract$1(address, _abi$3, signerOrProvider);
10709
12719
  }
10710
12720
  }
10711
12721
 
@@ -10896,6 +12906,8 @@ const DEFAULT_MAX_HOPS = 2;
10896
12906
  const MAX_MAX_HOPS = 10;
10897
12907
  // a max hop of 1 will require a direct swap with no intermediary pools
10898
12908
  const MIN_MAX_HOPS = 1;
12909
+ // 10% maximum secondary fee
12910
+ const MAX_SECONDARY_FEE_BASIS_POINTS = 10000;
10899
12911
 
10900
12912
  const quoteReturnMapping = {
10901
12913
  // eslint-disable-next-line @typescript-eslint/naming-convention
@@ -10952,37 +12964,377 @@ const tokenInfoToUniswapToken = (tokenInfo) => new Token(tokenInfo.chainId, toke
10952
12964
  /* Autogenerated file. Do not edit manually. */
10953
12965
  /* tslint:disable */
10954
12966
  /* eslint-disable */
10955
- const _abi$1 = [
12967
+ const _abi$2 = [
10956
12968
  {
10957
12969
  inputs: [],
10958
12970
  name: "getCurrentBlockTimestamp",
10959
12971
  outputs: [
10960
12972
  {
10961
12973
  internalType: "uint256",
10962
- name: "timestamp",
12974
+ name: "timestamp",
12975
+ type: "uint256",
12976
+ },
12977
+ ],
12978
+ stateMutability: "view",
12979
+ type: "function",
12980
+ },
12981
+ {
12982
+ inputs: [
12983
+ {
12984
+ internalType: "address",
12985
+ name: "addr",
12986
+ type: "address",
12987
+ },
12988
+ ],
12989
+ name: "getEthBalance",
12990
+ outputs: [
12991
+ {
12992
+ internalType: "uint256",
12993
+ name: "balance",
12994
+ type: "uint256",
12995
+ },
12996
+ ],
12997
+ stateMutability: "view",
12998
+ type: "function",
12999
+ },
13000
+ {
13001
+ inputs: [
13002
+ {
13003
+ components: [
13004
+ {
13005
+ internalType: "address",
13006
+ name: "target",
13007
+ type: "address",
13008
+ },
13009
+ {
13010
+ internalType: "uint256",
13011
+ name: "gasLimit",
13012
+ type: "uint256",
13013
+ },
13014
+ {
13015
+ internalType: "bytes",
13016
+ name: "callData",
13017
+ type: "bytes",
13018
+ },
13019
+ ],
13020
+ internalType: "struct UniswapInterfaceMulticall.Call[]",
13021
+ name: "calls",
13022
+ type: "tuple[]",
13023
+ },
13024
+ ],
13025
+ name: "multicall",
13026
+ outputs: [
13027
+ {
13028
+ internalType: "uint256",
13029
+ name: "blockNumber",
13030
+ type: "uint256",
13031
+ },
13032
+ {
13033
+ components: [
13034
+ {
13035
+ internalType: "bool",
13036
+ name: "success",
13037
+ type: "bool",
13038
+ },
13039
+ {
13040
+ internalType: "uint256",
13041
+ name: "gasUsed",
13042
+ type: "uint256",
13043
+ },
13044
+ {
13045
+ internalType: "bytes",
13046
+ name: "returnData",
13047
+ type: "bytes",
13048
+ },
13049
+ ],
13050
+ internalType: "struct UniswapInterfaceMulticall.Result[]",
13051
+ name: "returnData",
13052
+ type: "tuple[]",
13053
+ },
13054
+ ],
13055
+ stateMutability: "nonpayable",
13056
+ type: "function",
13057
+ },
13058
+ ];
13059
+ const _bytecode$2 = "0x608060405234801561001057600080fd5b50610567806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80630f28c97d146100465780631749e1e3146100645780634d2301cc14610085575b600080fd5b61004e610098565b60405161005b919061041f565b60405180910390f35b6100776100723660046102a7565b61009c565b60405161005b929190610428565b61004e610093366004610286565b610220565b4290565b8051439060609067ffffffffffffffff811180156100b957600080fd5b506040519080825280602002602001820160405280156100f357816020015b6100e061023a565b8152602001906001900390816100d85790505b50905060005b835181101561021a57600080600086848151811061011357fe5b60200260200101516000015187858151811061012b57fe5b60200260200101516020015188868151811061014357fe5b60200260200101516040015192509250925060005a90506000808573ffffffffffffffffffffffffffffffffffffffff1685856040516101839190610403565b60006040518083038160008787f1925050503d80600081146101c1576040519150601f19603f3d011682016040523d82523d6000602084013e6101c6565b606091505b509150915060005a8403905060405180606001604052808415158152602001828152602001838152508989815181106101fb57fe5b60200260200101819052505050505050505080806001019150506100f9565b50915091565b73ffffffffffffffffffffffffffffffffffffffff163190565b604051806060016040528060001515815260200160008152602001606081525090565b803573ffffffffffffffffffffffffffffffffffffffff8116811461028157600080fd5b919050565b600060208284031215610297578081fd5b6102a08261025d565b9392505050565b600060208083850312156102b9578182fd5b823567ffffffffffffffff808211156102d0578384fd5b818501915085601f8301126102e3578384fd5b8135818111156102ef57fe5b6102fc8485830201610506565b81815284810190848601875b848110156103f457813587017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0606081838f03011215610346578a8bfd5b60408051606081018181108b8211171561035c57fe5b8252610369848d0161025d565b8152818401358c82015260608401358a811115610384578d8efd5b8085019450508e603f850112610398578c8dfd5b8b8401358a8111156103a657fe5b6103b68d85601f84011601610506565b93508084528f838287010111156103cb578d8efd5b808386018e86013783018c018d9052908101919091528552509287019290870190600101610308565b50909998505050505050505050565b6000825161041581846020870161052a565b9190910192915050565b90815260200190565b600060408083018584526020828186015281865180845260609350838701915083838202880101838901875b838110156104f6578983037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa001855281518051151584528681015187850152880151888401889052805188850181905260806104b582828801858c0161052a565b96880196601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01694909401909301925090850190600101610454565b50909a9950505050505050505050565b60405181810167ffffffffffffffff8111828210171561052257fe5b604052919050565b60005b8381101561054557818101518382015260200161052d565b83811115610554576000848401525b5050505056fea164736f6c6343000706000a";
13060
+ const isSuperArgs$2 = (xs) => xs.length > 1;
13061
+ class Multicall__factory extends ContractFactory {
13062
+ constructor(...args) {
13063
+ if (isSuperArgs$2(args)) {
13064
+ super(...args);
13065
+ }
13066
+ else {
13067
+ super(_abi$2, _bytecode$2, args[0]);
13068
+ }
13069
+ }
13070
+ deploy(overrides) {
13071
+ return super.deploy(overrides || {});
13072
+ }
13073
+ getDeployTransaction(overrides) {
13074
+ return super.getDeployTransaction(overrides || {});
13075
+ }
13076
+ attach(address) {
13077
+ return super.attach(address);
13078
+ }
13079
+ connect(signer) {
13080
+ return super.connect(signer);
13081
+ }
13082
+ static bytecode = _bytecode$2;
13083
+ static abi = _abi$2;
13084
+ static createInterface() {
13085
+ return new utils.Interface(_abi$2);
13086
+ }
13087
+ static connect(address, signerOrProvider) {
13088
+ return new Contract$1(address, _abi$2, signerOrProvider);
13089
+ }
13090
+ }
13091
+
13092
+ /* Autogenerated file. Do not edit manually. */
13093
+ /* tslint:disable */
13094
+ /* eslint-disable */
13095
+ const _abi$1 = [
13096
+ {
13097
+ inputs: [
13098
+ {
13099
+ internalType: "address",
13100
+ name: "_uniRouter",
13101
+ type: "address",
13102
+ },
13103
+ ],
13104
+ stateMutability: "nonpayable",
13105
+ type: "constructor",
13106
+ },
13107
+ {
13108
+ anonymous: false,
13109
+ inputs: [
13110
+ {
13111
+ indexed: true,
13112
+ internalType: "address",
13113
+ name: "feeToken",
13114
+ type: "address",
13115
+ },
13116
+ {
13117
+ indexed: true,
13118
+ internalType: "address",
13119
+ name: "feePayer",
13120
+ type: "address",
13121
+ },
13122
+ {
13123
+ indexed: true,
13124
+ internalType: "address",
13125
+ name: "feeRecipient",
13126
+ type: "address",
13127
+ },
13128
+ {
13129
+ indexed: false,
13130
+ internalType: "uint256",
13131
+ name: "feeAmount",
13132
+ type: "uint256",
13133
+ },
13134
+ ],
13135
+ name: "FeeTaken",
13136
+ type: "event",
13137
+ },
13138
+ {
13139
+ anonymous: false,
13140
+ inputs: [
13141
+ {
13142
+ indexed: true,
13143
+ internalType: "address",
13144
+ name: "previousOwner",
13145
+ type: "address",
13146
+ },
13147
+ {
13148
+ indexed: true,
13149
+ internalType: "address",
13150
+ name: "newOwner",
13151
+ type: "address",
13152
+ },
13153
+ ],
13154
+ name: "OwnershipTransferred",
13155
+ type: "event",
13156
+ },
13157
+ {
13158
+ anonymous: false,
13159
+ inputs: [
13160
+ {
13161
+ indexed: false,
13162
+ internalType: "address",
13163
+ name: "account",
13164
+ type: "address",
13165
+ },
13166
+ ],
13167
+ name: "Paused",
13168
+ type: "event",
13169
+ },
13170
+ {
13171
+ anonymous: false,
13172
+ inputs: [
13173
+ {
13174
+ indexed: false,
13175
+ internalType: "address",
13176
+ name: "account",
13177
+ type: "address",
13178
+ },
13179
+ ],
13180
+ name: "Unpaused",
13181
+ type: "event",
13182
+ },
13183
+ {
13184
+ inputs: [],
13185
+ name: "BASIS_POINT_PRECISION",
13186
+ outputs: [
13187
+ {
13188
+ internalType: "uint16",
13189
+ name: "",
13190
+ type: "uint16",
13191
+ },
13192
+ ],
13193
+ stateMutability: "view",
13194
+ type: "function",
13195
+ },
13196
+ {
13197
+ inputs: [],
13198
+ name: "MAX_SERVICE_FEE",
13199
+ outputs: [
13200
+ {
13201
+ internalType: "uint16",
13202
+ name: "",
13203
+ type: "uint16",
13204
+ },
13205
+ ],
13206
+ stateMutability: "view",
13207
+ type: "function",
13208
+ },
13209
+ {
13210
+ inputs: [
13211
+ {
13212
+ components: [
13213
+ {
13214
+ internalType: "address",
13215
+ name: "recipient",
13216
+ type: "address",
13217
+ },
13218
+ {
13219
+ internalType: "uint16",
13220
+ name: "feePrcntBasisPoints",
13221
+ type: "uint16",
13222
+ },
13223
+ ],
13224
+ internalType: "struct ISecondaryFee.ServiceFeeParams[]",
13225
+ name: "serviceFee",
13226
+ type: "tuple[]",
13227
+ },
13228
+ {
13229
+ components: [
13230
+ {
13231
+ internalType: "address",
13232
+ name: "tokenIn",
13233
+ type: "address",
13234
+ },
13235
+ {
13236
+ internalType: "address",
13237
+ name: "tokenOut",
13238
+ type: "address",
13239
+ },
13240
+ {
13241
+ internalType: "uint24",
13242
+ name: "fee",
13243
+ type: "uint24",
13244
+ },
13245
+ {
13246
+ internalType: "address",
13247
+ name: "recipient",
13248
+ type: "address",
13249
+ },
13250
+ {
13251
+ internalType: "uint256",
13252
+ name: "amountIn",
13253
+ type: "uint256",
13254
+ },
13255
+ {
13256
+ internalType: "uint256",
13257
+ name: "amountOutMinimum",
13258
+ type: "uint256",
13259
+ },
13260
+ {
13261
+ internalType: "uint160",
13262
+ name: "sqrtPriceLimitX96",
13263
+ type: "uint160",
13264
+ },
13265
+ ],
13266
+ internalType: "struct IV3SwapRouter.ExactInputSingleParams",
13267
+ name: "params",
13268
+ type: "tuple",
13269
+ },
13270
+ ],
13271
+ name: "exactInputSingleWithServiceFee",
13272
+ outputs: [
13273
+ {
13274
+ internalType: "uint256",
13275
+ name: "amountOut",
10963
13276
  type: "uint256",
10964
13277
  },
10965
13278
  ],
10966
- stateMutability: "view",
13279
+ stateMutability: "payable",
10967
13280
  type: "function",
10968
13281
  },
10969
13282
  {
10970
13283
  inputs: [
10971
13284
  {
10972
- internalType: "address",
10973
- name: "addr",
10974
- type: "address",
13285
+ components: [
13286
+ {
13287
+ internalType: "address",
13288
+ name: "recipient",
13289
+ type: "address",
13290
+ },
13291
+ {
13292
+ internalType: "uint16",
13293
+ name: "feePrcntBasisPoints",
13294
+ type: "uint16",
13295
+ },
13296
+ ],
13297
+ internalType: "struct ISecondaryFee.ServiceFeeParams[]",
13298
+ name: "serviceFee",
13299
+ type: "tuple[]",
13300
+ },
13301
+ {
13302
+ components: [
13303
+ {
13304
+ internalType: "bytes",
13305
+ name: "path",
13306
+ type: "bytes",
13307
+ },
13308
+ {
13309
+ internalType: "address",
13310
+ name: "recipient",
13311
+ type: "address",
13312
+ },
13313
+ {
13314
+ internalType: "uint256",
13315
+ name: "amountIn",
13316
+ type: "uint256",
13317
+ },
13318
+ {
13319
+ internalType: "uint256",
13320
+ name: "amountOutMinimum",
13321
+ type: "uint256",
13322
+ },
13323
+ ],
13324
+ internalType: "struct IV3SwapRouter.ExactInputParams",
13325
+ name: "params",
13326
+ type: "tuple",
10975
13327
  },
10976
13328
  ],
10977
- name: "getEthBalance",
13329
+ name: "exactInputWithServiceFee",
10978
13330
  outputs: [
10979
13331
  {
10980
13332
  internalType: "uint256",
10981
- name: "balance",
13333
+ name: "amountOut",
10982
13334
  type: "uint256",
10983
13335
  },
10984
13336
  ],
10985
- stateMutability: "view",
13337
+ stateMutability: "payable",
10986
13338
  type: "function",
10987
13339
  },
10988
13340
  {
@@ -10991,62 +13343,251 @@ const _abi$1 = [
10991
13343
  components: [
10992
13344
  {
10993
13345
  internalType: "address",
10994
- name: "target",
13346
+ name: "recipient",
13347
+ type: "address",
13348
+ },
13349
+ {
13350
+ internalType: "uint16",
13351
+ name: "feePrcntBasisPoints",
13352
+ type: "uint16",
13353
+ },
13354
+ ],
13355
+ internalType: "struct ISecondaryFee.ServiceFeeParams[]",
13356
+ name: "serviceFee",
13357
+ type: "tuple[]",
13358
+ },
13359
+ {
13360
+ components: [
13361
+ {
13362
+ internalType: "address",
13363
+ name: "tokenIn",
13364
+ type: "address",
13365
+ },
13366
+ {
13367
+ internalType: "address",
13368
+ name: "tokenOut",
13369
+ type: "address",
13370
+ },
13371
+ {
13372
+ internalType: "uint24",
13373
+ name: "fee",
13374
+ type: "uint24",
13375
+ },
13376
+ {
13377
+ internalType: "address",
13378
+ name: "recipient",
10995
13379
  type: "address",
10996
13380
  },
10997
13381
  {
10998
13382
  internalType: "uint256",
10999
- name: "gasLimit",
13383
+ name: "amountOut",
11000
13384
  type: "uint256",
11001
13385
  },
11002
13386
  {
11003
- internalType: "bytes",
11004
- name: "callData",
11005
- type: "bytes",
13387
+ internalType: "uint256",
13388
+ name: "amountInMaximum",
13389
+ type: "uint256",
13390
+ },
13391
+ {
13392
+ internalType: "uint160",
13393
+ name: "sqrtPriceLimitX96",
13394
+ type: "uint160",
11006
13395
  },
11007
13396
  ],
11008
- internalType: "struct UniswapInterfaceMulticall.Call[]",
11009
- name: "calls",
11010
- type: "tuple[]",
13397
+ internalType: "struct IV3SwapRouter.ExactOutputSingleParams",
13398
+ name: "params",
13399
+ type: "tuple",
11011
13400
  },
11012
13401
  ],
11013
- name: "multicall",
13402
+ name: "exactOutputSingleWithServiceFee",
11014
13403
  outputs: [
11015
13404
  {
11016
13405
  internalType: "uint256",
11017
- name: "blockNumber",
13406
+ name: "amountIn",
11018
13407
  type: "uint256",
11019
13408
  },
13409
+ ],
13410
+ stateMutability: "payable",
13411
+ type: "function",
13412
+ },
13413
+ {
13414
+ inputs: [
11020
13415
  {
11021
13416
  components: [
11022
13417
  {
11023
- internalType: "bool",
11024
- name: "success",
11025
- type: "bool",
13418
+ internalType: "address",
13419
+ name: "recipient",
13420
+ type: "address",
11026
13421
  },
11027
13422
  {
11028
- internalType: "uint256",
11029
- name: "gasUsed",
11030
- type: "uint256",
13423
+ internalType: "uint16",
13424
+ name: "feePrcntBasisPoints",
13425
+ type: "uint16",
11031
13426
  },
13427
+ ],
13428
+ internalType: "struct ISecondaryFee.ServiceFeeParams[]",
13429
+ name: "serviceFee",
13430
+ type: "tuple[]",
13431
+ },
13432
+ {
13433
+ components: [
11032
13434
  {
11033
13435
  internalType: "bytes",
11034
- name: "returnData",
13436
+ name: "path",
11035
13437
  type: "bytes",
11036
13438
  },
13439
+ {
13440
+ internalType: "address",
13441
+ name: "recipient",
13442
+ type: "address",
13443
+ },
13444
+ {
13445
+ internalType: "uint256",
13446
+ name: "amountOut",
13447
+ type: "uint256",
13448
+ },
13449
+ {
13450
+ internalType: "uint256",
13451
+ name: "amountInMaximum",
13452
+ type: "uint256",
13453
+ },
11037
13454
  ],
11038
- internalType: "struct UniswapInterfaceMulticall.Result[]",
11039
- name: "returnData",
11040
- type: "tuple[]",
13455
+ internalType: "struct IV3SwapRouter.ExactOutputParams",
13456
+ name: "params",
13457
+ type: "tuple",
13458
+ },
13459
+ ],
13460
+ name: "exactOutputWithServiceFee",
13461
+ outputs: [
13462
+ {
13463
+ internalType: "uint256",
13464
+ name: "amountIn",
13465
+ type: "uint256",
13466
+ },
13467
+ ],
13468
+ stateMutability: "payable",
13469
+ type: "function",
13470
+ },
13471
+ {
13472
+ inputs: [
13473
+ {
13474
+ internalType: "uint256",
13475
+ name: "deadline",
13476
+ type: "uint256",
13477
+ },
13478
+ {
13479
+ internalType: "bytes[]",
13480
+ name: "data",
13481
+ type: "bytes[]",
13482
+ },
13483
+ ],
13484
+ name: "multicall",
13485
+ outputs: [
13486
+ {
13487
+ internalType: "bytes[]",
13488
+ name: "",
13489
+ type: "bytes[]",
13490
+ },
13491
+ ],
13492
+ stateMutability: "payable",
13493
+ type: "function",
13494
+ },
13495
+ {
13496
+ inputs: [
13497
+ {
13498
+ internalType: "bytes[]",
13499
+ name: "data",
13500
+ type: "bytes[]",
13501
+ },
13502
+ ],
13503
+ name: "multicall",
13504
+ outputs: [
13505
+ {
13506
+ internalType: "bytes[]",
13507
+ name: "results",
13508
+ type: "bytes[]",
13509
+ },
13510
+ ],
13511
+ stateMutability: "nonpayable",
13512
+ type: "function",
13513
+ },
13514
+ {
13515
+ inputs: [],
13516
+ name: "owner",
13517
+ outputs: [
13518
+ {
13519
+ internalType: "address",
13520
+ name: "",
13521
+ type: "address",
13522
+ },
13523
+ ],
13524
+ stateMutability: "view",
13525
+ type: "function",
13526
+ },
13527
+ {
13528
+ inputs: [],
13529
+ name: "pause",
13530
+ outputs: [],
13531
+ stateMutability: "nonpayable",
13532
+ type: "function",
13533
+ },
13534
+ {
13535
+ inputs: [],
13536
+ name: "paused",
13537
+ outputs: [
13538
+ {
13539
+ internalType: "bool",
13540
+ name: "",
13541
+ type: "bool",
13542
+ },
13543
+ ],
13544
+ stateMutability: "view",
13545
+ type: "function",
13546
+ },
13547
+ {
13548
+ inputs: [],
13549
+ name: "renounceOwnership",
13550
+ outputs: [],
13551
+ stateMutability: "nonpayable",
13552
+ type: "function",
13553
+ },
13554
+ {
13555
+ inputs: [
13556
+ {
13557
+ internalType: "address",
13558
+ name: "newOwner",
13559
+ type: "address",
13560
+ },
13561
+ ],
13562
+ name: "transferOwnership",
13563
+ outputs: [],
13564
+ stateMutability: "nonpayable",
13565
+ type: "function",
13566
+ },
13567
+ {
13568
+ inputs: [],
13569
+ name: "uniswapRouter",
13570
+ outputs: [
13571
+ {
13572
+ internalType: "contract IV3SwapRouter",
13573
+ name: "",
13574
+ type: "address",
11041
13575
  },
11042
13576
  ],
13577
+ stateMutability: "view",
13578
+ type: "function",
13579
+ },
13580
+ {
13581
+ inputs: [],
13582
+ name: "unpause",
13583
+ outputs: [],
11043
13584
  stateMutability: "nonpayable",
11044
13585
  type: "function",
11045
13586
  },
11046
13587
  ];
11047
- const _bytecode$1 = "0x608060405234801561001057600080fd5b50610567806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80630f28c97d146100465780631749e1e3146100645780634d2301cc14610085575b600080fd5b61004e610098565b60405161005b919061041f565b60405180910390f35b6100776100723660046102a7565b61009c565b60405161005b929190610428565b61004e610093366004610286565b610220565b4290565b8051439060609067ffffffffffffffff811180156100b957600080fd5b506040519080825280602002602001820160405280156100f357816020015b6100e061023a565b8152602001906001900390816100d85790505b50905060005b835181101561021a57600080600086848151811061011357fe5b60200260200101516000015187858151811061012b57fe5b60200260200101516020015188868151811061014357fe5b60200260200101516040015192509250925060005a90506000808573ffffffffffffffffffffffffffffffffffffffff1685856040516101839190610403565b60006040518083038160008787f1925050503d80600081146101c1576040519150601f19603f3d011682016040523d82523d6000602084013e6101c6565b606091505b509150915060005a8403905060405180606001604052808415158152602001828152602001838152508989815181106101fb57fe5b60200260200101819052505050505050505080806001019150506100f9565b50915091565b73ffffffffffffffffffffffffffffffffffffffff163190565b604051806060016040528060001515815260200160008152602001606081525090565b803573ffffffffffffffffffffffffffffffffffffffff8116811461028157600080fd5b919050565b600060208284031215610297578081fd5b6102a08261025d565b9392505050565b600060208083850312156102b9578182fd5b823567ffffffffffffffff808211156102d0578384fd5b818501915085601f8301126102e3578384fd5b8135818111156102ef57fe5b6102fc8485830201610506565b81815284810190848601875b848110156103f457813587017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0606081838f03011215610346578a8bfd5b60408051606081018181108b8211171561035c57fe5b8252610369848d0161025d565b8152818401358c82015260608401358a811115610384578d8efd5b8085019450508e603f850112610398578c8dfd5b8b8401358a8111156103a657fe5b6103b68d85601f84011601610506565b93508084528f838287010111156103cb578d8efd5b808386018e86013783018c018d9052908101919091528552509287019290870190600101610308565b50909998505050505050505050565b6000825161041581846020870161052a565b9190910192915050565b90815260200190565b600060408083018584526020828186015281865180845260609350838701915083838202880101838901875b838110156104f6578983037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa001855281518051151584528681015187850152880151888401889052805188850181905260806104b582828801858c0161052a565b96880196601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01694909401909301925090850190600101610454565b50909a9950505050505050505050565b60405181810167ffffffffffffffff8111828210171561052257fe5b604052919050565b60005b8381101561054557818101518382015260200161052d565b83811115610554576000848401525b5050505056fea164736f6c6343000706000a";
13588
+ const _bytecode$1 = "0x60806040523480156200001157600080fd5b5060405162002123380380620021238339810160408190526200003491620000c2565b6200003f3362000072565b6000805460ff60a01b19169055600180546001600160a01b0319166001600160a01b0392909216919091179055620000f4565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600060208284031215620000d557600080fd5b81516001600160a01b0381168114620000ed57600080fd5b9392505050565b61201f80620001046000396000f3fe6080604052600436106100e85760003560e01c8063735de9f71161008a578063ac9650d811610059578063ac9650d814610243578063d9a6f70514610263578063ed921d3c14610279578063f2fde38b1461028c57600080fd5b8063735de9f7146101c5578063742ac944146101fd5780638456cb59146102105780638da5cb5b1461022557600080fd5b80633f4ba83a116100c65780633f4ba83a1461014f5780635ae401dc146101665780635c975abb14610186578063715018a6146101b057600080fd5b80631411734e146100ed57806314d90e1b146101135780631fd168ff1461013c575b600080fd5b6101006100fb366004611a14565b6102ac565b6040519081526020015b60405180910390f35b34801561011f57600080fd5b506101296103e881565b60405161ffff909116815260200161010a565b61010061014a366004611a14565b61040a565b34801561015b57600080fd5b5061016461057a565b005b610179610174366004611ac0565b61058c565b60405161010a9190611b5b565b34801561019257600080fd5b50600054600160a01b900460ff16604051901515815260200161010a565b3480156101bc57600080fd5b506101646105e2565b3480156101d157600080fd5b506001546101e5906001600160a01b031681565b6040516001600160a01b03909116815260200161010a565b61010061020b366004611c50565b6105f4565b34801561021c57600080fd5b50610164610731565b34801561023157600080fd5b506000546001600160a01b03166101e5565b34801561024f57600080fd5b5061017961025e366004611ca5565b610741565b34801561026f57600080fd5b5061012961271081565b610100610287366004611c50565b610836565b34801561029857600080fd5b506101646102a7366004611ce6565b61095e565b60208101516000906001600160a01b031633148015906102d9575060208201516001600160a01b03163014155b156102ff5760405162461bcd60e51b81526004016102f690611d03565b60405180910390fd5b600061030e83600001516109d7565b905060008061037983866040015187602001518a8a808060200260200160405190810160405280939291908181526020016000905b8282101561036f5761036060408302860136819003810190611d50565b81526020019060010190610343565b50505050506109e3565b60408088018390526001600160a01b0380831660208a0152600154915163b858183f60e01b8152939550919350169063b858183f906103bc908890600401611dfc565b6020604051808303816000875af11580156103db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ff9190611e0f565b979650505050505050565b6040810151815160009190829061042090610ac4565b9050600061043185600001516109d7565b90506000806000806104a4868a606001518b604001518c602001518f8f808060200260200160405190810160405280939291908181526020016000905b8282101561049a5761048b60408302860136819003810190611d50565b8152602001906001019061046e565b5050505050610af2565b9350935093509350838960400181815250508289602001906001600160a01b031690816001600160a01b031681525050600160009054906101000a90046001600160a01b03166001600160a01b03166309b813468a6040518263ffffffff1660e01b81526004016105159190611dfc565b6020604051808303816000875af1158015610534573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105589190611e0f565b975061056c8787878c604001518587610bd3565b505050505050509392505050565b610582610e16565b61058a610e70565b565b6060834211156105d05760405162461bcd60e51b815260206004820152600f60248201526e111958591b1a5b99481c185cdcd959608a1b60448201526064016102f6565b6105da8383610741565b949350505050565b6105ea610e16565b61058a6000610ec5565b60608101516000906001600160a01b03163314801590610621575060608201516001600160a01b03163014155b1561063e5760405162461bcd60e51b81526004016102f690611d03565b6000806106a18460000151856080015186606001518989808060200260200160405190810160405280939291908181526020016000905b8282101561036f5761069260408302860136819003810190611d50565b81526020019060010190610675565b608086018290526001600160a01b0380821660608801526001546040516304e45aaf60e01b815293955091935016906304e45aaf906106e4908790600401611e28565b6020604051808303816000875af1158015610703573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107279190611e0f565b9695505050505050565b610739610e16565b61058a610f15565b6060816001600160401b0381111561075b5761075b61189c565b60405190808252806020026020018201604052801561078e57816020015b60608152602001906001900390816107795790505b50905060005b8281101561082e576107fe308585848181106107b2576107b2611e87565b90506020028101906107c49190611e9d565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610f5892505050565b82828151811061081057610810611e87565b6020026020010181905250808061082690611ef9565b915050610794565b505b92915050565b600080826080015190506000806000806108ab87600001518860a0015189608001518a606001518d8d808060200260200160405190810160405280939291908181526020016000905b8282101561049a5761089c60408302860136819003810190611d50565b8152602001906001019061087f565b60808b018490526001600160a01b0380841660608d0152600154604051635023b4df60e01b815295995093975091955093501690635023b4df906108f3908a90600401611e28565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109369190611e0f565b955061095285886000015189602001518a608001518587610bd3565b50505050509392505050565b610966610e16565b6001600160a01b0381166109cb5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016102f6565b6109d481610ec5565b50565b60006108308282610f84565b600080548190600160a01b900460ff16610a2257600080610a048786610fe9565b9092509050610a138288611f12565b9650610a1f88826111c6565b50505b6040516323b872dd60e01b8152336004820152306024820152604481018690526001600160a01b038716906323b872dd906064016020604051808303816000875af1158015610a75573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a999190611f25565b50610aa48686611341565b306001600160a01b03851603610ab8573393505b50929491935090915050565b60008060148351610ad59190611f12565b90506000610ae584836014611438565b90506105da816000610f84565b6000806060818082610b0e60005460ff600160a01b9091041690565b610b2e57610b1c8988610fe9565b9092509050610b2b828a611f47565b98505b6001600160a01b0388163014610b42573097505b610b4c8b8b611341565b6040516323b872dd60e01b8152336004820152306024820152604481018b90526001600160a01b038c16906323b872dd906064016020604051808303816000875af1158015610b9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bc39190611f25565b50979a9699509697505050505050565b600054600160a01b900460ff16610bee57610bee8482611545565b6040516370a0823160e01b81523060048201526000906001600160a01b038616906370a0823190602401602060405180830381865afa158015610c35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c599190611e0f565b9050610c658385611f12565b811015610cb45760405162461bcd60e51b815260206004820181905260248201527f696e636f72726563742066656520616d6f756e7420646973747269627574656460448201526064016102f6565b60405163a9059cbb60e01b8152336004820152602481018890526001600160a01b0386169063a9059cbb906044016020604051808303816000875af1158015610d01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d259190611f25565b506040516370a0823160e01b81523060048201526000906001600160a01b038816906370a0823190602401602060405180830381865afa158015610d6d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d919190611e0f565b90508015610e0c5760405163a9059cbb60e01b8152336004820152602481018290526001600160a01b0388169063a9059cbb906044016020604051808303816000875af1158015610de6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e0a9190611f25565b505b5050505050505050565b6000546001600160a01b0316331461058a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102f6565b610e786116b4565b6000805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b610f1d611704565b6000805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610ea83390565b6060610f7d8383604051806060016040528060278152602001611fc360279139611751565b9392505050565b6000610f91826014611f47565b83511015610fd95760405162461bcd60e51b8152602060048201526015602482015274746f416464726573735f6f75744f66426f756e647360581b60448201526064016102f6565b500160200151600160601b900490565b6000606081805b845181101561103a5784818151811061100b5761100b611e87565b60200260200101516020015161ffff16826110269190611f47565b91508061103281611ef9565b915050610ff0565b506103e881111561108d5760405162461bcd60e51b815260206004820152601d60248201527f5365727669636520666565203e204d41585f534552564943455f46454500000060448201526064016102f6565b60008085516001600160401b038111156110a9576110a961189c565b6040519080825280602002602001820160405280156110ee57816020015b60408051808201909152600080825260208201528152602001906001900390816110c75790505b50905060005b86518110156111b757600061271061ffff1688838151811061111857611118611e87565b60200260200101516020015161ffff168a6111339190611f5a565b61113d9190611f71565b9050604051806040016040528089848151811061115c5761115c611e87565b6020026020010151600001516001600160a01b031681526020018281525083838151811061118c5761118c611e87565b60209081029190910101526111a18185611f47565b93505080806111af90611ef9565b9150506110f4565b509093509150505b9250929050565b60005b815181101561133c57826001600160a01b03166323b872dd338484815181106111f4576111f4611e87565b60200260200101516000015185858151811061121257611212611e87565b60209081029190910181015101516040516001600160e01b031960e086901b1681526001600160a01b03938416600482015292909116602483015260448201526064016020604051808303816000875af1158015611274573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112989190611f25565b508181815181106112ab576112ab611e87565b6020026020010151600001516001600160a01b0316336001600160a01b0316846001600160a01b03167f1f9a9fdac86b6ca3c5300bec0b61555cded1f1a234378602dcca6c27085eac8e85858151811061130757611307611e87565b60200260200101516020015160405161132291815260200190565b60405180910390a48061133481611ef9565b9150506111c9565b505050565b600154604051636eb1769f60e11b81523060048201526001600160a01b039182166024820152829184169063dd62ed3e90604401602060405180830381865afa158015611392573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113b69190611e0f565b10156114345760015460405163095ea7b360e01b81526001600160a01b03918216600482015260001960248201529083169063095ea7b3906044016020604051808303816000875af1158015611410573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061133c9190611f25565b5050565b60608161144681601f611f47565b10156114855760405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b60448201526064016102f6565b61148f8284611f47565b845110156114d35760405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b60448201526064016102f6565b6060821580156114f2576040519150600082526020820160405261153c565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561152b578051835260209283019201611513565b5050858452601f01601f1916604052505b50949350505050565b60005b815181101561133c57826001600160a01b031663a9059cbb83838151811061157257611572611e87565b60200260200101516000015184848151811061159057611590611e87565b6020026020010151602001516040518363ffffffff1660e01b81526004016115cd9291906001600160a01b03929092168252602082015260400190565b6020604051808303816000875af11580156115ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116109190611f25565b5081818151811061162357611623611e87565b6020026020010151600001516001600160a01b0316336001600160a01b0316846001600160a01b03167f1f9a9fdac86b6ca3c5300bec0b61555cded1f1a234378602dcca6c27085eac8e85858151811061167f5761167f611e87565b60200260200101516020015160405161169a91815260200190565b60405180910390a4806116ac81611ef9565b915050611548565b600054600160a01b900460ff1661058a5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016102f6565b600054600160a01b900460ff161561058a5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016102f6565b6060600080856001600160a01b03168560405161176e9190611f93565b600060405180830381855af49150503d80600081146117a9576040519150601f19603f3d011682016040523d82523d6000602084013e6117ae565b606091505b50915091506107278683838760608315611829578251600003611822576001600160a01b0385163b6118225760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016102f6565b50816105da565b6105da838381511561183e5781518083602001fd5b8060405162461bcd60e51b81526004016102f69190611faf565b60008083601f84011261186a57600080fd5b5081356001600160401b0381111561188157600080fd5b6020830191508360208260061b85010111156111bf57600080fd5b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b03811182821017156118d4576118d461189c565b60405290565b60405160e081016001600160401b03811182821017156118d4576118d461189c565b604051601f8201601f191681016001600160401b03811182821017156119245761192461189c565b604052919050565b6001600160a01b03811681146109d457600080fd5b803561194c8161192c565b919050565b60006080828403121561196357600080fd5b61196b6118b2565b905081356001600160401b038082111561198457600080fd5b818401915084601f83011261199857600080fd5b81356020828211156119ac576119ac61189c565b6119be601f8301601f191682016118fc565b925081835286818386010111156119d457600080fd5b818185018285013760008183850101528285526119f2818701611941565b8186015250505050604082013560408201526060820135606082015292915050565b600080600060408486031215611a2957600080fd5b83356001600160401b0380821115611a4057600080fd5b611a4c87838801611858565b90955093506020860135915080821115611a6557600080fd5b50611a7286828701611951565b9150509250925092565b60008083601f840112611a8e57600080fd5b5081356001600160401b03811115611aa557600080fd5b6020830191508360208260051b85010111156111bf57600080fd5b600080600060408486031215611ad557600080fd5b8335925060208401356001600160401b03811115611af257600080fd5b611afe86828701611a7c565b9497909650939450505050565b60005b83811015611b26578181015183820152602001611b0e565b50506000910152565b60008151808452611b47816020860160208601611b0b565b601f01601f19169290920160200192915050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015611bb057603f19888603018452611b9e858351611b2f565b94509285019290850190600101611b82565b5092979650505050505050565b600060e08284031215611bcf57600080fd5b611bd76118da565b90508135611be48161192c565b81526020820135611bf48161192c565b6020820152604082013562ffffff81168114611c0f57600080fd5b6040820152611c2060608301611941565b60608201526080820135608082015260a082013560a0820152611c4560c08301611941565b60c082015292915050565b60008060006101008486031215611c6657600080fd5b83356001600160401b03811115611c7c57600080fd5b611c8886828701611858565b9094509250611c9c90508560208601611bbd565b90509250925092565b60008060208385031215611cb857600080fd5b82356001600160401b03811115611cce57600080fd5b611cda85828601611a7c565b90969095509350505050565b600060208284031215611cf857600080fd5b8135610f7d8161192c565b6020808252602d908201527f726563697069656e74206d757374206265206d73672e73656e646572206f722060408201526c1d1a1a5cc818dbdb9d1c9858dd609a1b606082015260800190565b600060408284031215611d6257600080fd5b604051604081018181106001600160401b0382111715611d8457611d8461189c565b6040528235611d928161192c565b8152602083013561ffff81168114611da957600080fd5b60208201529392505050565b6000815160808452611dca6080850182611b2f565b6020848101516001600160a01b0316908601526040808501519086015260609384015193909401929092525090919050565b602081526000610f7d6020830184611db5565b600060208284031215611e2157600080fd5b5051919050565b60e08101610830828480516001600160a01b03908116835260208083015182169084015260408083015162ffffff16908401526060808301518216908401526080808301519084015260a0828101519084015260c09182015116910152565b634e487b7160e01b600052603260045260246000fd5b6000808335601e19843603018112611eb457600080fd5b8301803591506001600160401b03821115611ece57600080fd5b6020019150368190038213156111bf57600080fd5b634e487b7160e01b600052601160045260246000fd5b600060018201611f0b57611f0b611ee3565b5060010190565b8181038181111561083057610830611ee3565b600060208284031215611f3757600080fd5b81518015158114610f7d57600080fd5b8082018082111561083057610830611ee3565b808202811582820484141761083057610830611ee3565b600082611f8e57634e487b7160e01b600052601260045260246000fd5b500490565b60008251611fa5818460208701611b0b565b9190910192915050565b602081526000610f7d6020830184611b2f56fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212203925f97cd63c2e61736a2a442ff1d4bf966f453350e9df354a849229f69092cf64736f6c63430008130033";
11048
13589
  const isSuperArgs$1 = (xs) => xs.length > 1;
11049
- class Multicall__factory extends ContractFactory {
13590
+ class SecondaryFee__factory extends ContractFactory {
11050
13591
  constructor(...args) {
11051
13592
  if (isSuperArgs$1(args)) {
11052
13593
  super(...args);
@@ -11055,11 +13596,11 @@ class Multicall__factory extends ContractFactory {
11055
13596
  super(_abi$1, _bytecode$1, args[0]);
11056
13597
  }
11057
13598
  }
11058
- deploy(overrides) {
11059
- return super.deploy(overrides || {});
13599
+ deploy(_uniRouter, overrides) {
13600
+ return super.deploy(_uniRouter, overrides || {});
11060
13601
  }
11061
- getDeployTransaction(overrides) {
11062
- return super.getDeployTransaction(overrides || {});
13602
+ getDeployTransaction(_uniRouter, overrides) {
13603
+ return super.getDeployTransaction(_uniRouter, overrides || {});
11063
13604
  }
11064
13605
  attach(address) {
11065
13606
  return super.attach(address);
@@ -12455,7 +14996,81 @@ maxHops) => {
12455
14996
  return routes;
12456
14997
  };
12457
14998
 
12458
- function createSwapParameters(trade, fromAddress, slippage, deadline) {
14999
+ const zeroNativeCurrencyValue = '0x00';
15000
+ const multicallWithDeadlineFunctionSignature = 'multicall(uint256,bytes[])';
15001
+ function buildSwapParametersForSinglePoolSwap(fromAddress, trade, route, amountIn, amountOut, secondaryFees, secondaryFeeContract) {
15002
+ const secondaryFeeValues = secondaryFees.map((fee) => ({
15003
+ feePrcntBasisPoints: fee.feeBasisPoints,
15004
+ recipient: fee.feeRecipient,
15005
+ }));
15006
+ if (trade.tradeType === TradeType.EXACT_INPUT) {
15007
+ return secondaryFeeContract.encodeFunctionData('exactInputSingleWithServiceFee', [secondaryFeeValues, {
15008
+ tokenIn: route.tokenPath[0].address,
15009
+ tokenOut: route.tokenPath[1].address,
15010
+ fee: route.pools[0].fee,
15011
+ recipient: fromAddress,
15012
+ amountIn,
15013
+ amountOutMinimum: amountOut,
15014
+ sqrtPriceLimitX96: 0,
15015
+ }]);
15016
+ }
15017
+ return secondaryFeeContract.encodeFunctionData('exactOutputSingleWithServiceFee', [secondaryFeeValues, {
15018
+ tokenIn: route.tokenPath[0].address,
15019
+ tokenOut: route.tokenPath[1].address,
15020
+ fee: route.pools[0].fee,
15021
+ recipient: fromAddress,
15022
+ amountInMaximum: amountIn,
15023
+ amountOut,
15024
+ sqrtPriceLimitX96: 0,
15025
+ }]);
15026
+ }
15027
+ function buildSwapParametersForMultiPoolSwap(fromAddress, trade, route, amountIn, amountOut, secondaryFees, secondaryFeeContract) {
15028
+ const path = encodeRouteToPath(route, trade.tradeType === TradeType.EXACT_OUTPUT);
15029
+ const secondaryFeeValues = secondaryFees.map((fee) => ({
15030
+ feePrcntBasisPoints: fee.feeBasisPoints,
15031
+ recipient: fee.feeRecipient,
15032
+ }));
15033
+ if (trade.tradeType === TradeType.EXACT_INPUT) {
15034
+ return secondaryFeeContract.encodeFunctionData('exactInputWithServiceFee', [secondaryFeeValues, {
15035
+ path,
15036
+ recipient: fromAddress,
15037
+ amountIn,
15038
+ amountOutMinimum: amountOut,
15039
+ }]);
15040
+ }
15041
+ return secondaryFeeContract.encodeFunctionData('exactOutputWithServiceFee', [secondaryFeeValues, {
15042
+ path,
15043
+ recipient: fromAddress,
15044
+ amountInMaximum: amountIn,
15045
+ amountOut,
15046
+ }]);
15047
+ }
15048
+ /**
15049
+ * Builds swap parameters
15050
+ * @param fromAddress the msg.sender of the transaction
15051
+ * @param secondaryFeeAddress the secondary fee contract address
15052
+ * @param trade details of the swap, including the route, input/output tokens and amounts
15053
+ * @param options additional swap options
15054
+ * @returns calldata for the swap
15055
+ */
15056
+ function buildSwapParameters(fromAddress, trade, options, secondaryFees, secondaryFeeContract) {
15057
+ // @dev we don't support multiple swaps in a single transaction
15058
+ // there will always be only one swap in the trade regardless of the trade type
15059
+ const { route, inputAmount, outputAmount } = trade.swaps[0];
15060
+ const amountIn = toHex$1(trade.maximumAmountIn(options.slippageTolerance, inputAmount).quotient);
15061
+ const amountOut = toHex$1(trade.minimumAmountOut(options.slippageTolerance, outputAmount).quotient);
15062
+ const isSinglePoolSwap = route.pools.length === 1;
15063
+ if (isSinglePoolSwap) {
15064
+ return buildSwapParametersForSinglePoolSwap(fromAddress, trade, route, amountIn, amountOut, secondaryFees, secondaryFeeContract);
15065
+ }
15066
+ return buildSwapParametersForMultiPoolSwap(fromAddress, trade, route, amountIn, amountOut, secondaryFees, secondaryFeeContract);
15067
+ }
15068
+ function createSwapCallParametersWithFees(trade, fromAddress, swapOptions, secondaryFees) {
15069
+ const secondaryFeeContract = SecondaryFee__factory.createInterface();
15070
+ const swapWithFeesCalldata = buildSwapParameters(fromAddress, trade, swapOptions, secondaryFees, secondaryFeeContract);
15071
+ return secondaryFeeContract.encodeFunctionData(multicallWithDeadlineFunctionSignature, [swapOptions.deadlineOrPreviousBlockhash, [swapWithFeesCalldata]]);
15072
+ }
15073
+ function createSwapParameters(trade, fromAddress, slippage, deadline, secondaryFees) {
12459
15074
  // Create an unchecked trade to be used in generating swap parameters.
12460
15075
  const uncheckedTrade = Trade.createUncheckedTrade({
12461
15076
  route: trade.route,
@@ -12469,20 +15084,24 @@ function createSwapParameters(trade, fromAddress, slippage, deadline) {
12469
15084
  recipient: fromAddress,
12470
15085
  deadlineOrPreviousBlockhash: deadline,
12471
15086
  };
12472
- // Generate the parameters.
12473
- return SwapRouter.swapCallParameters([uncheckedTrade], options);
15087
+ if (secondaryFees.length === 0) {
15088
+ // Generate swap parameters without secondary fee contract details
15089
+ return SwapRouter.swapCallParameters([uncheckedTrade], options).calldata;
15090
+ }
15091
+ return createSwapCallParametersWithFees(uncheckedTrade, fromAddress, options, secondaryFees);
12474
15092
  }
12475
- function getSwap(nativeToken, routeAndQuote, fromAddress, slippage, deadline, peripheryRouterAddress, gasPrice) {
12476
- const params = createSwapParameters(routeAndQuote.trade, fromAddress, slippage, deadline);
15093
+ function getSwap(nativeToken, routeAndQuote, fromAddress, slippage, deadline, peripheryRouterAddress, secondaryFeesAddress, gasPrice, secondaryFees) {
15094
+ const calldata = createSwapParameters(routeAndQuote.trade, fromAddress, slippage, deadline, secondaryFees);
15095
+ // TODO: Add additional gas fee estimates for secondary fees
12477
15096
  const gasFeeEstimate = gasPrice ? {
12478
15097
  token: nativeToken,
12479
15098
  value: calculateGasFee(gasPrice, routeAndQuote.trade.gasEstimate),
12480
15099
  } : null;
12481
15100
  return {
12482
15101
  transaction: {
12483
- data: params.calldata,
12484
- to: peripheryRouterAddress,
12485
- value: params.value,
15102
+ data: calldata,
15103
+ to: secondaryFees.length > 0 ? secondaryFeesAddress : peripheryRouterAddress,
15104
+ value: zeroNativeCurrencyValue,
12486
15105
  from: fromAddress,
12487
15106
  },
12488
15107
  gasFeeEstimate,
@@ -12495,6 +15114,7 @@ const CONTRACTS_FOR_CHAIN_ID = {
12495
15114
  coreFactory: '0x12739A8f1A8035F439092D016DAE19A2874F30d2',
12496
15115
  quoterV2: '0xF674847fBcca5C80315e3AE37043Dce99F6CC529',
12497
15116
  peripheryRouter: '0x0Afe6F5f4DC34461A801420634239FFaD50A2e44',
15117
+ secondaryFee: '0x8dBE1f0900C5e92ad87A54521902a33ba1598C51',
12498
15118
  },
12499
15119
  };
12500
15120
  const SUPPORTED_SANDBOX_CHAINS = {
@@ -12523,29 +15143,36 @@ function validateOverrides(overrides) {
12523
15143
  throw new InvalidConfigurationError(`Invalid exchange contract address for ${key}`);
12524
15144
  }
12525
15145
  });
12526
- if (!overrides.secondaryFees) {
12527
- return;
12528
- }
12529
- for (const secondaryFee of overrides.secondaryFees) {
15146
+ }
15147
+ function validateSecondaryFees(secondaryFees) {
15148
+ let totalSecondaryFeeBasisPoints = 0;
15149
+ for (const secondaryFee of secondaryFees) {
12530
15150
  if (!isValidNonZeroAddress(secondaryFee.feeRecipient)) {
12531
15151
  throw new InvalidConfigurationError(`Invalid secondary fee recipient address: ${secondaryFee.feeRecipient}`);
12532
15152
  }
12533
- if (secondaryFee.feeBasisPoints < 0 || secondaryFee.feeBasisPoints > 10000) {
12534
- throw new InvalidConfigurationError(`Invalid secondary fee percentage: ${secondaryFee.feeBasisPoints}`);
15153
+ if (secondaryFee.feeBasisPoints < 0 || secondaryFee.feeBasisPoints > MAX_SECONDARY_FEE_BASIS_POINTS) {
15154
+ throw new InvalidConfigurationError(`Invalid secondary fee basis points: ${secondaryFee.feeBasisPoints}`);
12535
15155
  }
15156
+ totalSecondaryFeeBasisPoints += secondaryFee.feeBasisPoints;
15157
+ }
15158
+ if (totalSecondaryFeeBasisPoints > MAX_SECONDARY_FEE_BASIS_POINTS) {
15159
+ throw new InvalidConfigurationError(`Invalid total secondary fee basis points: ${totalSecondaryFeeBasisPoints}`);
12536
15160
  }
12537
15161
  }
12538
15162
  /**
12539
15163
  * {@link ExchangeConfiguration} is used to configure the {@link Exchange} class.
12540
15164
  * @param chainId the ID of the chain to configure. {@link SUPPORTED_CHAIN_IDS_FOR_ENVIRONMENT} contains the supported chains for each environment.
12541
15165
  * @param baseConfig the base {@link ImmutableConfiguration} for the {@link Exchange} class
15166
+ * @param secondaryFees an optional array of {@link SecondaryFee}s to apply to all transactions. Total secondary fees must be less than {@link MAX_SECONDARY_FEE_BASIS_POINTS}.
12542
15167
  */
12543
15168
  class ExchangeConfiguration {
12544
15169
  baseConfig;
12545
15170
  chain;
12546
- secondaryFees;
12547
- constructor({ chainId, baseConfig, overrides }) {
15171
+ secondaryFees = [];
15172
+ constructor({ chainId, baseConfig, secondaryFees, overrides, }) {
12548
15173
  this.baseConfig = baseConfig;
15174
+ this.secondaryFees = secondaryFees || [];
15175
+ validateSecondaryFees(this.secondaryFees);
12549
15176
  if (overrides) {
12550
15177
  validateOverrides(overrides);
12551
15178
  this.chain = {
@@ -12555,10 +15182,9 @@ class ExchangeConfiguration {
12555
15182
  commonRoutingTokens: overrides.commonRoutingTokens,
12556
15183
  nativeToken: overrides.nativeToken,
12557
15184
  };
12558
- this.secondaryFees = overrides.secondaryFees ? overrides.secondaryFees : [];
15185
+ this.secondaryFees = secondaryFees || [];
12559
15186
  return;
12560
15187
  }
12561
- this.secondaryFees = [];
12562
15188
  const chain = SUPPORTED_CHAIN_IDS_FOR_ENVIRONMENT[baseConfig.environment][chainId];
12563
15189
  if (!chain) {
12564
15190
  throw new ChainNotSupportedError(chainId, baseConfig.environment);
@@ -12577,13 +15203,14 @@ class Exchange {
12577
15203
  const config = new ExchangeConfiguration(configuration);
12578
15204
  this.chainId = config.chain.chainId;
12579
15205
  this.nativeToken = config.chain.nativeToken;
12580
- this.provider = new ethers.providers.JsonRpcProvider(config.chain.rpcUrl);
12581
15206
  this.secondaryFees = config.secondaryFees;
15207
+ this.provider = new ethers.providers.JsonRpcProvider(config.chain.rpcUrl);
12582
15208
  this.router = new Router(this.provider, config.chain.commonRoutingTokens, {
12583
15209
  multicallAddress: config.chain.contracts.multicall,
12584
15210
  factoryAddress: config.chain.contracts.coreFactory,
12585
15211
  quoterAddress: config.chain.contracts.quoterV2,
12586
15212
  peripheryRouterAddress: config.chain.contracts.peripheryRouter,
15213
+ secondaryFeeAddress: config.chain.contracts.secondaryFee,
12587
15214
  });
12588
15215
  }
12589
15216
  static validate(tokenInAddress, tokenOutAddress, maxHops, slippagePercent, fromAddress) {
@@ -12621,7 +15248,7 @@ class Exchange {
12621
15248
  const gasPrice = await fetchGasPrice(this.provider);
12622
15249
  // we always use the tokenIn address because we are always selling the tokenIn
12623
15250
  const approval = await getApproval(this.nativeToken, this.provider, fromAddress, tokenInAddress, ethers.BigNumber.from(amount), this.router.routingContracts.peripheryRouterAddress, gasPrice);
12624
- const swap = getSwap(this.nativeToken, routeAndQuote, fromAddress, slippagePercent, deadline, this.router.routingContracts.peripheryRouterAddress, gasPrice);
15251
+ const swap = getSwap(this.nativeToken, routeAndQuote, fromAddress, slippagePercent, deadline, this.router.routingContracts.peripheryRouterAddress, this.router.routingContracts.secondaryFeeAddress, gasPrice, this.secondaryFees);
12625
15252
  const quote = getQuote(otherToken, tradeType, routeAndQuote.trade, slippagePercent);
12626
15253
  return {
12627
15254
  approval,
@@ -12661,9 +15288,6 @@ class Exchange {
12661
15288
  async getUnsignedSwapTxFromAmountOut(fromAddress, tokenInAddress, tokenOutAddress, amountOut, slippagePercent = DEFAULT_SLIPPAGE, maxHops = DEFAULT_MAX_HOPS, deadline = DEFAULT_DEADLINE) {
12662
15289
  return await this.getUnsignedSwapTx(fromAddress, tokenInAddress, tokenOutAddress, amountOut, slippagePercent, maxHops, deadline, TradeType.EXACT_OUTPUT);
12663
15290
  }
12664
- thereAreSecondaryFees() {
12665
- return this.secondaryFees.length > 0;
12666
- }
12667
15291
  }
12668
15292
 
12669
15293
  /* eslint-disable class-methods-use-this */