@avalabs/bridge-unified 2.0.0 → 2.0.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.
- package/.turbo/turbo-build.log +8 -8
- package/.turbo/turbo-lint.log +1 -1
- package/.turbo/turbo-test.log +3 -3
- package/CHANGELOG.md +6 -0
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/bridges/cctp/__mocks__/config.mock.ts +4 -1
- package/src/bridges/cctp/handlers/track-transfer.test.ts +8 -4
- package/src/bridges/cctp/handlers/track-transfer.ts +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types/asset.ts","../src/types/bridge.ts","../src/types/environment.ts","../src/types/error.ts","../src/errors/bridge-error.ts","../src/errors/bridge-unavailable-error.ts","../src/errors/bridge-initialization-error.ts","../src/errors/invalid-params-error.ts","../src/bridges/cctp/utils/config.ts","../src/bridges/cctp/handlers/get-assets.ts","../src/utils/client.ts","../src/utils/caip2.ts","../src/bridges/cctp/abis/token-router.ts","../src/bridges/cctp/utils/transfer-data.ts","../src/bridges/cctp/handlers/get-fees.ts","../src/bridges/cctp/handlers/transfer-asset.ts","../src/bridges/cctp/abis/erc20.ts","../src/utils/ensure-config.ts","../src/bridges/cctp/handlers/track-transfer.ts","../src/utils/network-fee.ts","../src/utils/wait.ts","../src/utils/retry-promise.ts","../src/bridges/cctp/factory.ts","../src/utils/bridge-types.ts","../src/unified-bridge-service.ts"],"names":["TokenType","BridgeType","BridgeSignatureReason","Environment","ErrorCode","ErrorReason","BridgeError","message","code","details","BridgeUnavailableError","BridgeInitializationError","InvalidParamsError","CONFIG_URLS","getConfig","environment","chainData","err","getTrackingDelayByChainId","chainId","getAssets","bridge","chainIds","assets","asset","destinations","createWalletClient","publicActions","custom","http","namespacePattern","referencePattern","delimeter","toJSON","identifier","namespace","reference","toString","caip2_default","_getChain","chain","getClientForChain","provider","chainInfo","transport","TOKEN_ROUTER_ABI","getTransferData","sourceChain","targetChain","amount","config","sourceChainData","targetChainData","burnToken","token","mintToken","getFees","params","feeAmount","encodeFunctionData","isAddress","ERC20_ABI","approveAndTransfer","fromAddress","maybeToAddress","sourceProvider","onStepChange","sign","toAddress","client","isAllowanceApprovalRequired","requiredSignatures","data","txHash","signedTxHash","request","getStartBlockNumber","targetClient","transferAsset","requiredSourceConfirmationCount","requiredTargetConfirmationCount","fees","bridgeFee","sourceStartedAt","targetBlockNumber","ensureHasConfig","decodeEventLog","getNetworkFeeEVM","transaction","receipt","wait","time","res","retryPromise","promise","delay","startAfter","isRunning","isCancelled","errorCount","resolve","reject","done","cancel","rej","execute","TRACKING_LIMIT_MS","MAX_BLOCKS","INITIAL_DELAY","updateTransfer","initial","updated","updateListener","value","trackSourceTx","targetProvider","bridgeTransfer","sourceClient","updateableTransfer","txReceipt","tx","networkFee","confirmationCount","hasMoreConfirmations","hasRequiredConfirmations","changes","transferEventLog","log","nonce","trackTargetTx","lastBlockNumber","lowestBlockNumber","fromBlock","highestBlockNumber","toBlock","targetLogs","trackTransfer","abortFn","sourceTracker","cancelSourceTracking","transferAfterSourceFinished","targetTracker","cancelTargetTracking","cctpBridgeFactory","supportedBridges","getEnabledBridgeServices","disabledBridgeTypes","bridgeType","factory","getBridgeForTransfer","enabledBridgeServices","targetChainId","isArray","mergeWith","createUnifiedBridgeService","updateConfigs","bridgeService","aggregatedAssets","chainAssetMap","bridgeAssets","existingAssets","bridgeAsset","index","symbol","objValue","srcValue"],"mappings":"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OACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,uBACN,KAAM,OACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,WACN,KAAM,OACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,kBACN,KAAM,OACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,uBACN,KAAM,OACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,oBACN,KAAM,OACR,EACA,CACE,UAAW,GACX,OAAQ,CACN,CACE,QAAS,GACT,aAAc,UACd,KAAM,QACN,KAAM,SACR,CACF,EACA,KAAM,aACN,KAAM,OACR,EACA,CACE,UAAW,GACX,OAAQ,CACN,CACE,QAAS,GACT,aAAc,UACd,KAAM,QACN,KAAM,SACR,CACF,EACA,KAAM,eACN,KAAM,OACR,EACA,CACE,UAAW,GACX,OAAQ,CACN,CACE,QAAS,GACT,aAAc,UACd,KAAM,QACN,KAAM,SACR,CACF,EACA,KAAM,iBACN,KAAM,OACR,EACA,CACE,UAAW,GACX,OAAQ,CACN,CACE,QAAS,GACT,aAAc,UACd,KAAM,QACN,KAAM,SACR,CACF,EACA,KAAM,mBACN,KAAM,OACR,EACA,CACE,UAAW,GACX,OAAQ,CACN,CACE,QAAS,GACT,aAAc,UACd,KAAM,eACN,KAAM,SACR,CACF,EACA,KAAM,oBACN,KAAM,OACR,EACA,CACE,UAAW,GACX,OAAQ,CACN,CACE,QAAS,GACT,aAAc,UACd,KAAM,eACN,KAAM,SACR,CACF,EACA,KAAM,sBACN,KAAM,OACR,EACA,CACE,UAAW,GACX,OAAQ,CACN,CACE,QAAS,GACT,aAAc,SACd,KAAM,SACN,KAAM,QACR,EACA,CACE,WAAY,CACV,CACE,aAAc,UACd,KAAM,SACN,KAAM,SACR,EACA,CACE,aAAc,UACd,KAAM,SACN,KAAM,SACR,EACA,CACE,aAAc,SACd,KAAM,gBACN,KAAM,QACR,EACA,CACE,aAAc,UACd,KAAM,SACN,KAAM,SACR,EACA,CACE,aAAc,OACd,KAAM,YACN,KAAM,MACR,CACF,EACA,QAAS,GACT,aAAc,wCACd,KAAM,mBACN,KAAM,OACR,CACF,EACA,KAAM,0BACN,KAAM,OACR,EACA,CACE,UAAW,GACX,OAAQ,CACN,CACE,QAAS,GACT,aAAc,UACd,KAAM,gBACN,KAAM,SACR,EACA,CACE,QAAS,GACT,aAAc,UACd,KAAM,WACN,KAAM,SACR,CACF,EACA,KAAM,uBACN,KAAM,OACR,EACA,CACE,UAAW,GACX,OAAQ,CACN,CACE,QAAS,GACT,aAAc,UACd,KAAM,UACN,KAAM,SACR,CACF,EACA,KAAM,SACN,KAAM,OACR,EACA,CACE,UAAW,GACX,OAAQ,CACN,CACE,QAAS,GACT,aAAc,SACd,KAAM,QACN,KAAM,QACR,EACA,CACE,QAAS,GACT,aAAc,UACd,KAAM,YACN,KAAM,SACR,EACA,CACE,QAAS,GACT,aAAc,UACd,KAAM,SACN,KAAM,SACR,EACA,CACE,QAAS,GACT,aAAc,UACd,KAAM,YACN,KAAM,SACR,EACA,CACE,QAAS,GACT,aAAc,UACd,KAAM,gBACN,KAAM,SACR,EACA,CACE,QAAS,GACT,aAAc,SACd,KAAM,oBACN,KAAM,QACR,EACA,CACE,QAAS,GACT,aAAc,UACd,KAAM,WACN,KAAM,SACR,CACF,EACA,KAAM,iBACN,KAAM,OACR,EACA,CACE,UAAW,GACX,OAAQ,CACN,CACE,QAAS,GACT,aAAc,UACd,KAAM,UACN,KAAM,SACR,CACF,EACA,KAAM,WACN,KAAM,OACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,UACd,KAAM,UACN,KAAM,SACR,CACF,EACA,KAAM,WACN,QAAS,CAAC,EACV,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,UACd,KAAM,eACN,KAAM,SACR,CACF,EACA,KAAM,kBACN,QAAS,CAAC,EACV,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,UACd,KAAM,QACN,KAAM,SACR,CACF,EACA,KAAM,wBACN,QAAS,CAAC,EACV,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,UACd,KAAM,SACN,KAAM,SACR,EACA,CACE,aAAc,SACd,KAAM,oBACN,KAAM,QACR,CACF,EACA,KAAM,eACN,QAAS,CACP,CACE,aAAc,UACd,KAAM,GACN,KAAM,SACR,CACF,EACA,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,uBACN,QAAS,CACP,CACE,aAAc,iCACd,KAAM,GACN,KAAM,SACR,CACF,EACA,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,8BACN,QAAS,CACP,CACE,aAAc,UACd,KAAM,GACN,KAAM,SACR,CACF,EACA,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,UACd,KAAM,QACN,KAAM,SACR,CACF,EACA,KAAM,cACN,QAAS,CACP,CACE,aAAc,OACd,KAAM,GACN,KAAM,MACR,CACF,EACA,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,UACd,KAAM,QACN,KAAM,SACR,CACF,EACA,KAAM,gBACN,QAAS,CACP,CACE,aAAc,UACd,KAAM,GACN,KAAM,SACR,CACF,EACA,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,SACd,KAAM,SACN,KAAM,QACR,CACF,EACA,KAAM,sBACN,QAAS,CACP,CACE,WAAY,CACV,CACE,aAAc,UACd,KAAM,SACN,KAAM,SACR,EACA,CACE,aAAc,UACd,KAAM,SACN,KAAM,SACR,EACA,CACE,aAAc,SACd,KAAM,gBACN,KAAM,QACR,EACA,CACE,aAAc,UACd,KAAM,SACN,KAAM,SACR,EACA,CACE,aAAc,OACd,KAAM,YACN,KAAM,MACR,CACF,EACA,aAAc,wCACd,KAAM,GACN,KAAM,OACR,CACF,EACA,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,SACd,KAAM,SACN,KAAM,QACR,CACF,EACA,KAAM,mBACN,QAAS,CACP,CACE,aAAc,SACd,KAAM,GACN,KAAM,QACR,CACF,EACA,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,SACd,KAAM,SACN,KAAM,QACR,CACF,EACA,KAAM,YACN,QAAS,CACP,CACE,aAAc,UACd,KAAM,GACN,KAAM,SACR,CACF,EACA,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,SACd,KAAM,SACN,KAAM,QACR,CACF,EACA,KAAM,YACN,QAAS,CACP,CACE,aAAc,UACd,KAAM,GACN,KAAM,SACR,CACF,EACA,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,SACd,KAAM,SACN,KAAM,QACR,CACF,EACA,KAAM,YACN,QAAS,CACP,CACE,aAAc,UACd,KAAM,GACN,KAAM,SACR,CACF,EACA,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,UACd,KAAM,UACN,KAAM,SACR,CACF,EACA,KAAM,UACN,QAAS,CACP,CACE,aAAc,OACd,KAAM,GACN,KAAM,MACR,CACF,EACA,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,UACd,KAAM,UACN,KAAM,SACR,CACF,EACA,KAAM,iBACN,QAAS,CACP,CACE,aAAc,OACd,KAAM,GACN,KAAM,MACR,CACF,EACA,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,UACd,KAAM,QACN,KAAM,SACR,CACF,EACA,KAAM,uBACN,QAAS,CACP,CACE,aAAc,OACd,KAAM,GACN,KAAM,MACR,CACF,EACA,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,SACd,KAAM,SACN,KAAM,QACR,CACF,EACA,KAAM,oBACN,QAAS,CACP,CACE,aAAc,OACd,KAAM,GACN,KAAM,MACR,CACF,EACA,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,QACN,QAAS,CACP,CACE,aAAc,UACd,KAAM,GACN,KAAM,SACR,CACF,EACA,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,QACN,QAAS,CAAC,EACV,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,SACN,QAAS,CACP,CACE,aAAc,OACd,KAAM,GACN,KAAM,MACR,CACF,EACA,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,UACd,KAAM,UACN,KAAM,SACR,CACF,EACA,KAAM,cACN,QAAS,CAAC,EACV,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,UACd,KAAM,eACN,KAAM,SACR,CACF,EACA,KAAM,qBACN,QAAS,CAAC,EACV,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,UACd,KAAM,QACN,KAAM,SACR,CACF,EACA,KAAM,2BACN,QAAS,CAAC,EACV,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,oBACN,QAAS,CAAC,EACV,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,SACd,KAAM,SACN,KAAM,QACR,EACA,CACE,WAAY,CACV,CACE,aAAc,UACd,KAAM,SACN,KAAM,SACR,EACA,CACE,aAAc,UACd,KAAM,SACN,KAAM,SACR,EACA,CACE,aAAc,SACd,KAAM,gBACN,KAAM,QACR,EACA,CACE,aAAc,UACd,KAAM,SACN,KAAM,SACR,EACA,CACE,aAAc,OACd,KAAM,YACN,KAAM,MACR,CACF,EACA,aAAc,wCACd,KAAM,mBACN,KAAM,OACR,CACF,EACA,KAAM,sBACN,QAAS,CAAC,EACV,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,UACd,KAAM,GACN,KAAM,SACR,CACF,EACA,KAAM,sBACN,QAAS,CACP,CACE,aAAc,OACd,KAAM,GACN,KAAM,MACR,CACF,EACA,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,UACd,KAAM,WACN,KAAM,SACR,CACF,EACA,KAAM,oBACN,QAAS,CAAC,EACV,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,UACd,KAAM,SACN,KAAM,SACR,EACA,CACE,aAAc,SACd,KAAM,oBACN,KAAM,QACR,EACA,CACE,aAAc,UACd,KAAM,gBACN,KAAM,SACR,EACA,CACE,aAAc,UACd,KAAM,YACN,KAAM,SACR,CACF,EACA,KAAM,iBACN,QAAS,CACP,CACE,aAAc,SACd,KAAM,QACN,KAAM,QACR,CACF,EACA,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,UACN,QAAS,CAAC,EACV,gBAAiB,aACjB,KAAM,UACR,CACF,ECn0BO,IAAMC,EAAkB,CAAC,CAAE,YAAAC,EAAa,YAAAC,EAAa,OAAAC,EAAQ,MAAAzB,CAAM,EAA0B0B,IAAmB,CACrH,GAAIH,EAAY,UAAYC,EAAY,QACtC,MAAM,IAAIpC,6BAAwD,EAGpE,GAAIqC,GAAU,GACZ,MAAM,IAAIrC,8BAA0D,kCAAkC,EAGxG,IAAMuC,EAAkBD,EAAO,KAAMlC,GAAcA,EAAU,UAAY+B,EAAY,OAAO,EAE5F,GAAI,CAACI,EACH,MAAM,IAAIvC,wBAER,kCAAkCmC,EAAY,OAAO,GACvD,EAGF,IAAMK,EAAkBF,EAAO,KAAMlC,GAAcA,EAAU,UAAYgC,EAAY,OAAO,EAE5F,GAAI,CAACI,EACH,MAAM,IAAIxC,wBAER,kCAAkCoC,EAAY,OAAO,GACvD,EAGF,IAAMK,EAAYF,EAAgB,OAAO,KAAMG,GAAUA,EAAM,SAAW9B,EAAM,MAAM,EAChF+B,EAAYH,EAAgB,OAAO,KAAME,GAAUA,EAAM,SAAW9B,EAAM,MAAM,EAEtF,GAAI,CAAC6B,GAAa,CAACE,EACjB,MAAM,IAAI3C,uBAAkD,EAG9D,MAAO,CACL,gBAAAuC,EACA,gBAAAC,EACA,UAAAC,EACA,UAAAE,CACF,CACF,EC1CA,eAAsBC,EAAQnC,EAAuBoC,EAAmB,CACtE,MAAMpC,EAAO,gBAAgB,EAE7B,GAAM,CAAE,YAAA0B,EAAa,YAAAC,EAAa,MAAAxB,EAAO,OAAAyB,EAAQ,SAAAP,CAAS,EAAIe,EACxD,CAAE,gBAAAN,EAAiB,gBAAAC,EAAiB,UAAAC,CAAU,EAAIP,EACtD,CAAE,YAAAC,EAAa,YAAAC,EAAa,MAAAxB,EAAO,OAAAyB,CAAO,EAC1C5B,EAAO,MACT,EAGMqC,EAAY,MADHjB,EAAkB,CAAE,MAAOM,EAAa,SAAAL,CAAS,CAAC,EAClC,aAAa,CAC1C,QAASS,EAAgB,mBACzB,IAAKN,EACL,aAAc,eACd,KAAM,CAACI,EAAQG,EAAgB,MAAM,CACvC,CAAC,EAED,MAAO,CACL,CAACC,EAAU,OAAO,EAAGK,CACvB,CACF,CCzBA,OAAS,sBAAAC,EAAoB,aAAAC,MAAoC,OCA1D,IAAMC,EAAY,CACvB,CACE,SAAU,GACV,OAAQ,CAAC,EACT,KAAM,OACN,QAAS,CAAC,CAAE,KAAM,GAAI,KAAM,QAAS,CAAC,EACtC,QAAS,GACT,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,SAAU,GACV,OAAQ,CACN,CAAE,KAAM,WAAY,KAAM,SAAU,EACpC,CAAE,KAAM,SAAU,KAAM,SAAU,CACpC,EACA,KAAM,UACN,QAAS,CAAC,CAAE,KAAM,GAAI,KAAM,MAAO,CAAC,EACpC,QAAS,GACT,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,SAAU,GACV,OAAQ,CAAC,EACT,KAAM,cACN,QAAS,CAAC,CAAE,KAAM,GAAI,KAAM,SAAU,CAAC,EACvC,QAAS,GACT,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,SAAU,GACV,OAAQ,CACN,CAAE,KAAM,QAAS,KAAM,SAAU,EACjC,CAAE,KAAM,MAAO,KAAM,SAAU,EAC/B,CAAE,KAAM,SAAU,KAAM,SAAU,CACpC,EACA,KAAM,eACN,QAAS,CAAC,CAAE,KAAM,GAAI,KAAM,MAAO,CAAC,EACpC,QAAS,GACT,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,SAAU,GACV,OAAQ,CAAC,EACT,KAAM,WACN,QAAS,CAAC,CAAE,KAAM,GAAI,KAAM,OAAQ,CAAC,EACrC,QAAS,GACT,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,SAAU,GACV,OAAQ,CAAC,CAAE,KAAM,SAAU,KAAM,SAAU,CAAC,EAC5C,KAAM,YACN,QAAS,CAAC,CAAE,KAAM,UAAW,KAAM,SAAU,CAAC,EAC9C,QAAS,GACT,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,SAAU,GACV,OAAQ,CAAC,EACT,KAAM,SACN,QAAS,CAAC,CAAE,KAAM,GAAI,KAAM,QAAS,CAAC,EACtC,QAAS,GACT,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,SAAU,GACV,OAAQ,CACN,CAAE,KAAM,MAAO,KAAM,SAAU,EAC/B,CAAE,KAAM,SAAU,KAAM,SAAU,CACpC,EACA,KAAM,WACN,QAAS,CAAC,CAAE,KAAM,GAAI,KAAM,MAAO,CAAC,EACpC,QAAS,GACT,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,SAAU,GACV,OAAQ,CACN,CAAE,KAAM,SAAU,KAAM,SAAU,EAClC,CAAE,KAAM,WAAY,KAAM,SAAU,CACtC,EACA,KAAM,YACN,QAAS,CAAC,CAAE,KAAM,GAAI,KAAM,SAAU,CAAC,EACvC,QAAS,GACT,gBAAiB,OACjB,KAAM,UACR,EACA,CAAE,QAAS,GAAM,gBAAiB,UAAW,KAAM,UAAW,EAC9D,CACE,UAAW,GACX,OAAQ,CACN,CAAE,QAAS,GAAM,KAAM,QAAS,KAAM,SAAU,EAChD,CAAE,QAAS,GAAM,KAAM,UAAW,KAAM,SAAU,EAClD,CAAE,QAAS,GAAO,KAAM,QAAS,KAAM,SAAU,CACnD,EACA,KAAM,WACN,KAAM,OACR,EACA,CACE,UAAW,GACX,OAAQ,CACN,CAAE,QAAS,GAAM,KAAM,OAAQ,KAAM,SAAU,EAC/C,CAAE,QAAS,GAAM,KAAM,KAAM,KAAM,SAAU,EAC7C,CAAE,QAAS,GAAO,KAAM,QAAS,KAAM,SAAU,CACnD,EACA,KAAM,WACN,KAAM,OACR,CACF,EDpGA,IAAMC,GAAqB,MAAOzC,EAAuBoC,IAA2B,CAClF,GAAM,CACJ,YAAAV,EACA,YAAAC,EACA,MAAAxB,EACA,OAAAyB,EACA,YAAAc,EACA,UAAWC,EACX,eAAAC,EACA,aAAAC,EACA,KAAAC,CACF,EAAIV,EACEW,EAAYJ,GAAkBD,EAEpC,GAAI,CAACH,EAAUG,CAAW,GAAK,CAACH,EAAUQ,CAAS,EACjD,MAAM,IAAIxD,8BAAyD,EAGrE,GAAM,CAAE,gBAAAuC,EAAiB,gBAAAC,EAAiB,UAAAC,CAAU,EAAIP,EACtD,CAAE,YAAAC,EAAa,YAAAC,EAAa,MAAAxB,EAAO,OAAAyB,CAAO,EAC1C5B,EAAO,MACT,EACMgD,EAAS5B,EAAkB,CAAE,MAAOM,EAAa,SAAUkB,CAAe,CAAC,EAS3EK,EAPY,MAAMD,EAAO,aAAa,CAC1C,QAAShB,EAAU,QACnB,IAAKQ,EACL,aAAc,YACd,KAAM,CAACE,EAAaZ,EAAgB,kBAAkB,CACxD,CAAC,EAE+CF,EAC1CsB,EAAqBD,EAA8B,EAAI,EAE7D,GAAIA,EAOF,GANAJ,IAAe,CACb,iBAAkB,EAClB,4CACA,mBAAAK,CACF,CAAC,EAEGJ,EAAM,CACR,IAAMK,EAAOb,EAAmB,CAC9B,IAAKE,EACL,aAAc,UACd,KAAM,CAACV,EAAgB,mBAAoBF,CAAM,CACnD,CAAC,EAEKwB,EAAS,MAAMN,EACnB,CACE,KAAMJ,EACN,GAAIV,EAAU,QACd,KAAAmB,CACF,EACCE,GAAsBL,EAAO,mBAAmB,CAAE,sBAAuBK,CAAa,CAAC,CAC1F,EAEA,MAAML,EAAO,0BAA0B,CAAE,KAAMI,EAAQ,gBAAiB,GAAM,CAAC,CACjF,KAAO,CACL,GAAM,CAAE,QAAAE,CAAQ,EAAI,MAAMN,EAAO,iBAAiB,CAChD,QAASN,EACT,QAASV,EAAU,QACnB,IAAKQ,EACL,aAAc,UACd,KAAM,CAACV,EAAgB,mBAAoBF,CAAM,CACnD,CAAC,EAEKwB,EAAS,MAAMJ,EAAO,cAAcM,CAAO,EACjD,MAAMN,EAAO,0BAA0B,CAAE,KAAMI,EAAQ,gBAAiB,GAAM,CAAC,CACjF,CASF,GANAP,IAAe,CACb,iBAAkBI,EAA8B,EAAI,EACpD,yCACA,mBAAAC,CACF,CAAC,EAEGJ,EAAM,CACR,IAAMK,EAAOb,EAAmB,CAC9B,IAAKd,EACL,aAAc,iBACd,KAAM,CAACI,EAAQG,EAAgB,OAAQgB,EAAWf,EAAU,OAAO,CACrE,CAAC,EAED,OAAOc,EACL,CACE,KAAMJ,EACN,GAAIZ,EAAgB,mBACpB,KAAAqB,CACF,EACCE,GAAsBL,EAAO,mBAAmB,CAAE,sBAAuBK,CAAa,CAAC,CAC1F,CACF,KAAO,CACL,GAAM,CAAE,QAAAC,CAAQ,EAAI,MAAMN,EAAO,iBAAiB,CAChD,QAASN,EACT,QAASZ,EAAgB,mBACzB,IAAKN,EACL,aAAc,iBACd,KAAM,CAACI,EAAQG,EAAgB,OAAQgB,EAAWf,EAAU,OAAO,CACrE,CAAC,EAED,OAAOgB,EAAO,cAAcM,CAAO,CACrC,CACF,EAEMC,GAAsB,MAAOC,GAA+B,CAChE,GAAI,CAEF,OADyB,MAAMA,EAAa,eAAe,CAE7D,MAAQ,CACN,MACF,CACF,EAEA,eAAsBC,EACpBzD,EACAoC,EACA1C,EACyB,CACzB,MAAMM,EAAO,gBAAgB,EAE7B,GAAM,CAAE,qBAAsB0D,CAAgC,EAC5D1D,EAAO,OAAQ,KAAML,GAAcA,EAAU,UAAYyC,EAAO,YAAY,OAAO,GAAK,CAAC,EACrF,CAAE,qBAAsBuB,CAAgC,EAC5D3D,EAAO,OAAQ,KAAML,GAAcA,EAAU,UAAYyC,EAAO,YAAY,OAAO,GAAK,CAAC,EAE3F,GAAI,CAACsB,GAAmC,CAACC,EACvC,MAAM,IAAIpE,8BAAyD,EAGrE,IAAMqE,EAAO,MAAM5D,EAAO,QAAQ,CAAE,GAAGoC,EAAQ,SAAUA,EAAO,cAAe,CAAC,EAE1EyB,GAAazB,EAAO,MAAM,SAAWwB,EAAKxB,EAAO,MAAM,OAAO,IAAM,GACpEgB,EAAS,MAAMX,GAAmBzC,EAAQoC,CAAM,EAChD0B,EAAkB,KAAK,IAAI,EAC3BN,EAAepC,EAAkB,CAAE,MAAOgB,EAAO,YAAa,SAAUA,EAAO,cAAe,CAAC,EAC/F2B,EAAoB,MAAMR,GAAoBC,CAAY,EAEhE,MAAO,CACL,KAAMxD,EAAO,KACb,YAAAN,EACA,YAAa0C,EAAO,YACpB,UAAWA,EAAO,WAAaA,EAAO,YACtC,OAAQA,EAAO,OACf,eAAgBA,EAAO,MAAM,SAC7B,OAAQA,EAAO,MAAM,OAErB,UAAAyB,EAEA,YAAazB,EAAO,YACpB,gBAAA0B,EACA,aAAcV,EACd,wBAAyB,EACzB,gCAAAM,EAEA,YAAatB,EAAO,YACpB,wBAAyB,EACzB,gCAAAuB,EAEA,iBAAkBI,CACpB,CACF,CE/KA,eAAsBC,EAAgBhE,EAAuB,CAC3D,GAAI,CAACA,EAAO,SACV,MAAMA,EAAO,aAAa,EAEtB,CAACA,EAAO,QACV,MAAM,IAAIV,wBAA0D,CAG1E,CCXA,OAAS,kBAAA2E,MAAoC,OCA7C,MAA0D,OAGnD,IAAMC,EAAmB,CAACC,EAA0BC,IAClDD,EAAY,UAAY,OAAOA,EAAY,SAAWC,EAAQ,OAAO,ECJvE,IAAMC,EAAO,MAAOC,GACzB,IAAI,QAASC,GAAQ,CACnB,WAAWA,EAAKD,CAAI,CACtB,CAAC,ECOI,IAAME,EAAe,CAAI,CAAE,QAAAC,EAAS,MAAAC,EAAO,WAAAC,CAAW,IAAiB,CAC5E,IAAIC,EAAY,GACZC,EAAc,GACdC,EAAqB,EACrBC,EACAC,EAEEC,EAAQ9B,GAAY,CACpB4B,GAAWH,IACbA,EAAY,GACZG,EAAQ5B,CAAI,EAEhB,EAEM+B,EAAS,IAAM,CACnBL,EAAc,GAEVG,GAAUJ,IACZA,EAAY,GACZI,EAAO,WAAW,EAEtB,EAoCA,MAAO,CACL,OAnCa,IAAI,QAAW,CAACT,EAAKY,IAAQ,CAC1CP,EAAY,GACZG,EAAUR,EACVS,EAASG,EAET,IAAMC,EAAU,SAA2B,CACzC,GAAI,GAACR,GAAaC,GAIlB,IAAI,CAGF,GAFA,MAAMJ,EAAQQ,CAAI,EAEd,CAACL,GAAaC,EAChB,OAGF,MAAMR,EAAKK,CAAK,CAClB,OAAS9E,EAAK,CACZ,QAAQ,MAAOA,EAAc,OAAO,EACpCkF,GAAc,EACd,MAAMT,EAAK,GAAKS,EAAaJ,CAAK,CACpC,CAEA,MAAMU,EAAQ,EAChB,EAEIT,EACF,WAAWS,EAAST,CAAU,EAE9BS,EAAQ,CAEZ,CAAC,EAIC,OAAAF,CACF,CACF,EHtDO,IAAMG,EAAoB,IAAO,GAAK,GAAK,EAErCC,EAAa,MAEbC,GAAgB,IAMvBC,EAAiB,CACrBC,EACAC,EACAC,IACG,CACH,OAAO,OAAOF,EAAS,OAAO,YAAY,OAAO,QAAQC,CAAO,EAAE,OAAO,CAAC,CAAC,CAAEE,CAAK,IAAMA,IAAU,MAAS,CAAC,CAAC,EAC7GD,EAAe,CAAE,GAAGF,CAAQ,CAAC,CAC/B,EAMaI,GAAgB,MAAOhE,EAAsBO,IAA2B,CACnF,GAAM,CAAE,eAAAQ,EAAgB,eAAAkD,EAAgB,eAAAH,EAAgB,eAAAI,CAAe,EAAI3D,EACrE4D,EAAe5E,EAAkB,CAAE,MAAO2E,EAAe,YAAa,SAAUnD,CAAe,CAAC,EAChGd,EAAkBD,EAAO,KAAMlC,GAAcA,EAAU,UAAYoG,EAAe,YAAY,OAAO,EACrGvC,EAAepC,EAAkB,CAAE,MAAO2E,EAAe,YAAa,SAAUD,CAAe,CAAC,EAChG/D,EAAkBF,EAAO,KAAMlC,GAAcA,EAAU,UAAYoG,EAAe,YAAY,OAAO,EACrGE,EAAqB,CAAE,GAAGF,CAAe,EAE/C,GAAI,CAACjE,GAAmB,CAACC,EACvB,MAAM,IAAIxC,uBAAkD,EA2H9D,OAAOiF,EAA6B,CAClC,QAzHc,MAAOS,GAA+B,CAMpD,GAAIgB,EAAmB,aAAeA,EAAmB,UAAU,MACjE,OAAOhB,EAAKgB,CAAkB,EAMhC,GAAIA,EAAmB,gBAAkBZ,GAAqB,KAAK,IAAI,EACrE,OAAAG,EAAeS,EAAoB,CAAE,YAAa,KAAK,IAAI,EAAG,cAA6B,EAAGN,CAAc,EACrGV,EAAKgB,CAAkB,EAOhC,IAAMC,EAAY,MAAMF,EAAa,sBAAsB,CACzD,KAAMC,EAAmB,YAC3B,CAAC,EAKD,GAAI,CAACA,EAAmB,iBAAkB,CACxC,IAAME,EAAK,MAAMH,EAAa,eAAe,CAAE,KAAMC,EAAmB,YAAwB,CAAC,EAC3FG,EAAalC,EAAiBiC,EAAID,CAAS,EAE7CE,GACFZ,EAAeS,EAAoB,CAAE,iBAAkBG,CAAW,EAAGT,CAAc,CAEvF,CAKA,GAAIO,EAAU,SAAW,WACvB,OAAAV,EACES,EACA,CAAE,YAAa,KAAK,IAAI,EAAG,cAA0C,EACrEN,CACF,EACOV,EAAKgB,CAAkB,EAShC,IAAMI,EAAoB,MAAML,EAAa,4BAA4B,CACvE,KAAMC,EAAmB,YAC3B,CAAC,EACKK,EAAuBD,EAAoBJ,EAAmB,wBAC9DM,EAA2BF,GAAqBJ,EAAmB,gCAEzE,GAAIK,EAAsB,CACxB,IAAME,EAAU,CAAC,EACjBA,EAAQ,wBAA0B,OAAOH,CAAiB,EAErDE,IACHC,EAAQ,iBAAmB,MAAMhD,EAAa,eAAe,GAG/DgC,EAAeS,EAAoBO,EAASb,CAAc,CAC5D,CAEA,GAAI,CAACY,EACH,OAGGN,EAAmB,kBACtBT,EAAeS,EAAoB,CAAE,iBAAkB,MAAMzC,EAAa,eAAe,CAAE,EAAGmC,CAAc,EAM9G,IAAMc,EAAmBP,EAAU,KAAK,KAAMQ,GACxCA,EAAI,UAAY5E,EAAgB,mBACpBmC,EAAe,CAC3B,IAAKzC,EACL,GAAGkF,CACL,CAAC,EAEY,YAAc,iBAGtB,EACR,EAED,GAAI,CAACD,EACH,MAAM,IAAIlH,mBAER,gEAAgE0G,EAAmB,YAAY,GACjG,EAcF,IAAMU,EAPgB1C,EAAe,CACnC,IAAKzC,EACL,UAAW,iBACX,GAAGiF,CACL,CAAC,EAG2B,KAAK,MACjC,OAAAjB,EAAeS,EAAoB,CAAE,gBAAiB,KAAK,IAAI,EAAG,SAAU,CAAE,MAAAU,CAAM,CAAE,EAAGhB,CAAc,EAChGV,EAAKgB,CAAkB,CAChC,EAIE,MAAOpG,EAA0BiC,EAAgB,OAAO,EACxD,WAAYyD,EACd,CAAC,CACH,EAMaqB,GAAgB,MAAO/E,EAAsBO,IAA2B,CACnF,GAAM,CAAE,eAAA0D,EAAgB,eAAAH,EAAgB,eAAAI,CAAe,EAAI3D,EACrD6D,EAAqB,CAAE,GAAGF,CAAe,EAE/C,GAAI,CAACA,EAAe,aAAe,CAACA,EAAe,UAAU,MAC3D,MAAM,IAAIxG,mBAA+C,kBAAkB,EAG7E,GAAI,CAACwG,EAAe,iBAClB,MAAM,IAAIxG,mBAA+C,6BAA6B,EAGxF,IAAMiE,EAAepC,EAAkB,CAAE,MAAO2E,EAAe,YAAa,SAAUD,CAAe,CAAC,EAChG/D,EAAkBF,EAAO,KAAMlC,GAAcA,EAAU,UAAYoG,EAAe,YAAY,OAAO,EAE3G,GAAI,CAAChE,EACH,MAAM,IAAIxC,mBAER,yBAAyBwG,EAAe,YAAY,OAAO,GAC7D,EAwHF,OAAOvB,EAA6B,CAClC,QAtHc,MAAOS,GAA+B,CAKpD,GAAIgB,EAAmB,YACrB,OAAOhB,EAAKgB,CAAkB,EAMhC,GAAI,CAACA,EAAmB,iBACtB,OAAAT,EACES,EACA,CAAE,YAAa,KAAK,IAAI,EAAG,cAAoC,EAC/DN,CACF,EACOV,EAAKgB,CAAkB,EAMhC,GAAIA,EAAmB,gBAAkBZ,GAAqB,KAAK,IAAI,EACrE,OAAAG,EAAeS,EAAoB,CAAE,YAAa,KAAK,IAAI,EAAG,cAA6B,EAAGN,CAAc,EACrGV,EAAKgB,CAAkB,EAGhC,GAAI,CAACA,EAAmB,aAAc,CACpC,IAAMY,EAAkB,MAAMrD,EAAa,eAAe,EACpDsD,EAAoBb,EAAmB,iBAAmBX,EAC1DyB,EAAYD,GAAqB,GAAKA,EAAoB,WAC1DE,EAAqBf,EAAmB,iBAAmBX,EAC3D2B,EAAUD,EAAqBH,EAAkBG,EAAqB,SAEtEE,EAAa,MAAM1D,EAAa,QAAQ,CAC5C,QAASzB,EAAgB,0BACzB,MAAO,CACL,KAAM,kBACN,KAAM,QACN,OAAQ,CACN,CAAE,QAAS,GAAM,aAAc,UAAW,KAAM,SAAU,KAAM,SAAU,EAC1E,CAAE,QAAS,GAAO,aAAc,SAAU,KAAM,eAAgB,KAAM,QAAS,EAC/E,CAAE,QAAS,GAAM,aAAc,SAAU,KAAM,QAAS,KAAM,QAAS,EACvE,CAAE,QAAS,GAAO,aAAc,UAAW,KAAM,SAAU,KAAM,SAAU,EAC3E,CAAE,QAAS,GAAO,aAAc,QAAS,KAAM,cAAe,KAAM,OAAQ,CAC9E,CACF,EACA,KAAM,CAAE,MAAOkE,EAAmB,SAAU,KAAgB,EAC5D,UAAAc,EACA,QAAAE,CACF,CAAC,EAED,GAAIC,EAAW,CAAC,GAAG,gBACjB1B,EAAeS,EAAoB,CAAE,aAAciB,EAAW,CAAC,EAAE,eAAgB,EAAGvB,CAAc,MAC7F,CACLH,EAAeS,EAAoB,CAAE,iBAAkBY,CAAgB,EAAGlB,CAAc,EACxF,MACF,CACF,CAMA,IAAMO,EAAY,MAAM1C,EAAa,sBAAsB,CACzD,KAAMyC,EAAmB,YAC3B,CAAC,EAKD,GAAI,CAACA,EAAmB,iBAAkB,CACxC,IAAME,EAAK,MAAM3C,EAAa,eAAe,CAAE,KAAMyC,EAAmB,YAAwB,CAAC,EAC3FG,EAAalC,EAAiBiC,EAAID,CAAS,EAE7CE,GACFZ,EAAeS,EAAoB,CAAE,iBAAkBG,CAAW,EAAGT,CAAc,CAEvF,CAKA,GAAIO,EAAU,SAAW,WACvB,OAAAV,EACES,EACA,CAAE,YAAa,KAAK,IAAI,EAAG,cAA0C,EACrEN,CACF,EACOV,EAAKgB,CAAkB,EAQhC,IAAMI,EAAoB,MAAM7C,EAAa,4BAA4B,CACvE,KAAMyC,EAAmB,YAC3B,CAAC,EACKK,EAAuBD,EAAoBJ,EAAmB,wBAC9DM,EAA2BF,GAAqBJ,EAAmB,gCAMzE,GAJIK,GACFd,EAAeS,EAAoB,CAAE,wBAAyB,OAAOI,CAAiB,CAAE,EAAGV,CAAc,EAGvG,EAACY,EAIL,OAAAf,EAAeS,EAAoB,CAAE,YAAa,KAAK,IAAI,CAAE,EAAGN,CAAc,EACvEV,EAAKgB,CAAkB,CAChC,EAIE,MAAOpG,EAA0BkC,EAAgB,OAAO,EACxD,WAAYwD,EACd,CAAC,CACH,EAEO,SAAS4B,GAAcnH,EAAuBoC,EAAwB,CAC3E,IAAIgF,EAEElC,EAAS,IAAM,CACnBkC,IAAU,CACZ,EA0BA,MAAO,CACL,QAzBsB,SAAY,CAClC,MAAMpH,EAAO,gBAAgB,EAE7B,GAAM,CAAE,eAAA4C,EAAgB,eAAAkD,EAAgB,eAAAH,EAAgB,eAAAI,CAAe,EAAI3D,EAErE,CAAE,OAAQiF,EAAe,OAAQC,CAAqB,EAAI,MAAMzB,GAAc7F,EAAO,OAAS,CAClG,eAAA4C,EACA,eAAAkD,EACA,eAAAH,EACA,eAAAI,CACF,CAAC,EACDqB,EAAUE,EACV,IAAMC,EAA8B,MAAMF,EAEpC,CAAE,OAAQG,EAAe,OAAQC,CAAqB,EAAI,MAAMb,GAAc5G,EAAO,OAAS,CAClG,eAAA4C,EACA,eAAAkD,EACA,eAAAH,EACA,eAAgB4B,CAClB,CAAC,EACD,OAAAH,EAAUK,EACHD,CACT,GAG0B,EACxB,OAAAtC,CACF,CACF,CIpWO,IAAMwC,GAA2ChI,IAC/C,CACL,YACA,OAAQ,KACR,aAAc,gBAAkB,CAC9B,KAAK,OAAS,MAAMD,EAAUC,CAAW,CAC3C,EACA,gBAAiB,gBAAkB,CACjC,OAAOsE,EAAgB,IAAI,CAC7B,EACA,UAAW,gBAAkB,CAC3B,OAAOjE,EAAU,IAAI,CACvB,EACA,QAAS,eAAgBqC,EAAQ,CAC/B,OAAOD,EAAQ,KAAMC,CAAM,CAC7B,EACA,cAAe,eAAgBA,EAAQ,CACrC,OAAOqB,EAAc,KAAMrB,EAAQ1C,CAAW,CAChD,EACA,cAAe,SAAU0C,EAAQ,CAC/B,OAAO+E,GAAc,KAAM/E,CAAM,CACnC,CACF,GCxBK,IAAMuF,GAAmB,IAAI,IAAI,CAAC,QAAkBD,EAAiB,CAAC,CAAC,EAEjEE,GAA2B,CAAClI,EAA0BmI,IAC1D,IAAI,IACT,CAAC,GAAGF,EAAgB,EACjB,OAAO,CAAC,CAACG,CAAU,IAAM,CAACD,GAAqB,SAASC,CAAU,CAAC,EACnE,IAAI,CAAC,CAACA,EAAYC,CAAO,IAAM,CAACD,EAAYC,EAAQrI,CAAW,CAAC,CAAC,CACtE,EAGWsI,EAAuB,CAClCC,EACA9H,EACA+H,IACG,CACH,IAAMJ,EAAa3H,EAAM,aAAa+H,CAAa,GAAG,KAAMJ,GAAeG,EAAsB,IAAIH,CAAU,CAAC,EAEhH,GAAI,CAACA,EACH,MAAM,IAAIzI,EAGZ,MAAO,CACL,KAAMyI,EACN,OAAQG,EAAsB,IAAIH,CAAU,CAC9C,CACF,EC3BA,OAAS,WAAAK,GAAS,aAAAC,OAAiB,SAG5B,IAAMC,GAA6B,CAAC,CAAE,YAAA3I,EAAa,oBAAAmI,CAAoB,IAA2B,CACvG,IAAMI,EAAwBL,GAAyBlI,EAAamI,CAAmB,EAEjFS,EAAgB,SAAY,CAChC,MAAM,QAAQ,WACZ,MAAM,KAAKL,CAAqB,EAAE,IAAI,CAAC,CAAC,CAAEM,CAAa,IAAMA,EAAc,aAAa,CAAC,CAC3F,CACF,EAgEA,MAAO,CACL,YAAA7I,EACA,QAASuI,EACT,KAjEW,SAAY,CACvB,MAAMK,EAAc,CACtB,EAgEE,cAAAA,EACA,UA/DgB,UACD,MAAM,QAAQ,IAAI,MAAM,KAAKL,CAAqB,EAAE,IAAI,CAAC,CAAC,CAAEjI,CAAM,IAAMA,EAAO,UAAU,CAAC,CAAC,GAC5F,OAAsB,CAACwI,EAAkBC,IAAkB,CACvE,OAAW,CAAC3I,EAAS4I,CAAY,IAAK,OAAO,QAAQD,CAAa,EAAG,CACnE,IAAME,EAAiBH,EAAiB1I,CAAO,EAE/C,GAAI6I,EACF,QAAWC,KAAeF,EAAc,CACtC,IAAMG,EAAQF,EAAe,UAAU,CAAC,CAAE,OAAAG,CAAO,IAAMA,IAAWF,EAAY,MAAM,EAEhFC,IAAU,GACZF,EAAe,KAAKC,CAAW,EAE/BR,GAAUO,EAAeE,CAAK,EAAGD,EAAa,CAACG,EAAUC,IAAa,CACpE,GAAIb,GAAQY,CAAQ,EAClB,MAAO,CAAC,GAAG,IAAI,IAAIA,EAAS,OAAOC,CAAQ,CAAC,CAAC,CAEjD,CAAC,CAEL,MAEAR,EAAiB1I,CAAO,EAAI4I,CAEhC,CAEA,OAAOF,CACT,EAAG,CAAC,CAAC,EAsCL,QAnCc,MAAOpG,GAAsB,CAC3C,GAAM,CAAE,OAAApC,CAAO,EAAIgI,EAAqBC,EAAuB7F,EAAO,MAAOA,EAAO,YAAY,OAAO,EACvG,OAAOpC,EAAO,QAAQoC,CAAM,CAC9B,EAiCE,iBA1BuB,CAACjC,EAAoB+H,IAA0B,CACtE,GAAI,CACF,OAAAF,EAAqBC,EAAuB9H,EAAO+H,CAAa,EACzD,EACT,MAAQ,CACN,MAAO,EACT,CACF,EAoBE,cAhCoB,MAAO9F,GAA2B,CACtD,GAAM,CAAE,OAAApC,CAAO,EAAIgI,EAAqBC,EAAuB7F,EAAO,MAAOA,EAAO,YAAY,OAAO,EACvG,OAAOpC,EAAO,cAAcoC,CAAM,CACpC,EA8BE,cAnBqBA,GAA2B,CAChD,IAAMpC,EAASiI,EAAsB,IAAI7F,EAAO,eAAe,IAAI,EAEnE,GAAI,CAACpC,EACH,MAAM,IAAIX,EAGZ,OAAOW,EAAO,cAAcoC,CAAM,CACpC,CAYA,CACF","sourcesContent":["import type { Address } from 'viem';\nimport type { BridgeType } from './bridge';\n\nexport enum TokenType {\n NATIVE = 'native',\n ERC20 = 'erc20',\n}\n\nexport type Asset = {\n type: TokenType;\n address?: Address;\n name: string;\n symbol: string;\n decimals: number;\n};\n\n// chainId - bridge type pairs\nexport type DestinationInfo = Record<string, BridgeType[]>;\n\nexport type BridgeAsset = Asset & {\n destinations: DestinationInfo;\n};\n\nexport type ChainAssetMap = Record<string, BridgeAsset[]>;\n\nexport type AssetFeeMap = Record<Address, bigint>;\n","import type { AssetFeeMap, BridgeAsset, ChainAssetMap } from './asset';\nimport type { Chain } from './chain';\nimport type { BridgeConfig } from './config';\nimport type { Environment } from './environment';\nimport type { Provider } from './provider';\nimport type { Signer } from './signer';\nimport type { BridgeTransfer } from './transfer';\n\nexport enum BridgeType {\n CCTP = 'cctp',\n}\n\nexport type FeeParams = {\n asset: BridgeAsset;\n amount: bigint;\n sourceChain: Chain;\n targetChain: Chain;\n provider?: Provider;\n};\n\nexport enum BridgeSignatureReason {\n AllowanceApproval = 'allowance-approval',\n TokensTransfer = 'tokens-transfer',\n}\n\nexport type BridgeStepDetails = {\n currentSignature: number;\n requiredSignatures: number;\n currentSignatureReason: BridgeSignatureReason;\n};\n\nexport type TransferParams = {\n asset: BridgeAsset;\n amount: bigint;\n fromAddress: string;\n toAddress?: string;\n sourceChain: Chain;\n targetChain: Chain;\n sourceProvider?: Provider;\n targetProvider?: Provider;\n onStepChange?: (stepDetails: BridgeStepDetails) => void;\n sign?: Signer;\n};\n\nexport type TrackingParams = {\n bridgeTransfer: BridgeTransfer;\n sourceProvider?: Provider;\n targetProvider?: Provider;\n updateListener: (transfer: BridgeTransfer) => void;\n};\n\nexport type BridgeService = {\n type: BridgeType;\n config: BridgeConfig | null;\n ensureHasConfig: () => Promise<void>;\n updateConfig: () => Promise<void>;\n getAssets: () => Promise<ChainAssetMap>;\n getFees: (params: FeeParams) => Promise<AssetFeeMap>;\n transferAsset: (params: TransferParams) => Promise<BridgeTransfer>;\n trackTransfer: (transfer: TrackingParams) => { cancel: () => void; result: Promise<BridgeTransfer> };\n};\n\nexport type BridgeServiceFactory = (environment: Environment) => BridgeService;\n","export enum Environment {\n PROD = 'production',\n TEST = 'test',\n}\n","export enum ErrorCode {\n BRIDGE_NOT_AVAILABLE = 5001,\n INITIALIZATION_FAILED = 5002,\n INVALID_PARAMS = 5003,\n TIMEOUT = 5004,\n TRANSACTION_REVERTED = 5005,\n}\n\nexport enum ErrorReason {\n UNKNOWN = 'UNKNOWN', // generic, not specified error\n CONFIG_NOT_AVAILABLE = 'CONFIG_NOT_AVAILABLE', // error while fetching or parsing the config\n INVALID_PARAMS = 'INVALID_PARAMS', // generic error with the params\n IDENTICAL_CHAINS_PROVIDED = 'IDENTICAL_CHAINS_PROVIDED', // provided source and target chains are the same\n INCORRECT_AMOUNT_PROVIDED = 'INCORRECT_AMOUNT_PROVIDED', // the transfer amount is incorrect (e.g.: lesser than or equal to zero)\n INCORRECT_ADDRESS_PROVIDED = 'INCORRECT_ADDRESS_PROVIDED', // the sender or recipient address is incorrect\n CHAIN_NOT_SUPPORTED = 'CHAIN_NOT_SUPPORTED', // the provided source or target chain is not supported by the bridge\n ASSET_NOT_SUPPORTED = 'ASSET_NOT_SUPPORTED', // the provided asset is not supported by the bridge\n CONFIRMATION_COUNT_UNKNOWN = 'CONFIRMATION_COUNT_UNKNOWN', // required confirmation count of the source or target chain is unknown\n}\n","import type { ErrorCode } from '../types';\n\nexport class BridgeError extends Error {\n constructor(\n message: string,\n public code: ErrorCode,\n public details?: string,\n ) {\n super(message);\n }\n}\n","import { ErrorCode, ErrorReason } from '../types';\nimport { BridgeError } from './bridge-error';\n\nexport class BridgeUnavailableError extends BridgeError {\n constructor(message = ErrorReason.UNKNOWN, details?: string) {\n super(message, ErrorCode.BRIDGE_NOT_AVAILABLE, details);\n this.name = 'BridgeUnavailableError';\n }\n}\n","import { ErrorCode, ErrorReason } from '../types';\nimport { BridgeError } from './bridge-error';\n\nexport class BridgeInitializationError extends BridgeError {\n constructor(message = ErrorReason.UNKNOWN, details?: string) {\n super(message, ErrorCode.INITIALIZATION_FAILED, details);\n this.name = 'BridgeInitializationError';\n }\n}\n","import { ErrorCode, ErrorReason } from '../types';\nimport { BridgeError } from './bridge-error';\n\nexport class InvalidParamsError extends BridgeError {\n constructor(message = ErrorReason.INVALID_PARAMS, details?: string) {\n super(message, ErrorCode.INVALID_PARAMS, details);\n this.name = 'InvalidParamsError';\n }\n}\n","import { BridgeInitializationError } from '../../../errors';\nimport { ErrorReason } from '../../../types';\nimport { Environment } from '../../../types/environment';\nimport { AvalancheChainIds } from '../types/chain';\nimport type { Config } from '../types/config';\n\nconst CONFIG_URLS: Record<Environment, string> = {\n [Environment.TEST]:\n 'https://raw.githubusercontent.com/ava-labs/avalanche-bridge-resources/main/cctp/cctp_config.test.json',\n [Environment.PROD]:\n 'https://raw.githubusercontent.com/ava-labs/avalanche-bridge-resources/main/cctp/cctp_config.json',\n};\n\nexport const getConfig = async (environment: Environment): Promise<Config> => {\n try {\n const response = await fetch(CONFIG_URLS[environment]!);\n const config: Config = await response.json();\n\n return config.map((chainData) => ({ ...chainData, chainId: `eip155:${chainData.chainId}` }));\n } catch (err) {\n throw new BridgeInitializationError(\n ErrorReason.CONFIG_NOT_AVAILABLE,\n `Error while fetching CCTP config: ${(err as unknown as Error).message}`,\n );\n }\n};\n\nexport const getTrackingDelayByChainId = (chainId: string) => {\n switch (chainId) {\n case AvalancheChainIds.MAINNET:\n case AvalancheChainIds.FUJI:\n return 1000;\n default:\n return 20000;\n }\n};\n","import { TokenType, type BridgeService, type ChainAssetMap, type DestinationInfo, BridgeType } from '../../../types';\n\nexport async function getAssets(bridge: BridgeService) {\n await bridge.ensureHasConfig();\n\n const chainIds = bridge.config!.map((chainData) => chainData.chainId);\n\n return bridge.config!.reduce<ChainAssetMap>((assets, chainData) => {\n assets[chainData.chainId] = chainData.tokens.map((asset) => ({\n ...asset,\n type: TokenType.ERC20,\n destinations: chainIds.reduce<DestinationInfo>((destinations, chainId) => {\n if (chainData.chainId !== chainId) {\n if (!destinations[chainId]) {\n destinations[chainId] = [];\n }\n\n destinations[chainId]?.push(BridgeType.CCTP);\n }\n\n return destinations;\n }, {}),\n }));\n\n return assets;\n }, {});\n}\n","import { createWalletClient, publicActions, custom, http } from 'viem';\nimport type { Chain } from '../types/chain';\nimport type { Provider } from '../types';\nimport caip2 from './caip2';\n\nconst _getChain = (chain: Chain) => {\n const { reference: chainId } = caip2.toJSON(chain.chainId);\n\n return {\n id: Number(chainId),\n name: chain.chainName,\n nativeCurrency: {\n decimals: chain.networkToken.decimals,\n symbol: chain.networkToken.symbol,\n name: chain.networkToken.name,\n },\n network: chain.chainName,\n rpcUrls: {\n default: {\n http: [chain.rpcUrl],\n },\n public: {\n http: [chain.rpcUrl],\n },\n },\n ...(chain.utilityAddresses?.multicall && {\n contracts: {\n multicall3: {\n address: chain.utilityAddresses.multicall,\n },\n },\n }),\n };\n};\n\nexport const getClientForChain = ({ chain, provider }: { chain: Chain; provider?: Provider }) => {\n const chainInfo = _getChain(chain);\n const transport = provider ? custom(provider) : http(chain.rpcUrl, { batch: true, retryCount: 0 });\n\n return createWalletClient({\n chain: chainInfo,\n transport,\n }).extend(publicActions);\n};\n","// ref: https://chainagnostic.org/CAIPs/caip-2\n\nexport type Caip2ChainId = {\n namespace: string;\n reference: string;\n};\n\nconst namespacePattern = '^[-a-z0-9]{3,8}$';\n// the standard allows up to 32 characters for the reference part, but we have to set it to 50 so it accepts our cb58 encoded chain IDs\nconst referencePattern = '^[-_a-zA-Z0-9]{1,50}$';\nconst delimeter = ':';\n\nconst toJSON = (identifier: string): Caip2ChainId => {\n const [namespace, reference] = identifier.split(delimeter);\n\n if (!namespace || !reference) {\n throw new Error('Invalid identifier provided.');\n }\n\n if (!new RegExp(namespacePattern).test(namespace)) {\n throw new Error('Invalid namespace provided.');\n }\n\n if (!new RegExp(referencePattern).test(reference)) {\n throw new Error('Invalid reference provided.');\n }\n\n return {\n namespace,\n reference,\n };\n};\n\nconst toString = ({ namespace, reference }: Caip2ChainId) => {\n return `${namespace}${delimeter}${reference}`;\n};\n\nexport default {\n toJSON,\n toString,\n};\n","export const TOKEN_ROUTER_ABI = [\n {\n inputs: [\n {\n internalType: 'address',\n name: 'circleTokenMessenger_',\n type: 'address',\n },\n {\n internalType: 'address',\n name: 'burnToken_',\n type: 'address',\n },\n ],\n stateMutability: 'nonpayable',\n type: 'constructor',\n },\n {\n inputs: [],\n name: 'AlreadyAdmin',\n type: 'error',\n },\n {\n inputs: [],\n name: 'AlreadyFeeCollector',\n type: 'error',\n },\n {\n inputs: [],\n name: 'AlreadySupportedBurnToken',\n type: 'error',\n },\n {\n inputs: [],\n name: 'AmountLessThanFee',\n type: 'error',\n },\n {\n inputs: [],\n name: 'BalanceNotIncreased',\n type: 'error',\n },\n {\n inputs: [],\n name: 'CannotRemoveLastAdmin',\n type: 'error',\n },\n {\n inputs: [],\n name: 'FeePercentageGreaterThanMax',\n type: 'error',\n },\n {\n inputs: [],\n name: 'InvalidAdminAddress',\n type: 'error',\n },\n {\n inputs: [],\n name: 'InvalidFeeCollector',\n type: 'error',\n },\n {\n inputs: [],\n name: 'InvalidMintRecipientAddress',\n type: 'error',\n },\n {\n inputs: [],\n name: 'InvalidTokenAddress',\n type: 'error',\n },\n {\n inputs: [],\n name: 'InvalidTokenMessengerAddress',\n type: 'error',\n },\n {\n inputs: [],\n name: 'MaxFeeLessThanMinFee',\n type: 'error',\n },\n {\n inputs: [],\n name: 'NotAdmin',\n type: 'error',\n },\n {\n inputs: [],\n name: 'NotFeeCollector',\n type: 'error',\n },\n {\n inputs: [],\n name: 'UnSupportedBurnToken',\n type: 'error',\n },\n {\n inputs: [],\n name: 'UnsupportedDomain',\n type: 'error',\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: false,\n internalType: 'address',\n name: 'admin',\n type: 'address',\n },\n ],\n name: 'AdminAdded',\n type: 'event',\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: false,\n internalType: 'address',\n name: 'admin',\n type: 'address',\n },\n ],\n name: 'AdminRemoved',\n type: 'event',\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: false,\n internalType: 'address',\n name: 'token',\n type: 'address',\n },\n ],\n name: 'BurnTokenAdded',\n type: 'event',\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: false,\n internalType: 'address',\n name: 'token',\n type: 'address',\n },\n ],\n name: 'BurnTokenRemoved',\n type: 'event',\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: false,\n internalType: 'address',\n name: 'feeCollector',\n type: 'address',\n },\n ],\n name: 'FeeCollectorAdded',\n type: 'event',\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: false,\n internalType: 'address',\n name: 'feeCollector',\n type: 'address',\n },\n ],\n name: 'FeeCollectorRemoved',\n type: 'event',\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: false,\n internalType: 'uint32',\n name: 'domain',\n type: 'uint32',\n },\n {\n components: [\n {\n internalType: 'uint256',\n name: 'maxFee',\n type: 'uint256',\n },\n {\n internalType: 'uint256',\n name: 'minFee',\n type: 'uint256',\n },\n {\n internalType: 'uint32',\n name: 'feePercentage',\n type: 'uint32',\n },\n {\n internalType: 'uint256',\n name: 'txnFee',\n type: 'uint256',\n },\n {\n internalType: 'bool',\n name: 'supported',\n type: 'bool',\n },\n ],\n indexed: false,\n internalType: 'struct FeeCalculator.FeeConfiguration',\n name: 'feeConfiguration',\n type: 'tuple',\n },\n ],\n name: 'FeeConfigurationUpdated',\n type: 'event',\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n internalType: 'address',\n name: 'previousOwner',\n type: 'address',\n },\n {\n indexed: true,\n internalType: 'address',\n name: 'newOwner',\n type: 'address',\n },\n ],\n name: 'OwnershipTransferred',\n type: 'event',\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: false,\n internalType: 'address',\n name: 'account',\n type: 'address',\n },\n ],\n name: 'Paused',\n type: 'event',\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: false,\n internalType: 'uint64',\n name: 'nonce',\n type: 'uint64',\n },\n {\n indexed: false,\n internalType: 'address',\n name: 'burnToken',\n type: 'address',\n },\n {\n indexed: false,\n internalType: 'uint256',\n name: 'amount',\n type: 'uint256',\n },\n {\n indexed: false,\n internalType: 'address',\n name: 'depositor',\n type: 'address',\n },\n {\n indexed: false,\n internalType: 'address',\n name: 'mintRecipient',\n type: 'address',\n },\n {\n indexed: false,\n internalType: 'uint32',\n name: 'destinationDomain',\n type: 'uint32',\n },\n {\n indexed: false,\n internalType: 'uint256',\n name: 'totalFee',\n type: 'uint256',\n },\n ],\n name: 'TransferTokens',\n type: 'event',\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: false,\n internalType: 'address',\n name: 'account',\n type: 'address',\n },\n ],\n name: 'Unpaused',\n type: 'event',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'account',\n type: 'address',\n },\n ],\n name: 'addAdmin',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'feeCollector',\n type: 'address',\n },\n ],\n name: 'addFeeCollector',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'token',\n type: 'address',\n },\n ],\n name: 'addSupportedBurnToken',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'uint256',\n name: 'amount',\n type: 'uint256',\n },\n {\n internalType: 'uint32',\n name: 'destinationDomain',\n type: 'uint32',\n },\n ],\n name: 'calculateFee',\n outputs: [\n {\n internalType: 'uint256',\n name: '',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'circleTokenMessenger',\n outputs: [\n {\n internalType: 'contract ICircleTokenMessenger',\n name: '',\n type: 'address',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'circleTokenMessengerAddress',\n outputs: [\n {\n internalType: 'address',\n name: '',\n type: 'address',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'token',\n type: 'address',\n },\n ],\n name: 'collectFees',\n outputs: [\n {\n internalType: 'bool',\n name: '',\n type: 'bool',\n },\n ],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'token',\n type: 'address',\n },\n ],\n name: 'getFeeAmounts',\n outputs: [\n {\n internalType: 'uint256',\n name: '',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'uint32',\n name: 'domain',\n type: 'uint32',\n },\n ],\n name: 'getFeeConfiguration',\n outputs: [\n {\n components: [\n {\n internalType: 'uint256',\n name: 'maxFee',\n type: 'uint256',\n },\n {\n internalType: 'uint256',\n name: 'minFee',\n type: 'uint256',\n },\n {\n internalType: 'uint32',\n name: 'feePercentage',\n type: 'uint32',\n },\n {\n internalType: 'uint256',\n name: 'txnFee',\n type: 'uint256',\n },\n {\n internalType: 'bool',\n name: 'supported',\n type: 'bool',\n },\n ],\n internalType: 'struct FeeCalculator.FeeConfiguration',\n name: '',\n type: 'tuple',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'uint32',\n name: 'domain',\n type: 'uint32',\n },\n ],\n name: 'getFeePercentage',\n outputs: [\n {\n internalType: 'uint32',\n name: '',\n type: 'uint32',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'uint32',\n name: 'domain',\n type: 'uint32',\n },\n ],\n name: 'getMaxFee',\n outputs: [\n {\n internalType: 'uint256',\n name: '',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'uint32',\n name: 'domain',\n type: 'uint32',\n },\n ],\n name: 'getMinFee',\n outputs: [\n {\n internalType: 'uint256',\n name: '',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'uint32',\n name: 'domain',\n type: 'uint32',\n },\n ],\n name: 'getTxnFee',\n outputs: [\n {\n internalType: 'uint256',\n name: '',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'account',\n type: 'address',\n },\n ],\n name: 'isAdmin',\n outputs: [\n {\n internalType: 'bool',\n name: '',\n type: 'bool',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'account',\n type: 'address',\n },\n ],\n name: 'isFeeCollector',\n outputs: [\n {\n internalType: 'bool',\n name: '',\n type: 'bool',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'token',\n type: 'address',\n },\n ],\n name: 'isSupportedBurnToken',\n outputs: [\n {\n internalType: 'bool',\n name: '',\n type: 'bool',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'uint32',\n name: 'domain',\n type: 'uint32',\n },\n ],\n name: 'isSupportedDomain',\n outputs: [\n {\n internalType: 'bool',\n name: '',\n type: 'bool',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'owner',\n outputs: [\n {\n internalType: 'address',\n name: '',\n type: 'address',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'pause',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [],\n name: 'paused',\n outputs: [\n {\n internalType: 'bool',\n name: '',\n type: 'bool',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'account',\n type: 'address',\n },\n ],\n name: 'removeAdmin',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'feeCollector',\n type: 'address',\n },\n ],\n name: 'removeFeeCollector',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'token',\n type: 'address',\n },\n ],\n name: 'removeSupportedBurnToken',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [],\n name: 'renounceOwnership',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'uint32',\n name: 'domain',\n type: 'uint32',\n },\n {\n components: [\n {\n internalType: 'uint256',\n name: 'maxFee',\n type: 'uint256',\n },\n {\n internalType: 'uint256',\n name: 'minFee',\n type: 'uint256',\n },\n {\n internalType: 'uint32',\n name: 'feePercentage',\n type: 'uint32',\n },\n {\n internalType: 'uint256',\n name: 'txnFee',\n type: 'uint256',\n },\n {\n internalType: 'bool',\n name: 'supported',\n type: 'bool',\n },\n ],\n internalType: 'struct FeeCalculator.FeeConfiguration',\n name: 'feeConfiguration',\n type: 'tuple',\n },\n ],\n name: 'setFeeConfiguration',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: '',\n type: 'address',\n },\n ],\n name: 'supportedBurnTokens',\n outputs: [\n {\n internalType: 'bool',\n name: '',\n type: 'bool',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'newOwner',\n type: 'address',\n },\n ],\n name: 'transferOwnership',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'uint256',\n name: 'amount',\n type: 'uint256',\n },\n {\n internalType: 'uint32',\n name: 'destinationDomain',\n type: 'uint32',\n },\n {\n internalType: 'address',\n name: 'mintRecipient',\n type: 'address',\n },\n {\n internalType: 'address',\n name: 'burnToken',\n type: 'address',\n },\n ],\n name: 'transferTokens',\n outputs: [\n {\n internalType: 'uint64',\n name: 'nonce',\n type: 'uint64',\n },\n ],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [],\n name: 'unpause',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n] as const;\n","import { InvalidParamsError } from '../../../errors';\nimport { ErrorReason } from '../../../types';\nimport type { TransferParams } from '../../../types/bridge';\nimport type { Config } from '../types/config';\n\ntype PartialTransferParams = Pick<TransferParams, 'sourceChain' | 'targetChain' | 'amount' | 'asset'>;\n\nexport const getTransferData = ({ sourceChain, targetChain, amount, asset }: PartialTransferParams, config: Config) => {\n if (sourceChain.chainId === targetChain.chainId) {\n throw new InvalidParamsError(ErrorReason.IDENTICAL_CHAINS_PROVIDED);\n }\n\n if (amount <= 0n) {\n throw new InvalidParamsError(ErrorReason.INCORRECT_AMOUNT_PROVIDED, 'Amount must be greater than zero');\n }\n\n const sourceChainData = config.find((chainData) => chainData.chainId === sourceChain.chainId);\n\n if (!sourceChainData) {\n throw new InvalidParamsError(\n ErrorReason.CHAIN_NOT_SUPPORTED,\n `Not supported on source chain \"${sourceChain.chainId}\"`,\n );\n }\n\n const targetChainData = config.find((chainData) => chainData.chainId === targetChain.chainId);\n\n if (!targetChainData) {\n throw new InvalidParamsError(\n ErrorReason.CHAIN_NOT_SUPPORTED,\n `Not supported on target chain \"${targetChain.chainId}\"`,\n );\n }\n\n const burnToken = sourceChainData.tokens.find((token) => token.symbol === asset.symbol);\n const mintToken = targetChainData.tokens.find((token) => token.symbol === asset.symbol);\n\n if (!burnToken || !mintToken) {\n throw new InvalidParamsError(ErrorReason.ASSET_NOT_SUPPORTED);\n }\n\n return {\n sourceChainData,\n targetChainData,\n burnToken,\n mintToken,\n };\n};\n","import type { AssetFeeMap, BridgeService, FeeParams } from '../../../types';\nimport { getClientForChain } from '../../../utils/client';\nimport { TOKEN_ROUTER_ABI } from '../abis/token-router';\nimport { getTransferData } from '../utils/transfer-data';\n\nexport async function getFees(bridge: BridgeService, params: FeeParams) {\n await bridge.ensureHasConfig();\n\n const { sourceChain, targetChain, asset, amount, provider } = params;\n const { sourceChainData, targetChainData, burnToken } = getTransferData(\n { sourceChain, targetChain, asset, amount },\n bridge.config!,\n );\n\n const client = getClientForChain({ chain: sourceChain, provider });\n const feeAmount = await client.readContract({\n address: sourceChainData.tokenRouterAddress,\n abi: TOKEN_ROUTER_ABI,\n functionName: 'calculateFee',\n args: [amount, targetChainData.domain],\n });\n\n return {\n [burnToken.address]: feeAmount,\n } as AssetFeeMap;\n}\n","import { encodeFunctionData, isAddress, type PublicClient } from 'viem';\nimport {\n ErrorReason,\n type BridgeService,\n type Environment,\n type TransferParams,\n type Hex,\n type BridgeTransfer,\n BridgeSignatureReason,\n} from '../../../types';\nimport { getClientForChain } from '../../../utils/client';\nimport { ERC20_ABI } from '../abis/erc20';\nimport { getTransferData } from '../utils/transfer-data';\nimport { TOKEN_ROUTER_ABI } from '../abis/token-router';\nimport { InvalidParamsError } from '../../../errors';\n\nconst approveAndTransfer = async (bridge: BridgeService, params: TransferParams) => {\n const {\n sourceChain,\n targetChain,\n asset,\n amount,\n fromAddress,\n toAddress: maybeToAddress,\n sourceProvider,\n onStepChange,\n sign,\n } = params;\n const toAddress = maybeToAddress ?? fromAddress;\n\n if (!isAddress(fromAddress) || !isAddress(toAddress)) {\n throw new InvalidParamsError(ErrorReason.INCORRECT_ADDRESS_PROVIDED);\n }\n\n const { sourceChainData, targetChainData, burnToken } = getTransferData(\n { sourceChain, targetChain, asset, amount },\n bridge.config!,\n );\n const client = getClientForChain({ chain: sourceChain, provider: sourceProvider });\n\n const allowance = await client.readContract({\n address: burnToken.address,\n abi: ERC20_ABI,\n functionName: 'allowance',\n args: [fromAddress, sourceChainData.tokenRouterAddress],\n });\n\n const isAllowanceApprovalRequired = allowance < amount;\n const requiredSignatures = isAllowanceApprovalRequired ? 2 : 1; // if approval is required, we'll need 2 signatures\n\n if (isAllowanceApprovalRequired) {\n onStepChange?.({\n currentSignature: 1,\n currentSignatureReason: BridgeSignatureReason.AllowanceApproval,\n requiredSignatures,\n });\n\n if (sign) {\n const data = encodeFunctionData({\n abi: ERC20_ABI,\n functionName: 'approve',\n args: [sourceChainData.tokenRouterAddress, amount],\n });\n\n const txHash = await sign(\n {\n from: fromAddress,\n to: burnToken.address,\n data,\n },\n (signedTxHash: Hex) => client.sendRawTransaction({ serializedTransaction: signedTxHash }),\n );\n\n await client.waitForTransactionReceipt({ hash: txHash, pollingInterval: 1_000 });\n } else {\n const { request } = await client.simulateContract({\n account: fromAddress,\n address: burnToken.address,\n abi: ERC20_ABI,\n functionName: 'approve',\n args: [sourceChainData.tokenRouterAddress, amount],\n });\n\n const txHash = await client.writeContract(request);\n await client.waitForTransactionReceipt({ hash: txHash, pollingInterval: 1_000 });\n }\n }\n\n onStepChange?.({\n currentSignature: isAllowanceApprovalRequired ? 2 : 1,\n currentSignatureReason: BridgeSignatureReason.TokensTransfer,\n requiredSignatures,\n });\n\n if (sign) {\n const data = encodeFunctionData({\n abi: TOKEN_ROUTER_ABI,\n functionName: 'transferTokens',\n args: [amount, targetChainData.domain, toAddress, burnToken.address],\n });\n\n return sign(\n {\n from: fromAddress,\n to: sourceChainData.tokenRouterAddress,\n data,\n },\n (signedTxHash: Hex) => client.sendRawTransaction({ serializedTransaction: signedTxHash }),\n );\n } else {\n const { request } = await client.simulateContract({\n account: fromAddress,\n address: sourceChainData.tokenRouterAddress,\n abi: TOKEN_ROUTER_ABI,\n functionName: 'transferTokens',\n args: [amount, targetChainData.domain, toAddress, burnToken.address],\n });\n\n return client.writeContract(request);\n }\n};\n\nconst getStartBlockNumber = async (targetClient: PublicClient) => {\n try {\n const startBlockNumber = await targetClient.getBlockNumber();\n return startBlockNumber;\n } catch {\n return undefined;\n }\n};\n\nexport async function transferAsset(\n bridge: BridgeService,\n params: TransferParams,\n environment: Environment,\n): Promise<BridgeTransfer> {\n await bridge.ensureHasConfig();\n\n const { minimumConfirmations: requiredSourceConfirmationCount } =\n bridge.config!.find((chainData) => chainData.chainId === params.sourceChain.chainId) ?? {};\n const { minimumConfirmations: requiredTargetConfirmationCount } =\n bridge.config!.find((chainData) => chainData.chainId === params.targetChain.chainId) ?? {};\n\n if (!requiredSourceConfirmationCount || !requiredTargetConfirmationCount) {\n throw new InvalidParamsError(ErrorReason.CONFIRMATION_COUNT_UNKNOWN);\n }\n\n const fees = await bridge.getFees({ ...params, provider: params.sourceProvider });\n\n const bridgeFee = (params.asset.address && fees[params.asset.address]) ?? 0n;\n const txHash = await approveAndTransfer(bridge, params);\n const sourceStartedAt = Date.now();\n const targetClient = getClientForChain({ chain: params.targetChain, provider: params.targetProvider });\n const targetBlockNumber = await getStartBlockNumber(targetClient);\n\n return {\n type: bridge.type,\n environment,\n fromAddress: params.fromAddress,\n toAddress: params.toAddress ?? params.fromAddress,\n amount: params.amount,\n amountDecimals: params.asset.decimals,\n symbol: params.asset.symbol,\n\n bridgeFee,\n\n sourceChain: params.sourceChain,\n sourceStartedAt,\n sourceTxHash: txHash,\n sourceConfirmationCount: 0,\n requiredSourceConfirmationCount,\n\n targetChain: params.targetChain,\n targetConfirmationCount: 0,\n requiredTargetConfirmationCount,\n\n startBlockNumber: targetBlockNumber,\n };\n}\n","export const ERC20_ABI = [\n {\n constant: true,\n inputs: [],\n name: 'name',\n outputs: [{ name: '', type: 'string' }],\n payable: false,\n stateMutability: 'view',\n type: 'function',\n },\n {\n constant: false,\n inputs: [\n { name: '_spender', type: 'address' },\n { name: '_value', type: 'uint256' },\n ],\n name: 'approve',\n outputs: [{ name: '', type: 'bool' }],\n payable: false,\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n constant: true,\n inputs: [],\n name: 'totalSupply',\n outputs: [{ name: '', type: 'uint256' }],\n payable: false,\n stateMutability: 'view',\n type: 'function',\n },\n {\n constant: false,\n inputs: [\n { name: '_from', type: 'address' },\n { name: '_to', type: 'address' },\n { name: '_value', type: 'uint256' },\n ],\n name: 'transferFrom',\n outputs: [{ name: '', type: 'bool' }],\n payable: false,\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n constant: true,\n inputs: [],\n name: 'decimals',\n outputs: [{ name: '', type: 'uint8' }],\n payable: false,\n stateMutability: 'view',\n type: 'function',\n },\n {\n constant: true,\n inputs: [{ name: '_owner', type: 'address' }],\n name: 'balanceOf',\n outputs: [{ name: 'balance', type: 'uint256' }],\n payable: false,\n stateMutability: 'view',\n type: 'function',\n },\n {\n constant: true,\n inputs: [],\n name: 'symbol',\n outputs: [{ name: '', type: 'string' }],\n payable: false,\n stateMutability: 'view',\n type: 'function',\n },\n {\n constant: false,\n inputs: [\n { name: '_to', type: 'address' },\n { name: '_value', type: 'uint256' },\n ],\n name: 'transfer',\n outputs: [{ name: '', type: 'bool' }],\n payable: false,\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n constant: true,\n inputs: [\n { name: '_owner', type: 'address' },\n { name: '_spender', type: 'address' },\n ],\n name: 'allowance',\n outputs: [{ name: '', type: 'uint256' }],\n payable: false,\n stateMutability: 'view',\n type: 'function',\n },\n { payable: true, stateMutability: 'payable', type: 'fallback' },\n {\n anonymous: false,\n inputs: [\n { indexed: true, name: 'owner', type: 'address' },\n { indexed: true, name: 'spender', type: 'address' },\n { indexed: false, name: 'value', type: 'uint256' },\n ],\n name: 'Approval',\n type: 'event',\n },\n {\n anonymous: false,\n inputs: [\n { indexed: true, name: 'from', type: 'address' },\n { indexed: true, name: 'to', type: 'address' },\n { indexed: false, name: 'value', type: 'uint256' },\n ],\n name: 'Transfer',\n type: 'event',\n },\n] as const;\n","import { BridgeInitializationError } from '../errors';\nimport { ErrorReason, type BridgeService } from '../types';\n\nexport async function ensureHasConfig(bridge: BridgeService) {\n if (!bridge.config) {\n await bridge.updateConfig();\n\n if (!bridge.config) {\n throw new BridgeInitializationError(ErrorReason.CONFIG_NOT_AVAILABLE);\n }\n }\n}\n","import { decodeEventLog, type Address } from 'viem';\nimport {\n ErrorReason,\n type BridgeConfig,\n type BridgeService,\n type BridgeTransfer,\n type TrackingParams,\n ErrorCode,\n} from '../../../types';\nimport { getClientForChain } from '../../../utils/client';\nimport { TOKEN_ROUTER_ABI } from '../abis/token-router';\nimport { getNetworkFeeEVM } from '../../../utils/network-fee';\nimport { retryPromise, type Done } from '../../../utils/retry-promise';\nimport { getTrackingDelayByChainId } from '../utils/config';\nimport { InvalidParamsError } from '../../../errors';\n\n// Maximum time (in ms) before the transaction is considered \"timed out\"\nexport const TRACKING_LIMIT_MS = 1000 * 60 * 60 * 3;\n// The max blocks that can be queried before receiving an error response\nexport const MAX_BLOCKS = 1024n;\n// The delay time before tracking starts\nexport const INITIAL_DELAY = 5000;\n\n/**\n * Mutates the `initial` transfer by merging it with the `updated` properties if they are not undefined\n * Invokes the `updateListener` with a copy of the updated `initial` transfer\n */\nconst updateTransfer = (\n initial: BridgeTransfer,\n updated: Partial<BridgeTransfer>,\n updateListener: TrackingParams['updateListener'],\n) => {\n Object.assign(initial, Object.fromEntries(Object.entries(updated).filter(([, value]) => value !== undefined)));\n updateListener({ ...initial });\n};\n\n/**\n * Polls the source network until it's able to get the CCTP message's `nonce` from the source transaction's logs\n * Updates the provided `BridgeTransfer` and broadcasts the changes via `updateListener`\n */\nexport const trackSourceTx = async (config: BridgeConfig, params: TrackingParams) => {\n const { sourceProvider, targetProvider, updateListener, bridgeTransfer } = params;\n const sourceClient = getClientForChain({ chain: bridgeTransfer.sourceChain, provider: sourceProvider });\n const sourceChainData = config.find((chainData) => chainData.chainId === bridgeTransfer.sourceChain.chainId);\n const targetClient = getClientForChain({ chain: bridgeTransfer.targetChain, provider: targetProvider });\n const targetChainData = config.find((chainData) => chainData.chainId === bridgeTransfer.targetChain.chainId);\n const updateableTransfer = { ...bridgeTransfer };\n\n if (!sourceChainData || !targetChainData) {\n throw new InvalidParamsError(ErrorReason.CHAIN_NOT_SUPPORTED);\n }\n\n const tracker = async (done: Done<BridgeTransfer>) => {\n /**\n * Return early if:\n * - transfer has already completed successfully or due to some error\n * - the transfer state already has the message's nonce\n */\n if (updateableTransfer.completedAt || updateableTransfer.metadata?.nonce) {\n return done(updateableTransfer);\n }\n\n /**\n * Check if the transaction has timed out\n */\n if (updateableTransfer.sourceStartedAt + TRACKING_LIMIT_MS <= Date.now()) {\n updateTransfer(updateableTransfer, { completedAt: Date.now(), errorCode: ErrorCode.TIMEOUT }, updateListener);\n return done(updateableTransfer);\n }\n\n /**\n * Get the transaction's receipt.\n * Throws if the transaction has't been processed by the network yet.\n */\n const txReceipt = await sourceClient.getTransactionReceipt({\n hash: updateableTransfer.sourceTxHash as Address,\n });\n\n /**\n * Calculate the network fee if needed.\n */\n if (!updateableTransfer.sourceNetworkFee) {\n const tx = await sourceClient.getTransaction({ hash: updateableTransfer.sourceTxHash as Address });\n const networkFee = getNetworkFeeEVM(tx, txReceipt);\n\n if (networkFee) {\n updateTransfer(updateableTransfer, { sourceNetworkFee: networkFee }, updateListener);\n }\n }\n\n /**\n * Update the state and terminate if the transaction was reverted\n */\n if (txReceipt.status === 'reverted') {\n updateTransfer(\n updateableTransfer,\n { completedAt: Date.now(), errorCode: ErrorCode.TRANSACTION_REVERTED },\n updateListener,\n );\n return done(updateableTransfer);\n }\n\n /**\n * Check the confirmation count.\n * - update the sourceConfirmationCount if it increased\n * - update the startBlockNumber if confirmation count increased but is not enough\n * - keeps polling until it's greater than requiredSourceConfirmationCount\n */\n const confirmationCount = await sourceClient.getTransactionConfirmations({\n hash: updateableTransfer.sourceTxHash as Address,\n });\n const hasMoreConfirmations = confirmationCount > updateableTransfer.sourceConfirmationCount;\n const hasRequiredConfirmations = confirmationCount >= updateableTransfer.requiredSourceConfirmationCount;\n\n if (hasMoreConfirmations) {\n const changes = {} as Partial<BridgeTransfer>;\n changes.sourceConfirmationCount = Number(confirmationCount);\n\n if (!hasRequiredConfirmations) {\n changes.startBlockNumber = await targetClient.getBlockNumber();\n }\n\n updateTransfer(updateableTransfer, changes, updateListener);\n }\n\n if (!hasRequiredConfirmations) {\n return;\n }\n\n if (!updateableTransfer.startBlockNumber) {\n updateTransfer(updateableTransfer, { startBlockNumber: await targetClient.getBlockNumber() }, updateListener);\n }\n\n /**\n * Get the `TransferTokens` event's log entry from the receipt\n */\n const transferEventLog = txReceipt.logs.find((log) => {\n if (log.address === sourceChainData.tokenRouterAddress) {\n const event = decodeEventLog({\n abi: TOKEN_ROUTER_ABI,\n ...log,\n });\n\n return event.eventName === 'TransferTokens';\n }\n\n return false;\n });\n\n if (!transferEventLog) {\n throw new InvalidParamsError(\n ErrorReason.INVALID_PARAMS,\n `unable to find a TransferTokens event in source transaction \"${updateableTransfer.sourceTxHash}\"`,\n );\n }\n\n /**\n * Get the nonce used by the message transmitter from the event's log\n * https://developers.circle.com/stablecoins/docs/evm-smart-contracts#receivemessage\n */\n const transferEvent = decodeEventLog({\n abi: TOKEN_ROUTER_ABI,\n eventName: 'TransferTokens',\n ...transferEventLog,\n });\n\n // save the nonce and broadcast\n const nonce = transferEvent.args.nonce;\n updateTransfer(updateableTransfer, { targetStartedAt: Date.now(), metadata: { nonce } }, updateListener);\n return done(updateableTransfer);\n };\n\n return retryPromise<BridgeTransfer>({\n promise: tracker,\n delay: getTrackingDelayByChainId(sourceChainData.chainId),\n startAfter: INITIAL_DELAY,\n });\n};\n\n/**\n * Polls the target network until it finds the transaction that matches the message's nonce\n * Updates the provided `BridgeTransfer` and broadcasts the changes via `updateListener`\n */\nexport const trackTargetTx = async (config: BridgeConfig, params: TrackingParams) => {\n const { targetProvider, updateListener, bridgeTransfer } = params;\n const updateableTransfer = { ...bridgeTransfer };\n\n if (!bridgeTransfer.completedAt && !bridgeTransfer.metadata?.nonce) {\n throw new InvalidParamsError(ErrorReason.INVALID_PARAMS, `nonce is missing`);\n }\n\n if (!bridgeTransfer.startBlockNumber) {\n throw new InvalidParamsError(ErrorReason.INVALID_PARAMS, `startBlockNumber is missing`);\n }\n\n const targetClient = getClientForChain({ chain: bridgeTransfer.targetChain, provider: targetProvider });\n const targetChainData = config.find((chainData) => chainData.chainId === bridgeTransfer.targetChain.chainId);\n\n if (!targetChainData) {\n throw new InvalidParamsError(\n ErrorReason.INVALID_PARAMS,\n `unknown target chain \"${bridgeTransfer.targetChain.chainId}\"`,\n );\n }\n\n const tracker = async (done: Done<BridgeTransfer>) => {\n /**\n * Return early if:\n * - transfer has already completed successfully or due to some error\n */\n if (updateableTransfer.completedAt) {\n return done(updateableTransfer);\n }\n\n /**\n * Check if `startBlockNumber` became falsy for whatever reason\n */\n if (!updateableTransfer.startBlockNumber) {\n updateTransfer(\n updateableTransfer,\n { completedAt: Date.now(), errorCode: ErrorCode.INVALID_PARAMS },\n updateListener,\n );\n return done(updateableTransfer);\n }\n\n /**\n * Check if the transaction has timed out\n */\n if (updateableTransfer.sourceStartedAt + TRACKING_LIMIT_MS <= Date.now()) {\n updateTransfer(updateableTransfer, { completedAt: Date.now(), errorCode: ErrorCode.TIMEOUT }, updateListener);\n return done(updateableTransfer);\n }\n\n if (!updateableTransfer.targetTxHash) {\n const lastBlockNumber = await targetClient.getBlockNumber();\n const lowestBlockNumber = updateableTransfer.startBlockNumber - MAX_BLOCKS;\n const fromBlock = lowestBlockNumber >= 0n ? lowestBlockNumber : 'earliest';\n const highestBlockNumber = updateableTransfer.startBlockNumber + MAX_BLOCKS;\n const toBlock = highestBlockNumber < lastBlockNumber ? highestBlockNumber : 'latest';\n\n const targetLogs = await targetClient.getLogs({\n address: targetChainData.messageTransmitterAddress,\n event: {\n name: 'MessageReceived',\n type: 'event',\n inputs: [\n { indexed: true, internalType: 'address', name: 'caller', type: 'address' },\n { indexed: false, internalType: 'uint32', name: 'sourceDomain', type: 'uint32' },\n { indexed: true, internalType: 'uint64', name: 'nonce', type: 'uint64' },\n { indexed: false, internalType: 'bytes32', name: 'sender', type: 'bytes32' },\n { indexed: false, internalType: 'bytes', name: 'messageBody', type: 'bytes' },\n ],\n },\n args: { nonce: updateableTransfer.metadata!.nonce as bigint },\n fromBlock,\n toBlock,\n });\n\n if (targetLogs[0]?.transactionHash) {\n updateTransfer(updateableTransfer, { targetTxHash: targetLogs[0].transactionHash }, updateListener);\n } else {\n updateTransfer(updateableTransfer, { startBlockNumber: lastBlockNumber }, updateListener);\n return;\n }\n }\n\n /**\n * Get the transaction's receipt.\n * Throws if the transaction has't been processed by the network yet.\n */\n const txReceipt = await targetClient.getTransactionReceipt({\n hash: updateableTransfer.targetTxHash as Address,\n });\n\n /**\n * Calculate the network fee if needed.\n */\n if (!updateableTransfer.targetNetworkFee) {\n const tx = await targetClient.getTransaction({ hash: updateableTransfer.targetTxHash as Address });\n const networkFee = getNetworkFeeEVM(tx, txReceipt);\n\n if (networkFee) {\n updateTransfer(updateableTransfer, { targetNetworkFee: networkFee }, updateListener);\n }\n }\n\n /**\n * Update the state and terminate if the transaction was reverted\n */\n if (txReceipt.status === 'reverted') {\n updateTransfer(\n updateableTransfer,\n { completedAt: Date.now(), errorCode: ErrorCode.TRANSACTION_REVERTED },\n updateListener,\n );\n return done(updateableTransfer);\n }\n\n /**\n * Check the confirmation count.\n * - update the targetConfirmationCount if it increased\n * - keeps polling until it's greater than requiredTargetConfirmationCount\n */\n const confirmationCount = await targetClient.getTransactionConfirmations({\n hash: updateableTransfer.targetTxHash as Address,\n });\n const hasMoreConfirmations = confirmationCount > updateableTransfer.targetConfirmationCount;\n const hasRequiredConfirmations = confirmationCount >= updateableTransfer.requiredTargetConfirmationCount;\n\n if (hasMoreConfirmations) {\n updateTransfer(updateableTransfer, { targetConfirmationCount: Number(confirmationCount) }, updateListener);\n }\n\n if (!hasRequiredConfirmations) {\n return;\n }\n\n updateTransfer(updateableTransfer, { completedAt: Date.now() }, updateListener);\n return done(updateableTransfer);\n };\n\n return retryPromise<BridgeTransfer>({\n promise: tracker,\n delay: getTrackingDelayByChainId(targetChainData.chainId),\n startAfter: INITIAL_DELAY,\n });\n};\n\nexport function trackTransfer(bridge: BridgeService, params: TrackingParams) {\n let abortFn: (() => void) | undefined;\n\n const cancel = () => {\n abortFn?.();\n };\n\n const executeTracking = async () => {\n await bridge.ensureHasConfig();\n\n const { sourceProvider, targetProvider, updateListener, bridgeTransfer } = params;\n\n const { result: sourceTracker, cancel: cancelSourceTracking } = await trackSourceTx(bridge.config!, {\n sourceProvider,\n targetProvider,\n updateListener,\n bridgeTransfer,\n });\n abortFn = cancelSourceTracking;\n const transferAfterSourceFinished = await sourceTracker;\n\n const { result: targetTracker, cancel: cancelTargetTracking } = await trackTargetTx(bridge.config!, {\n sourceProvider,\n targetProvider,\n updateListener,\n bridgeTransfer: transferAfterSourceFinished,\n });\n abortFn = cancelTargetTracking;\n return targetTracker;\n };\n\n return {\n result: executeTracking(),\n cancel,\n };\n}\n","import { type Transaction, type TransactionReceipt } from 'viem';\n\n// returns the network fee for EVM transaction in wei (10**-18)\nexport const getNetworkFeeEVM = (transaction: Transaction, receipt: TransactionReceipt) => {\n return transaction.gasPrice && BigInt(transaction.gasPrice * receipt.gasUsed);\n};\n","export const wait = async (time: number) =>\n new Promise((res) => {\n setTimeout(res, time);\n });\n","import { wait } from './wait';\n\nexport type Done<T> = (data: T) => void;\n\ntype Params<T> = {\n promise: (done: Done<T>) => Promise<unknown>;\n delay: number;\n startAfter?: number;\n};\n\nexport const retryPromise = <T>({ promise, delay, startAfter }: Params<T>) => {\n let isRunning = false;\n let isCancelled = false;\n let errorCount: number = 0;\n let resolve: ((data: T) => void) | undefined = undefined;\n let reject: ((reason?: string) => void) | undefined = undefined;\n\n const done = (data: T) => {\n if (resolve && isRunning) {\n isRunning = false;\n resolve(data);\n }\n };\n\n const cancel = () => {\n isCancelled = true;\n\n if (reject && isRunning) {\n isRunning = false;\n reject('cancelled');\n }\n };\n\n const result = new Promise<T>((res, rej) => {\n isRunning = true;\n resolve = res;\n reject = rej;\n\n const execute = async (): Promise<void> => {\n if (!isRunning || isCancelled) {\n return;\n }\n\n try {\n await promise(done);\n\n if (!isRunning || isCancelled) {\n return;\n }\n\n await wait(delay);\n } catch (err) {\n console.error((err as Error).message);\n errorCount += 1;\n await wait(2 ** errorCount * delay);\n }\n\n await execute();\n };\n\n if (startAfter) {\n setTimeout(execute, startAfter);\n } else {\n execute();\n }\n });\n\n return {\n result,\n cancel,\n };\n};\n","import { type BridgeServiceFactory, BridgeType } from '../../types/bridge';\nimport { getConfig } from './utils/config';\nimport { getAssets } from './handlers/get-assets';\nimport { getFees } from './handlers/get-fees';\nimport { transferAsset } from './handlers/transfer-asset';\nimport { ensureHasConfig } from '../../utils/ensure-config';\nimport { trackTransfer } from './handlers/track-transfer';\n\nexport const cctpBridgeFactory: BridgeServiceFactory = (environment) => {\n return {\n type: BridgeType.CCTP,\n config: null,\n updateConfig: async function () {\n this.config = await getConfig(environment);\n },\n ensureHasConfig: async function () {\n return ensureHasConfig(this);\n },\n getAssets: async function () {\n return getAssets(this);\n },\n getFees: async function (params) {\n return getFees(this, params);\n },\n transferAsset: async function (params) {\n return transferAsset(this, params, environment);\n },\n trackTransfer: function (params) {\n return trackTransfer(this, params);\n },\n };\n};\n","import { cctpBridgeFactory } from '../bridges/cctp/factory';\nimport { BridgeUnavailableError } from '../errors';\nimport type { BridgeAsset } from '../types/asset';\nimport { type BridgeService, BridgeType } from '../types/bridge';\nimport { Environment } from '../types/environment';\n\nexport const supportedBridges = new Map([[BridgeType.CCTP, cctpBridgeFactory]]);\n\nexport const getEnabledBridgeServices = (environment: Environment, disabledBridgeTypes?: BridgeType[]) => {\n return new Map(\n [...supportedBridges]\n .filter(([bridgeType]) => !disabledBridgeTypes?.includes(bridgeType))\n .map(([bridgeType, factory]) => [bridgeType, factory(environment)]),\n );\n};\n\nexport const getBridgeForTransfer = (\n enabledBridgeServices: Map<BridgeType, BridgeService>,\n asset: BridgeAsset,\n targetChainId: string,\n) => {\n const bridgeType = asset.destinations[targetChainId]?.find((bridgeType) => enabledBridgeServices.has(bridgeType));\n\n if (!bridgeType) {\n throw new BridgeUnavailableError();\n }\n\n return {\n type: bridgeType,\n bridge: enabledBridgeServices.get(bridgeType)!,\n };\n};\n","import type { FeeParams, TrackingParams, TransferParams } from './types/bridge';\nimport type { BridgeServiceConfig } from './types/config';\nimport { getBridgeForTransfer, getEnabledBridgeServices } from './utils';\nimport type { BridgeAsset, ChainAssetMap } from './types';\nimport { isArray, mergeWith } from 'lodash';\nimport { BridgeUnavailableError } from './errors';\n\nexport const createUnifiedBridgeService = ({ environment, disabledBridgeTypes }: BridgeServiceConfig) => {\n const enabledBridgeServices = getEnabledBridgeServices(environment, disabledBridgeTypes);\n\n const updateConfigs = async () => {\n await Promise.allSettled(\n Array.from(enabledBridgeServices).map(([, bridgeService]) => bridgeService.updateConfig()),\n );\n };\n\n const init = async () => {\n await updateConfigs();\n };\n\n const getAssets = async () => {\n const assets = await Promise.all(Array.from(enabledBridgeServices).map(([, bridge]) => bridge.getAssets()));\n return assets.reduce<ChainAssetMap>((aggregatedAssets, chainAssetMap) => {\n for (const [chainId, bridgeAssets] of Object.entries(chainAssetMap)) {\n const existingAssets = aggregatedAssets[chainId];\n\n if (existingAssets) {\n for (const bridgeAsset of bridgeAssets) {\n const index = existingAssets.findIndex(({ symbol }) => symbol === bridgeAsset.symbol);\n\n if (index === -1) {\n existingAssets.push(bridgeAsset);\n } else {\n mergeWith(existingAssets[index], bridgeAsset, (objValue, srcValue) => {\n if (isArray(objValue)) {\n return [...new Set(objValue.concat(srcValue))];\n }\n });\n }\n }\n } else {\n aggregatedAssets[chainId] = bridgeAssets;\n }\n }\n\n return aggregatedAssets;\n }, {});\n };\n\n const getFees = async (params: FeeParams) => {\n const { bridge } = getBridgeForTransfer(enabledBridgeServices, params.asset, params.targetChain.chainId);\n return bridge.getFees(params);\n };\n\n const transferAsset = async (params: TransferParams) => {\n const { bridge } = getBridgeForTransfer(enabledBridgeServices, params.asset, params.targetChain.chainId);\n return bridge.transferAsset(params);\n };\n\n const canTransferAsset = (asset: BridgeAsset, targetChainId: string) => {\n try {\n getBridgeForTransfer(enabledBridgeServices, asset, targetChainId);\n return true;\n } catch {\n return false;\n }\n };\n\n const trackTransfer = (params: TrackingParams) => {\n const bridge = enabledBridgeServices.get(params.bridgeTransfer.type);\n\n if (!bridge) {\n throw new BridgeUnavailableError();\n }\n\n return bridge.trackTransfer(params);\n };\n\n return {\n environment,\n bridges: enabledBridgeServices,\n init,\n updateConfigs,\n getAssets,\n getFees,\n canTransferAsset,\n transferAsset,\n trackTransfer,\n };\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/types/asset.ts","../src/types/bridge.ts","../src/types/environment.ts","../src/types/error.ts","../src/errors/bridge-error.ts","../src/errors/bridge-unavailable-error.ts","../src/errors/bridge-initialization-error.ts","../src/errors/invalid-params-error.ts","../src/bridges/cctp/utils/config.ts","../src/bridges/cctp/handlers/get-assets.ts","../src/utils/client.ts","../src/utils/caip2.ts","../src/bridges/cctp/abis/token-router.ts","../src/bridges/cctp/utils/transfer-data.ts","../src/bridges/cctp/handlers/get-fees.ts","../src/bridges/cctp/handlers/transfer-asset.ts","../src/bridges/cctp/abis/erc20.ts","../src/utils/ensure-config.ts","../src/bridges/cctp/handlers/track-transfer.ts","../src/utils/network-fee.ts","../src/utils/wait.ts","../src/utils/retry-promise.ts","../src/bridges/cctp/factory.ts","../src/utils/bridge-types.ts","../src/unified-bridge-service.ts"],"names":["TokenType","BridgeType","BridgeSignatureReason","Environment","ErrorCode","ErrorReason","BridgeError","message","code","details","BridgeUnavailableError","BridgeInitializationError","InvalidParamsError","CONFIG_URLS","getConfig","environment","chainData","err","getTrackingDelayByChainId","chainId","getAssets","bridge","chainIds","assets","asset","destinations","createWalletClient","publicActions","custom","http","namespacePattern","referencePattern","delimeter","toJSON","identifier","namespace","reference","toString","caip2_default","_getChain","chain","getClientForChain","provider","chainInfo","transport","TOKEN_ROUTER_ABI","getTransferData","sourceChain","targetChain","amount","config","sourceChainData","targetChainData","burnToken","token","mintToken","getFees","params","feeAmount","encodeFunctionData","isAddress","ERC20_ABI","approveAndTransfer","fromAddress","maybeToAddress","sourceProvider","onStepChange","sign","toAddress","client","isAllowanceApprovalRequired","requiredSignatures","data","txHash","signedTxHash","request","getStartBlockNumber","targetClient","transferAsset","requiredSourceConfirmationCount","requiredTargetConfirmationCount","fees","bridgeFee","sourceStartedAt","targetBlockNumber","ensureHasConfig","decodeEventLog","getNetworkFeeEVM","transaction","receipt","wait","time","res","retryPromise","promise","delay","startAfter","isRunning","isCancelled","errorCount","resolve","reject","done","cancel","rej","execute","TRACKING_LIMIT_MS","MAX_BLOCKS","INITIAL_DELAY","updateTransfer","initial","updated","updateListener","value","trackSourceTx","targetProvider","bridgeTransfer","sourceClient","updateableTransfer","txReceipt","tx","networkFee","confirmationCount","hasMoreConfirmations","hasRequiredConfirmations","changes","transferEventLog","log","nonce","trackTargetTx","lastBlockNumber","lowestBlockNumber","fromBlock","highestBlockNumber","toBlock","targetLogs","trackTransfer","abortFn","sourceTracker","cancelSourceTracking","transferAfterSourceFinished","targetTracker","cancelTargetTracking","cctpBridgeFactory","supportedBridges","getEnabledBridgeServices","disabledBridgeTypes","bridgeType","factory","getBridgeForTransfer","enabledBridgeServices","targetChainId","isArray","mergeWith","createUnifiedBridgeService","updateConfigs","bridgeService","aggregatedAssets","chainAssetMap","bridgeAssets","existingAssets","bridgeAsset","index","symbol","objValue","srcValue"],"mappings":"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OACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,uBACN,KAAM,OACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,WACN,KAAM,OACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,kBACN,KAAM,OACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,uBACN,KAAM,OACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,oBACN,KAAM,OACR,EACA,CACE,UAAW,GACX,OAAQ,CACN,CACE,QAAS,GACT,aAAc,UACd,KAAM,QACN,KAAM,SACR,CACF,EACA,KAAM,aACN,KAAM,OACR,EACA,CACE,UAAW,GACX,OAAQ,CACN,CACE,QAAS,GACT,aAAc,UACd,KAAM,QACN,KAAM,SACR,CACF,EACA,KAAM,eACN,KAAM,OACR,EACA,CACE,UAAW,GACX,OAAQ,CACN,CACE,QAAS,GACT,aAAc,UACd,KAAM,QACN,KAAM,SACR,CACF,EACA,KAAM,iBACN,KAAM,OACR,EACA,CACE,UAAW,GACX,OAAQ,CACN,CACE,QAAS,GACT,aAAc,UACd,KAAM,QACN,KAAM,SACR,CACF,EACA,KAAM,mBACN,KAAM,OACR,EACA,CACE,UAAW,GACX,OAAQ,CACN,CACE,QAAS,GACT,aAAc,UACd,KAAM,eACN,KAAM,SACR,CACF,EACA,KAAM,oBACN,KAAM,OACR,EACA,CACE,UAAW,GACX,OAAQ,CACN,CACE,QAAS,GACT,aAAc,UACd,KAAM,eACN,KAAM,SACR,CACF,EACA,KAAM,sBACN,KAAM,OACR,EACA,CACE,UAAW,GACX,OAAQ,CACN,CACE,QAAS,GACT,aAAc,SACd,KAAM,SACN,KAAM,QACR,EACA,CACE,WAAY,CACV,CACE,aAAc,UACd,KAAM,SACN,KAAM,SACR,EACA,CACE,aAAc,UACd,KAAM,SACN,KAAM,SACR,EACA,CACE,aAAc,SACd,KAAM,gBACN,KAAM,QACR,EACA,CACE,aAAc,UACd,KAAM,SACN,KAAM,SACR,EACA,CACE,aAAc,OACd,KAAM,YACN,KAAM,MACR,CACF,EACA,QAAS,GACT,aAAc,wCACd,KAAM,mBACN,KAAM,OACR,CACF,EACA,KAAM,0BACN,KAAM,OACR,EACA,CACE,UAAW,GACX,OAAQ,CACN,CACE,QAAS,GACT,aAAc,UACd,KAAM,gBACN,KAAM,SACR,EACA,CACE,QAAS,GACT,aAAc,UACd,KAAM,WACN,KAAM,SACR,CACF,EACA,KAAM,uBACN,KAAM,OACR,EACA,CACE,UAAW,GACX,OAAQ,CACN,CACE,QAAS,GACT,aAAc,UACd,KAAM,UACN,KAAM,SACR,CACF,EACA,KAAM,SACN,KAAM,OACR,EACA,CACE,UAAW,GACX,OAAQ,CACN,CACE,QAAS,GACT,aAAc,SACd,KAAM,QACN,KAAM,QACR,EACA,CACE,QAAS,GACT,aAAc,UACd,KAAM,YACN,KAAM,SACR,EACA,CACE,QAAS,GACT,aAAc,UACd,KAAM,SACN,KAAM,SACR,EACA,CACE,QAAS,GACT,aAAc,UACd,KAAM,YACN,KAAM,SACR,EACA,CACE,QAAS,GACT,aAAc,UACd,KAAM,gBACN,KAAM,SACR,EACA,CACE,QAAS,GACT,aAAc,SACd,KAAM,oBACN,KAAM,QACR,EACA,CACE,QAAS,GACT,aAAc,UACd,KAAM,WACN,KAAM,SACR,CACF,EACA,KAAM,iBACN,KAAM,OACR,EACA,CACE,UAAW,GACX,OAAQ,CACN,CACE,QAAS,GACT,aAAc,UACd,KAAM,UACN,KAAM,SACR,CACF,EACA,KAAM,WACN,KAAM,OACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,UACd,KAAM,UACN,KAAM,SACR,CACF,EACA,KAAM,WACN,QAAS,CAAC,EACV,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,UACd,KAAM,eACN,KAAM,SACR,CACF,EACA,KAAM,kBACN,QAAS,CAAC,EACV,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,UACd,KAAM,QACN,KAAM,SACR,CACF,EACA,KAAM,wBACN,QAAS,CAAC,EACV,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,UACd,KAAM,SACN,KAAM,SACR,EACA,CACE,aAAc,SACd,KAAM,oBACN,KAAM,QACR,CACF,EACA,KAAM,eACN,QAAS,CACP,CACE,aAAc,UACd,KAAM,GACN,KAAM,SACR,CACF,EACA,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,uBACN,QAAS,CACP,CACE,aAAc,iCACd,KAAM,GACN,KAAM,SACR,CACF,EACA,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,8BACN,QAAS,CACP,CACE,aAAc,UACd,KAAM,GACN,KAAM,SACR,CACF,EACA,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,UACd,KAAM,QACN,KAAM,SACR,CACF,EACA,KAAM,cACN,QAAS,CACP,CACE,aAAc,OACd,KAAM,GACN,KAAM,MACR,CACF,EACA,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,UACd,KAAM,QACN,KAAM,SACR,CACF,EACA,KAAM,gBACN,QAAS,CACP,CACE,aAAc,UACd,KAAM,GACN,KAAM,SACR,CACF,EACA,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,SACd,KAAM,SACN,KAAM,QACR,CACF,EACA,KAAM,sBACN,QAAS,CACP,CACE,WAAY,CACV,CACE,aAAc,UACd,KAAM,SACN,KAAM,SACR,EACA,CACE,aAAc,UACd,KAAM,SACN,KAAM,SACR,EACA,CACE,aAAc,SACd,KAAM,gBACN,KAAM,QACR,EACA,CACE,aAAc,UACd,KAAM,SACN,KAAM,SACR,EACA,CACE,aAAc,OACd,KAAM,YACN,KAAM,MACR,CACF,EACA,aAAc,wCACd,KAAM,GACN,KAAM,OACR,CACF,EACA,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,SACd,KAAM,SACN,KAAM,QACR,CACF,EACA,KAAM,mBACN,QAAS,CACP,CACE,aAAc,SACd,KAAM,GACN,KAAM,QACR,CACF,EACA,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,SACd,KAAM,SACN,KAAM,QACR,CACF,EACA,KAAM,YACN,QAAS,CACP,CACE,aAAc,UACd,KAAM,GACN,KAAM,SACR,CACF,EACA,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,SACd,KAAM,SACN,KAAM,QACR,CACF,EACA,KAAM,YACN,QAAS,CACP,CACE,aAAc,UACd,KAAM,GACN,KAAM,SACR,CACF,EACA,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,SACd,KAAM,SACN,KAAM,QACR,CACF,EACA,KAAM,YACN,QAAS,CACP,CACE,aAAc,UACd,KAAM,GACN,KAAM,SACR,CACF,EACA,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,UACd,KAAM,UACN,KAAM,SACR,CACF,EACA,KAAM,UACN,QAAS,CACP,CACE,aAAc,OACd,KAAM,GACN,KAAM,MACR,CACF,EACA,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,UACd,KAAM,UACN,KAAM,SACR,CACF,EACA,KAAM,iBACN,QAAS,CACP,CACE,aAAc,OACd,KAAM,GACN,KAAM,MACR,CACF,EACA,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,UACd,KAAM,QACN,KAAM,SACR,CACF,EACA,KAAM,uBACN,QAAS,CACP,CACE,aAAc,OACd,KAAM,GACN,KAAM,MACR,CACF,EACA,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,SACd,KAAM,SACN,KAAM,QACR,CACF,EACA,KAAM,oBACN,QAAS,CACP,CACE,aAAc,OACd,KAAM,GACN,KAAM,MACR,CACF,EACA,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,QACN,QAAS,CACP,CACE,aAAc,UACd,KAAM,GACN,KAAM,SACR,CACF,EACA,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,QACN,QAAS,CAAC,EACV,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,SACN,QAAS,CACP,CACE,aAAc,OACd,KAAM,GACN,KAAM,MACR,CACF,EACA,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,UACd,KAAM,UACN,KAAM,SACR,CACF,EACA,KAAM,cACN,QAAS,CAAC,EACV,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,UACd,KAAM,eACN,KAAM,SACR,CACF,EACA,KAAM,qBACN,QAAS,CAAC,EACV,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,UACd,KAAM,QACN,KAAM,SACR,CACF,EACA,KAAM,2BACN,QAAS,CAAC,EACV,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,oBACN,QAAS,CAAC,EACV,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,SACd,KAAM,SACN,KAAM,QACR,EACA,CACE,WAAY,CACV,CACE,aAAc,UACd,KAAM,SACN,KAAM,SACR,EACA,CACE,aAAc,UACd,KAAM,SACN,KAAM,SACR,EACA,CACE,aAAc,SACd,KAAM,gBACN,KAAM,QACR,EACA,CACE,aAAc,UACd,KAAM,SACN,KAAM,SACR,EACA,CACE,aAAc,OACd,KAAM,YACN,KAAM,MACR,CACF,EACA,aAAc,wCACd,KAAM,mBACN,KAAM,OACR,CACF,EACA,KAAM,sBACN,QAAS,CAAC,EACV,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,UACd,KAAM,GACN,KAAM,SACR,CACF,EACA,KAAM,sBACN,QAAS,CACP,CACE,aAAc,OACd,KAAM,GACN,KAAM,MACR,CACF,EACA,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,OAAQ,CACN,CACE,aAAc,UACd,KAAM,WACN,KAAM,SACR,CACF,EACA,KAAM,oBA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","sourcesContent":["import type { Address } from 'viem';\nimport type { BridgeType } from './bridge';\n\nexport enum TokenType {\n NATIVE = 'native',\n ERC20 = 'erc20',\n}\n\nexport type Asset = {\n type: TokenType;\n address?: Address;\n name: string;\n symbol: string;\n decimals: number;\n};\n\n// chainId - bridge type pairs\nexport type DestinationInfo = Record<string, BridgeType[]>;\n\nexport type BridgeAsset = Asset & {\n destinations: DestinationInfo;\n};\n\nexport type ChainAssetMap = Record<string, BridgeAsset[]>;\n\nexport type AssetFeeMap = Record<Address, bigint>;\n","import type { AssetFeeMap, BridgeAsset, ChainAssetMap } from './asset';\nimport type { Chain } from './chain';\nimport type { BridgeConfig } from './config';\nimport type { Environment } from './environment';\nimport type { Provider } from './provider';\nimport type { Signer } from './signer';\nimport type { BridgeTransfer } from './transfer';\n\nexport enum BridgeType {\n CCTP = 'cctp',\n}\n\nexport type FeeParams = {\n asset: BridgeAsset;\n amount: bigint;\n sourceChain: Chain;\n targetChain: Chain;\n provider?: Provider;\n};\n\nexport enum BridgeSignatureReason {\n AllowanceApproval = 'allowance-approval',\n TokensTransfer = 'tokens-transfer',\n}\n\nexport type BridgeStepDetails = {\n currentSignature: number;\n requiredSignatures: number;\n currentSignatureReason: BridgeSignatureReason;\n};\n\nexport type TransferParams = {\n asset: BridgeAsset;\n amount: bigint;\n fromAddress: string;\n toAddress?: string;\n sourceChain: Chain;\n targetChain: Chain;\n sourceProvider?: Provider;\n targetProvider?: Provider;\n onStepChange?: (stepDetails: BridgeStepDetails) => void;\n sign?: Signer;\n};\n\nexport type TrackingParams = {\n bridgeTransfer: BridgeTransfer;\n sourceProvider?: Provider;\n targetProvider?: Provider;\n updateListener: (transfer: BridgeTransfer) => void;\n};\n\nexport type BridgeService = {\n type: BridgeType;\n config: BridgeConfig | null;\n ensureHasConfig: () => Promise<void>;\n updateConfig: () => Promise<void>;\n getAssets: () => Promise<ChainAssetMap>;\n getFees: (params: FeeParams) => Promise<AssetFeeMap>;\n transferAsset: (params: TransferParams) => Promise<BridgeTransfer>;\n trackTransfer: (transfer: TrackingParams) => { cancel: () => void; result: Promise<BridgeTransfer> };\n};\n\nexport type BridgeServiceFactory = (environment: Environment) => BridgeService;\n","export enum Environment {\n PROD = 'production',\n TEST = 'test',\n}\n","export enum ErrorCode {\n BRIDGE_NOT_AVAILABLE = 5001,\n INITIALIZATION_FAILED = 5002,\n INVALID_PARAMS = 5003,\n TIMEOUT = 5004,\n TRANSACTION_REVERTED = 5005,\n}\n\nexport enum ErrorReason {\n UNKNOWN = 'UNKNOWN', // generic, not specified error\n CONFIG_NOT_AVAILABLE = 'CONFIG_NOT_AVAILABLE', // error while fetching or parsing the config\n INVALID_PARAMS = 'INVALID_PARAMS', // generic error with the params\n IDENTICAL_CHAINS_PROVIDED = 'IDENTICAL_CHAINS_PROVIDED', // provided source and target chains are the same\n INCORRECT_AMOUNT_PROVIDED = 'INCORRECT_AMOUNT_PROVIDED', // the transfer amount is incorrect (e.g.: lesser than or equal to zero)\n INCORRECT_ADDRESS_PROVIDED = 'INCORRECT_ADDRESS_PROVIDED', // the sender or recipient address is incorrect\n CHAIN_NOT_SUPPORTED = 'CHAIN_NOT_SUPPORTED', // the provided source or target chain is not supported by the bridge\n ASSET_NOT_SUPPORTED = 'ASSET_NOT_SUPPORTED', // the provided asset is not supported by the bridge\n CONFIRMATION_COUNT_UNKNOWN = 'CONFIRMATION_COUNT_UNKNOWN', // required confirmation count of the source or target chain is unknown\n}\n","import type { ErrorCode } from '../types';\n\nexport class BridgeError extends Error {\n constructor(\n message: string,\n public code: ErrorCode,\n public details?: string,\n ) {\n super(message);\n }\n}\n","import { ErrorCode, ErrorReason } from '../types';\nimport { BridgeError } from './bridge-error';\n\nexport class BridgeUnavailableError extends BridgeError {\n constructor(message = ErrorReason.UNKNOWN, details?: string) {\n super(message, ErrorCode.BRIDGE_NOT_AVAILABLE, details);\n this.name = 'BridgeUnavailableError';\n }\n}\n","import { ErrorCode, ErrorReason } from '../types';\nimport { BridgeError } from './bridge-error';\n\nexport class BridgeInitializationError extends BridgeError {\n constructor(message = ErrorReason.UNKNOWN, details?: string) {\n super(message, ErrorCode.INITIALIZATION_FAILED, details);\n this.name = 'BridgeInitializationError';\n }\n}\n","import { ErrorCode, ErrorReason } from '../types';\nimport { BridgeError } from './bridge-error';\n\nexport class InvalidParamsError extends BridgeError {\n constructor(message = ErrorReason.INVALID_PARAMS, details?: string) {\n super(message, ErrorCode.INVALID_PARAMS, details);\n this.name = 'InvalidParamsError';\n }\n}\n","import { BridgeInitializationError } from '../../../errors';\nimport { ErrorReason } from '../../../types';\nimport { Environment } from '../../../types/environment';\nimport { AvalancheChainIds } from '../types/chain';\nimport type { Config } from '../types/config';\n\nconst CONFIG_URLS: Record<Environment, string> = {\n [Environment.TEST]:\n 'https://raw.githubusercontent.com/ava-labs/avalanche-bridge-resources/main/cctp/cctp_config.test.json',\n [Environment.PROD]:\n 'https://raw.githubusercontent.com/ava-labs/avalanche-bridge-resources/main/cctp/cctp_config.json',\n};\n\nexport const getConfig = async (environment: Environment): Promise<Config> => {\n try {\n const response = await fetch(CONFIG_URLS[environment]!);\n const config: Config = await response.json();\n\n return config.map((chainData) => ({ ...chainData, chainId: `eip155:${chainData.chainId}` }));\n } catch (err) {\n throw new BridgeInitializationError(\n ErrorReason.CONFIG_NOT_AVAILABLE,\n `Error while fetching CCTP config: ${(err as unknown as Error).message}`,\n );\n }\n};\n\nexport const getTrackingDelayByChainId = (chainId: string) => {\n switch (chainId) {\n case AvalancheChainIds.MAINNET:\n case AvalancheChainIds.FUJI:\n return 1000;\n default:\n return 20000;\n }\n};\n","import { TokenType, type BridgeService, type ChainAssetMap, type DestinationInfo, BridgeType } from '../../../types';\n\nexport async function getAssets(bridge: BridgeService) {\n await bridge.ensureHasConfig();\n\n const chainIds = bridge.config!.map((chainData) => chainData.chainId);\n\n return bridge.config!.reduce<ChainAssetMap>((assets, chainData) => {\n assets[chainData.chainId] = chainData.tokens.map((asset) => ({\n ...asset,\n type: TokenType.ERC20,\n destinations: chainIds.reduce<DestinationInfo>((destinations, chainId) => {\n if (chainData.chainId !== chainId) {\n if (!destinations[chainId]) {\n destinations[chainId] = [];\n }\n\n destinations[chainId]?.push(BridgeType.CCTP);\n }\n\n return destinations;\n }, {}),\n }));\n\n return assets;\n }, {});\n}\n","import { createWalletClient, publicActions, custom, http } from 'viem';\nimport type { Chain } from '../types/chain';\nimport type { Provider } from '../types';\nimport caip2 from './caip2';\n\nconst _getChain = (chain: Chain) => {\n const { reference: chainId } = caip2.toJSON(chain.chainId);\n\n return {\n id: Number(chainId),\n name: chain.chainName,\n nativeCurrency: {\n decimals: chain.networkToken.decimals,\n symbol: chain.networkToken.symbol,\n name: chain.networkToken.name,\n },\n network: chain.chainName,\n rpcUrls: {\n default: {\n http: [chain.rpcUrl],\n },\n public: {\n http: [chain.rpcUrl],\n },\n },\n ...(chain.utilityAddresses?.multicall && {\n contracts: {\n multicall3: {\n address: chain.utilityAddresses.multicall,\n },\n },\n }),\n };\n};\n\nexport const getClientForChain = ({ chain, provider }: { chain: Chain; provider?: Provider }) => {\n const chainInfo = _getChain(chain);\n const transport = provider ? custom(provider) : http(chain.rpcUrl, { batch: true, retryCount: 0 });\n\n return createWalletClient({\n chain: chainInfo,\n transport,\n }).extend(publicActions);\n};\n","// ref: https://chainagnostic.org/CAIPs/caip-2\n\nexport type Caip2ChainId = {\n namespace: string;\n reference: string;\n};\n\nconst namespacePattern = '^[-a-z0-9]{3,8}$';\n// the standard allows up to 32 characters for the reference part, but we have to set it to 50 so it accepts our cb58 encoded chain IDs\nconst referencePattern = '^[-_a-zA-Z0-9]{1,50}$';\nconst delimeter = ':';\n\nconst toJSON = (identifier: string): Caip2ChainId => {\n const [namespace, reference] = identifier.split(delimeter);\n\n if (!namespace || !reference) {\n throw new Error('Invalid identifier provided.');\n }\n\n if (!new RegExp(namespacePattern).test(namespace)) {\n throw new Error('Invalid namespace provided.');\n }\n\n if (!new RegExp(referencePattern).test(reference)) {\n throw new Error('Invalid reference provided.');\n }\n\n return {\n namespace,\n reference,\n };\n};\n\nconst toString = ({ namespace, reference }: Caip2ChainId) => {\n return `${namespace}${delimeter}${reference}`;\n};\n\nexport default {\n toJSON,\n toString,\n};\n","export const TOKEN_ROUTER_ABI = [\n {\n inputs: [\n {\n internalType: 'address',\n name: 'circleTokenMessenger_',\n type: 'address',\n },\n {\n internalType: 'address',\n name: 'burnToken_',\n type: 'address',\n },\n ],\n stateMutability: 'nonpayable',\n type: 'constructor',\n },\n {\n inputs: [],\n name: 'AlreadyAdmin',\n type: 'error',\n },\n {\n inputs: [],\n name: 'AlreadyFeeCollector',\n type: 'error',\n },\n {\n inputs: [],\n name: 'AlreadySupportedBurnToken',\n type: 'error',\n },\n {\n inputs: [],\n name: 'AmountLessThanFee',\n type: 'error',\n },\n {\n inputs: [],\n name: 'BalanceNotIncreased',\n type: 'error',\n },\n {\n inputs: [],\n name: 'CannotRemoveLastAdmin',\n type: 'error',\n },\n {\n inputs: [],\n name: 'FeePercentageGreaterThanMax',\n type: 'error',\n },\n {\n inputs: [],\n name: 'InvalidAdminAddress',\n type: 'error',\n },\n {\n inputs: [],\n name: 'InvalidFeeCollector',\n type: 'error',\n },\n {\n inputs: [],\n name: 'InvalidMintRecipientAddress',\n type: 'error',\n },\n {\n inputs: [],\n name: 'InvalidTokenAddress',\n type: 'error',\n },\n {\n inputs: [],\n name: 'InvalidTokenMessengerAddress',\n type: 'error',\n },\n {\n inputs: [],\n name: 'MaxFeeLessThanMinFee',\n type: 'error',\n },\n {\n inputs: [],\n name: 'NotAdmin',\n type: 'error',\n },\n {\n inputs: [],\n name: 'NotFeeCollector',\n type: 'error',\n },\n {\n inputs: [],\n name: 'UnSupportedBurnToken',\n type: 'error',\n },\n {\n inputs: [],\n name: 'UnsupportedDomain',\n type: 'error',\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: false,\n internalType: 'address',\n name: 'admin',\n type: 'address',\n },\n ],\n name: 'AdminAdded',\n type: 'event',\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: false,\n internalType: 'address',\n name: 'admin',\n type: 'address',\n },\n ],\n name: 'AdminRemoved',\n type: 'event',\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: false,\n internalType: 'address',\n name: 'token',\n type: 'address',\n },\n ],\n name: 'BurnTokenAdded',\n type: 'event',\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: false,\n internalType: 'address',\n name: 'token',\n type: 'address',\n },\n ],\n name: 'BurnTokenRemoved',\n type: 'event',\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: false,\n internalType: 'address',\n name: 'feeCollector',\n type: 'address',\n },\n ],\n name: 'FeeCollectorAdded',\n type: 'event',\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: false,\n internalType: 'address',\n name: 'feeCollector',\n type: 'address',\n },\n ],\n name: 'FeeCollectorRemoved',\n type: 'event',\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: false,\n internalType: 'uint32',\n name: 'domain',\n type: 'uint32',\n },\n {\n components: [\n {\n internalType: 'uint256',\n name: 'maxFee',\n type: 'uint256',\n },\n {\n internalType: 'uint256',\n name: 'minFee',\n type: 'uint256',\n },\n {\n internalType: 'uint32',\n name: 'feePercentage',\n type: 'uint32',\n },\n {\n internalType: 'uint256',\n name: 'txnFee',\n type: 'uint256',\n },\n {\n internalType: 'bool',\n name: 'supported',\n type: 'bool',\n },\n ],\n indexed: false,\n internalType: 'struct FeeCalculator.FeeConfiguration',\n name: 'feeConfiguration',\n type: 'tuple',\n },\n ],\n name: 'FeeConfigurationUpdated',\n type: 'event',\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n internalType: 'address',\n name: 'previousOwner',\n type: 'address',\n },\n {\n indexed: true,\n internalType: 'address',\n name: 'newOwner',\n type: 'address',\n },\n ],\n name: 'OwnershipTransferred',\n type: 'event',\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: false,\n internalType: 'address',\n name: 'account',\n type: 'address',\n },\n ],\n name: 'Paused',\n type: 'event',\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: false,\n internalType: 'uint64',\n name: 'nonce',\n type: 'uint64',\n },\n {\n indexed: false,\n internalType: 'address',\n name: 'burnToken',\n type: 'address',\n },\n {\n indexed: false,\n internalType: 'uint256',\n name: 'amount',\n type: 'uint256',\n },\n {\n indexed: false,\n internalType: 'address',\n name: 'depositor',\n type: 'address',\n },\n {\n indexed: false,\n internalType: 'address',\n name: 'mintRecipient',\n type: 'address',\n },\n {\n indexed: false,\n internalType: 'uint32',\n name: 'destinationDomain',\n type: 'uint32',\n },\n {\n indexed: false,\n internalType: 'uint256',\n name: 'totalFee',\n type: 'uint256',\n },\n ],\n name: 'TransferTokens',\n type: 'event',\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: false,\n internalType: 'address',\n name: 'account',\n type: 'address',\n },\n ],\n name: 'Unpaused',\n type: 'event',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'account',\n type: 'address',\n },\n ],\n name: 'addAdmin',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'feeCollector',\n type: 'address',\n },\n ],\n name: 'addFeeCollector',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'token',\n type: 'address',\n },\n ],\n name: 'addSupportedBurnToken',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'uint256',\n name: 'amount',\n type: 'uint256',\n },\n {\n internalType: 'uint32',\n name: 'destinationDomain',\n type: 'uint32',\n },\n ],\n name: 'calculateFee',\n outputs: [\n {\n internalType: 'uint256',\n name: '',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'circleTokenMessenger',\n outputs: [\n {\n internalType: 'contract ICircleTokenMessenger',\n name: '',\n type: 'address',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'circleTokenMessengerAddress',\n outputs: [\n {\n internalType: 'address',\n name: '',\n type: 'address',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'token',\n type: 'address',\n },\n ],\n name: 'collectFees',\n outputs: [\n {\n internalType: 'bool',\n name: '',\n type: 'bool',\n },\n ],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'token',\n type: 'address',\n },\n ],\n name: 'getFeeAmounts',\n outputs: [\n {\n internalType: 'uint256',\n name: '',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'uint32',\n name: 'domain',\n type: 'uint32',\n },\n ],\n name: 'getFeeConfiguration',\n outputs: [\n {\n components: [\n {\n internalType: 'uint256',\n name: 'maxFee',\n type: 'uint256',\n },\n {\n internalType: 'uint256',\n name: 'minFee',\n type: 'uint256',\n },\n {\n internalType: 'uint32',\n name: 'feePercentage',\n type: 'uint32',\n },\n {\n internalType: 'uint256',\n name: 'txnFee',\n type: 'uint256',\n },\n {\n internalType: 'bool',\n name: 'supported',\n type: 'bool',\n },\n ],\n internalType: 'struct FeeCalculator.FeeConfiguration',\n name: '',\n type: 'tuple',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'uint32',\n name: 'domain',\n type: 'uint32',\n },\n ],\n name: 'getFeePercentage',\n outputs: [\n {\n internalType: 'uint32',\n name: '',\n type: 'uint32',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'uint32',\n name: 'domain',\n type: 'uint32',\n },\n ],\n name: 'getMaxFee',\n outputs: [\n {\n internalType: 'uint256',\n name: '',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'uint32',\n name: 'domain',\n type: 'uint32',\n },\n ],\n name: 'getMinFee',\n outputs: [\n {\n internalType: 'uint256',\n name: '',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'uint32',\n name: 'domain',\n type: 'uint32',\n },\n ],\n name: 'getTxnFee',\n outputs: [\n {\n internalType: 'uint256',\n name: '',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'account',\n type: 'address',\n },\n ],\n name: 'isAdmin',\n outputs: [\n {\n internalType: 'bool',\n name: '',\n type: 'bool',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'account',\n type: 'address',\n },\n ],\n name: 'isFeeCollector',\n outputs: [\n {\n internalType: 'bool',\n name: '',\n type: 'bool',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'token',\n type: 'address',\n },\n ],\n name: 'isSupportedBurnToken',\n outputs: [\n {\n internalType: 'bool',\n name: '',\n type: 'bool',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'uint32',\n name: 'domain',\n type: 'uint32',\n },\n ],\n name: 'isSupportedDomain',\n outputs: [\n {\n internalType: 'bool',\n name: '',\n type: 'bool',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'owner',\n outputs: [\n {\n internalType: 'address',\n name: '',\n type: 'address',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'pause',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [],\n name: 'paused',\n outputs: [\n {\n internalType: 'bool',\n name: '',\n type: 'bool',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'account',\n type: 'address',\n },\n ],\n name: 'removeAdmin',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'feeCollector',\n type: 'address',\n },\n ],\n name: 'removeFeeCollector',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'token',\n type: 'address',\n },\n ],\n name: 'removeSupportedBurnToken',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [],\n name: 'renounceOwnership',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'uint32',\n name: 'domain',\n type: 'uint32',\n },\n {\n components: [\n {\n internalType: 'uint256',\n name: 'maxFee',\n type: 'uint256',\n },\n {\n internalType: 'uint256',\n name: 'minFee',\n type: 'uint256',\n },\n {\n internalType: 'uint32',\n name: 'feePercentage',\n type: 'uint32',\n },\n {\n internalType: 'uint256',\n name: 'txnFee',\n type: 'uint256',\n },\n {\n internalType: 'bool',\n name: 'supported',\n type: 'bool',\n },\n ],\n internalType: 'struct FeeCalculator.FeeConfiguration',\n name: 'feeConfiguration',\n type: 'tuple',\n },\n ],\n name: 'setFeeConfiguration',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: '',\n type: 'address',\n },\n ],\n name: 'supportedBurnTokens',\n outputs: [\n {\n internalType: 'bool',\n name: '',\n type: 'bool',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'address',\n name: 'newOwner',\n type: 'address',\n },\n ],\n name: 'transferOwnership',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n {\n internalType: 'uint256',\n name: 'amount',\n type: 'uint256',\n },\n {\n internalType: 'uint32',\n name: 'destinationDomain',\n type: 'uint32',\n },\n {\n internalType: 'address',\n name: 'mintRecipient',\n type: 'address',\n },\n {\n internalType: 'address',\n name: 'burnToken',\n type: 'address',\n },\n ],\n name: 'transferTokens',\n outputs: [\n {\n internalType: 'uint64',\n name: 'nonce',\n type: 'uint64',\n },\n ],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [],\n name: 'unpause',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n] as const;\n","import { InvalidParamsError } from '../../../errors';\nimport { ErrorReason } from '../../../types';\nimport type { TransferParams } from '../../../types/bridge';\nimport type { Config } from '../types/config';\n\ntype PartialTransferParams = Pick<TransferParams, 'sourceChain' | 'targetChain' | 'amount' | 'asset'>;\n\nexport const getTransferData = ({ sourceChain, targetChain, amount, asset }: PartialTransferParams, config: Config) => {\n if (sourceChain.chainId === targetChain.chainId) {\n throw new InvalidParamsError(ErrorReason.IDENTICAL_CHAINS_PROVIDED);\n }\n\n if (amount <= 0n) {\n throw new InvalidParamsError(ErrorReason.INCORRECT_AMOUNT_PROVIDED, 'Amount must be greater than zero');\n }\n\n const sourceChainData = config.find((chainData) => chainData.chainId === sourceChain.chainId);\n\n if (!sourceChainData) {\n throw new InvalidParamsError(\n ErrorReason.CHAIN_NOT_SUPPORTED,\n `Not supported on source chain \"${sourceChain.chainId}\"`,\n );\n }\n\n const targetChainData = config.find((chainData) => chainData.chainId === targetChain.chainId);\n\n if (!targetChainData) {\n throw new InvalidParamsError(\n ErrorReason.CHAIN_NOT_SUPPORTED,\n `Not supported on target chain \"${targetChain.chainId}\"`,\n );\n }\n\n const burnToken = sourceChainData.tokens.find((token) => token.symbol === asset.symbol);\n const mintToken = targetChainData.tokens.find((token) => token.symbol === asset.symbol);\n\n if (!burnToken || !mintToken) {\n throw new InvalidParamsError(ErrorReason.ASSET_NOT_SUPPORTED);\n }\n\n return {\n sourceChainData,\n targetChainData,\n burnToken,\n mintToken,\n };\n};\n","import type { AssetFeeMap, BridgeService, FeeParams } from '../../../types';\nimport { getClientForChain } from '../../../utils/client';\nimport { TOKEN_ROUTER_ABI } from '../abis/token-router';\nimport { getTransferData } from '../utils/transfer-data';\n\nexport async function getFees(bridge: BridgeService, params: FeeParams) {\n await bridge.ensureHasConfig();\n\n const { sourceChain, targetChain, asset, amount, provider } = params;\n const { sourceChainData, targetChainData, burnToken } = getTransferData(\n { sourceChain, targetChain, asset, amount },\n bridge.config!,\n );\n\n const client = getClientForChain({ chain: sourceChain, provider });\n const feeAmount = await client.readContract({\n address: sourceChainData.tokenRouterAddress,\n abi: TOKEN_ROUTER_ABI,\n functionName: 'calculateFee',\n args: [amount, targetChainData.domain],\n });\n\n return {\n [burnToken.address]: feeAmount,\n } as AssetFeeMap;\n}\n","import { encodeFunctionData, isAddress, type PublicClient } from 'viem';\nimport {\n ErrorReason,\n type BridgeService,\n type Environment,\n type TransferParams,\n type Hex,\n type BridgeTransfer,\n BridgeSignatureReason,\n} from '../../../types';\nimport { getClientForChain } from '../../../utils/client';\nimport { ERC20_ABI } from '../abis/erc20';\nimport { getTransferData } from '../utils/transfer-data';\nimport { TOKEN_ROUTER_ABI } from '../abis/token-router';\nimport { InvalidParamsError } from '../../../errors';\n\nconst approveAndTransfer = async (bridge: BridgeService, params: TransferParams) => {\n const {\n sourceChain,\n targetChain,\n asset,\n amount,\n fromAddress,\n toAddress: maybeToAddress,\n sourceProvider,\n onStepChange,\n sign,\n } = params;\n const toAddress = maybeToAddress ?? fromAddress;\n\n if (!isAddress(fromAddress) || !isAddress(toAddress)) {\n throw new InvalidParamsError(ErrorReason.INCORRECT_ADDRESS_PROVIDED);\n }\n\n const { sourceChainData, targetChainData, burnToken } = getTransferData(\n { sourceChain, targetChain, asset, amount },\n bridge.config!,\n );\n const client = getClientForChain({ chain: sourceChain, provider: sourceProvider });\n\n const allowance = await client.readContract({\n address: burnToken.address,\n abi: ERC20_ABI,\n functionName: 'allowance',\n args: [fromAddress, sourceChainData.tokenRouterAddress],\n });\n\n const isAllowanceApprovalRequired = allowance < amount;\n const requiredSignatures = isAllowanceApprovalRequired ? 2 : 1; // if approval is required, we'll need 2 signatures\n\n if (isAllowanceApprovalRequired) {\n onStepChange?.({\n currentSignature: 1,\n currentSignatureReason: BridgeSignatureReason.AllowanceApproval,\n requiredSignatures,\n });\n\n if (sign) {\n const data = encodeFunctionData({\n abi: ERC20_ABI,\n functionName: 'approve',\n args: [sourceChainData.tokenRouterAddress, amount],\n });\n\n const txHash = await sign(\n {\n from: fromAddress,\n to: burnToken.address,\n data,\n },\n (signedTxHash: Hex) => client.sendRawTransaction({ serializedTransaction: signedTxHash }),\n );\n\n await client.waitForTransactionReceipt({ hash: txHash, pollingInterval: 1_000 });\n } else {\n const { request } = await client.simulateContract({\n account: fromAddress,\n address: burnToken.address,\n abi: ERC20_ABI,\n functionName: 'approve',\n args: [sourceChainData.tokenRouterAddress, amount],\n });\n\n const txHash = await client.writeContract(request);\n await client.waitForTransactionReceipt({ hash: txHash, pollingInterval: 1_000 });\n }\n }\n\n onStepChange?.({\n currentSignature: isAllowanceApprovalRequired ? 2 : 1,\n currentSignatureReason: BridgeSignatureReason.TokensTransfer,\n requiredSignatures,\n });\n\n if (sign) {\n const data = encodeFunctionData({\n abi: TOKEN_ROUTER_ABI,\n functionName: 'transferTokens',\n args: [amount, targetChainData.domain, toAddress, burnToken.address],\n });\n\n return sign(\n {\n from: fromAddress,\n to: sourceChainData.tokenRouterAddress,\n data,\n },\n (signedTxHash: Hex) => client.sendRawTransaction({ serializedTransaction: signedTxHash }),\n );\n } else {\n const { request } = await client.simulateContract({\n account: fromAddress,\n address: sourceChainData.tokenRouterAddress,\n abi: TOKEN_ROUTER_ABI,\n functionName: 'transferTokens',\n args: [amount, targetChainData.domain, toAddress, burnToken.address],\n });\n\n return client.writeContract(request);\n }\n};\n\nconst getStartBlockNumber = async (targetClient: PublicClient) => {\n try {\n const startBlockNumber = await targetClient.getBlockNumber();\n return startBlockNumber;\n } catch {\n return undefined;\n }\n};\n\nexport async function transferAsset(\n bridge: BridgeService,\n params: TransferParams,\n environment: Environment,\n): Promise<BridgeTransfer> {\n await bridge.ensureHasConfig();\n\n const { minimumConfirmations: requiredSourceConfirmationCount } =\n bridge.config!.find((chainData) => chainData.chainId === params.sourceChain.chainId) ?? {};\n const { minimumConfirmations: requiredTargetConfirmationCount } =\n bridge.config!.find((chainData) => chainData.chainId === params.targetChain.chainId) ?? {};\n\n if (!requiredSourceConfirmationCount || !requiredTargetConfirmationCount) {\n throw new InvalidParamsError(ErrorReason.CONFIRMATION_COUNT_UNKNOWN);\n }\n\n const fees = await bridge.getFees({ ...params, provider: params.sourceProvider });\n\n const bridgeFee = (params.asset.address && fees[params.asset.address]) ?? 0n;\n const txHash = await approveAndTransfer(bridge, params);\n const sourceStartedAt = Date.now();\n const targetClient = getClientForChain({ chain: params.targetChain, provider: params.targetProvider });\n const targetBlockNumber = await getStartBlockNumber(targetClient);\n\n return {\n type: bridge.type,\n environment,\n fromAddress: params.fromAddress,\n toAddress: params.toAddress ?? params.fromAddress,\n amount: params.amount,\n amountDecimals: params.asset.decimals,\n symbol: params.asset.symbol,\n\n bridgeFee,\n\n sourceChain: params.sourceChain,\n sourceStartedAt,\n sourceTxHash: txHash,\n sourceConfirmationCount: 0,\n requiredSourceConfirmationCount,\n\n targetChain: params.targetChain,\n targetConfirmationCount: 0,\n requiredTargetConfirmationCount,\n\n startBlockNumber: targetBlockNumber,\n };\n}\n","export const ERC20_ABI = [\n {\n constant: true,\n inputs: [],\n name: 'name',\n outputs: [{ name: '', type: 'string' }],\n payable: false,\n stateMutability: 'view',\n type: 'function',\n },\n {\n constant: false,\n inputs: [\n { name: '_spender', type: 'address' },\n { name: '_value', type: 'uint256' },\n ],\n name: 'approve',\n outputs: [{ name: '', type: 'bool' }],\n payable: false,\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n constant: true,\n inputs: [],\n name: 'totalSupply',\n outputs: [{ name: '', type: 'uint256' }],\n payable: false,\n stateMutability: 'view',\n type: 'function',\n },\n {\n constant: false,\n inputs: [\n { name: '_from', type: 'address' },\n { name: '_to', type: 'address' },\n { name: '_value', type: 'uint256' },\n ],\n name: 'transferFrom',\n outputs: [{ name: '', type: 'bool' }],\n payable: false,\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n constant: true,\n inputs: [],\n name: 'decimals',\n outputs: [{ name: '', type: 'uint8' }],\n payable: false,\n stateMutability: 'view',\n type: 'function',\n },\n {\n constant: true,\n inputs: [{ name: '_owner', type: 'address' }],\n name: 'balanceOf',\n outputs: [{ name: 'balance', type: 'uint256' }],\n payable: false,\n stateMutability: 'view',\n type: 'function',\n },\n {\n constant: true,\n inputs: [],\n name: 'symbol',\n outputs: [{ name: '', type: 'string' }],\n payable: false,\n stateMutability: 'view',\n type: 'function',\n },\n {\n constant: false,\n inputs: [\n { name: '_to', type: 'address' },\n { name: '_value', type: 'uint256' },\n ],\n name: 'transfer',\n outputs: [{ name: '', type: 'bool' }],\n payable: false,\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n constant: true,\n inputs: [\n { name: '_owner', type: 'address' },\n { name: '_spender', type: 'address' },\n ],\n name: 'allowance',\n outputs: [{ name: '', type: 'uint256' }],\n payable: false,\n stateMutability: 'view',\n type: 'function',\n },\n { payable: true, stateMutability: 'payable', type: 'fallback' },\n {\n anonymous: false,\n inputs: [\n { indexed: true, name: 'owner', type: 'address' },\n { indexed: true, name: 'spender', type: 'address' },\n { indexed: false, name: 'value', type: 'uint256' },\n ],\n name: 'Approval',\n type: 'event',\n },\n {\n anonymous: false,\n inputs: [\n { indexed: true, name: 'from', type: 'address' },\n { indexed: true, name: 'to', type: 'address' },\n { indexed: false, name: 'value', type: 'uint256' },\n ],\n name: 'Transfer',\n type: 'event',\n },\n] as const;\n","import { BridgeInitializationError } from '../errors';\nimport { ErrorReason, type BridgeService } from '../types';\n\nexport async function ensureHasConfig(bridge: BridgeService) {\n if (!bridge.config) {\n await bridge.updateConfig();\n\n if (!bridge.config) {\n throw new BridgeInitializationError(ErrorReason.CONFIG_NOT_AVAILABLE);\n }\n }\n}\n","import { decodeEventLog, type Address } from 'viem';\nimport {\n ErrorReason,\n type BridgeConfig,\n type BridgeService,\n type BridgeTransfer,\n type TrackingParams,\n ErrorCode,\n} from '../../../types';\nimport { getClientForChain } from '../../../utils/client';\nimport { TOKEN_ROUTER_ABI } from '../abis/token-router';\nimport { getNetworkFeeEVM } from '../../../utils/network-fee';\nimport { retryPromise, type Done } from '../../../utils/retry-promise';\nimport { getTrackingDelayByChainId } from '../utils/config';\nimport { InvalidParamsError } from '../../../errors';\n\n// Maximum time (in ms) before the transaction is considered \"timed out\"\nexport const TRACKING_LIMIT_MS = 1000 * 60 * 60 * 3;\n// The max blocks that can be queried before receiving an error response\nexport const MAX_BLOCKS = 1024n;\n// The delay time before tracking starts\nexport const INITIAL_DELAY = 5000;\n\n/**\n * Mutates the `initial` transfer by merging it with the `updated` properties if they are not undefined\n * Invokes the `updateListener` with a copy of the updated `initial` transfer\n */\nconst updateTransfer = (\n initial: BridgeTransfer,\n updated: Partial<BridgeTransfer>,\n updateListener: TrackingParams['updateListener'],\n) => {\n Object.assign(initial, Object.fromEntries(Object.entries(updated).filter(([, value]) => value !== undefined)));\n updateListener({ ...initial });\n};\n\n/**\n * Polls the source network until it's able to get the CCTP message's `nonce` from the source transaction's logs\n * Updates the provided `BridgeTransfer` and broadcasts the changes via `updateListener`\n */\nexport const trackSourceTx = async (config: BridgeConfig, params: TrackingParams) => {\n const { sourceProvider, targetProvider, updateListener, bridgeTransfer } = params;\n const sourceClient = getClientForChain({ chain: bridgeTransfer.sourceChain, provider: sourceProvider });\n const sourceChainData = config.find((chainData) => chainData.chainId === bridgeTransfer.sourceChain.chainId);\n const targetClient = getClientForChain({ chain: bridgeTransfer.targetChain, provider: targetProvider });\n const targetChainData = config.find((chainData) => chainData.chainId === bridgeTransfer.targetChain.chainId);\n const updateableTransfer = { ...bridgeTransfer };\n\n if (!sourceChainData || !targetChainData) {\n throw new InvalidParamsError(ErrorReason.CHAIN_NOT_SUPPORTED);\n }\n\n const tracker = async (done: Done<BridgeTransfer>) => {\n /**\n * Return early if:\n * - transfer has already completed successfully or due to some error\n * - the transfer state already has the message's nonce\n */\n if (updateableTransfer.completedAt || updateableTransfer.metadata?.nonce) {\n return done(updateableTransfer);\n }\n\n /**\n * Check if the transaction has timed out\n */\n if (updateableTransfer.sourceStartedAt + TRACKING_LIMIT_MS <= Date.now()) {\n updateTransfer(updateableTransfer, { completedAt: Date.now(), errorCode: ErrorCode.TIMEOUT }, updateListener);\n return done(updateableTransfer);\n }\n\n /**\n * Get the transaction's receipt.\n * Throws if the transaction has't been processed by the network yet.\n */\n const txReceipt = await sourceClient.getTransactionReceipt({\n hash: updateableTransfer.sourceTxHash as Address,\n });\n\n /**\n * Calculate the network fee if needed.\n */\n if (!updateableTransfer.sourceNetworkFee) {\n const tx = await sourceClient.getTransaction({ hash: updateableTransfer.sourceTxHash as Address });\n const networkFee = getNetworkFeeEVM(tx, txReceipt);\n\n if (networkFee) {\n updateTransfer(updateableTransfer, { sourceNetworkFee: networkFee }, updateListener);\n }\n }\n\n /**\n * Update the state and terminate if the transaction was reverted\n */\n if (txReceipt.status === 'reverted') {\n updateTransfer(\n updateableTransfer,\n { completedAt: Date.now(), errorCode: ErrorCode.TRANSACTION_REVERTED },\n updateListener,\n );\n return done(updateableTransfer);\n }\n\n /**\n * Check the confirmation count.\n * - update the sourceConfirmationCount if it increased\n * - update the startBlockNumber if confirmation count increased but is not enough\n * - keeps polling until it's greater than requiredSourceConfirmationCount\n */\n const confirmationCount = await sourceClient.getTransactionConfirmations({\n hash: updateableTransfer.sourceTxHash as Address,\n });\n const hasMoreConfirmations = confirmationCount > updateableTransfer.sourceConfirmationCount;\n const hasRequiredConfirmations = confirmationCount >= updateableTransfer.requiredSourceConfirmationCount;\n\n if (hasMoreConfirmations) {\n const changes = {} as Partial<BridgeTransfer>;\n changes.sourceConfirmationCount = Number(confirmationCount);\n\n if (!hasRequiredConfirmations) {\n changes.startBlockNumber = await targetClient.getBlockNumber();\n }\n\n updateTransfer(updateableTransfer, changes, updateListener);\n }\n\n if (!hasRequiredConfirmations) {\n return;\n }\n\n if (!updateableTransfer.startBlockNumber) {\n updateTransfer(updateableTransfer, { startBlockNumber: await targetClient.getBlockNumber() }, updateListener);\n }\n\n /**\n * Get the `TransferTokens` event's log entry from the receipt\n */\n const transferEventLog = txReceipt.logs.find((log) => {\n if (log.address.toLowerCase() === sourceChainData.tokenRouterAddress.toLowerCase()) {\n const event = decodeEventLog({\n abi: TOKEN_ROUTER_ABI,\n ...log,\n });\n\n return event.eventName === 'TransferTokens';\n }\n\n return false;\n });\n\n if (!transferEventLog) {\n throw new InvalidParamsError(\n ErrorReason.INVALID_PARAMS,\n `unable to find a TransferTokens event in source transaction \"${updateableTransfer.sourceTxHash}\"`,\n );\n }\n\n /**\n * Get the nonce used by the message transmitter from the event's log\n * https://developers.circle.com/stablecoins/docs/evm-smart-contracts#receivemessage\n */\n const transferEvent = decodeEventLog({\n abi: TOKEN_ROUTER_ABI,\n eventName: 'TransferTokens',\n ...transferEventLog,\n });\n\n // save the nonce and broadcast\n const nonce = transferEvent.args.nonce;\n updateTransfer(updateableTransfer, { targetStartedAt: Date.now(), metadata: { nonce } }, updateListener);\n return done(updateableTransfer);\n };\n\n return retryPromise<BridgeTransfer>({\n promise: tracker,\n delay: getTrackingDelayByChainId(sourceChainData.chainId),\n startAfter: INITIAL_DELAY,\n });\n};\n\n/**\n * Polls the target network until it finds the transaction that matches the message's nonce\n * Updates the provided `BridgeTransfer` and broadcasts the changes via `updateListener`\n */\nexport const trackTargetTx = async (config: BridgeConfig, params: TrackingParams) => {\n const { targetProvider, updateListener, bridgeTransfer } = params;\n const updateableTransfer = { ...bridgeTransfer };\n\n if (!bridgeTransfer.completedAt && !bridgeTransfer.metadata?.nonce) {\n throw new InvalidParamsError(ErrorReason.INVALID_PARAMS, `nonce is missing`);\n }\n\n if (!bridgeTransfer.startBlockNumber) {\n throw new InvalidParamsError(ErrorReason.INVALID_PARAMS, `startBlockNumber is missing`);\n }\n\n const targetClient = getClientForChain({ chain: bridgeTransfer.targetChain, provider: targetProvider });\n const targetChainData = config.find((chainData) => chainData.chainId === bridgeTransfer.targetChain.chainId);\n\n if (!targetChainData) {\n throw new InvalidParamsError(\n ErrorReason.INVALID_PARAMS,\n `unknown target chain \"${bridgeTransfer.targetChain.chainId}\"`,\n );\n }\n\n const tracker = async (done: Done<BridgeTransfer>) => {\n /**\n * Return early if:\n * - transfer has already completed successfully or due to some error\n */\n if (updateableTransfer.completedAt) {\n return done(updateableTransfer);\n }\n\n /**\n * Check if `startBlockNumber` became falsy for whatever reason\n */\n if (!updateableTransfer.startBlockNumber) {\n updateTransfer(\n updateableTransfer,\n { completedAt: Date.now(), errorCode: ErrorCode.INVALID_PARAMS },\n updateListener,\n );\n return done(updateableTransfer);\n }\n\n /**\n * Check if the transaction has timed out\n */\n if (updateableTransfer.sourceStartedAt + TRACKING_LIMIT_MS <= Date.now()) {\n updateTransfer(updateableTransfer, { completedAt: Date.now(), errorCode: ErrorCode.TIMEOUT }, updateListener);\n return done(updateableTransfer);\n }\n\n if (!updateableTransfer.targetTxHash) {\n const lastBlockNumber = await targetClient.getBlockNumber();\n const lowestBlockNumber = updateableTransfer.startBlockNumber - MAX_BLOCKS;\n const fromBlock = lowestBlockNumber >= 0n ? lowestBlockNumber : 'earliest';\n const highestBlockNumber = updateableTransfer.startBlockNumber + MAX_BLOCKS;\n const toBlock = highestBlockNumber < lastBlockNumber ? highestBlockNumber : 'latest';\n\n const targetLogs = await targetClient.getLogs({\n address: targetChainData.messageTransmitterAddress,\n event: {\n name: 'MessageReceived',\n type: 'event',\n inputs: [\n { indexed: true, internalType: 'address', name: 'caller', type: 'address' },\n { indexed: false, internalType: 'uint32', name: 'sourceDomain', type: 'uint32' },\n { indexed: true, internalType: 'uint64', name: 'nonce', type: 'uint64' },\n { indexed: false, internalType: 'bytes32', name: 'sender', type: 'bytes32' },\n { indexed: false, internalType: 'bytes', name: 'messageBody', type: 'bytes' },\n ],\n },\n args: { nonce: updateableTransfer.metadata!.nonce as bigint },\n fromBlock,\n toBlock,\n });\n\n if (targetLogs[0]?.transactionHash) {\n updateTransfer(updateableTransfer, { targetTxHash: targetLogs[0].transactionHash }, updateListener);\n } else {\n updateTransfer(updateableTransfer, { startBlockNumber: lastBlockNumber }, updateListener);\n return;\n }\n }\n\n /**\n * Get the transaction's receipt.\n * Throws if the transaction has't been processed by the network yet.\n */\n const txReceipt = await targetClient.getTransactionReceipt({\n hash: updateableTransfer.targetTxHash as Address,\n });\n\n /**\n * Calculate the network fee if needed.\n */\n if (!updateableTransfer.targetNetworkFee) {\n const tx = await targetClient.getTransaction({ hash: updateableTransfer.targetTxHash as Address });\n const networkFee = getNetworkFeeEVM(tx, txReceipt);\n\n if (networkFee) {\n updateTransfer(updateableTransfer, { targetNetworkFee: networkFee }, updateListener);\n }\n }\n\n /**\n * Update the state and terminate if the transaction was reverted\n */\n if (txReceipt.status === 'reverted') {\n updateTransfer(\n updateableTransfer,\n { completedAt: Date.now(), errorCode: ErrorCode.TRANSACTION_REVERTED },\n updateListener,\n );\n return done(updateableTransfer);\n }\n\n /**\n * Check the confirmation count.\n * - update the targetConfirmationCount if it increased\n * - keeps polling until it's greater than requiredTargetConfirmationCount\n */\n const confirmationCount = await targetClient.getTransactionConfirmations({\n hash: updateableTransfer.targetTxHash as Address,\n });\n const hasMoreConfirmations = confirmationCount > updateableTransfer.targetConfirmationCount;\n const hasRequiredConfirmations = confirmationCount >= updateableTransfer.requiredTargetConfirmationCount;\n\n if (hasMoreConfirmations) {\n updateTransfer(updateableTransfer, { targetConfirmationCount: Number(confirmationCount) }, updateListener);\n }\n\n if (!hasRequiredConfirmations) {\n return;\n }\n\n updateTransfer(updateableTransfer, { completedAt: Date.now() }, updateListener);\n return done(updateableTransfer);\n };\n\n return retryPromise<BridgeTransfer>({\n promise: tracker,\n delay: getTrackingDelayByChainId(targetChainData.chainId),\n startAfter: INITIAL_DELAY,\n });\n};\n\nexport function trackTransfer(bridge: BridgeService, params: TrackingParams) {\n let abortFn: (() => void) | undefined;\n\n const cancel = () => {\n abortFn?.();\n };\n\n const executeTracking = async () => {\n await bridge.ensureHasConfig();\n\n const { sourceProvider, targetProvider, updateListener, bridgeTransfer } = params;\n\n const { result: sourceTracker, cancel: cancelSourceTracking } = await trackSourceTx(bridge.config!, {\n sourceProvider,\n targetProvider,\n updateListener,\n bridgeTransfer,\n });\n abortFn = cancelSourceTracking;\n const transferAfterSourceFinished = await sourceTracker;\n\n const { result: targetTracker, cancel: cancelTargetTracking } = await trackTargetTx(bridge.config!, {\n sourceProvider,\n targetProvider,\n updateListener,\n bridgeTransfer: transferAfterSourceFinished,\n });\n abortFn = cancelTargetTracking;\n return targetTracker;\n };\n\n return {\n result: executeTracking(),\n cancel,\n };\n}\n","import { type Transaction, type TransactionReceipt } from 'viem';\n\n// returns the network fee for EVM transaction in wei (10**-18)\nexport const getNetworkFeeEVM = (transaction: Transaction, receipt: TransactionReceipt) => {\n return transaction.gasPrice && BigInt(transaction.gasPrice * receipt.gasUsed);\n};\n","export const wait = async (time: number) =>\n new Promise((res) => {\n setTimeout(res, time);\n });\n","import { wait } from './wait';\n\nexport type Done<T> = (data: T) => void;\n\ntype Params<T> = {\n promise: (done: Done<T>) => Promise<unknown>;\n delay: number;\n startAfter?: number;\n};\n\nexport const retryPromise = <T>({ promise, delay, startAfter }: Params<T>) => {\n let isRunning = false;\n let isCancelled = false;\n let errorCount: number = 0;\n let resolve: ((data: T) => void) | undefined = undefined;\n let reject: ((reason?: string) => void) | undefined = undefined;\n\n const done = (data: T) => {\n if (resolve && isRunning) {\n isRunning = false;\n resolve(data);\n }\n };\n\n const cancel = () => {\n isCancelled = true;\n\n if (reject && isRunning) {\n isRunning = false;\n reject('cancelled');\n }\n };\n\n const result = new Promise<T>((res, rej) => {\n isRunning = true;\n resolve = res;\n reject = rej;\n\n const execute = async (): Promise<void> => {\n if (!isRunning || isCancelled) {\n return;\n }\n\n try {\n await promise(done);\n\n if (!isRunning || isCancelled) {\n return;\n }\n\n await wait(delay);\n } catch (err) {\n console.error((err as Error).message);\n errorCount += 1;\n await wait(2 ** errorCount * delay);\n }\n\n await execute();\n };\n\n if (startAfter) {\n setTimeout(execute, startAfter);\n } else {\n execute();\n }\n });\n\n return {\n result,\n cancel,\n };\n};\n","import { type BridgeServiceFactory, BridgeType } from '../../types/bridge';\nimport { getConfig } from './utils/config';\nimport { getAssets } from './handlers/get-assets';\nimport { getFees } from './handlers/get-fees';\nimport { transferAsset } from './handlers/transfer-asset';\nimport { ensureHasConfig } from '../../utils/ensure-config';\nimport { trackTransfer } from './handlers/track-transfer';\n\nexport const cctpBridgeFactory: BridgeServiceFactory = (environment) => {\n return {\n type: BridgeType.CCTP,\n config: null,\n updateConfig: async function () {\n this.config = await getConfig(environment);\n },\n ensureHasConfig: async function () {\n return ensureHasConfig(this);\n },\n getAssets: async function () {\n return getAssets(this);\n },\n getFees: async function (params) {\n return getFees(this, params);\n },\n transferAsset: async function (params) {\n return transferAsset(this, params, environment);\n },\n trackTransfer: function (params) {\n return trackTransfer(this, params);\n },\n };\n};\n","import { cctpBridgeFactory } from '../bridges/cctp/factory';\nimport { BridgeUnavailableError } from '../errors';\nimport type { BridgeAsset } from '../types/asset';\nimport { type BridgeService, BridgeType } from '../types/bridge';\nimport { Environment } from '../types/environment';\n\nexport const supportedBridges = new Map([[BridgeType.CCTP, cctpBridgeFactory]]);\n\nexport const getEnabledBridgeServices = (environment: Environment, disabledBridgeTypes?: BridgeType[]) => {\n return new Map(\n [...supportedBridges]\n .filter(([bridgeType]) => !disabledBridgeTypes?.includes(bridgeType))\n .map(([bridgeType, factory]) => [bridgeType, factory(environment)]),\n );\n};\n\nexport const getBridgeForTransfer = (\n enabledBridgeServices: Map<BridgeType, BridgeService>,\n asset: BridgeAsset,\n targetChainId: string,\n) => {\n const bridgeType = asset.destinations[targetChainId]?.find((bridgeType) => enabledBridgeServices.has(bridgeType));\n\n if (!bridgeType) {\n throw new BridgeUnavailableError();\n }\n\n return {\n type: bridgeType,\n bridge: enabledBridgeServices.get(bridgeType)!,\n };\n};\n","import type { FeeParams, TrackingParams, TransferParams } from './types/bridge';\nimport type { BridgeServiceConfig } from './types/config';\nimport { getBridgeForTransfer, getEnabledBridgeServices } from './utils';\nimport type { BridgeAsset, ChainAssetMap } from './types';\nimport { isArray, mergeWith } from 'lodash';\nimport { BridgeUnavailableError } from './errors';\n\nexport const createUnifiedBridgeService = ({ environment, disabledBridgeTypes }: BridgeServiceConfig) => {\n const enabledBridgeServices = getEnabledBridgeServices(environment, disabledBridgeTypes);\n\n const updateConfigs = async () => {\n await Promise.allSettled(\n Array.from(enabledBridgeServices).map(([, bridgeService]) => bridgeService.updateConfig()),\n );\n };\n\n const init = async () => {\n await updateConfigs();\n };\n\n const getAssets = async () => {\n const assets = await Promise.all(Array.from(enabledBridgeServices).map(([, bridge]) => bridge.getAssets()));\n return assets.reduce<ChainAssetMap>((aggregatedAssets, chainAssetMap) => {\n for (const [chainId, bridgeAssets] of Object.entries(chainAssetMap)) {\n const existingAssets = aggregatedAssets[chainId];\n\n if (existingAssets) {\n for (const bridgeAsset of bridgeAssets) {\n const index = existingAssets.findIndex(({ symbol }) => symbol === bridgeAsset.symbol);\n\n if (index === -1) {\n existingAssets.push(bridgeAsset);\n } else {\n mergeWith(existingAssets[index], bridgeAsset, (objValue, srcValue) => {\n if (isArray(objValue)) {\n return [...new Set(objValue.concat(srcValue))];\n }\n });\n }\n }\n } else {\n aggregatedAssets[chainId] = bridgeAssets;\n }\n }\n\n return aggregatedAssets;\n }, {});\n };\n\n const getFees = async (params: FeeParams) => {\n const { bridge } = getBridgeForTransfer(enabledBridgeServices, params.asset, params.targetChain.chainId);\n return bridge.getFees(params);\n };\n\n const transferAsset = async (params: TransferParams) => {\n const { bridge } = getBridgeForTransfer(enabledBridgeServices, params.asset, params.targetChain.chainId);\n return bridge.transferAsset(params);\n };\n\n const canTransferAsset = (asset: BridgeAsset, targetChainId: string) => {\n try {\n getBridgeForTransfer(enabledBridgeServices, asset, targetChainId);\n return true;\n } catch {\n return false;\n }\n };\n\n const trackTransfer = (params: TrackingParams) => {\n const bridge = enabledBridgeServices.get(params.bridgeTransfer.type);\n\n if (!bridge) {\n throw new BridgeUnavailableError();\n }\n\n return bridge.trackTransfer(params);\n };\n\n return {\n environment,\n bridges: enabledBridgeServices,\n init,\n updateConfigs,\n getAssets,\n getFees,\n canTransferAsset,\n transferAsset,\n trackTransfer,\n };\n};\n"]}
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { custom, http, createWalletClient, publicActions, isAddress, encodeFunctionData, decodeEventLog } from 'viem';
|
|
2
2
|
import { mergeWith, isArray } from 'lodash';
|
|
3
3
|
|
|
4
|
-
var H=(r=>(r.NATIVE="native",r.ERC20="erc20",r))(H||{});var E=(t=>(t.CCTP="cctp",t))(E||{}),V=(r=>(r.AllowanceApproval="allowance-approval",r.TokensTransfer="tokens-transfer",r))(V||{});var K=(r=>(r.PROD="production",r.TEST="test",r))(K||{});var R=(n=>(n[n.BRIDGE_NOT_AVAILABLE=5001]="BRIDGE_NOT_AVAILABLE",n[n.INITIALIZATION_FAILED=5002]="INITIALIZATION_FAILED",n[n.INVALID_PARAMS=5003]="INVALID_PARAMS",n[n.TIMEOUT=5004]="TIMEOUT",n[n.TRANSACTION_REVERTED=5005]="TRANSACTION_REVERTED",n))(R||{}),w=(i=>(i.UNKNOWN="UNKNOWN",i.CONFIG_NOT_AVAILABLE="CONFIG_NOT_AVAILABLE",i.INVALID_PARAMS="INVALID_PARAMS",i.IDENTICAL_CHAINS_PROVIDED="IDENTICAL_CHAINS_PROVIDED",i.INCORRECT_AMOUNT_PROVIDED="INCORRECT_AMOUNT_PROVIDED",i.INCORRECT_ADDRESS_PROVIDED="INCORRECT_ADDRESS_PROVIDED",i.CHAIN_NOT_SUPPORTED="CHAIN_NOT_SUPPORTED",i.ASSET_NOT_SUPPORTED="ASSET_NOT_SUPPORTED",i.CONFIRMATION_COUNT_UNKNOWN="CONFIRMATION_COUNT_UNKNOWN",i))(w||{});var N=class extends Error{constructor(r,a,p){super(r);this.code=a;this.details=p;}};var P=class extends N{constructor(t="UNKNOWN",r){super(t,5001,r),this.name="BridgeUnavailableError";}};var B=class extends N{constructor(t="UNKNOWN",r){super(t,5002,r),this.name="BridgeInitializationError";}};var T=class extends N{constructor(t="INVALID_PARAMS",r){super(t,5003,r),this.name="InvalidParamsError";}};var ae={test:"https://raw.githubusercontent.com/ava-labs/avalanche-bridge-resources/main/cctp/cctp_config.test.json",production:"https://raw.githubusercontent.com/ava-labs/avalanche-bridge-resources/main/cctp/cctp_config.json"},q=async e=>{try{return (await(await fetch(ae[e])).json()).map(a=>({...a,chainId:`eip155:${a.chainId}`}))}catch(t){throw new B("CONFIG_NOT_AVAILABLE",`Error while fetching CCTP config: ${t.message}`)}},M=e=>{switch(e){case"eip155:43114":case"eip155:43113":return 1e3;default:return 2e4}};async function $(e){await e.ensureHasConfig();let t=e.config.map(r=>r.chainId);return e.config.reduce((r,a)=>(r[a.chainId]=a.tokens.map(p=>({...p,type:"erc20",destinations:t.reduce((n,o)=>(a.chainId!==o&&(n[o]||(n[o]=[]),n[o]?.push("cctp")),n),{})})),r),{})}var se="^[-a-z0-9]{3,8}$",ie="^[-_a-zA-Z0-9]{1,50}$",G=":",oe=e=>{let[t,r]=e.split(G);if(!t||!r)throw new Error("Invalid identifier provided.");if(!new RegExp(se).test(t))throw new Error("Invalid namespace provided.");if(!new RegExp(ie).test(r))throw new Error("Invalid reference provided.");return {namespace:t,reference:r}},pe=({namespace:e,reference:t})=>`${e}${G}${t}`,S={toJSON:oe,toString:pe};var le=e=>{let{reference:t}=S.toJSON(e.chainId);return {id:Number(t),name:e.chainName,nativeCurrency:{decimals:e.networkToken.decimals,symbol:e.networkToken.symbol,name:e.networkToken.name},network:e.chainName,rpcUrls:{default:{http:[e.rpcUrl]},public:{http:[e.rpcUrl]}},...e.utilityAddresses?.multicall&&{contracts:{multicall3:{address:e.utilityAddresses.multicall}}}}},I=({chain:e,provider:t})=>{let r=le(e),a=t?custom(t):http(e.rpcUrl,{batch:!0,retryCount:0});return createWalletClient({chain:r,transport:a}).extend(publicActions)};var x=[{inputs:[{internalType:"address",name:"circleTokenMessenger_",type:"address"},{internalType:"address",name:"burnToken_",type:"address"}],stateMutability:"nonpayable",type:"constructor"},{inputs:[],name:"AlreadyAdmin",type:"error"},{inputs:[],name:"AlreadyFeeCollector",type:"error"},{inputs:[],name:"AlreadySupportedBurnToken",type:"error"},{inputs:[],name:"AmountLessThanFee",type:"error"},{inputs:[],name:"BalanceNotIncreased",type:"error"},{inputs:[],name:"CannotRemoveLastAdmin",type:"error"},{inputs:[],name:"FeePercentageGreaterThanMax",type:"error"},{inputs:[],name:"InvalidAdminAddress",type:"error"},{inputs:[],name:"InvalidFeeCollector",type:"error"},{inputs:[],name:"InvalidMintRecipientAddress",type:"error"},{inputs:[],name:"InvalidTokenAddress",type:"error"},{inputs:[],name:"InvalidTokenMessengerAddress",type:"error"},{inputs:[],name:"MaxFeeLessThanMinFee",type:"error"},{inputs:[],name:"NotAdmin",type:"error"},{inputs:[],name:"NotFeeCollector",type:"error"},{inputs:[],name:"UnSupportedBurnToken",type:"error"},{inputs:[],name:"UnsupportedDomain",type:"error"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"admin",type:"address"}],name:"AdminAdded",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"admin",type:"address"}],name:"AdminRemoved",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"token",type:"address"}],name:"BurnTokenAdded",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"token",type:"address"}],name:"BurnTokenRemoved",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"feeCollector",type:"address"}],name:"FeeCollectorAdded",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"feeCollector",type:"address"}],name:"FeeCollectorRemoved",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"uint32",name:"domain",type:"uint32"},{components:[{internalType:"uint256",name:"maxFee",type:"uint256"},{internalType:"uint256",name:"minFee",type:"uint256"},{internalType:"uint32",name:"feePercentage",type:"uint32"},{internalType:"uint256",name:"txnFee",type:"uint256"},{internalType:"bool",name:"supported",type:"bool"}],indexed:!1,internalType:"struct FeeCalculator.FeeConfiguration",name:"feeConfiguration",type:"tuple"}],name:"FeeConfigurationUpdated",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"previousOwner",type:"address"},{indexed:!0,internalType:"address",name:"newOwner",type:"address"}],name:"OwnershipTransferred",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"account",type:"address"}],name:"Paused",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"uint64",name:"nonce",type:"uint64"},{indexed:!1,internalType:"address",name:"burnToken",type:"address"},{indexed:!1,internalType:"uint256",name:"amount",type:"uint256"},{indexed:!1,internalType:"address",name:"depositor",type:"address"},{indexed:!1,internalType:"address",name:"mintRecipient",type:"address"},{indexed:!1,internalType:"uint32",name:"destinationDomain",type:"uint32"},{indexed:!1,internalType:"uint256",name:"totalFee",type:"uint256"}],name:"TransferTokens",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"account",type:"address"}],name:"Unpaused",type:"event"},{inputs:[{internalType:"address",name:"account",type:"address"}],name:"addAdmin",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"feeCollector",type:"address"}],name:"addFeeCollector",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"token",type:"address"}],name:"addSupportedBurnToken",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"uint256",name:"amount",type:"uint256"},{internalType:"uint32",name:"destinationDomain",type:"uint32"}],name:"calculateFee",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[],name:"circleTokenMessenger",outputs:[{internalType:"contract ICircleTokenMessenger",name:"",type:"address"}],stateMutability:"view",type:"function"},{inputs:[],name:"circleTokenMessengerAddress",outputs:[{internalType:"address",name:"",type:"address"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"token",type:"address"}],name:"collectFees",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"token",type:"address"}],name:"getFeeAmounts",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"}],name:"getFeeConfiguration",outputs:[{components:[{internalType:"uint256",name:"maxFee",type:"uint256"},{internalType:"uint256",name:"minFee",type:"uint256"},{internalType:"uint32",name:"feePercentage",type:"uint32"},{internalType:"uint256",name:"txnFee",type:"uint256"},{internalType:"bool",name:"supported",type:"bool"}],internalType:"struct FeeCalculator.FeeConfiguration",name:"",type:"tuple"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"}],name:"getFeePercentage",outputs:[{internalType:"uint32",name:"",type:"uint32"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"}],name:"getMaxFee",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"}],name:"getMinFee",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"}],name:"getTxnFee",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"account",type:"address"}],name:"isAdmin",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"account",type:"address"}],name:"isFeeCollector",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"token",type:"address"}],name:"isSupportedBurnToken",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"}],name:"isSupportedDomain",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[],name:"owner",outputs:[{internalType:"address",name:"",type:"address"}],stateMutability:"view",type:"function"},{inputs:[],name:"pause",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[],name:"paused",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"account",type:"address"}],name:"removeAdmin",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"feeCollector",type:"address"}],name:"removeFeeCollector",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"token",type:"address"}],name:"removeSupportedBurnToken",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[],name:"renounceOwnership",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"},{components:[{internalType:"uint256",name:"maxFee",type:"uint256"},{internalType:"uint256",name:"minFee",type:"uint256"},{internalType:"uint32",name:"feePercentage",type:"uint32"},{internalType:"uint256",name:"txnFee",type:"uint256"},{internalType:"bool",name:"supported",type:"bool"}],internalType:"struct FeeCalculator.FeeConfiguration",name:"feeConfiguration",type:"tuple"}],name:"setFeeConfiguration",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"",type:"address"}],name:"supportedBurnTokens",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"newOwner",type:"address"}],name:"transferOwnership",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"uint256",name:"amount",type:"uint256"},{internalType:"uint32",name:"destinationDomain",type:"uint32"},{internalType:"address",name:"mintRecipient",type:"address"},{internalType:"address",name:"burnToken",type:"address"}],name:"transferTokens",outputs:[{internalType:"uint64",name:"nonce",type:"uint64"}],stateMutability:"nonpayable",type:"function"},{inputs:[],name:"unpause",outputs:[],stateMutability:"nonpayable",type:"function"}];var _=({sourceChain:e,targetChain:t,amount:r,asset:a},p)=>{if(e.chainId===t.chainId)throw new T("IDENTICAL_CHAINS_PROVIDED");if(r<=0n)throw new T("INCORRECT_AMOUNT_PROVIDED","Amount must be greater than zero");let n=p.find(i=>i.chainId===e.chainId);if(!n)throw new T("CHAIN_NOT_SUPPORTED",`Not supported on source chain "${e.chainId}"`);let o=p.find(i=>i.chainId===t.chainId);if(!o)throw new T("CHAIN_NOT_SUPPORTED",`Not supported on target chain "${t.chainId}"`);let d=n.tokens.find(i=>i.symbol===a.symbol),y=o.tokens.find(i=>i.symbol===a.symbol);if(!d||!y)throw new T("ASSET_NOT_SUPPORTED");return {sourceChainData:n,targetChainData:o,burnToken:d,mintToken:y}};async function W(e,t){await e.ensureHasConfig();let{sourceChain:r,targetChain:a,asset:p,amount:n,provider:o}=t,{sourceChainData:d,targetChainData:y,burnToken:i}=_({sourceChain:r,targetChain:a,asset:p,amount:n},e.config),u=await I({chain:r,provider:o}).readContract({address:d.tokenRouterAddress,abi:x,functionName:"calculateFee",args:[n,y.domain]});return {[i.address]:u}}var D=[{constant:!0,inputs:[],name:"name",outputs:[{name:"",type:"string"}],payable:!1,stateMutability:"view",type:"function"},{constant:!1,inputs:[{name:"_spender",type:"address"},{name:"_value",type:"uint256"}],name:"approve",outputs:[{name:"",type:"bool"}],payable:!1,stateMutability:"nonpayable",type:"function"},{constant:!0,inputs:[],name:"totalSupply",outputs:[{name:"",type:"uint256"}],payable:!1,stateMutability:"view",type:"function"},{constant:!1,inputs:[{name:"_from",type:"address"},{name:"_to",type:"address"},{name:"_value",type:"uint256"}],name:"transferFrom",outputs:[{name:"",type:"bool"}],payable:!1,stateMutability:"nonpayable",type:"function"},{constant:!0,inputs:[],name:"decimals",outputs:[{name:"",type:"uint8"}],payable:!1,stateMutability:"view",type:"function"},{constant:!0,inputs:[{name:"_owner",type:"address"}],name:"balanceOf",outputs:[{name:"balance",type:"uint256"}],payable:!1,stateMutability:"view",type:"function"},{constant:!0,inputs:[],name:"symbol",outputs:[{name:"",type:"string"}],payable:!1,stateMutability:"view",type:"function"},{constant:!1,inputs:[{name:"_to",type:"address"},{name:"_value",type:"uint256"}],name:"transfer",outputs:[{name:"",type:"bool"}],payable:!1,stateMutability:"nonpayable",type:"function"},{constant:!0,inputs:[{name:"_owner",type:"address"},{name:"_spender",type:"address"}],name:"allowance",outputs:[{name:"",type:"uint256"}],payable:!1,stateMutability:"view",type:"function"},{payable:!0,stateMutability:"payable",type:"fallback"},{anonymous:!1,inputs:[{indexed:!0,name:"owner",type:"address"},{indexed:!0,name:"spender",type:"address"},{indexed:!1,name:"value",type:"uint256"}],name:"Approval",type:"event"},{anonymous:!1,inputs:[{indexed:!0,name:"from",type:"address"},{indexed:!0,name:"to",type:"address"},{indexed:!1,name:"value",type:"uint256"}],name:"Transfer",type:"event"}];var ye=async(e,t)=>{let{sourceChain:r,targetChain:a,asset:p,amount:n,fromAddress:o,toAddress:d,sourceProvider:y,onStepChange:i,sign:s}=t,u=d??o;if(!isAddress(o)||!isAddress(u))throw new T("INCORRECT_ADDRESS_PROVIDED");let{sourceChainData:c,targetChainData:f,burnToken:l}=_({sourceChain:r,targetChain:a,asset:p,amount:n},e.config),m=I({chain:r,provider:y}),b=await m.readContract({address:l.address,abi:D,functionName:"allowance",args:[o,c.tokenRouterAddress]})<n,h=b?2:1;if(b)if(i?.({currentSignature:1,currentSignatureReason:"allowance-approval",requiredSignatures:h}),s){let g=encodeFunctionData({abi:D,functionName:"approve",args:[c.tokenRouterAddress,n]}),A=await s({from:o,to:l.address,data:g},k=>m.sendRawTransaction({serializedTransaction:k}));await m.waitForTransactionReceipt({hash:A,pollingInterval:1e3});}else {let{request:g}=await m.simulateContract({account:o,address:l.address,abi:D,functionName:"approve",args:[c.tokenRouterAddress,n]}),A=await m.writeContract(g);await m.waitForTransactionReceipt({hash:A,pollingInterval:1e3});}if(i?.({currentSignature:b?2:1,currentSignatureReason:"tokens-transfer",requiredSignatures:h}),s){let g=encodeFunctionData({abi:x,functionName:"transferTokens",args:[n,f.domain,u,l.address]});return s({from:o,to:c.tokenRouterAddress,data:g},A=>m.sendRawTransaction({serializedTransaction:A}))}else {let{request:g}=await m.simulateContract({account:o,address:c.tokenRouterAddress,abi:x,functionName:"transferTokens",args:[n,f.domain,u,l.address]});return m.writeContract(g)}},fe=async e=>{try{return await e.getBlockNumber()}catch{return}};async function J(e,t,r){await e.ensureHasConfig();let{minimumConfirmations:a}=e.config.find(u=>u.chainId===t.sourceChain.chainId)??{},{minimumConfirmations:p}=e.config.find(u=>u.chainId===t.targetChain.chainId)??{};if(!a||!p)throw new T("CONFIRMATION_COUNT_UNKNOWN");let n=await e.getFees({...t,provider:t.sourceProvider}),o=(t.asset.address&&n[t.asset.address])??0n,d=await ye(e,t),y=Date.now(),i=I({chain:t.targetChain,provider:t.targetProvider}),s=await fe(i);return {type:e.type,environment:r,fromAddress:t.fromAddress,toAddress:t.toAddress??t.fromAddress,amount:t.amount,amountDecimals:t.asset.decimals,symbol:t.asset.symbol,bridgeFee:o,sourceChain:t.sourceChain,sourceStartedAt:y,sourceTxHash:d,sourceConfirmationCount:0,requiredSourceConfirmationCount:a,targetChain:t.targetChain,targetConfirmationCount:0,requiredTargetConfirmationCount:p,startBlockNumber:s}}async function Z(e){if(!e.config&&(await e.updateConfig(),!e.config))throw new B("CONFIG_NOT_AVAILABLE")}var O=(e,t)=>e.gasPrice&&BigInt(e.gasPrice*t.gasUsed);var L=async e=>new Promise(t=>{setTimeout(t,e);});var U=({promise:e,delay:t,startAfter:r})=>{let a=!1,p=!1,n=0,o,d,y=u=>{o&&a&&(a=!1,o(u));},i=()=>{p=!0,d&&a&&(a=!1,d("cancelled"));};return {result:new Promise((u,c)=>{a=!0,o=u,d=c;let f=async()=>{if(!(!a||p)){try{if(await e(y),!a||p)return;await L(t);}catch(l){console.error(l.message),n+=1,await L(2**n*t);}await f();}};r?setTimeout(f,r):f();}),cancel:i}};var Q=1e3*60*60*3,Y=1024n,ee=5e3,C=(e,t,r)=>{Object.assign(e,Object.fromEntries(Object.entries(t).filter(([,a])=>a!==void 0))),r({...e});},Te=async(e,t)=>{let{sourceProvider:r,targetProvider:a,updateListener:p,bridgeTransfer:n}=t,o=I({chain:n.sourceChain,provider:r}),d=e.find(c=>c.chainId===n.sourceChain.chainId),y=I({chain:n.targetChain,provider:a}),i=e.find(c=>c.chainId===n.targetChain.chainId),s={...n};if(!d||!i)throw new T("CHAIN_NOT_SUPPORTED");return U({promise:async c=>{if(s.completedAt||s.metadata?.nonce)return c(s);if(s.sourceStartedAt+Q<=Date.now())return C(s,{completedAt:Date.now(),errorCode:5004},p),c(s);let f=await o.getTransactionReceipt({hash:s.sourceTxHash});if(!s.sourceNetworkFee){let A=await o.getTransaction({hash:s.sourceTxHash}),k=O(A,f);k&&C(s,{sourceNetworkFee:k},p);}if(f.status==="reverted")return C(s,{completedAt:Date.now(),errorCode:5005},p),c(s);let l=await o.getTransactionConfirmations({hash:s.sourceTxHash}),m=l>s.sourceConfirmationCount,v=l>=s.requiredSourceConfirmationCount;if(m){let A={};A.sourceConfirmationCount=Number(l),v||(A.startBlockNumber=await y.getBlockNumber()),C(s,A,p);}if(!v)return;s.startBlockNumber||C(s,{startBlockNumber:await y.getBlockNumber()},p);let b=f.logs.find(A=>A.address===d.tokenRouterAddress?decodeEventLog({abi:x,...A}).eventName==="TransferTokens":!1);if(!b)throw new T("INVALID_PARAMS",`unable to find a TransferTokens event in source transaction "${s.sourceTxHash}"`);let g=decodeEventLog({abi:x,eventName:"TransferTokens",...b}).args.nonce;return C(s,{targetStartedAt:Date.now(),metadata:{nonce:g}},p),c(s)},delay:M(d.chainId),startAfter:ee})},ge=async(e,t)=>{let{targetProvider:r,updateListener:a,bridgeTransfer:p}=t,n={...p};if(!p.completedAt&&!p.metadata?.nonce)throw new T("INVALID_PARAMS","nonce is missing");if(!p.startBlockNumber)throw new T("INVALID_PARAMS","startBlockNumber is missing");let o=I({chain:p.targetChain,provider:r}),d=e.find(i=>i.chainId===p.targetChain.chainId);if(!d)throw new T("INVALID_PARAMS",`unknown target chain "${p.targetChain.chainId}"`);return U({promise:async i=>{if(n.completedAt)return i(n);if(!n.startBlockNumber)return C(n,{completedAt:Date.now(),errorCode:5003},a),i(n);if(n.sourceStartedAt+Q<=Date.now())return C(n,{completedAt:Date.now(),errorCode:5004},a),i(n);if(!n.targetTxHash){let l=await o.getBlockNumber(),m=n.startBlockNumber-Y,v=m>=0n?m:"earliest",b=n.startBlockNumber+Y,h=b<l?b:"latest",g=await o.getLogs({address:d.messageTransmitterAddress,event:{name:"MessageReceived",type:"event",inputs:[{indexed:!0,internalType:"address",name:"caller",type:"address"},{indexed:!1,internalType:"uint32",name:"sourceDomain",type:"uint32"},{indexed:!0,internalType:"uint64",name:"nonce",type:"uint64"},{indexed:!1,internalType:"bytes32",name:"sender",type:"bytes32"},{indexed:!1,internalType:"bytes",name:"messageBody",type:"bytes"}]},args:{nonce:n.metadata.nonce},fromBlock:v,toBlock:h});if(g[0]?.transactionHash)C(n,{targetTxHash:g[0].transactionHash},a);else {C(n,{startBlockNumber:l},a);return}}let s=await o.getTransactionReceipt({hash:n.targetTxHash});if(!n.targetNetworkFee){let l=await o.getTransaction({hash:n.targetTxHash}),m=O(l,s);m&&C(n,{targetNetworkFee:m},a);}if(s.status==="reverted")return C(n,{completedAt:Date.now(),errorCode:5005},a),i(n);let u=await o.getTransactionConfirmations({hash:n.targetTxHash}),c=u>n.targetConfirmationCount,f=u>=n.requiredTargetConfirmationCount;if(c&&C(n,{targetConfirmationCount:Number(u)},a),!!f)return C(n,{completedAt:Date.now()},a),i(n)},delay:M(d.chainId),startAfter:ee})};function te(e,t){let r,a=()=>{r?.();};return {result:(async()=>{await e.ensureHasConfig();let{sourceProvider:n,targetProvider:o,updateListener:d,bridgeTransfer:y}=t,{result:i,cancel:s}=await Te(e.config,{sourceProvider:n,targetProvider:o,updateListener:d,bridgeTransfer:y});r=s;let u=await i,{result:c,cancel:f}=await ge(e.config,{sourceProvider:n,targetProvider:o,updateListener:d,bridgeTransfer:u});return r=f,c})(),cancel:a}}var ne=e=>({type:"cctp",config:null,updateConfig:async function(){this.config=await q(e);},ensureHasConfig:async function(){return Z(this)},getAssets:async function(){return $(this)},getFees:async function(t){return W(this,t)},transferAsset:async function(t){return J(this,t,e)},trackTransfer:function(t){return te(this,t)}});var Ae=new Map([["cctp",ne]]),re=(e,t)=>new Map([...Ae].filter(([r])=>!t?.includes(r)).map(([r,a])=>[r,a(e)])),F=(e,t,r)=>{let a=t.destinations[r]?.find(p=>e.has(p));if(!a)throw new P;return {type:a,bridge:e.get(a)}};var dn=({environment:e,disabledBridgeTypes:t})=>{let r=re(e,t),a=async()=>{await Promise.allSettled(Array.from(r).map(([,s])=>s.updateConfig()));};return {environment:e,bridges:r,init:async()=>{await a();},updateConfigs:a,getAssets:async()=>(await Promise.all(Array.from(r).map(([,u])=>u.getAssets()))).reduce((u,c)=>{for(let[f,l]of Object.entries(c)){let m=u[f];if(m)for(let v of l){let b=m.findIndex(({symbol:h})=>h===v.symbol);b===-1?m.push(v):mergeWith(m[b],v,(h,g)=>{if(isArray(h))return [...new Set(h.concat(g))]});}else u[f]=l;}return u},{}),getFees:async s=>{let{bridge:u}=F(r,s.asset,s.targetChain.chainId);return u.getFees(s)},canTransferAsset:(s,u)=>{try{return F(r,s,u),!0}catch{return !1}},transferAsset:async s=>{let{bridge:u}=F(r,s.asset,s.targetChain.chainId);return u.transferAsset(s)},trackTransfer:s=>{let u=r.get(s.bridgeTransfer.type);if(!u)throw new P;return u.trackTransfer(s)}}};
|
|
4
|
+
var H=(r=>(r.NATIVE="native",r.ERC20="erc20",r))(H||{});var E=(t=>(t.CCTP="cctp",t))(E||{}),V=(r=>(r.AllowanceApproval="allowance-approval",r.TokensTransfer="tokens-transfer",r))(V||{});var K=(r=>(r.PROD="production",r.TEST="test",r))(K||{});var R=(n=>(n[n.BRIDGE_NOT_AVAILABLE=5001]="BRIDGE_NOT_AVAILABLE",n[n.INITIALIZATION_FAILED=5002]="INITIALIZATION_FAILED",n[n.INVALID_PARAMS=5003]="INVALID_PARAMS",n[n.TIMEOUT=5004]="TIMEOUT",n[n.TRANSACTION_REVERTED=5005]="TRANSACTION_REVERTED",n))(R||{}),v=(i=>(i.UNKNOWN="UNKNOWN",i.CONFIG_NOT_AVAILABLE="CONFIG_NOT_AVAILABLE",i.INVALID_PARAMS="INVALID_PARAMS",i.IDENTICAL_CHAINS_PROVIDED="IDENTICAL_CHAINS_PROVIDED",i.INCORRECT_AMOUNT_PROVIDED="INCORRECT_AMOUNT_PROVIDED",i.INCORRECT_ADDRESS_PROVIDED="INCORRECT_ADDRESS_PROVIDED",i.CHAIN_NOT_SUPPORTED="CHAIN_NOT_SUPPORTED",i.ASSET_NOT_SUPPORTED="ASSET_NOT_SUPPORTED",i.CONFIRMATION_COUNT_UNKNOWN="CONFIRMATION_COUNT_UNKNOWN",i))(v||{});var N=class extends Error{constructor(r,a,p){super(r);this.code=a;this.details=p;}};var P=class extends N{constructor(t="UNKNOWN",r){super(t,5001,r),this.name="BridgeUnavailableError";}};var B=class extends N{constructor(t="UNKNOWN",r){super(t,5002,r),this.name="BridgeInitializationError";}};var T=class extends N{constructor(t="INVALID_PARAMS",r){super(t,5003,r),this.name="InvalidParamsError";}};var ae={test:"https://raw.githubusercontent.com/ava-labs/avalanche-bridge-resources/main/cctp/cctp_config.test.json",production:"https://raw.githubusercontent.com/ava-labs/avalanche-bridge-resources/main/cctp/cctp_config.json"},q=async e=>{try{return (await(await fetch(ae[e])).json()).map(a=>({...a,chainId:`eip155:${a.chainId}`}))}catch(t){throw new B("CONFIG_NOT_AVAILABLE",`Error while fetching CCTP config: ${t.message}`)}},M=e=>{switch(e){case"eip155:43114":case"eip155:43113":return 1e3;default:return 2e4}};async function $(e){await e.ensureHasConfig();let t=e.config.map(r=>r.chainId);return e.config.reduce((r,a)=>(r[a.chainId]=a.tokens.map(p=>({...p,type:"erc20",destinations:t.reduce((n,o)=>(a.chainId!==o&&(n[o]||(n[o]=[]),n[o]?.push("cctp")),n),{})})),r),{})}var se="^[-a-z0-9]{3,8}$",ie="^[-_a-zA-Z0-9]{1,50}$",G=":",oe=e=>{let[t,r]=e.split(G);if(!t||!r)throw new Error("Invalid identifier provided.");if(!new RegExp(se).test(t))throw new Error("Invalid namespace provided.");if(!new RegExp(ie).test(r))throw new Error("Invalid reference provided.");return {namespace:t,reference:r}},pe=({namespace:e,reference:t})=>`${e}${G}${t}`,S={toJSON:oe,toString:pe};var le=e=>{let{reference:t}=S.toJSON(e.chainId);return {id:Number(t),name:e.chainName,nativeCurrency:{decimals:e.networkToken.decimals,symbol:e.networkToken.symbol,name:e.networkToken.name},network:e.chainName,rpcUrls:{default:{http:[e.rpcUrl]},public:{http:[e.rpcUrl]}},...e.utilityAddresses?.multicall&&{contracts:{multicall3:{address:e.utilityAddresses.multicall}}}}},I=({chain:e,provider:t})=>{let r=le(e),a=t?custom(t):http(e.rpcUrl,{batch:!0,retryCount:0});return createWalletClient({chain:r,transport:a}).extend(publicActions)};var x=[{inputs:[{internalType:"address",name:"circleTokenMessenger_",type:"address"},{internalType:"address",name:"burnToken_",type:"address"}],stateMutability:"nonpayable",type:"constructor"},{inputs:[],name:"AlreadyAdmin",type:"error"},{inputs:[],name:"AlreadyFeeCollector",type:"error"},{inputs:[],name:"AlreadySupportedBurnToken",type:"error"},{inputs:[],name:"AmountLessThanFee",type:"error"},{inputs:[],name:"BalanceNotIncreased",type:"error"},{inputs:[],name:"CannotRemoveLastAdmin",type:"error"},{inputs:[],name:"FeePercentageGreaterThanMax",type:"error"},{inputs:[],name:"InvalidAdminAddress",type:"error"},{inputs:[],name:"InvalidFeeCollector",type:"error"},{inputs:[],name:"InvalidMintRecipientAddress",type:"error"},{inputs:[],name:"InvalidTokenAddress",type:"error"},{inputs:[],name:"InvalidTokenMessengerAddress",type:"error"},{inputs:[],name:"MaxFeeLessThanMinFee",type:"error"},{inputs:[],name:"NotAdmin",type:"error"},{inputs:[],name:"NotFeeCollector",type:"error"},{inputs:[],name:"UnSupportedBurnToken",type:"error"},{inputs:[],name:"UnsupportedDomain",type:"error"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"admin",type:"address"}],name:"AdminAdded",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"admin",type:"address"}],name:"AdminRemoved",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"token",type:"address"}],name:"BurnTokenAdded",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"token",type:"address"}],name:"BurnTokenRemoved",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"feeCollector",type:"address"}],name:"FeeCollectorAdded",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"feeCollector",type:"address"}],name:"FeeCollectorRemoved",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"uint32",name:"domain",type:"uint32"},{components:[{internalType:"uint256",name:"maxFee",type:"uint256"},{internalType:"uint256",name:"minFee",type:"uint256"},{internalType:"uint32",name:"feePercentage",type:"uint32"},{internalType:"uint256",name:"txnFee",type:"uint256"},{internalType:"bool",name:"supported",type:"bool"}],indexed:!1,internalType:"struct FeeCalculator.FeeConfiguration",name:"feeConfiguration",type:"tuple"}],name:"FeeConfigurationUpdated",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"previousOwner",type:"address"},{indexed:!0,internalType:"address",name:"newOwner",type:"address"}],name:"OwnershipTransferred",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"account",type:"address"}],name:"Paused",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"uint64",name:"nonce",type:"uint64"},{indexed:!1,internalType:"address",name:"burnToken",type:"address"},{indexed:!1,internalType:"uint256",name:"amount",type:"uint256"},{indexed:!1,internalType:"address",name:"depositor",type:"address"},{indexed:!1,internalType:"address",name:"mintRecipient",type:"address"},{indexed:!1,internalType:"uint32",name:"destinationDomain",type:"uint32"},{indexed:!1,internalType:"uint256",name:"totalFee",type:"uint256"}],name:"TransferTokens",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"account",type:"address"}],name:"Unpaused",type:"event"},{inputs:[{internalType:"address",name:"account",type:"address"}],name:"addAdmin",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"feeCollector",type:"address"}],name:"addFeeCollector",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"token",type:"address"}],name:"addSupportedBurnToken",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"uint256",name:"amount",type:"uint256"},{internalType:"uint32",name:"destinationDomain",type:"uint32"}],name:"calculateFee",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[],name:"circleTokenMessenger",outputs:[{internalType:"contract ICircleTokenMessenger",name:"",type:"address"}],stateMutability:"view",type:"function"},{inputs:[],name:"circleTokenMessengerAddress",outputs:[{internalType:"address",name:"",type:"address"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"token",type:"address"}],name:"collectFees",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"token",type:"address"}],name:"getFeeAmounts",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"}],name:"getFeeConfiguration",outputs:[{components:[{internalType:"uint256",name:"maxFee",type:"uint256"},{internalType:"uint256",name:"minFee",type:"uint256"},{internalType:"uint32",name:"feePercentage",type:"uint32"},{internalType:"uint256",name:"txnFee",type:"uint256"},{internalType:"bool",name:"supported",type:"bool"}],internalType:"struct FeeCalculator.FeeConfiguration",name:"",type:"tuple"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"}],name:"getFeePercentage",outputs:[{internalType:"uint32",name:"",type:"uint32"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"}],name:"getMaxFee",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"}],name:"getMinFee",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"}],name:"getTxnFee",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"account",type:"address"}],name:"isAdmin",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"account",type:"address"}],name:"isFeeCollector",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"token",type:"address"}],name:"isSupportedBurnToken",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"}],name:"isSupportedDomain",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[],name:"owner",outputs:[{internalType:"address",name:"",type:"address"}],stateMutability:"view",type:"function"},{inputs:[],name:"pause",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[],name:"paused",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"account",type:"address"}],name:"removeAdmin",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"feeCollector",type:"address"}],name:"removeFeeCollector",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"token",type:"address"}],name:"removeSupportedBurnToken",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[],name:"renounceOwnership",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"},{components:[{internalType:"uint256",name:"maxFee",type:"uint256"},{internalType:"uint256",name:"minFee",type:"uint256"},{internalType:"uint32",name:"feePercentage",type:"uint32"},{internalType:"uint256",name:"txnFee",type:"uint256"},{internalType:"bool",name:"supported",type:"bool"}],internalType:"struct FeeCalculator.FeeConfiguration",name:"feeConfiguration",type:"tuple"}],name:"setFeeConfiguration",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"",type:"address"}],name:"supportedBurnTokens",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"newOwner",type:"address"}],name:"transferOwnership",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"uint256",name:"amount",type:"uint256"},{internalType:"uint32",name:"destinationDomain",type:"uint32"},{internalType:"address",name:"mintRecipient",type:"address"},{internalType:"address",name:"burnToken",type:"address"}],name:"transferTokens",outputs:[{internalType:"uint64",name:"nonce",type:"uint64"}],stateMutability:"nonpayable",type:"function"},{inputs:[],name:"unpause",outputs:[],stateMutability:"nonpayable",type:"function"}];var _=({sourceChain:e,targetChain:t,amount:r,asset:a},p)=>{if(e.chainId===t.chainId)throw new T("IDENTICAL_CHAINS_PROVIDED");if(r<=0n)throw new T("INCORRECT_AMOUNT_PROVIDED","Amount must be greater than zero");let n=p.find(i=>i.chainId===e.chainId);if(!n)throw new T("CHAIN_NOT_SUPPORTED",`Not supported on source chain "${e.chainId}"`);let o=p.find(i=>i.chainId===t.chainId);if(!o)throw new T("CHAIN_NOT_SUPPORTED",`Not supported on target chain "${t.chainId}"`);let d=n.tokens.find(i=>i.symbol===a.symbol),y=o.tokens.find(i=>i.symbol===a.symbol);if(!d||!y)throw new T("ASSET_NOT_SUPPORTED");return {sourceChainData:n,targetChainData:o,burnToken:d,mintToken:y}};async function W(e,t){await e.ensureHasConfig();let{sourceChain:r,targetChain:a,asset:p,amount:n,provider:o}=t,{sourceChainData:d,targetChainData:y,burnToken:i}=_({sourceChain:r,targetChain:a,asset:p,amount:n},e.config),u=await I({chain:r,provider:o}).readContract({address:d.tokenRouterAddress,abi:x,functionName:"calculateFee",args:[n,y.domain]});return {[i.address]:u}}var D=[{constant:!0,inputs:[],name:"name",outputs:[{name:"",type:"string"}],payable:!1,stateMutability:"view",type:"function"},{constant:!1,inputs:[{name:"_spender",type:"address"},{name:"_value",type:"uint256"}],name:"approve",outputs:[{name:"",type:"bool"}],payable:!1,stateMutability:"nonpayable",type:"function"},{constant:!0,inputs:[],name:"totalSupply",outputs:[{name:"",type:"uint256"}],payable:!1,stateMutability:"view",type:"function"},{constant:!1,inputs:[{name:"_from",type:"address"},{name:"_to",type:"address"},{name:"_value",type:"uint256"}],name:"transferFrom",outputs:[{name:"",type:"bool"}],payable:!1,stateMutability:"nonpayable",type:"function"},{constant:!0,inputs:[],name:"decimals",outputs:[{name:"",type:"uint8"}],payable:!1,stateMutability:"view",type:"function"},{constant:!0,inputs:[{name:"_owner",type:"address"}],name:"balanceOf",outputs:[{name:"balance",type:"uint256"}],payable:!1,stateMutability:"view",type:"function"},{constant:!0,inputs:[],name:"symbol",outputs:[{name:"",type:"string"}],payable:!1,stateMutability:"view",type:"function"},{constant:!1,inputs:[{name:"_to",type:"address"},{name:"_value",type:"uint256"}],name:"transfer",outputs:[{name:"",type:"bool"}],payable:!1,stateMutability:"nonpayable",type:"function"},{constant:!0,inputs:[{name:"_owner",type:"address"},{name:"_spender",type:"address"}],name:"allowance",outputs:[{name:"",type:"uint256"}],payable:!1,stateMutability:"view",type:"function"},{payable:!0,stateMutability:"payable",type:"fallback"},{anonymous:!1,inputs:[{indexed:!0,name:"owner",type:"address"},{indexed:!0,name:"spender",type:"address"},{indexed:!1,name:"value",type:"uint256"}],name:"Approval",type:"event"},{anonymous:!1,inputs:[{indexed:!0,name:"from",type:"address"},{indexed:!0,name:"to",type:"address"},{indexed:!1,name:"value",type:"uint256"}],name:"Transfer",type:"event"}];var ye=async(e,t)=>{let{sourceChain:r,targetChain:a,asset:p,amount:n,fromAddress:o,toAddress:d,sourceProvider:y,onStepChange:i,sign:s}=t,u=d??o;if(!isAddress(o)||!isAddress(u))throw new T("INCORRECT_ADDRESS_PROVIDED");let{sourceChainData:c,targetChainData:f,burnToken:l}=_({sourceChain:r,targetChain:a,asset:p,amount:n},e.config),m=I({chain:r,provider:y}),b=await m.readContract({address:l.address,abi:D,functionName:"allowance",args:[o,c.tokenRouterAddress]})<n,h=b?2:1;if(b)if(i?.({currentSignature:1,currentSignatureReason:"allowance-approval",requiredSignatures:h}),s){let g=encodeFunctionData({abi:D,functionName:"approve",args:[c.tokenRouterAddress,n]}),A=await s({from:o,to:l.address,data:g},k=>m.sendRawTransaction({serializedTransaction:k}));await m.waitForTransactionReceipt({hash:A,pollingInterval:1e3});}else {let{request:g}=await m.simulateContract({account:o,address:l.address,abi:D,functionName:"approve",args:[c.tokenRouterAddress,n]}),A=await m.writeContract(g);await m.waitForTransactionReceipt({hash:A,pollingInterval:1e3});}if(i?.({currentSignature:b?2:1,currentSignatureReason:"tokens-transfer",requiredSignatures:h}),s){let g=encodeFunctionData({abi:x,functionName:"transferTokens",args:[n,f.domain,u,l.address]});return s({from:o,to:c.tokenRouterAddress,data:g},A=>m.sendRawTransaction({serializedTransaction:A}))}else {let{request:g}=await m.simulateContract({account:o,address:c.tokenRouterAddress,abi:x,functionName:"transferTokens",args:[n,f.domain,u,l.address]});return m.writeContract(g)}},fe=async e=>{try{return await e.getBlockNumber()}catch{return}};async function J(e,t,r){await e.ensureHasConfig();let{minimumConfirmations:a}=e.config.find(u=>u.chainId===t.sourceChain.chainId)??{},{minimumConfirmations:p}=e.config.find(u=>u.chainId===t.targetChain.chainId)??{};if(!a||!p)throw new T("CONFIRMATION_COUNT_UNKNOWN");let n=await e.getFees({...t,provider:t.sourceProvider}),o=(t.asset.address&&n[t.asset.address])??0n,d=await ye(e,t),y=Date.now(),i=I({chain:t.targetChain,provider:t.targetProvider}),s=await fe(i);return {type:e.type,environment:r,fromAddress:t.fromAddress,toAddress:t.toAddress??t.fromAddress,amount:t.amount,amountDecimals:t.asset.decimals,symbol:t.asset.symbol,bridgeFee:o,sourceChain:t.sourceChain,sourceStartedAt:y,sourceTxHash:d,sourceConfirmationCount:0,requiredSourceConfirmationCount:a,targetChain:t.targetChain,targetConfirmationCount:0,requiredTargetConfirmationCount:p,startBlockNumber:s}}async function Z(e){if(!e.config&&(await e.updateConfig(),!e.config))throw new B("CONFIG_NOT_AVAILABLE")}var O=(e,t)=>e.gasPrice&&BigInt(e.gasPrice*t.gasUsed);var L=async e=>new Promise(t=>{setTimeout(t,e);});var U=({promise:e,delay:t,startAfter:r})=>{let a=!1,p=!1,n=0,o,d,y=u=>{o&&a&&(a=!1,o(u));},i=()=>{p=!0,d&&a&&(a=!1,d("cancelled"));};return {result:new Promise((u,c)=>{a=!0,o=u,d=c;let f=async()=>{if(!(!a||p)){try{if(await e(y),!a||p)return;await L(t);}catch(l){console.error(l.message),n+=1,await L(2**n*t);}await f();}};r?setTimeout(f,r):f();}),cancel:i}};var Q=1e3*60*60*3,Y=1024n,ee=5e3,C=(e,t,r)=>{Object.assign(e,Object.fromEntries(Object.entries(t).filter(([,a])=>a!==void 0))),r({...e});},Te=async(e,t)=>{let{sourceProvider:r,targetProvider:a,updateListener:p,bridgeTransfer:n}=t,o=I({chain:n.sourceChain,provider:r}),d=e.find(c=>c.chainId===n.sourceChain.chainId),y=I({chain:n.targetChain,provider:a}),i=e.find(c=>c.chainId===n.targetChain.chainId),s={...n};if(!d||!i)throw new T("CHAIN_NOT_SUPPORTED");return U({promise:async c=>{if(s.completedAt||s.metadata?.nonce)return c(s);if(s.sourceStartedAt+Q<=Date.now())return C(s,{completedAt:Date.now(),errorCode:5004},p),c(s);let f=await o.getTransactionReceipt({hash:s.sourceTxHash});if(!s.sourceNetworkFee){let A=await o.getTransaction({hash:s.sourceTxHash}),k=O(A,f);k&&C(s,{sourceNetworkFee:k},p);}if(f.status==="reverted")return C(s,{completedAt:Date.now(),errorCode:5005},p),c(s);let l=await o.getTransactionConfirmations({hash:s.sourceTxHash}),m=l>s.sourceConfirmationCount,w=l>=s.requiredSourceConfirmationCount;if(m){let A={};A.sourceConfirmationCount=Number(l),w||(A.startBlockNumber=await y.getBlockNumber()),C(s,A,p);}if(!w)return;s.startBlockNumber||C(s,{startBlockNumber:await y.getBlockNumber()},p);let b=f.logs.find(A=>A.address.toLowerCase()===d.tokenRouterAddress.toLowerCase()?decodeEventLog({abi:x,...A}).eventName==="TransferTokens":!1);if(!b)throw new T("INVALID_PARAMS",`unable to find a TransferTokens event in source transaction "${s.sourceTxHash}"`);let g=decodeEventLog({abi:x,eventName:"TransferTokens",...b}).args.nonce;return C(s,{targetStartedAt:Date.now(),metadata:{nonce:g}},p),c(s)},delay:M(d.chainId),startAfter:ee})},ge=async(e,t)=>{let{targetProvider:r,updateListener:a,bridgeTransfer:p}=t,n={...p};if(!p.completedAt&&!p.metadata?.nonce)throw new T("INVALID_PARAMS","nonce is missing");if(!p.startBlockNumber)throw new T("INVALID_PARAMS","startBlockNumber is missing");let o=I({chain:p.targetChain,provider:r}),d=e.find(i=>i.chainId===p.targetChain.chainId);if(!d)throw new T("INVALID_PARAMS",`unknown target chain "${p.targetChain.chainId}"`);return U({promise:async i=>{if(n.completedAt)return i(n);if(!n.startBlockNumber)return C(n,{completedAt:Date.now(),errorCode:5003},a),i(n);if(n.sourceStartedAt+Q<=Date.now())return C(n,{completedAt:Date.now(),errorCode:5004},a),i(n);if(!n.targetTxHash){let l=await o.getBlockNumber(),m=n.startBlockNumber-Y,w=m>=0n?m:"earliest",b=n.startBlockNumber+Y,h=b<l?b:"latest",g=await o.getLogs({address:d.messageTransmitterAddress,event:{name:"MessageReceived",type:"event",inputs:[{indexed:!0,internalType:"address",name:"caller",type:"address"},{indexed:!1,internalType:"uint32",name:"sourceDomain",type:"uint32"},{indexed:!0,internalType:"uint64",name:"nonce",type:"uint64"},{indexed:!1,internalType:"bytes32",name:"sender",type:"bytes32"},{indexed:!1,internalType:"bytes",name:"messageBody",type:"bytes"}]},args:{nonce:n.metadata.nonce},fromBlock:w,toBlock:h});if(g[0]?.transactionHash)C(n,{targetTxHash:g[0].transactionHash},a);else {C(n,{startBlockNumber:l},a);return}}let s=await o.getTransactionReceipt({hash:n.targetTxHash});if(!n.targetNetworkFee){let l=await o.getTransaction({hash:n.targetTxHash}),m=O(l,s);m&&C(n,{targetNetworkFee:m},a);}if(s.status==="reverted")return C(n,{completedAt:Date.now(),errorCode:5005},a),i(n);let u=await o.getTransactionConfirmations({hash:n.targetTxHash}),c=u>n.targetConfirmationCount,f=u>=n.requiredTargetConfirmationCount;if(c&&C(n,{targetConfirmationCount:Number(u)},a),!!f)return C(n,{completedAt:Date.now()},a),i(n)},delay:M(d.chainId),startAfter:ee})};function te(e,t){let r,a=()=>{r?.();};return {result:(async()=>{await e.ensureHasConfig();let{sourceProvider:n,targetProvider:o,updateListener:d,bridgeTransfer:y}=t,{result:i,cancel:s}=await Te(e.config,{sourceProvider:n,targetProvider:o,updateListener:d,bridgeTransfer:y});r=s;let u=await i,{result:c,cancel:f}=await ge(e.config,{sourceProvider:n,targetProvider:o,updateListener:d,bridgeTransfer:u});return r=f,c})(),cancel:a}}var ne=e=>({type:"cctp",config:null,updateConfig:async function(){this.config=await q(e);},ensureHasConfig:async function(){return Z(this)},getAssets:async function(){return $(this)},getFees:async function(t){return W(this,t)},transferAsset:async function(t){return J(this,t,e)},trackTransfer:function(t){return te(this,t)}});var Ae=new Map([["cctp",ne]]),re=(e,t)=>new Map([...Ae].filter(([r])=>!t?.includes(r)).map(([r,a])=>[r,a(e)])),F=(e,t,r)=>{let a=t.destinations[r]?.find(p=>e.has(p));if(!a)throw new P;return {type:a,bridge:e.get(a)}};var dn=({environment:e,disabledBridgeTypes:t})=>{let r=re(e,t),a=async()=>{await Promise.allSettled(Array.from(r).map(([,s])=>s.updateConfig()));};return {environment:e,bridges:r,init:async()=>{await a();},updateConfigs:a,getAssets:async()=>(await Promise.all(Array.from(r).map(([,u])=>u.getAssets()))).reduce((u,c)=>{for(let[f,l]of Object.entries(c)){let m=u[f];if(m)for(let w of l){let b=m.findIndex(({symbol:h})=>h===w.symbol);b===-1?m.push(w):mergeWith(m[b],w,(h,g)=>{if(isArray(h))return [...new Set(h.concat(g))]});}else u[f]=l;}return u},{}),getFees:async s=>{let{bridge:u}=F(r,s.asset,s.targetChain.chainId);return u.getFees(s)},canTransferAsset:(s,u)=>{try{return F(r,s,u),!0}catch{return !1}},transferAsset:async s=>{let{bridge:u}=F(r,s.asset,s.targetChain.chainId);return u.transferAsset(s)},trackTransfer:s=>{let u=r.get(s.bridgeTransfer.type);if(!u)throw new P;return u.trackTransfer(s)}}};
|
|
5
5
|
|
|
6
|
-
export { V as BridgeSignatureReason, E as BridgeType, K as Environment, R as ErrorCode,
|
|
6
|
+
export { V as BridgeSignatureReason, E as BridgeType, K as Environment, R as ErrorCode, v as ErrorReason, H as TokenType, S as caip2, dn as createUnifiedBridgeService };
|
|
7
7
|
//# sourceMappingURL=out.js.map
|
|
8
8
|
//# sourceMappingURL=index.js.map
|