@avalabs/bridge-unified 2.1.1 → 3.0.0

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.
Files changed (77) hide show
  1. package/LICENSE +9 -0
  2. package/README.md +115 -31
  3. package/dist/index.cjs +36 -10
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.d.cts +252 -84
  6. package/dist/index.d.ts +252 -84
  7. package/dist/index.js +9 -4
  8. package/dist/index.js.map +1 -1
  9. package/package.json +14 -4
  10. package/.turbo/turbo-build.log +0 -22
  11. package/.turbo/turbo-lint.log +0 -4
  12. package/.turbo/turbo-test.log +0 -26
  13. package/CHANGELOG.md +0 -37
  14. package/jest.config.js +0 -9
  15. package/src/bridges/cctp/__mocks__/asset.mock.ts +0 -15
  16. package/src/bridges/cctp/__mocks__/bridge-transfer.mock.ts +0 -48
  17. package/src/bridges/cctp/__mocks__/chain.mocks.ts +0 -33
  18. package/src/bridges/cctp/__mocks__/config.mock.ts +0 -45
  19. package/src/bridges/cctp/abis/erc20.ts +0 -117
  20. package/src/bridges/cctp/abis/message-transmitter.ts +0 -318
  21. package/src/bridges/cctp/abis/token-router.ts +0 -843
  22. package/src/bridges/cctp/factory.test.ts +0 -73
  23. package/src/bridges/cctp/factory.ts +0 -36
  24. package/src/bridges/cctp/handlers/estimate-gas.test.ts +0 -110
  25. package/src/bridges/cctp/handlers/estimate-gas.ts +0 -58
  26. package/src/bridges/cctp/handlers/get-assets.test.ts +0 -47
  27. package/src/bridges/cctp/handlers/get-assets.ts +0 -27
  28. package/src/bridges/cctp/handlers/get-fees.test.ts +0 -61
  29. package/src/bridges/cctp/handlers/get-fees.ts +0 -26
  30. package/src/bridges/cctp/handlers/track-transfer.test.ts +0 -779
  31. package/src/bridges/cctp/handlers/track-transfer.ts +0 -365
  32. package/src/bridges/cctp/handlers/transfer-asset.test.ts +0 -429
  33. package/src/bridges/cctp/handlers/transfer-asset.ts +0 -179
  34. package/src/bridges/cctp/index.ts +0 -1
  35. package/src/bridges/cctp/types/chain.ts +0 -9
  36. package/src/bridges/cctp/types/config.ts +0 -20
  37. package/src/bridges/cctp/utils/build-tx.ts +0 -30
  38. package/src/bridges/cctp/utils/config.test.ts +0 -49
  39. package/src/bridges/cctp/utils/config.ts +0 -36
  40. package/src/bridges/cctp/utils/transfer-data.test.ts +0 -83
  41. package/src/bridges/cctp/utils/transfer-data.ts +0 -48
  42. package/src/errors/bridge-error.ts +0 -11
  43. package/src/errors/bridge-initialization-error.ts +0 -9
  44. package/src/errors/bridge-unavailable-error.ts +0 -9
  45. package/src/errors/index.ts +0 -4
  46. package/src/errors/invalid-params-error.ts +0 -9
  47. package/src/index.ts +0 -3
  48. package/src/types/asset.ts +0 -26
  49. package/src/types/bridge.ts +0 -64
  50. package/src/types/chain.ts +0 -10
  51. package/src/types/config.ts +0 -10
  52. package/src/types/environment.ts +0 -4
  53. package/src/types/error.ts +0 -19
  54. package/src/types/index.ts +0 -9
  55. package/src/types/provider.ts +0 -12
  56. package/src/types/signer.ts +0 -18
  57. package/src/types/transfer.ts +0 -35
  58. package/src/unified-bridge-service.test.ts +0 -209
  59. package/src/unified-bridge-service.ts +0 -97
  60. package/src/utils/bridge-types.test.ts +0 -103
  61. package/src/utils/bridge-types.ts +0 -32
  62. package/src/utils/caip2.test.ts +0 -44
  63. package/src/utils/caip2.ts +0 -41
  64. package/src/utils/client.test.ts +0 -97
  65. package/src/utils/client.ts +0 -44
  66. package/src/utils/ensure-config.test.ts +0 -43
  67. package/src/utils/ensure-config.ts +0 -12
  68. package/src/utils/index.ts +0 -2
  69. package/src/utils/network-fee.test.ts +0 -24
  70. package/src/utils/network-fee.ts +0 -6
  71. package/src/utils/retry-promise.test.ts +0 -115
  72. package/src/utils/retry-promise.ts +0 -72
  73. package/src/utils/wait.test.ts +0 -33
  74. package/src/utils/wait.ts +0 -4
  75. package/tsconfig.jest.json +0 -7
  76. package/tsconfig.json +0 -9
  77. package/tsup.config.ts +0 -4
@@ -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/bridges/cctp/utils/build-tx.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/handlers/estimate-gas.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","isAddress","ERC20_ABI","encodeFunctionData","buildTransferTxData","toAddress","buildApprovalTxData","approveAndTransfer","fromAddress","maybeToAddress","sourceProvider","onStepChange","sign","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","ETH_APPROVAL_TX_GAS_ESTIMATE","ETH_TRANSFER_TX_GAS_ESTIMATE","AVAX_APPROVAL_TX_GAS_ESTIMATE","AVAX_TRANSFER_TX_GAS_ESTIMATE","estimateGas","allowance","isOffboarding","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 estimateGas: (params: TransferParams) => Promise<bigint>;\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 { 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';\nimport { buildApprovalTxData, buildTransferTxData } from '../utils/build-tx';\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 = buildApprovalTxData({\n amount,\n sourceChainData,\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 = buildTransferTxData({\n amount,\n burnToken,\n targetChainData,\n toAddress,\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 { encodeFunctionData } from 'viem';\nimport type { ChainData, Token } from '../types/config';\nimport { TOKEN_ROUTER_ABI } from '../abis/token-router';\nimport { ERC20_ABI } from '../abis/erc20';\n\nexport function buildTransferTxData({\n amount,\n burnToken,\n targetChainData,\n toAddress,\n}: {\n targetChainData: ChainData;\n toAddress: `0x${string}`;\n burnToken: Token;\n amount: bigint;\n}) {\n return encodeFunctionData({\n abi: TOKEN_ROUTER_ABI,\n functionName: 'transferTokens',\n args: [amount, targetChainData.domain, toAddress, burnToken.address],\n });\n}\n\nexport function buildApprovalTxData({ amount, sourceChainData }: { amount: bigint; sourceChainData: ChainData }) {\n return encodeFunctionData({\n abi: ERC20_ABI,\n functionName: 'approve',\n args: [sourceChainData.tokenRouterAddress, amount],\n });\n}\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 { isAddress } from 'viem';\n\nimport { InvalidParamsError } from '../../../errors';\nimport { getClientForChain } from '../../../utils/client';\nimport { ErrorReason, type BridgeService, type TransferParams } from '../../../types';\n\nimport { ERC20_ABI } from '../abis/erc20';\nimport { getTransferData } from '../utils/transfer-data';\nimport { ChainDomain } from '../types/chain';\n\nconst ETH_APPROVAL_TX_GAS_ESTIMATE = 60_000n; // 55.5k gas on average (+/- 200 units)\nconst ETH_TRANSFER_TX_GAS_ESTIMATE = 175_000n; // 161.5k gas on average (+/- 200 units)\nconst AVAX_APPROVAL_TX_GAS_ESTIMATE = 60_000n; // 55.5k gas on average (+/- 200 units)\nconst AVAX_TRANSFER_TX_GAS_ESTIMATE = 215_000n; // 203k gas on average (+/- 200 units)\n/**\n * The CCTP bridging consists of up to two transactions:\n *\n * 1. Token spend approval (technically optional, but realistically performed basically every time)\n * 2. Token transfer (required)\n *\n * Since the 2nd one needs the first transaction to be complete, calling .estimateGas() is not possible.\n * The RPC call raises an error since it cannot execute the transfer transaction locally without\n * the allowance being set. For that reason, we're using hard-coded estimates here, with small buffers added.\n *\n * NOTE: These estimates are only supposed to be used to approximate the network fees in the UI.\n * DO NOT use them as `gasLimit` prop on the transactions!\n */\nexport async function estimateGas(bridge: BridgeService, params: TransferParams): Promise<bigint> {\n await bridge.ensureHasConfig();\n\n const { sourceChain, targetChain, asset, amount, fromAddress, toAddress: maybeToAddress, sourceProvider } = 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, burnToken } = getTransferData({ sourceChain, targetChain, asset, amount }, 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 isOffboarding = sourceChainData.domain === ChainDomain.Avalanche;\n\n if (allowance >= amount) {\n return isOffboarding ? AVAX_TRANSFER_TX_GAS_ESTIMATE : ETH_TRANSFER_TX_GAS_ESTIMATE;\n }\n\n return isOffboarding\n ? AVAX_APPROVAL_TX_GAS_ESTIMATE + AVAX_TRANSFER_TX_GAS_ESTIMATE\n : ETH_APPROVAL_TX_GAS_ESTIMATE + ETH_TRANSFER_TX_GAS_ESTIMATE;\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';\nimport { estimateGas } from './handlers/estimate-gas';\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 estimateGas: function (params) {\n return estimateGas(this, params);\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 const estimateGas = async (params: TransferParams) => {\n const { bridge } = getBridgeForTransfer(enabledBridgeServices, params.asset, params.targetChain.chainId);\n\n return bridge.estimateGas(params);\n };\n\n return {\n environment,\n bridges: enabledBridgeServices,\n init,\n updateConfigs,\n getAssets,\n getFees,\n estimateGas,\n canTransferAsset,\n transferAsset,\n trackTransfer,\n };\n};\n"]}
1
+ {"version":3,"sources":["../src/types/asset.ts","../src/types/bridge.ts","../src/types/chain.ts","../src/types/environment.ts","../src/types/error.ts","../src/unified-bridge-service.ts","../src/bridges/cctp/handlers/get-assets.ts","../src/utils/evm/client.ts","../src/utils/caip2.ts","../src/bridges/cctp/abis/token-router.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/transfer-data.ts","../src/bridges/cctp/handlers/get-fees.ts","../src/bridges/cctp/handlers/transfer-asset.ts","../src/abis/erc20.ts","../src/bridges/cctp/utils/build-tx.ts","../src/bridges/cctp/handlers/track-transfer.ts","../src/utils/wait.ts","../src/utils/retry-promise.ts","../src/bridges/cctp/types/config.ts","../src/bridges/cctp/types/chain.ts","../src/utils/evm/evm-address-schema.ts","../src/bridges/cctp/utils/config.ts","../src/utils/tracking/evm-source-tracker.ts","../src/utils/tracking/utils.ts","../src/utils/network-fee.ts","../src/utils/tracking/evm-target-tracker.ts","../src/bridges/cctp/utils/cctp-tracking.ts","../src/bridges/cctp/handlers/estimate-gas.ts","../src/bridges/cctp/handlers/get-minimum-transfer-amount.ts","../src/bridges/cctp/handlers/estimate-receive-amount.ts","../src/bridges/cctp/handlers/analyze-tx.ts","../src/utils/consts.ts","../src/utils/evm/utils.ts","../src/utils/evm/validation.ts","../src/bridges/cctp/factory.ts","../src/bridges/ictt-erc20-erc20/utils/transfer-data.ts","../src/bridges/ictt-erc20-erc20/handlers/estimate-gas.ts","../src/bridges/ictt-erc20-erc20/handlers/get-assets.ts","../src/bridges/ictt-erc20-erc20/handlers/get-fees.ts","../src/bridges/ictt-erc20-erc20/handlers/transfer-asset.ts","../src/bridges/ictt-erc20-erc20/utils/build-tx.ts","../src/bridges/ictt-erc20-erc20/abis/erc20-token-home.ts","../src/bridges/ictt-erc20-erc20/abis/erc20-token-remote.ts","../src/bridges/ictt-erc20-erc20/utils/ictt-erc20-erc20-tracking.ts","../src/bridges/ictt-erc20-erc20/handlers/track-transfer.ts","../src/bridges/ictt-erc20-erc20/handlers/get-minimum-transfer-amount.ts","../src/utils/base58check.ts","../src/bridges/ictt-erc20-erc20/types/config.ts","../src/bridges/ictt-erc20-erc20/utils/consts.ts","../src/bridges/ictt-erc20-erc20/utils/config.ts","../src/bridges/ictt-erc20-erc20/utils/retrieve-json.ts","../src/bridges/ictt-erc20-erc20/handlers/estimate-receive-amount.ts","../src/bridges/ictt-erc20-erc20/handlers/analyze-tx.ts","../src/bridges/ictt-erc20-erc20/factory.ts","../src/utils/bridge-types.ts","../src/bridges/avalanche/evm/handlers/estimate-gas.ts","../src/bridges/avalanche/evm/abis/wavax-abi.ts","../src/bridges/avalanche/evm/abis/weth-abi.ts","../src/bridges/avalanche/types/config.ts","../src/bridges/avalanche/bitcoin/utils/address.ts","../src/bridges/avalanche/utils/chain.ts","../src/bridges/avalanche/evm/utils/consts.ts","../src/bridges/avalanche/evm/utils/transfer-data.ts","../src/bridges/avalanche/utils/asset.ts","../src/bridges/avalanche/evm/utils/fee.ts","../src/bridges/avalanche/utils/fees.ts","../src/bridges/avalanche/evm/handlers/get-fees.ts","../src/bridges/avalanche/evm/handlers/estimate-receive-amount.ts","../src/bridges/avalanche/evm/handlers/get-assets.ts","../src/bridges/avalanche/evm/handlers/get-minimum-transfer-amount.ts","../src/bridges/avalanche/evm/utils/tracking.ts","../src/bridges/avalanche/evm/handlers/track-transfer.ts","../src/bridges/avalanche/utils/unwrapping.ts","../src/bridges/avalanche/evm/utils/wrapping.ts","../src/bridges/avalanche/evm/handlers/transfer-asset.ts","../src/bridges/avalanche/evm/utils/convert-config.ts","../src/bridges/avalanche/utils/runtime-config.ts","../src/bridges/avalanche/utils/warden-config.ts","../src/bridges/avalanche/evm/utils/config.ts","../src/bridges/avalanche/evm/handlers/analyze-tx.ts","../src/bridges/avalanche/evm/factory.ts","../src/bridges/avalanche/bitcoin/utils/fee.ts","../src/bridges/avalanche/bitcoin/utils/convert-config.ts","../src/bridges/avalanche/bitcoin/utils/config.ts","../src/bridges/avalanche/bitcoin/btc-ava/handlers/analyze-tx.ts","../src/bridges/avalanche/bitcoin/types/utxo.ts","../src/bridges/avalanche/bitcoin/btc-ava/utils/utxo.ts","../src/bridges/avalanche/bitcoin/btc-ava/utils/transfer-data.ts","../src/bridges/avalanche/bitcoin/btc-ava/handlers/estimate-gas.ts","../src/bridges/avalanche/bitcoin/btc-ava/handlers/get-fees.ts","../src/bridges/avalanche/bitcoin/btc-ava/handlers/estimate-receive-amount.ts","../src/bridges/avalanche/bitcoin/btc-ava/handlers/get-assets.ts","../src/bridges/avalanche/bitcoin/btc-ava/handlers/get-minimum-transfer-amount.ts","../src/bridges/avalanche/bitcoin/btc-ava/utils/btc-to-ava-source-tracker.ts","../src/bridges/avalanche/bitcoin/btc-ava/utils/btc-to-ava-target-tracker.ts","../src/bridges/avalanche/bitcoin/btc-ava/utils/tracking.ts","../src/bridges/avalanche/bitcoin/btc-ava/handlers/track-transfer.ts","../src/bridges/avalanche/bitcoin/btc-ava/utils/wrapping.ts","../src/bridges/avalanche/bitcoin/btc-ava/handlers/transfer-asset.ts","../src/bridges/avalanche/bitcoin/btc-ava/types/bridge.ts","../src/bridges/avalanche/bitcoin/btc-ava/factory.ts","../src/bridges/avalanche/bitcoin/ava-btc/handlers/analyze-tx.ts","../src/bridges/avalanche/bitcoin/ava-btc/utils/transfer-data.ts","../src/bridges/avalanche/bitcoin/ava-btc/handlers/estimate-gas.ts","../src/bridges/avalanche/bitcoin/ava-btc/handlers/get-fees.ts","../src/bridges/avalanche/bitcoin/ava-btc/handlers/estimate-receive-amount.ts","../src/bridges/avalanche/bitcoin/ava-btc/handlers/get-assets.ts","../src/bridges/avalanche/bitcoin/ava-btc/handlers/get-minimum-transfer-amount.ts","../src/bridges/avalanche/bitcoin/ava-btc/utils/ava-to-btc-source-tracker.ts","../src/bridges/avalanche/bitcoin/ava-btc/utils/ava-to-btc-target-tracker.ts","../src/bridges/avalanche/bitcoin/ava-btc/handlers/track-transfer.ts","../src/bridges/avalanche/bitcoin/ava-btc/handlers/transfer-asset.ts","../src/bridges/avalanche/bitcoin/ava-btc/types/bridge.ts","../src/bridges/avalanche/bitcoin/ava-btc/factory.ts"],"names":["TokenType","isErc20Asset","asset","isNativeAsset","BridgeType","BTC_BRIDGE_TYPES","EVM_BRIDGE_TYPES","isEvmBridgeInitializer","initializer","isAvaToBtcBridgeInitializer","isBtcToAvaBridgeInitializer","BridgeSignatureReason","AvalancheChainIds","EthereumChainIds","BitcoinChainIds","AVALANCHE_FUJI_CHAIN","AVALANCHE_MAINNET_CHAIN","ETHEREUM_SEPOLIA_CHAIN","ETHEREUM_MAINNET_CHAIN","BITCOIN_TESTNET_CHAIN","BITCOIN_MAINNET_CHAIN","Environment","ErrorCode","ErrorReason","isArray","mergeWith","getAssets","config","chainIds","chainData","assets","destinations","chainId","createWalletClient","publicActions","http","namespacePattern","referencePattern","delimeter","toJSON","identifier","namespace","reference","toString","caip2_default","_getChain","chain","getClientForChain","chainInfo","transport","TOKEN_ROUTER_ABI","BridgeError","message","code","details","BridgeUnavailableError","BridgeInitializationError","InvalidParamsError","getTransferData","sourceChain","targetChain","amount","sourceChainData","targetChainData","burnToken","token","mintToken","getFees","params","feeAmount","ERC20_ABI","encodeFunctionData","buildTransferTxData","toAddress","buildApprovalTxData","approveAndTransfer","signer","fromAddress","onStepChange","client","isAllowanceApprovalRequired","requiredSignatures","data","txHash","signedTxHash","getStartBlockNumber","targetClient","transferAsset","environment","sourceRequiredConfirmationCount","targetRequiredConfirmationCount","fees","bridgeFee","sourceStartedAt","targetBlockNumber","isHash","wait","time","res","retryPromise","promise","delay","startAfter","isRunning","isCancelled","errorCount","resolve","reject","done","cancel","rej","execute","err","z","ChainDomain","isAddress","evmAddressSchema","arg","a","tokenSchema","chainIdSchema","numericString","ctx","prefixedString","parsed","chainDataSchema","configSchema","isSupportedEnvironment","env","CONFIG_URLS","getConfig","json","getTrackingDelayByChainId","cloneDeep","isNil","omitBy","updateTransfer","initial","updated","updateListener","updatedNonNil","nextTransfer","TRACKING_LIMIT_MS","MAX_BLOCKS","INITIAL_DELAY","DEFAULT_TRACKING_CONFIG","getNetworkFeeEVM","transaction","receipt","createEvmSourceTracker","sourceClient","getMetadata","checkMetadata","bridgeTransfer","trackingLimitMs","updatableTransfer","txReceipt","tx","networkFee","confirmationCount","hasMoreConfirmations","hasRequiredConfirmations","changes","metadata","createEvmTargetTracker","getTargetTxHash","maxBlocks","lastBlockNumber","lowestBlockNumber","fromBlock","highestBlockNumber","toBlock","targetTxHash","isObject","decodeEventLog","createGetMetadata","transferEventLog","log","MESSAGE_RECEIVED_EVENT_ABI","createGetTargetTxHash","trackSourceTx","transferData","tracker","trackTargetTx","trackTransfer","abortFn","sourceTracker","cancelSourceTracking","transferAfterSourceFinished","targetTracker","cancelTargetTracking","ETH_APPROVAL_TX_GAS_ESTIMATE","ETH_TRANSFER_TX_GAS_ESTIMATE","AVAX_APPROVAL_TX_GAS_ESTIMATE","AVAX_TRANSFER_TX_GAS_ESTIMATE","estimateGas","allowance","isOffboarding","getMinimumTransferAmount","estimateReceiveAmount","targetAsset","isAddressEqual","ZERO_ADDRESS","analyzeTx","chainConfig","supportedTokenTransfer","symbol","bridgeTokenSymbol","isAvalanche","isTestnet","ethereumChain","avalancheChain","isFromMessageTransmitter","isMinted","validateEvmAddresses","addressParams","toEvmAnalyzeTxParams","from","to","tokenTransfers","evmTokenTransfer","tokenTransfer","toValidEvmGasEstimationParams","rest","toValidEvmTransferParams","maybeFromAddress","maybeToAddress","cctpBridgeFactory","getHomeToRemoteConfig","chainBridgeConfig","tokenHomeConfig","erc20Bridge","remoteChain","tokenRemoteConfig","remoteConfig","getRemoteToHomeConfig","homeToRemoteConfig","remoteToHomeConfig","homeToRemote","remoteToHome","existingAssets","ERC20_TOKEN_HOME_ABI","ERC20_TOKEN_REMOTE_ABI","REQUIRED_GAS_LIMIT","buildSendTxData","destinationBlockchainID","destinationTokenTransferrerAddress","recipient","address","approveAndTransferWithSign","approveAndTransferRouter","isHex","contractAddress","abi","eventName","RECEIVE_CROSS_CHAIN_MESSAGE_EVENT","lastLog","lastLogTxHash","tokenWithdrawnEventLog","base58","sha256","concatBytes","base58check","string","chainApiSchema","chainsApiSchema","bridgeApiSchema","bridgesApiSchema","TELEPORTER_MESSENGER_ADDRESS_V1","MainnetCChain","TestnetCChain","toHex","retrieveJson","url","isFulfilled","result","getChains","baseUrl","chainsJson","getBridges","chains","chainBridgesJson","b","bridges","bridge","homeChainInfo","chainID","homeChainConfig","homeChain","tokenBridge","tokenHomeAddress","blockchainIdAsHex","caipId","tokenRemoteAddress","bridgeConfig","baseToken","isTeleporterInvolved","isFromTokenHome","icttErc20Erc20BridgeFactory","compact","WAVAX_ABI","WETH_ABI","bech32","isBech32Format","btcAddress","isBech32Address","isBech32AddressInNetwork","isMainnet","btcAddressSchema","Blockchain","BlockchainEnum","AssetBase","EthereumAssetConfig","CriticalConfigBase","EthereumCriticalConfig","EthereumNonCriticalConfigBase","EthereumStaticFeeNonCriticalConfig","DynamicFeeEstimation","EthereumDynamicFeeNonCriticalConfig","EthereumStaticFeeConfig","EthereumDynamicFeeConfig","BitcoinAssetConfig","BitcoinCritical","BitcoinCurrentBridgeFeeEstimateDynamic","BitcoinCurrentBridgeFeeEstimateStatic","BitcoinNetworkInfo","BitcoinNonCritical","BitcoinConfig","ConfigWithDynamicEthereum","ConfigWithStaticEthereum","WardenConfigSchema","isCaip2EthereumChainId","caip2ChainId","isEthereumChain","isCaip2AvalancheChainId","isAvalancheChain","isCaip2BitcoinChainId","isMainnetCaip2ChainId","isTestnetCaip2ChainId","isMainnetChain","ETH_TOKEN","isEqual","convertBridgeAssetToAsset","ethHandler","assetsMatch","bridgeAsset","prepEthToAvaTransferData","ethToken","avaToken","prepAvaToEthTransferData","isValidChainCombination","sourceChainId","targetChainId","source","target","ethereumWalletAddress","ethToAva","estimate","isDynamicFee","feeApproximation","capped","value","max","min","getDynamicFeeAmount","minimumFeeAmount","maximumFeeAmount","feePercentage","feePercentageDecimals","minimumFee","maximumFee","percentage","fee","bigintFee","cost","assetsWithEthTokens","list","tokenConfig","ethChainId","avaChainId","currentList","allAssets","homesteadKey","sepoliaKey","FEE_ESTIMATION_MULTIPLIER","feeResult","args","event","logs","foundLog","includesOriginTxId","isMintLogOrTransferLog","transferAssetFromAvaToHome","sign","VulnerableRouterAddresses","wrapERC20Asset","hasAddressVulnerableMultichainApproval","ethWethConfig","avaWethConfig","wrapNativeAsset","wrapData","wrapTxHash","transferAssetFromEthToAva","minimumAmount","targetStartBlockNumber","e","convertToConfig","wardenConfig","wardenTokenList","ethereum","avalanche","avalancheWalletAddress","homeTokens","assetList","wardenAsset","nativeNetworkToken","wrapFee","wethHomeToken","homeToken","avaTokens","avaNetworkToken","unwrapFee","wethAvaToken","avalancheMinimumConfirmation","ethereumMinimumConfirmation","devConfig","stageConfig","testConfig","prodConfig","RUNTIME_CONFIGS","getRuntimeConfig","maxBy","memoize","fetchConfigs","wardenConfigUrls","promises","responses","configs","response","responseJson","parsedConfig","consolidateByCriticalConfig","count","otherConfig","getWardenConfig","runtimeConfig","consolidatedConfigs","mostFrequentConfig","consolidatedConfig","avalancheEvmBridgeFactory","isNetworkInfoDynamic","currentBridgeFeeEstimate","bridgeFeeEstimate","criticalBitcoin","btcAsset","bitcoinNetworkInfo","bridgeFeeEstimateHome","bitcoinCaip2","btcHomeToken","bridgeFeeEstimateRemote","btcRemoteToken","isBitcoin","bitcoinChain","isSourceTx","BitcoinInputUTXO","BitcoinInputUTXOArray","BitcoinInputUTXOWithOptionalScript","BitcoinOutputUTXO","BitcoinOutputUTXOArray","coinSelect","filterDuplicateUTXOs","utxos","seen","utxo","key","selectUtxos","changeAddress","feeRate","sourceUtxos","filtered","targets","inputs","outputs","validatedInput","finalOuts","change","validatedOutput","bitcoinFunctions","bridgeAddress","uxtoWithScripts","bitcoinAsset","bitcoinBridgeAsset","baseFee","getBaseFee","minimumOnboardSize","createBtcToAvaSourceTracker","sourceTxHash","roundedFee","createBtcToAvaTargetTracker","trackBtcSourceTx","trackAvaTargetTx","transferAssetFromBtcToAva","low","high","toValidBtcToAvaTransferParams","mainnet","toValidBtcToAvaGasEstimationParams","avalancheBtcToAvaBridgeFactory","isTargetTx","constAmount","numeratorPerSat","denominatorPerSat","txFee","constUnwrapFeeAmount","unwrapFeeNumerator","unwrapFeeDenominator","costInNumber","avaBitcoinAsset","avaBitcoinBridgeAsset","dustThreshold","createAvaToBtcSourceTracker","updateableTransfer","createAvaToBtcTargetTracker","confirmed","unconfirmed","txOutput","o","trackAvaSourceTx","trackBtcTargetTx","toValidAvaToBtcTransferParams","toValidAvaToBtcGasEstimationParams","avalancheAvaToBtcBridgeFactory","supportedBridges","getEnabledBridgeServices","enabledBridgeInitializers","bridgePromisesResults","factory","getBridgeForTransfer","enabledBridgeServices","bridgeType","createUnifiedBridgeService","aggregatedAssets","chainAssetMap","bridgeAssets","index","objValue","srcValue","services","type","x","service"],"mappings":"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,OACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,4BACN,KAAM,OACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,oBACN,KAAM,OACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,sBACN,KAAM,OACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,wBACN,KAAM,OACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,8BACN,KAAM,OACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,sBACN,KAAM,OACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,sBACN,KAAM,OACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,8BACN,KAAM,OACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,sBACN,KAAM,OACR,EACA,CACE,OAAQ,CAAC,EACT,KAAM,+BACN,KAAM,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,ECx0BO,IAAMC,EAAN,cAA0B,KAAM,CACrC,YACEC,EACOC,EACAC,EACP,CACA,MAAMF,CAAO,EAHN,UAAAC,EACA,aAAAC,CAGT,CACF,ECPO,IAAMC,GAAN,cAAqCJ,CAAY,CACtD,YAAYC,YAA+BE,EAAkB,CAC3D,MAAMF,OAAyCE,CAAO,EACtD,KAAK,KAAO,wBACd,CACF,ECLO,IAAME,EAAN,cAAwCL,CAAY,CACzD,YAAYC,YAA+BE,EAAkB,CAC3D,MAAMF,OAA0CE,CAAO,EACvD,KAAK,KAAO,2BACd,CACF,ECLO,IAAMG,EAAN,cAAiCN,CAAY,CA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,OCAlC,OAAS,sBAAA4C,OAAwC,OCA1C,IAAM0K,GAAuB,CAClC,CACE,KAAM,cACN,OAAQ,CACN,CACE,KAAM,4BACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,oBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,gBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,iBACN,KAAM,QACN,aAAc,OAChB,CACF,EACA,gBAAiB,YACnB,EACA,CACE,KAAM,WACN,KAAM,gBACN,OAAQ,CACN,CACE,KAAM,qBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,gCACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,SACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CAAC,EACV,gBAAiB,YACnB,EACA,CACE,KAAM,WACN,KAAM,eACN,OAAQ,CAAC,EACT,QAAS,CACP,CACE,KAAM,GACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,0BACN,OAAQ,CAAC,EACT,QAAS,CACP,CACE,KAAM,GACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,4BACN,OAAQ,CACN,CACE,KAAM,oBACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CACP,CACE,KAAM,GACN,KAAM,OACN,aAAc,MAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,QACN,OAAQ,CAAC,EACT,QAAS,CACP,CACE,KAAM,GACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,yBACN,OAAQ,CACN,CACE,KAAM,oBACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CAAC,EACV,gBAAiB,YACnB,EACA,CACE,KAAM,WACN,KAAM,2BACN,OAAQ,CACN,CACE,KAAM,qBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,sBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,UACN,KAAM,QACN,aAAc,OAChB,CACF,EACA,QAAS,CAAC,EACV,gBAAiB,YACnB,EACA,CACE,KAAM,WACN,KAAM,oBACN,OAAQ,CACN,CACE,KAAM,qBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,gCACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CACP,CACE,KAAM,aACN,KAAM,OACN,aAAc,MAChB,EACA,CACE,KAAM,mBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,kBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,mBACN,KAAM,OACN,aAAc,MAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,oBACN,OAAQ,CAAC,EACT,QAAS,CAAC,EACV,gBAAiB,YACnB,EACA,CACE,KAAM,WACN,KAAM,OACN,OAAQ,CACN,CACE,KAAM,QACN,KAAM,QACN,aAAc,yBACd,WAAY,CACV,CACE,KAAM,0BACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,qCACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,YACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,yBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,aACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,eACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,mBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,mBACN,KAAM,UACN,aAAc,SAChB,CACF,CACF,EACA,CACE,KAAM,SACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CAAC,EACV,gBAAiB,YACnB,EACA,CACE,KAAM,WACN,KAAM,cACN,OAAQ,CACN,CACE,KAAM,QACN,KAAM,QACN,aAAc,0BACd,WAAY,CACV,CACE,KAAM,0BACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,qCACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,oBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,mBACN,KAAM,QACN,aAAc,OAChB,EACA,CACE,KAAM,mBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,oBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,mBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,oBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,yBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,aACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,eACN,KAAM,UACN,aAAc,SAChB,CACF,CACF,EACA,CACE,KAAM,SACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CAAC,EACV,gBAAiB,YACnB,EACA,CACE,KAAM,WACN,KAAM,qBACN,OAAQ,CAAC,EACT,QAAS,CACP,CACE,KAAM,GACN,KAAM,UACN,aAAc,6BAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,QACN,OAAQ,CAAC,EACT,QAAS,CACP,CACE,KAAM,GACN,KAAM,UACN,aAAc,iBAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,eACN,OAAQ,CAAC,EACT,QAAS,CACP,CACE,KAAM,GACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,gBACN,OAAQ,CAAC,EACT,QAAS,CACP,CACE,KAAM,GACN,KAAM,QACN,aAAc,OAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,oBACN,OAAQ,CACN,CACE,KAAM,WACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CAAC,EACV,gBAAiB,YACnB,EACA,CACE,KAAM,WACN,KAAM,sBACN,OAAQ,CACN,CACE,KAAM,qBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,gCACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CACP,CACE,KAAM,UACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,2BACN,OAAQ,CACN,CACE,KAAM,oBACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CAAC,EACV,gBAAiB,YACnB,EACA,CACE,KAAM,WACN,KAAM,6BACN,OAAQ,CACN,CACE,KAAM,UACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CAAC,EACV,gBAAiB,YACnB,EACA,CACE,KAAM,QACN,KAAM,aACN,OAAQ,CACN,CACE,KAAM,oBACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,SACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,CACF,EACA,UAAW,EACb,EACA,CACE,KAAM,QACN,KAAM,gBACN,OAAQ,CACN,CACE,KAAM,oBACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,SACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,CACF,EACA,UAAW,EACb,EACA,CACE,KAAM,QACN,KAAM,kBACN,OAAQ,CACN,CACE,KAAM,qBACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,gCACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,SACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,YACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,CACF,EACA,UAAW,EACb,EACA,CACE,KAAM,QACN,KAAM,8BACN,OAAQ,CACN,CACE,KAAM,0BACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,0BACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,CACF,EACA,UAAW,EACb,EACA,CACE,KAAM,QACN,KAAM,uBACN,OAAQ,CACN,CACE,KAAM,gBACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,WACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,CACF,EACA,UAAW,EACb,EACA,CACE,KAAM,QACN,KAAM,mBACN,OAAQ,CACN,CACE,KAAM,qBACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,gCACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,0BACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,gBACN,KAAM,QACN,QAAS,GACT,aAAc,OAChB,CACF,EACA,UAAW,EACb,EACA,CACE,KAAM,QACN,KAAM,0BACN,OAAQ,CACN,CACE,KAAM,oBACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,CACF,EACA,UAAW,EACb,EACA,CACE,KAAM,QACN,KAAM,4BACN,OAAQ,CACN,CACE,KAAM,oBACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,CACF,EACA,UAAW,EACb,EACA,CACE,KAAM,QACN,KAAM,sBACN,OAAQ,CACN,CACE,KAAM,sBACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,QACN,KAAM,QACN,QAAS,GACT,aAAc,0BACd,WAAY,CACV,CACE,KAAM,0BACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,qCACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,oBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,mBACN,KAAM,QACN,aAAc,OAChB,EACA,CACE,KAAM,mBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,oBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,mBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,oBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,yBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,aACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,eACN,KAAM,UACN,aAAc,SAChB,CACF,CACF,EACA,CACE,KAAM,SACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,CACF,EACA,UAAW,EACb,EACA,CACE,KAAM,QACN,KAAM,oBACN,OAAQ,CACN,CACE,KAAM,sBACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,SACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,QACN,KAAM,QACN,QAAS,GACT,aAAc,0BACd,WAAY,CACV,CACE,KAAM,0BACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,qCACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,oBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,mBACN,KAAM,QACN,aAAc,OAChB,EACA,CACE,KAAM,mBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,oBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,mBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,oBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,yBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,aACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,eACN,KAAM,UACN,aAAc,SAChB,CACF,CACF,EACA,CACE,KAAM,SACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,CACF,EACA,UAAW,EACb,EACA,CACE,KAAM,QACN,KAAM,eACN,OAAQ,CACN,CACE,KAAM,sBACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,QACN,KAAM,QACN,QAAS,GACT,aAAc,yBACd,WAAY,CACV,CACE,KAAM,0BACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,qCACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,YACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,yBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,aACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,eACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,mBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,mBACN,KAAM,UACN,aAAc,SAChB,CACF,CACF,EACA,CACE,KAAM,SACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,CACF,EACA,UAAW,EACb,EACA,CACE,KAAM,QACN,KAAM,aACN,OAAQ,CACN,CACE,KAAM,sBACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,SACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,QACN,KAAM,QACN,QAAS,GACT,aAAc,yBACd,WAAY,CACV,CACE,KAAM,0BACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,qCACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,YACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,yBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,aACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,eACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,mBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,mBACN,KAAM,UACN,aAAc,SAChB,CACF,CACF,EACA,CACE,KAAM,SACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,CACF,EACA,UAAW,EACb,EACA,CACE,KAAM,QACN,KAAM,kBACN,OAAQ,CACN,CACE,KAAM,YACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,SACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,CACF,EACA,UAAW,EACb,CACF,ECr6BO,IAAMC,GAAyB,CACpC,CACE,KAAM,cACN,OAAQ,CACN,CACE,KAAM,WACN,KAAM,QACN,aAAc,6BACd,WAAY,CACV,CACE,KAAM,4BACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,oBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,wBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,mBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,oBACN,KAAM,QACN,aAAc,OAChB,CACF,CACF,EACA,CACE,KAAM,YACN,KAAM,SACN,aAAc,QAChB,EACA,CACE,KAAM,cACN,KAAM,SACN,aAAc,QAChB,EACA,CACE,KAAM,iBACN,KAAM,QACN,aAAc,OAChB,CACF,EACA,gBAAiB,YACnB,EACA,CACE,KAAM,WACN,KAAM,8BACN,OAAQ,CAAC,EACT,QAAS,CACP,CACE,KAAM,GACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,8BACN,OAAQ,CAAC,EACT,QAAS,CACP,CACE,KAAM,GACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,8BACN,OAAQ,CAAC,EACT,QAAS,CACP,CACE,KAAM,GACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,+BACN,OAAQ,CAAC,EACT,QAAS,CACP,CACE,KAAM,GACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,YACN,OAAQ,CACN,CACE,KAAM,QACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,UACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CACP,CACE,KAAM,GACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,UACN,OAAQ,CACN,CACE,KAAM,UACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,SACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CACP,CACE,KAAM,GACN,KAAM,OACN,aAAc,MAChB,CACF,EACA,gBAAiB,YACnB,EACA,CACE,KAAM,WACN,KAAM,YACN,OAAQ,CACN,CACE,KAAM,UACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CACP,CACE,KAAM,GACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,eACN,OAAQ,CAAC,EACT,QAAS,CACP,CACE,KAAM,GACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,oBACN,OAAQ,CACN,CACE,KAAM,cACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CACP,CACE,KAAM,GACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,WACN,OAAQ,CAAC,EACT,QAAS,CACP,CACE,KAAM,GACN,KAAM,QACN,aAAc,OAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,oBACN,OAAQ,CACN,CACE,KAAM,UACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,kBACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CACP,CACE,KAAM,GACN,KAAM,OACN,aAAc,MAChB,CACF,EACA,gBAAiB,YACnB,EACA,CACE,KAAM,WACN,KAAM,0BACN,OAAQ,CAAC,EACT,QAAS,CACP,CACE,KAAM,GACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,oBACN,OAAQ,CAAC,EACT,QAAS,CACP,CACE,KAAM,GACN,KAAM,QACN,aAAc,OAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,oBACN,OAAQ,CACN,CACE,KAAM,UACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,aACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CACP,CACE,KAAM,GACN,KAAM,OACN,aAAc,MAChB,CACF,EACA,gBAAiB,YACnB,EACA,CACE,KAAM,WACN,KAAM,0BACN,OAAQ,CAAC,EACT,QAAS,CACP,CACE,KAAM,GACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,mBACN,OAAQ,CAAC,EACT,QAAS,CACP,CACE,KAAM,GACN,KAAM,OACN,aAAc,MAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,eACN,OAAQ,CAAC,EACT,QAAS,CACP,CACE,KAAM,GACN,KAAM,OACN,aAAc,MAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,4BACN,OAAQ,CACN,CACE,KAAM,oBACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CACP,CACE,KAAM,GACN,KAAM,OACN,aAAc,MAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,mBACN,OAAQ,CAAC,EACT,QAAS,CACP,CACE,KAAM,GACN,KAAM,OACN,aAAc,MAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,OACN,OAAQ,CAAC,EACT,QAAS,CACP,CACE,KAAM,GACN,KAAM,SACN,aAAc,QAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,QACN,OAAQ,CAAC,EACT,QAAS,CACP,CACE,KAAM,GACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,yBACN,OAAQ,CACN,CACE,KAAM,oBACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CAAC,EACV,gBAAiB,YACnB,EACA,CACE,KAAM,WACN,KAAM,2BACN,OAAQ,CACN,CACE,KAAM,qBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,sBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,UACN,KAAM,QACN,aAAc,OAChB,CACF,EACA,QAAS,CAAC,EACV,gBAAiB,YACnB,EACA,CACE,KAAM,WACN,KAAM,mBACN,OAAQ,CACN,CACE,KAAM,UACN,KAAM,QACN,aAAc,2BACd,WAAY,CACV,CACE,KAAM,kBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,SACN,KAAM,UACN,aAAc,SAChB,CACF,CACF,CACF,EACA,QAAS,CAAC,EACV,gBAAiB,YACnB,EACA,CACE,KAAM,WACN,KAAM,oBACN,OAAQ,CAAC,EACT,QAAS,CAAC,EACV,gBAAiB,YACnB,EACA,CACE,KAAM,WACN,KAAM,OACN,OAAQ,CACN,CACE,KAAM,QACN,KAAM,QACN,aAAc,yBACd,WAAY,CACV,CACE,KAAM,0BACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,qCACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,YACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,yBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,aACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,eACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,mBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,mBACN,KAAM,UACN,aAAc,SAChB,CACF,CACF,EACA,CACE,KAAM,SACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CAAC,EACV,gBAAiB,YACnB,EACA,CACE,KAAM,WACN,KAAM,cACN,OAAQ,CACN,CACE,KAAM,QACN,KAAM,QACN,aAAc,0BACd,WAAY,CACV,CACE,KAAM,0BACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,qCACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,oBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,mBACN,KAAM,QACN,aAAc,OAChB,EACA,CACE,KAAM,mBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,oBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,mBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,oBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,yBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,aACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,eACN,KAAM,UACN,aAAc,SAChB,CACF,CACF,EACA,CACE,KAAM,SACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CAAC,EACV,gBAAiB,YACnB,EACA,CACE,KAAM,WACN,KAAM,SACN,OAAQ,CAAC,EACT,QAAS,CACP,CACE,KAAM,GACN,KAAM,SACN,aAAc,QAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,qBACN,OAAQ,CAAC,EACT,QAAS,CACP,CACE,KAAM,GACN,KAAM,UACN,aAAc,6BAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,gBACN,OAAQ,CAAC,EACT,QAAS,CACP,CACE,KAAM,GACN,KAAM,QACN,aAAc,OAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,mBACN,OAAQ,CAAC,EACT,QAAS,CACP,CACE,KAAM,GACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,wBACN,OAAQ,CAAC,EACT,QAAS,CACP,CACE,KAAM,GACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,kBACN,OAAQ,CAAC,EACT,QAAS,CACP,CACE,KAAM,GACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,cACN,OAAQ,CAAC,EACT,QAAS,CACP,CACE,KAAM,GACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,gBAAiB,MACnB,EACA,CACE,KAAM,WACN,KAAM,WACN,OAAQ,CACN,CACE,KAAM,KACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,SACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CACP,CACE,KAAM,GACN,KAAM,OACN,aAAc,MAChB,CACF,EACA,gBAAiB,YACnB,EACA,CACE,KAAM,WACN,KAAM,eACN,OAAQ,CACN,CACE,KAAM,OACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,KACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,SACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CACP,CACE,KAAM,GACN,KAAM,OACN,aAAc,MAChB,CACF,EACA,gBAAiB,YACnB,EACA,CACE,KAAM,WACN,KAAM,oBACN,OAAQ,CACN,CACE,KAAM,WACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CAAC,EACV,gBAAiB,YACnB,EACA,CACE,KAAM,WACN,KAAM,2BACN,OAAQ,CACN,CACE,KAAM,oBACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CAAC,EACV,gBAAiB,YACnB,EACA,CACE,KAAM,WACN,KAAM,6BACN,OAAQ,CACN,CACE,KAAM,UACN,KAAM,UACN,aAAc,SAChB,CACF,EACA,QAAS,CAAC,EACV,gBAAiB,YACnB,EACA,CACE,KAAM,QACN,KAAM,WACN,OAAQ,CACN,CACE,KAAM,QACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,UACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,QACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,CACF,EACA,UAAW,EACb,EACA,CACE,KAAM,QACN,KAAM,aACN,OAAQ,CACN,CACE,KAAM,oBACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,SACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,CACF,EACA,UAAW,EACb,EACA,CACE,KAAM,QACN,KAAM,gBACN,OAAQ,CACN,CACE,KAAM,oBACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,SACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,CACF,EACA,UAAW,EACb,EACA,CACE,KAAM,QACN,KAAM,8BACN,OAAQ,CACN,CACE,KAAM,0BACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,0BACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,CACF,EACA,UAAW,EACb,EACA,CACE,KAAM,QACN,KAAM,uBACN,OAAQ,CACN,CACE,KAAM,gBACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,WACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,CACF,EACA,UAAW,EACb,EACA,CACE,KAAM,QACN,KAAM,0BACN,OAAQ,CACN,CACE,KAAM,oBACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,CACF,EACA,UAAW,EACb,EACA,CACE,KAAM,QACN,KAAM,4BACN,OAAQ,CACN,CACE,KAAM,oBACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,CACF,EACA,UAAW,EACb,EACA,CACE,KAAM,QACN,KAAM,oBACN,OAAQ,CACN,CACE,KAAM,sBACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,SACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,QACN,KAAM,QACN,QAAS,GACT,aAAc,0BACd,WAAY,CACV,CACE,KAAM,0BACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,qCACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,oBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,mBACN,KAAM,QACN,aAAc,OAChB,EACA,CACE,KAAM,mBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,oBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,mBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,oBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,yBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,aACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,eACN,KAAM,UACN,aAAc,SAChB,CACF,CACF,EACA,CACE,KAAM,SACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,CACF,EACA,UAAW,EACb,EACA,CACE,KAAM,QACN,KAAM,aACN,OAAQ,CACN,CACE,KAAM,sBACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,SACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,QACN,KAAM,QACN,QAAS,GACT,aAAc,yBACd,WAAY,CACV,CACE,KAAM,0BACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,qCACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,YACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,yBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,aACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,eACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,mBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,mBACN,KAAM,UACN,aAAc,SAChB,CACF,CACF,EACA,CACE,KAAM,SACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,CACF,EACA,UAAW,EACb,EACA,CACE,KAAM,QACN,KAAM,kBACN,OAAQ,CACN,CACE,KAAM,YACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,SACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,CACF,EACA,UAAW,EACb,EACA,CACE,KAAM,QACN,KAAM,WACN,OAAQ,CACN,CACE,KAAM,OACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,KACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,QACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,CACF,EACA,UAAW,EACb,CACF,EF7kCO,IAAMC,GAAqB,OAErBC,GAAkB,CAAC,CAC9B,aAAAN,EACA,OAAAjL,EACA,wBAAAwL,EACA,mCAAAC,EACA,UAAAC,CACF,IAOShL,GAAmB,CACxB,IAAKuK,EAAeG,GAAuBC,GAC3C,aAAc,OACd,KAAM,CACJ,CACE,wBAAAG,EACA,mCAAAC,EACA,UAAAC,EACA,uBAAwB7C,EACxB,WAAY,GACZ,aAAc,GACd,iBAAkByC,GAClB,iBAAkBzC,CACpB,EACA7I,CACF,CACF,CAAC,EAGI,SAASa,GAAoB,CAAE,OAAAb,EAAQ,QAAA2L,CAAQ,EAAyC,CAC7F,OAAOjL,GAAmB,CACxB,IAAKD,EACL,aAAc,UACd,KAAM,CAACkL,EAAS3L,CAAM,CACxB,CAAC,CACH,CDjBA,IAAM4L,GAA6B,MAAO,CACxC,OAAQ,CAAE,aAAA3K,EAAc,OAAAjB,EAAQ,YAAAgB,EAAa,YAAAlB,EAAa,UAAAc,CAAU,EACpE,aAAA4G,EACA,4BAAArG,EACA,mBAAAC,EACA,OAAAL,CACF,IAAkD,CAChD,GAAM,CAAE,kBAAA6J,EAAmB,gBAAAH,EAAiB,aAAAQ,EAAc,kBAAAT,CAAkB,EAAIhD,EAC1EtG,EAAShC,EAAkB,CAAE,MAAOY,CAAY,CAAC,EACvD,GAAIqB,EAA6B,CAC/BF,IAAe,CACb,iBAAkB,EAClB,4CACA,mBAAAG,CACF,CAAC,EACD,IAAMC,EAAOR,GAAoB,CAC/B,OAAAb,EACA,QAASiL,EAAeR,EAAgB,iBAAmBG,EAAkB,kBAC/E,CAAC,EACKtJ,EAAS,MAAMP,EAAO,KAC1B,CACE,KAAMC,EACN,GAAIiK,EAAezD,EAAa,gBAAgB,UAAU,QAAUoD,EAAkB,mBACtF,KAAAvJ,CACF,EACCE,GAAsBL,EAAO,mBAAmB,CAAE,sBAAuBK,CAAa,CAAC,CAC1F,EAEA,MAAML,EAAO,0BAA0B,CACrC,KAAMI,EACN,gBAAiB,GACnB,CAAC,CACH,CACAL,IAAe,CACb,iBAAkBE,EAA8B,EAAI,EACpD,yCACA,mBAAAC,CACF,CAAC,EACD,IAAMoK,EAA0BP,EAC5BL,EAAkB,YAAY,aAC9BJ,EAAkB,UAAU,aAC1BiB,EAAqCR,EACvCL,EAAkB,mBAClBH,EAAgB,iBACdpJ,EAAOkK,GAAgB,CAC3B,OAAAvL,EACA,UAAWY,EACX,wBAAA4K,EACA,mCAAAC,EACA,aAAAR,CACF,CAAC,EACD,OAAOlK,EAAO,KACZ,CACE,KAAMC,EACN,GAAIiK,EAAeR,EAAgB,iBAAmBG,EAAkB,mBACxE,KAAAvJ,CACF,EACCE,GAAsBL,EAAO,mBAAmB,CAAE,sBAAuBK,CAAa,CAAC,CAC1F,CACF,EAMMsK,GAA2B,MAAO,CAAE,OAAAtL,EAAQ,aAAAiH,EAAc,OAAAzG,CAAO,IAA8B,CACnG,GAAM,CAAE,YAAAjB,EAAa,YAAAkB,EAAa,OAAAhB,CAAO,EAAIO,EACvCW,EAAShC,EAAkB,CAAE,MAAOY,CAAY,CAAC,EACjD,CAAE,aAAAmL,EAAc,gBAAAR,EAAiB,kBAAAG,CAAkB,EAAIpD,EAQvDrG,EAPY,MAAMD,EAAO,aAAa,CAC1C,QAAS+J,EAAeR,EAAgB,UAAU,QAAUG,EAAkB,mBAC9E,IAAKnK,EACL,aAAc,YACd,KAAM,CAACO,EAAaiK,EAAeR,EAAgB,iBAAmBG,EAAkB,kBAAkB,CAC5G,CAAC,EAE+C5K,EAEhD,OAAO4L,GAA2B,CAChC,OAAArL,EACA,aAAAiH,EACA,4BAAArG,EACA,mBALyBA,EAA8B,EAAI,EAM3D,OAAAJ,CACF,CAAC,CACH,EAEMD,GAAqB,MAAOhD,EAA8ByC,EAAgCQ,IAAsB,CACpH,GAAM,CAAE,YAAAjB,EAAa,YAAAC,EAAa,MAAA1D,EAAO,OAAA2D,CAAO,EAAIO,EAE9CiH,EAAe3H,EAAgB,CAAE,YAAAC,EAAa,YAAAC,EAAa,MAAA1D,EAAO,OAAA2D,CAAO,EAAGlC,CAAM,EACxF,OAAO+N,GAAyB,CAAE,OAAAtL,EAAQ,aAAAiH,EAAc,OAAAzG,CAAO,CAAC,CAClE,EAEMS,GAAsB,MAAOC,GAA+B,CAChE,GAAI,CAEF,OADyB,MAAMA,EAAa,eAAe,CAE7D,MAAQ,CACN,MACF,CACF,EAEA,eAAsBC,GACpB5D,EACAyC,EACAoB,EACAZ,EACyB,CACzB,IAAMe,EAAO,MAAMxB,GAAQxC,EAAQ,CACjC,MAAOyC,EAAO,MACd,OAAQA,EAAO,OACf,YAAaA,EAAO,YACpB,YAAaA,EAAO,WACtB,CAAC,EAEKwB,EAAY3F,EAAamE,EAAO,KAAK,EAAIuB,EAAKvB,EAAO,MAAM,OAAO,GAAK,GAAK,GAC5Ee,EAAS,MAAMR,GAAmBhD,EAAQyC,EAAQQ,CAAM,EACxDiB,EAAkB,KAAK,IAAI,EAC3BP,EAAevC,EAAkB,CACrC,MAAOqB,EAAO,WAChB,CAAC,EACK0B,EAAoB,MAAMT,GAAoBC,CAAY,EAEhE,MAAO,CACL,wBACA,YAAAE,EACA,YAAapB,EAAO,YACpB,UAAWA,EAAO,UAClB,OAAQA,EAAO,OACf,MAAOA,EAAO,MAEd,UAAAwB,EAEA,YAAaxB,EAAO,YACpB,gBAAAyB,EACA,aAAcV,EACd,wBAAyB,EACzB,gCAAiC,EAEjC,YAAaf,EAAO,YACpB,wBAAyB,EACzB,gCAAiC,EAEjC,uBAAwB0B,CAC1B,CACF,CIzKA,OAAS,kBAAAgF,GAAgB,SAAA6E,OAAsC,OAE/D,OAAS,SAAArH,GAAO,YAAAuC,OAAgB,SAEzB,IAAME,GACX,CAAC,CACC,aAAc,CAAE,aAAA+D,EAAc,gBAAAR,EAAiB,kBAAAG,CAAkB,CACnE,IAGC7E,GAAc,CAIb,IAAMgG,EAAkBd,EAAeR,EAAgB,iBAAmBG,EAAkB,mBACtFoB,EAAMf,EAAeG,GAAuBC,GAC5CY,EAAY,aAEZ9E,EAAmBpB,EAAU,KAAK,KAAMqB,GACxCA,EAAI,QAAQ,YAAY,IAAM2E,EAAgB,YAAY,EAC9C9E,GAAe,CAC3B,IAAA+E,EACA,GAAG5E,CACL,CAAC,EAEY,YAAc6E,EAGtB,EACR,EAED,GAAI,CAAC9E,EACH,MAAM,IAAIvH,mBAER,4DAA4DmG,EAAU,eAAe,GACvF,EAWF,MAAO,CAAE,oBARakB,GAAe,CACnC,IAAA+E,EACA,UAAAC,EACA,GAAG9E,CACL,CAAC,EAGyC,KAAK,mBAClB,CAC/B,EAEW+E,GAAoC,CAC/C,KAAM,2BACN,KAAM,QACN,OAAQ,CACN,CACE,KAAM,YACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,qBACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,YACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,iBACN,KAAM,UACN,QAAS,GACT,aAAc,SAChB,EACA,CACE,KAAM,UACN,KAAM,QACN,QAAS,GACT,aAAc,2BACd,WAAY,CACV,CACE,KAAM,eACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,sBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,0BACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,qBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,mBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,0BACN,KAAM,YACN,aAAc,WAChB,EACA,CACE,KAAM,WACN,KAAM,UACN,aAAc,oCACd,WAAY,CACV,CACE,KAAM,uBACN,KAAM,UACN,aAAc,SAChB,EACA,CACE,KAAM,uBACN,KAAM,UACN,aAAc,SAChB,CACF,CACF,EACA,CACE,KAAM,UACN,KAAM,QACN,aAAc,OAChB,CACF,CACF,CACF,CACF,EAEa5E,GACX,CAAC,CACC,UAAA1G,EACA,aAAc,CAAE,gBAAA6J,EAAiB,aAAAQ,EAAc,kBAAAL,CAAkB,EACjE,aAAAnJ,CACF,IAKA,MAAO,CAAE,UAAAmF,EAAW,QAAAE,EAAS,SAAAR,CAAS,IAAM,CAC1C,GAAI,CAACX,GAAcW,CAAQ,EACzB,MAAM,IAAI1G,kBAA6C,EAWzD,IAAMuM,GAT+B,MAAM1K,EAAa,QAAQ,CAC9D,QAASgJ,EAAgB,kBACzB,MAAOyB,GACP,KAAM,CACJ,UAAW5F,EAAS,mBACtB,EACA,UAAAM,EACA,QAAAE,CACF,CAAC,GAC4C,GAAG,EAAE,EAClD,GAAIrC,GAAM0H,CAAO,EACf,OAEF,IAAMC,EAAgBD,EAAQ,gBACxBpG,EAAY,MAAMtE,EAAa,sBAAsB,CACzD,KAAM2K,CACR,CAAC,EAQKJ,EAAMf,EAAeI,GAAyBD,GAC9CW,EAAkBd,EAAeL,EAAkB,mBAAqBH,EAAgB,iBACxF4B,EAAyBtG,EAAU,KAAK,KAAMqB,GAC9CA,EAAI,QAAQ,YAAY,IAAM2E,EAAgB,YAAY,EAC9C9E,GAAe,CAC3B,IAAA+E,EACA,GAAG5E,CACL,CAAC,EAEY,YAAc,kBAGtB,EACR,EAED,GAAI3C,GAAM4H,CAAsB,EAC9B,OAQF,GAN4BpF,GAAe,CACzC,IAAA+E,EACA,UAAW,kBACX,GAAGK,CACL,CAAC,EAEuB,KAAK,UAAU,YAAY,IAAMzL,EAAU,YAAY,EAC7E,OAAOwL,CAGX,EAEWzG,GAAiBW,GACrBU,GAASV,CAAQ,GAAKwF,GAAMxF,EAAS,mBAAmB,EC9MjE,IAAMiB,GAAgB,MAAOzJ,EAA8ByC,IAA2B,CACpF,GAAM,CAAE,eAAAqF,CAAe,EAAIrF,EACrB,CAAE,MAAAlE,EAAO,OAAA2D,EAAQ,YAAAF,EAAa,YAAAC,CAAY,EAAI6F,EAC9C4B,EAAe3H,EAAgB,CAAE,YAAAC,EAAa,YAAAC,EAAa,MAAA1D,EAAO,OAAA2D,CAAO,EAAGlC,CAAM,EAClF2H,EAAevG,EAAkB,CACrC,MAAO0G,EAAe,WACxB,CAAC,EAEKnE,EAAevC,EAAkB,CACrC,MAAO0G,EAAe,WACxB,CAAC,EAEKF,EAAcwB,GAAkB,CAAE,aAAAM,CAAa,CAAC,EAEhDC,EAAUjC,GAAuB,CACrC,aAAAC,EACA,aAAAhE,EACA,YAAAiE,EACA,cAAAC,GACA,eAAgBpF,EAChB,eAAgB6E,CAClB,CAAC,EAED,OAAO9C,EAA6B,CAClC,QAASmF,EACT,MAAO,IACP,WAAYrC,EAAwB,cACtC,CAAC,CACH,EAMasC,GAAgB,MAAO5J,EAA8ByC,IAA2B,CAC3F,GAAM,CAAE,eAAAqF,CAAe,EAAIrF,EACrB,CAAE,YAAAR,EAAa,YAAAD,EAAa,MAAAzD,EAAO,OAAA2D,EAAQ,UAAAY,CAAU,EAAIgF,EACzD4B,EAAe3H,EAAgB,CAAE,YAAAC,EAAa,YAAAC,EAAa,MAAA1D,EAAO,OAAA2D,CAAO,EAAGlC,CAAM,EAElF2D,EAAevC,EAAkB,CACrC,MAAO0G,EAAe,WACxB,CAAC,EAEKY,EAAkBc,GAAsB,CAC5C,aAAAE,EACA,aAAA/F,EACA,UAAAb,CACF,CAAC,EAEK6G,EAAUlB,GAAuB,CACrC,aAAA9E,EACA,gBAAA+E,EACA,cAAAb,GACA,eAAgBpF,EAChB,eAAgB6E,CAClB,CAAC,EAED,OAAO9C,EAA6B,CAClC,QAASmF,EACT,MAAO,IACP,WAAYrC,EAAwB,cACtC,CAAC,CACH,EAEO,SAASuC,GAAc7J,EAA8ByC,EAAwB,CAClF,IAAIqH,EAEE5E,EAAS,IAAM,CACnB4E,IAAU,CACZ,EAgBA,MAAO,CACL,QAfsB,SAAY,CAClC,GAAM,CAAE,eAAA9C,CAAe,EAAIvE,EACrB,CAAE,OAAQsH,EAAe,OAAQC,CAAqB,EAAI,MAAMP,GAAczJ,EAAQyC,CAAM,EAClGqH,EAAUE,EACV,IAAMC,EAA8B,MAAMF,EAEpC,CAAE,OAAQG,EAAe,OAAQC,CAAqB,EAAI,MAAMP,GAAc5J,EAAQ,CAC1F,eAAAgH,EACA,eAAgBiD,CAClB,CAAC,EACD,OAAAH,EAAUK,EACHD,CACT,GAG0B,EACxB,OAAAhF,CACF,CACF,CC9FA,eAAsByF,GAAyB3K,EAA8ByC,EAAmB,CAC9F,OAAAV,EAAgBU,EAAQzC,CAAM,EACvB,EACT,CCPA,OAAS,UAAAwO,OAAc,cAEvB,OAAS,UAAAC,OAAc,uBACvB,OAAS,eAAAC,OAAmB,sBAErB,IAAMC,GAA0B,CACrC,OAAOpL,EAAM,CACX,OAAOiL,GAAO,OAAOE,GAAYnL,EAAMkL,GAAOlL,CAAI,EAAE,SAAS,EAAE,CAAC,CAAC,CACnE,EACA,OAAOqL,EAAQ,CACb,OAAOJ,GAAO,OAAOI,CAAM,EAAE,SAAS,EAAG,EAAE,CAC7C,CACF,ECZA,OAAS,KAAAtJ,MAAS,MAkCX,IAAMuJ,GAAiBvJ,EAAE,OAAO,CACrC,WAAYA,EAAE,OAAO,EACrB,SAAUA,EAAE,OAAO,EACnB,aAAcA,EAAE,OAAO,EACvB,QAASA,EAAE,OAAO,EAClB,QAASA,EAAE,OAAO,CACpB,CAAC,EAEYwJ,GAAkBxJ,EAAE,MAAMuJ,EAAc,EAExCE,GAAkBzJ,EAAE,OAAO,CACtC,KAAMA,EAAE,OAAO,EACf,KAAMA,EAAE,OAAO,EACf,MAAOA,EAAE,OAAO,EAChB,SAAUA,EAAE,OAAO,EACnB,aAAcG,EACd,YAAaH,EAAE,OAAO,EACtB,UAAWA,EAAE,OAAO,EACpB,cAAeA,EAAE,OAAO,EACxB,iBAAkBG,EAClB,iBAAkBH,EAAE,OAAO,EAC3B,mBAAoBG,EACpB,mBAAoBH,EAAE,OAAO,EAC7B,QAASA,EAAE,OAAO,EAClB,wBAAyBA,EAAE,KAAK,CAAC,IAAK,GAAG,CAAC,EAC1C,UAAWA,EAAE,OAAO,EACpB,UAAWA,EAAE,OAAO,CACtB,CAAC,EAEY0J,GAAmB1J,EAAE,MAAMyJ,EAAe,ECvDhD,IAAME,GAA2C,6CAI3C3I,GAAoD,CAC9D,KAAmB,sEACnB,WAAmB,mEACtB,EAEa4I,GAAgB,CAC3B,QAAS,MACT,aAAc,mDAChB,EAEaC,GAAgB,CAC3B,QAAS,MACT,aAAc,mDAChB,ECZA,OAAS,SAAAC,OAAa,OCbf,IAAMC,GAAe,MAAOC,GAE1B,MADU,MAAM,MAAMA,CAAG,GACV,KAAK,EDc7B,IAAMlJ,GAA0BC,GACvBA,kBAA4BA,WAG/BkJ,GAAkBC,GACtBA,EAAO,SAAW,YAEdC,GAAY,MAAOC,EAAiBrJ,IAAqB,CAC7D,IAAMsJ,EAAa,MAAMN,GAAa,GAAGK,CAAO,SAAS,EAEzD,MAAO,CAACrJ,iBAA2B6I,GAAgBC,GAAe,GAAGL,GAAgB,MAAMa,CAAU,CAAC,CACxG,EAEMC,GAAa,MAAOF,EAAiBG,KAClB,MAAM,QAAQ,WACnCA,EAAO,IAAI,MAAO1O,GAAU,CAC1B,IAAM2O,EAAmB,MAAMT,GAAa,GAAGK,CAAO,WAAWvO,EAAM,OAAO,UAAU,EACxF,OAAO6N,GAAiB,MAAMc,CAAgB,CAChD,CAAC,CACH,GACsB,OAAOP,EAAW,EAAE,QAASQ,GAAMA,EAAE,KAAK,EAGrDxJ,GAAY,MAAO1C,GAA4D,CAC1F,GAAI,CAACuC,GAAuBvC,CAAW,EACrC,MAAM,IAAIhC,8BAER,yBAAyBgC,CAAW,cACtC,EAGF,GAAI,CACF,IAAM6L,EAAUpJ,GAAYzC,CAAW,EACjCgM,EAAS,MAAMJ,GAAUC,EAAS7L,CAAW,EAC7CmM,EAAU,MAAMJ,GAAWF,EAASG,CAAM,EAC1C7P,EAA+B,CAAC,EAEtC,OAAAgQ,EAAQ,QAASC,GAAW,CAC1B,IAAMC,EAAgBL,EAAO,KAAK,CAAC,CAAE,QAAAM,CAAQ,IAAMA,IAAYF,EAAO,gBAAgB,EAEtF,GAAI,CAACC,EAEH,OAGF,IAAIE,EAAkBpQ,EAAO,KAC3B,CAAC,CAAE,UAAAqQ,CAAU,IACXA,EAAU,UAAYpP,EAAM,SAAS,CAAE,UAAW,SAAU,UAAW,OAAOiP,EAAc,OAAO,CAAE,CAAC,CAC1G,EACKE,IACHA,EAAkB,CAChB,UAAW,CACT,QAASnP,EAAM,SAAS,CAAE,UAAW,SAAU,UAAW,OAAOiP,EAAc,OAAO,CAAE,CAAC,EACzF,aAAcd,GAAMT,GAAY,OAAOuB,EAAc,YAAY,CAAC,CACpE,EACA,aAAc,CAAC,CACjB,EACAlQ,EAAO,KAAKoQ,CAAe,GAG7B,IAAIE,EAAcF,EAAgB,aAAa,KAC7C,CAAC,CAAE,iBAAAG,CAAiB,IAAMA,IAAqBN,EAAO,gBACxD,EACKK,IACHA,EAAc,CACZ,UAAW,CACT,QAASL,EAAO,aAChB,SAAUA,EAAO,cACjB,KAAMA,EAAO,WAAaA,EAAO,YACjC,OAAQA,EAAO,YACf,YACF,EACA,QAAS,CAAC,EACV,kBAAmBhB,GACnB,iBAAkBgB,EAAO,iBACzB,kBAAmBA,EAAO,aAC5B,EACAG,EAAgB,aAAa,KAAKE,CAAW,GAG/C,IAAMzD,EAAcgD,EAAO,KAAK,CAAC,CAAE,QAAAM,CAAQ,IAAMA,IAAYF,EAAO,kBAAkB,EAEtF,GAAI,CAACpD,EAEH,OAGF,IAAM2D,EAAoBpB,GAAMT,GAAY,OAAO9B,EAAY,YAAY,CAAC,EACtE4D,EAASxP,EAAM,SAAS,CAAE,UAAW,SAAU,UAAW,OAAOgP,EAAO,kBAAkB,CAAE,CAAC,EAC5EK,EAAY,QAAQ,KACzC,CAAC,CAAE,mBAAAI,EAAoB,YAAa,CAAE,QAAArQ,CAAQ,CAAE,IAC9CqQ,IAAuBT,EAAO,oBAAsB5P,IAAYoQ,CACpE,GAEEH,EAAY,QAAQ,KAAK,CACvB,YAAa,CACX,QAASG,EACT,aAAcD,CAChB,EACA,mBAAoBP,EAAO,kBAC7B,CAAC,CAEL,CAAC,EAGMjQ,EACJ,IAAKiL,IAAiB,CACrB,GAAGA,EACH,aAAcA,EAAY,aAAa,OAAQ0F,GAAiBA,EAAa,QAAQ,OAAS,CAAC,CACjG,EAAE,EACD,OAAQ1F,GAAgBA,EAAY,aAAa,OAAS,CAAC,CAChE,OAAS5F,EAAK,CACZ,MAAM,IAAIxD,yBAER,iDAAkDwD,EAAyB,OAAO,EACpF,CACF,CACF,EE/HO,IAAMuF,GAAwB,MAAO5K,EAA8ByC,IAAwC,CAChH,GAAM,CACJ,aAAA0K,EACA,gBAAiB,CAAE,UAAAyD,CAAU,EAC7B,kBAAmB,CAAE,mBAAAF,CAAmB,CAC1C,EAAI3O,EAAgBU,EAAQzC,CAAM,EAC5B6K,EAAqB,CAAE,GAAG+F,EAAW,QAASzD,EAAeuD,EAAqBE,EAAU,OAAQ,EACpG5M,EAAO,MAAMxB,GAAQxC,EAAQyC,CAAM,EACzC,MAAO,CACL,OAAQA,EAAO,QAAUuB,EAAK4M,EAAU,OAAO,GAAK,IACpD,MAAO/F,CACT,CACF,EClBA,OAAS,kBAAAC,OAAsB,OAMxB,SAASE,GAAUhL,EAA8ByC,EAA6C,CACnG,QAAWwI,KAAejL,EACxB,QAAWiQ,KAAUhF,EAAY,aAAc,CAC7C,IAAMC,EAAyBzI,EAAO,eAAe,KAAK,CAAC,CAAE,OAAA0I,CAAO,IAAMA,IAAW8E,EAAO,UAAU,MAAM,EAE5G,GAAI,CAAC/E,EACH,SAGF,IAAM2F,EAAuB/F,GAAemF,EAAO,kBAAmBxN,EAAO,EAAE,EACzEqO,EACJhG,GAAerI,EAAO,KAAMwN,EAAO,gBAAgB,GACnDnF,GAAeI,EAAuB,KAAM+E,EAAO,gBAAgB,EAC/DvE,EACJZ,GAAerI,EAAO,KAAMsI,CAAY,GAAKD,GAAeI,EAAuB,KAAMH,CAAY,EAIvG,GAAI8F,IAAyBC,GAAmBpF,GAC9C,MAAO,CACL,WAAY,GAEZ,cAAeuE,EAAO,QAAQ,SAAW,EAAIA,EAAO,QAAQ,CAAC,EAAG,YAAY,QAAU,OACtF,cAAexN,EAAO,QACtB,6BACF,EAQF,GAHEqI,GAAerI,EAAO,GAAIwN,EAAO,gBAAgB,GACjDnF,GAAeI,EAAuB,GAAI+E,EAAO,gBAAgB,EAGjE,MAAO,CACL,WAAY,GACZ,cAAexN,EAAO,QAEtB,cAAewN,EAAO,QAAQ,SAAW,EAAIA,EAAO,QAAQ,CAAC,EAAG,YAAY,QAAU,OACtF,6BACF,CAEJ,CAGF,MAAO,CACL,WAAY,EACd,CACF,CCzCO,IAAMc,GAAuD,MAAOlN,EAAaZ,IAAW,CACjG,IAAMjD,EAAS,MAAMuG,GAAU1C,CAAW,EAC1C,MAAO,CACL,wBACA,UAAYpB,GAA4BuI,GAAUhL,EAAQ6L,GAAqBpJ,CAAM,CAAC,EACtF,YAAcA,GAAgC+H,GAAYxK,EAAQmM,EAA8B1J,CAAM,CAAC,EACvG,sBAAwBA,GACtBmI,GAAsB5K,EAAQmM,EAA8B1J,CAAM,CAAC,EACrE,UAAW,IAAM1C,GAAUC,CAAM,EACjC,QAAUyC,GAAWD,GAAQxC,EAAQyC,CAAM,EAC3C,yBAA2BA,GAAWkI,GAAyB3K,EAAQyC,CAAM,EAC7E,cAAgBA,GAAWmB,GAAc5D,EAAQqM,GAAyB5J,CAAM,EAAGoB,EAAaZ,CAAM,EACtG,cAAgBR,GAAWoH,GAAc7J,EAAQyC,CAAM,CACzD,CACF,ECbA,OAAS,WAAAuO,OAAe,SCdxB,OAAS,sBAAApO,GAAoB,aAAA4C,OAAiB,OCAvC,IAAMyL,GAAY,CACvB,CACE,UAAW,GACX,OAAQ,CACN,CACE,QAAS,GACT,aAAc,UACd,KAAM,MACN,KAAM,SACR,EACA,CACE,QAAS,GACT,aAAc,UACd,KAAM,MACN,KAAM,SACR,EACA,CACE,QAAS,GACT,aAAc,UACd,KAAM,MACN,KAAM,SACR,CACF,EACA,KAAM,WACN,KAAM,OACR,EACA,CACE,UAAW,GACX,OAAQ,CACN,CACE,QAAS,GACT,aAAc,UACd,KAAM,MACN,KAAM,SACR,EACA,CACE,QAAS,GACT,aAAc,UACd,KAAM,MACN,KAAM,SACR,CACF,EACA,KAAM,UACN,KAAM,OACR,EACA,CACE,UAAW,GACX,OAAQ,CACN,CACE,QAAS,GACT,aAAc,UACd,KAAM,MACN,KAAM,SACR,EACA,CACE,QAAS,GACT,aAAc,UACd,KAAM,MACN,KAAM,SACR,EACA,CACE,QAAS,GACT,aAAc,UACd,KAAM,MACN,KAAM,SACR,CACF,EACA,KAAM,WACN,KAAM,OACR,EACA,CACE,UAAW,GACX,OAAQ,CACN,CACE,QAAS,GACT,aAAc,UACd,KAAM,MACN,KAAM,SACR,EACA,CACE,QAAS,GACT,aAAc,UACd,KAAM,MACN,KAAM,SACR,CACF,EACA,KAAM,aACN,KAAM,OACR,EACA,CACE,QAAS,GACT,gBAAiB,UACjB,KAAM,UACR,EACA,CACE,SAAU,GACV,OAAQ,CACN,CACE,aAAc,UACd,KAAM,GACN,KAAM,SACR,EACA,CACE,aAAc,UACd,KAAM,GACN,KAAM,SACR,CACF,EACA,KAAM,YACN,QAAS,CACP,CACE,aAAc,UACd,KAAM,GACN,KAAM,SACR,CACF,EACA,QAAS,GACT,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,SAAU,GACV,OAAQ,CACN,CACE,aAAc,UACd,KAAM,MACN,KAAM,SACR,EACA,CACE,aAAc,UACd,KAAM,MACN,KAAM,SACR,CACF,EACA,KAAM,UACN,QAAS,CACP,CACE,aAAc,OACd,KAAM,GACN,KAAM,MACR,CACF,EACA,QAAS,GACT,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,SAAU,GACV,OAAQ,CACN,CACE,aAAc,UACd,KAAM,GACN,KAAM,SACR,CACF,EACA,KAAM,YACN,QAAS,CACP,CACE,aAAc,UACd,KAAM,GACN,KAAM,SACR,CACF,EACA,QAAS,GACT,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,SAAU,GACV,OAAQ,CAAC,EACT,KAAM,WACN,QAAS,CACP,CACE,aAAc,QACd,KAAM,GACN,KAAM,OACR,CACF,EACA,QAAS,GACT,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,SAAU,GACV,OAAQ,CAAC,EACT,KAAM,UACN,QAAS,CAAC,EACV,QAAS,GACT,gBAAiB,UACjB,KAAM,UACR,EACA,CACE,SAAU,GACV,OAAQ,CAAC,EACT,KAAM,OACN,QAAS,CACP,CACE,aAAc,SACd,KAAM,GACN,KAAM,QACR,CACF,EACA,QAAS,GACT,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,SAAU,GACV,OAAQ,CAAC,EACT,KAAM,SACN,QAAS,CACP,CACE,aAAc,SACd,KAAM,GACN,KAAM,QACR,CACF,EACA,QAAS,GACT,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,SAAU,GACV,OAAQ,CACN,CACE,aAAc,UACd,KAAM,MACN,KAAM,SACR,EACA,CACE,aAAc,UACd,KAAM,MACN,KAAM,SACR,CACF,EACA,KAAM,WACN,QAAS,CACP,CACE,aAAc,OACd,KAAM,GACN,KAAM,MACR,CACF,EACA,QAAS,GACT,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,SAAU,GACV,OAAQ,CACN,CACE,aAAc,UACd,KAAM,MACN,KAAM,SACR,EACA,CACE,aAAc,UACd,KAAM,MACN,KAAM,SACR,EACA,CACE,aAAc,UACd,KAAM,MACN,KAAM,SACR,CACF,EACA,KAAM,eACN,QAAS,CACP,CACE,aAAc,OACd,KAAM,GACN,KAAM,MACR,CACF,EACA,QAAS,GACT,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,SAAU,GACV,OAAQ,CACN,CACE,aAAc,UACd,KAAM,MACN,KAAM,SACR,CACF,EACA,KAAM,WACN,QAAS,CAAC,EACV,QAAS,GACT,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,SAAU,GACV,OAAQ,CACN,CACE,aAAc,UACd,KAAM,QACN,KAAM,SACR,EACA,CACE,aAAc,UACd,KAAM,WACN,KAAM,SACR,CACF,EACA,KAAM,SACN,QAAS,CAAC,EACV,QAAS,GACT,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,SAAU,GACV,OAAQ,CAAC,EACT,KAAM,cACN,QAAS,CACP,CACE,KAAM,GACN,KAAM,SACR,CACF,EACA,QAAS,GACT,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,SAAU,GACV,OAAQ,CACN,CACE,aAAc,UACd,KAAM,QACN,KAAM,SACR,EACA,CACE,aAAc,UACd,KAAM,SACN,KAAM,SACR,CACF,EACA,KAAM,OACN,QAAS,CACP,CACE,aAAc,OACd,KAAM,GACN,KAAM,MACR,CACF,EACA,QAAS,GACT,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,SAAU,GACV,OAAQ,CACN,CACE,aAAc,UACd,KAAM,GACN,KAAM,SACR,CACF,EACA,KAAM,aACN,QAAS,CACP,CACE,aAAc,UACd,KAAM,GACN,KAAM,SACR,CACF,EACA,QAAS,GACT,gBAAiB,OACjB,KAAM,UACR,CACF,ECtXO,IAAMC,GAAW,CACtB,CACE,SAAU,GACV,OAAQ,CAAC,EACT,KAAM,OACN,QAAS,CACP,CACE,KAAM,GACN,KAAM,QACR,CACF,EACA,QAAS,GACT,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,SAAU,GACV,OAAQ,CACN,CACE,KAAM,MACN,KAAM,SACR,EACA,CACE,KAAM,MACN,KAAM,SACR,CACF,EACA,KAAM,UACN,QAAS,CACP,CACE,KAAM,GACN,KAAM,MACR,CACF,EACA,QAAS,GACT,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,SAAU,GACV,OAAQ,CAAC,EACT,KAAM,cACN,QAAS,CACP,CACE,KAAM,GACN,KAAM,SACR,CACF,EACA,QAAS,GACT,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,SAAU,GACV,OAAQ,CACN,CACE,KAAM,MACN,KAAM,SACR,EACA,CACE,KAAM,MACN,KAAM,SACR,EACA,CACE,KAAM,MACN,KAAM,SACR,CACF,EACA,KAAM,eACN,QAAS,CACP,CACE,KAAM,GACN,KAAM,MACR,CACF,EACA,QAAS,GACT,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,SAAU,GACV,OAAQ,CACN,CACE,KAAM,MACN,KAAM,SACR,CACF,EACA,KAAM,WACN,QAAS,CAAC,EACV,QAAS,GACT,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,SAAU,GACV,OAAQ,CAAC,EACT,KAAM,WACN,QAAS,CACP,CACE,KAAM,GACN,KAAM,OACR,CACF,EACA,QAAS,GACT,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,SAAU,GACV,OAAQ,CACN,CACE,KAAM,GACN,KAAM,SACR,CACF,EACA,KAAM,YACN,QAAS,CACP,CACE,KAAM,GACN,KAAM,SACR,CACF,EACA,QAAS,GACT,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,SAAU,GACV,OAAQ,CAAC,EACT,KAAM,SACN,QAAS,CACP,CACE,KAAM,GACN,KAAM,QACR,CACF,EACA,QAAS,GACT,gBAAiB,OACjB,KAAM,UACR,EACA,CACE,SAAU,GACV,OAAQ,CACN,CACE,KAAM,MACN,KAAM,SACR,EACA,CACE,KAAM,MACN,KAAM,SACR,CACF,EACA,KAAM,WACN,QAAS,CACP,CACE,KAAM,GACN,KAAM,MACR,CACF,EACA,QAAS,GACT,gBAAiB,aACjB,KAAM,UACR,EACA,CACE,SAAU,GACV,OAAQ,CAAC,EACT,KAAM,UACN,QAAS,CAAC,EACV,QAAS,GACT,gBAAiB,UACjB,KAAM,UACR,EACA,CACE,SAAU,GACV,OAAQ,CACN,CACE,KAAM,GACN,KAAM,SACR,EACA,CACE,KAAM,GACN,KAAM,SACR,CACF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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\ntype BaseAsset = {\n name: string;\n symbol: string;\n decimals: number;\n};\n\nexport type Erc20Asset = BaseAsset & {\n type: TokenType.ERC20;\n address: Address;\n};\n\nexport type NativeAsset = BaseAsset & {\n type: TokenType.NATIVE;\n};\n\nexport const isErc20Asset = (asset: Asset): asset is Erc20Asset => asset.type === TokenType.ERC20;\nexport const isNativeAsset = (asset: Asset): asset is NativeAsset => asset.type === TokenType.NATIVE;\n\nexport type Asset = Erc20Asset | NativeAsset;\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 = Partial<Record<Address | 'NATIVE', bigint>>;\n","import type { Chain } from './chain';\nimport type { Environment } from './environment';\nimport type { BtcSigner, EvmSigner } from './signer';\nimport type { BridgeTransfer } from './transfer';\nimport type { Asset, AssetFeeMap, BridgeAsset, ChainAssetMap } from './asset';\nimport type { BitcoinFunctions } from './bitcoin-functions';\n\nexport enum BridgeType {\n AVALANCHE_EVM = 'avalanche-evm',\n AVALANCHE_BTC_AVA = 'avalanche-btc-ava',\n AVALANCHE_AVA_BTC = 'avalanche-ava-btc',\n CCTP = 'cctp',\n ICTT_ERC20_ERC20 = 'ictt-erc20-erc20',\n}\n\nexport const BTC_BRIDGE_TYPES = [BridgeType.AVALANCHE_AVA_BTC, BridgeType.AVALANCHE_BTC_AVA] as const;\nexport const EVM_BRIDGE_TYPES = [BridgeType.AVALANCHE_EVM, BridgeType.CCTP, BridgeType.ICTT_ERC20_ERC20] as const;\n\nexport type ArrayElement<A> = A extends readonly (infer T)[] ? T : never;\n\nexport type EvmBridgeInitializer = {\n type: ArrayElement<typeof EVM_BRIDGE_TYPES>;\n signer: EvmSigner;\n};\n\nexport type AvaToBtcBridgeInitializer = {\n type: BridgeType.AVALANCHE_AVA_BTC;\n signer: EvmSigner;\n bitcoinFunctions: BitcoinFunctions;\n};\n\nexport type BtcToAvaBridgeInitializer = {\n type: BridgeType.AVALANCHE_BTC_AVA;\n signer: BtcSigner;\n bitcoinFunctions: BitcoinFunctions;\n};\n\nexport type BridgeInitializer = EvmBridgeInitializer | AvaToBtcBridgeInitializer | BtcToAvaBridgeInitializer;\n\nexport const isEvmBridgeInitializer = (initializer: BridgeInitializer): initializer is EvmBridgeInitializer => {\n return (EVM_BRIDGE_TYPES as readonly BridgeType[]).includes(initializer.type);\n};\n\nexport const isAvaToBtcBridgeInitializer = (\n initializer: BridgeInitializer,\n): initializer is AvaToBtcBridgeInitializer => {\n return initializer.type === BridgeType.AVALANCHE_AVA_BTC;\n};\n\nexport const isBtcToAvaBridgeInitializer = (\n initializer: BridgeInitializer,\n): initializer is BtcToAvaBridgeInitializer => {\n return initializer.type === BridgeType.AVALANCHE_BTC_AVA;\n};\n\nexport type FeeParams = {\n asset: BridgeAsset;\n amount: bigint;\n sourceChain: Chain;\n targetChain: Chain;\n};\n\nexport enum BridgeSignatureReason {\n AllowanceApproval = 'allowance-approval',\n TokensTransfer = 'tokens-transfer',\n WrapToken = 'wrap-token',\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 onStepChange?: (stepDetails: BridgeStepDetails) => void;\n};\n\nexport type GasEstimationParams = Omit<TransferParams, 'onStepChange' | 'toAddress'>;\n\nexport type TrackingParams = {\n bridgeTransfer: BridgeTransfer;\n updateListener: (transfer: BridgeTransfer) => void;\n};\n\nexport type AnalyzeTxParams = {\n chainId: string;\n from: string;\n to: string;\n tokenTransfers: {\n from?: string;\n to?: string;\n symbol: string;\n }[];\n};\n\nexport type AnalyzeTxResult =\n | {\n isBridgeTx: true;\n bridgeType: BridgeType;\n // We can't always provide both of these cheaply (i.e. for ICTT)\n sourceChainId?: string;\n targetChainId?: string;\n }\n | { isBridgeTx: false };\n\nexport type BridgeService = {\n type: BridgeType;\n analyzeTx: (params: AnalyzeTxParams) => AnalyzeTxResult;\n estimateGas: (params: GasEstimationParams) => Promise<bigint>;\n estimateReceiveAmount: (params: GasEstimationParams) => Promise<{\n asset: Asset;\n amount: bigint;\n }>;\n transferAsset: (params: TransferParams) => Promise<BridgeTransfer>;\n trackTransfer: (transfer: TrackingParams) => { cancel: () => void; result: Promise<BridgeTransfer> };\n getAssets: () => ChainAssetMap;\n getFees: (params: FeeParams) => Promise<AssetFeeMap>;\n getMinimumTransferAmount: (params: FeeParams) => Promise<bigint>;\n};\n\nexport type BridgeServiceFactory = (environment: Environment) => Promise<BridgeService>;\n","import type { Address } from 'viem';\nimport { TokenType, type NativeAsset } from './asset';\n\nexport type Chain = {\n chainName: string;\n chainId: string;\n rpcUrl: string;\n utilityAddresses?: { multicall: Address };\n networkToken: NativeAsset;\n};\n\nexport enum AvalancheChainIds {\n FUJI = 'eip155:43113',\n MAINNET = 'eip155:43114',\n}\n\nexport enum EthereumChainIds {\n MAINNET = 'eip155:1',\n SEPOLIA = 'eip155:11155111',\n}\n\nexport enum BitcoinChainIds {\n MAINNET = 'bip122:000000000019d6689c085ae165831e93',\n TESTNET = 'bip122:000000000933ea01ad0ee984209779ba',\n}\n\nexport const AVALANCHE_FUJI_CHAIN: Chain = {\n chainId: AvalancheChainIds.FUJI,\n chainName: 'Avalanche Fuji',\n rpcUrl: 'https://api.avax-test.network/ext/bc/C/rpc',\n networkToken: {\n type: TokenType.NATIVE,\n name: 'AVAX',\n symbol: 'AVAX',\n decimals: 18,\n },\n};\n\nexport const AVALANCHE_MAINNET_CHAIN: Chain = {\n chainId: AvalancheChainIds.MAINNET,\n chainName: 'Avalanche Mainnet',\n rpcUrl: 'https://api.avax.network/ext/bc/C/rpc',\n networkToken: {\n type: TokenType.NATIVE,\n name: 'AVAX',\n symbol: 'AVAX',\n decimals: 18,\n },\n};\n\nexport const ETHEREUM_SEPOLIA_CHAIN: Chain = {\n chainId: EthereumChainIds.SEPOLIA,\n chainName: 'Ethereum Sepolia',\n rpcUrl: 'https://proxy-api.avax.network/proxy/infura/sepolia',\n networkToken: {\n type: TokenType.NATIVE,\n name: 'ETH',\n symbol: 'ETH',\n decimals: 18,\n },\n};\n\nexport const ETHEREUM_MAINNET_CHAIN: Chain = {\n chainId: EthereumChainIds.MAINNET,\n chainName: 'Ethereum Mainnet',\n rpcUrl: 'https://proxy-api.avax.network/proxy/infura/mainnet',\n networkToken: {\n type: TokenType.NATIVE,\n name: 'ETH',\n symbol: 'ETH',\n decimals: 18,\n },\n};\n\nexport const BITCOIN_TESTNET_CHAIN: Chain = {\n chainId: BitcoinChainIds.TESTNET,\n chainName: 'Bitcoin Testnet',\n rpcUrl: '',\n networkToken: {\n type: TokenType.NATIVE,\n name: 'Bitcoin',\n symbol: 'BTC',\n decimals: 8,\n },\n};\n\nexport const BITCOIN_MAINNET_CHAIN: Chain = {\n chainId: BitcoinChainIds.MAINNET,\n chainName: 'Bitcoin Mainnet',\n rpcUrl: '',\n networkToken: {\n type: TokenType.NATIVE,\n name: 'Bitcoin',\n symbol: 'BTC',\n decimals: 8,\n },\n};\n","export enum Environment {\n DEV = 'dev',\n PROD = 'production',\n STAGING = 'staging',\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 ASSET_NOT_SUPPORTED = 'ASSET_NOT_SUPPORTED', // the provided asset is not supported by the bridge\n CHAIN_NOT_SUPPORTED = 'CHAIN_NOT_SUPPORTED', // the provided source or target chain is not supported by the bridge\n CONFIG_NOT_AVAILABLE = 'CONFIG_NOT_AVAILABLE', // error while fetching or parsing the config\n CONFIRMATION_COUNT_UNKNOWN = 'CONFIRMATION_COUNT_UNKNOWN', // required confirmation count of the source or target chain is unknown\n ENVIRONMENT_NOT_SUPPORTED = 'ENVIRONMENT_NOT_SUPPORTED', // bridge does not support specified environment\n IDENTICAL_CHAINS_PROVIDED = 'IDENTICAL_CHAINS_PROVIDED', // provided source and target chains are the same\n INCORRECT_ADDRESS_PROVIDED = 'INCORRECT_ADDRESS_PROVIDED', // the sender or recipient address is incorrect\n INCORRECT_AMOUNT_PROVIDED = 'INCORRECT_AMOUNT_PROVIDED', // the transfer amount is incorrect (e.g.: lesser than or equal to zero)\n INCORRECT_HASH_PROVIDED = 'INCORRECT_HASH_PROVIDED', // the transaction is not hex\n INCORRECT_PROVIDER_PROVIDED = 'INCORRECT_PROVIDER_PROVIDED', // The provided provider is incorrect type (Provider VS BitcoinProvider)\n INCORRECT_SIGNER_PROVIDED = 'INCORRECT_SIGNER_PROVIDED', // The provided signer is incorrect type\n INCORRECT_TXHASH_PROVIDED = 'INCORRECT_TXHASH_PROVIDED', // the sourceTxHash or targetTxHash is incorrect\n INVALID_PARAMS = 'INVALID_PARAMS', // generic error with the params\n UNKNOWN = 'UNKNOWN', // generic, not specified error\n VULNERABLE_TOKEN_APPROVAL_ADDRESS = 'VULNERABLE_TOKEN_APPROVAL_ADDRESS', // error when the address has token approvals for addresses involved in the multichain incident\n WARDEN_CONFIG_MISMATCH = 'WARDEN_CONFIG_MISMATCH', // error when warden config was not found or it is over the mismatch threshold\n WARDEN_CONFIG_MISSING_NETWORK = 'WARDEN_CONFIG_MISSING_NETWORK', // fetched warden config does not contain network IDs\n}\n","import { isArray, mergeWith } from 'lodash';\nimport {\n type BridgeServiceConfig,\n type ChainAssetMap,\n type FeeParams,\n type GasEstimationParams,\n type TransferParams,\n type BridgeAsset,\n type TrackingParams,\n type AnalyzeTxParams,\n type AnalyzeTxResult,\n BridgeType,\n type BridgeService,\n type BridgeTransfer,\n type UnifiedBridgeService,\n} from './types';\nimport { getBridgeForTransfer } from './utils';\n\nexport const createUnifiedBridgeService = ({ environment, enabledBridgeServices }: BridgeServiceConfig) => {\n const getAssets = () => {\n const assets: ChainAssetMap[] = Array.from(enabledBridgeServices.values()).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 estimateReceiveAmount = async (params: GasEstimationParams) => {\n const { bridge } = getBridgeForTransfer(enabledBridgeServices, params.asset, params.targetChain.chainId);\n return bridge.estimateReceiveAmount(params);\n };\n\n const getMinimumTransferAmount = async (params: FeeParams) => {\n const { bridge } = getBridgeForTransfer(enabledBridgeServices, params.asset, params.targetChain.chainId);\n return bridge.getMinimumTransferAmount(params);\n };\n\n const transferAsset = async (params: TransferParams): Promise<BridgeTransfer> => {\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 } = getBridgeForTransfer(\n enabledBridgeServices,\n params.bridgeTransfer.asset,\n params.bridgeTransfer.targetChain.chainId,\n );\n\n return bridge.trackTransfer(params);\n };\n\n const estimateGas = async (params: GasEstimationParams) => {\n const { bridge } = getBridgeForTransfer(enabledBridgeServices, params.asset, params.targetChain.chainId);\n return bridge.estimateGas(params);\n };\n\n const analyzeTx = (params: AnalyzeTxParams): AnalyzeTxResult => {\n // Sometimes multiple bridge implementations may return \"isBridgeTx\" === true.\n // Some bridge solutions offer better certainty, though, so we look at them first.\n const services = [BridgeType.AVALANCHE_EVM, BridgeType.ICTT_ERC20_ERC20, BridgeType.CCTP]\n .map((type) => enabledBridgeServices.get(type))\n .filter((x): x is BridgeService => !!x);\n\n for (const service of services) {\n const result = service.analyzeTx(params);\n\n if (result.isBridgeTx) {\n return result;\n }\n }\n\n return {\n isBridgeTx: false,\n };\n };\n\n const service: UnifiedBridgeService = {\n canTransferAsset,\n environment,\n estimateGas,\n estimateReceiveAmount,\n getAssets,\n getFees,\n analyzeTx,\n getMinimumTransferAmount,\n trackTransfer,\n transferAsset,\n };\n return service;\n};\n","import { TokenType, type ChainAssetMap, type DestinationInfo, BridgeType } from '../../../types';\nimport type { Config } from '../types/config';\n\nexport function getAssets(config: Config) {\n const chainIds = config.map((chainData) => chainData.chainId);\n\n return 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, http } from 'viem';\nimport type { Chain } from '../../types/chain';\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 }: { chain: Chain }) => {\n const chainInfo = _getChain(chain);\n const transport = http(chain.rpcUrl, { batch: true, retryCount: 0 });\n return createWalletClient({\n chain: chainInfo,\n transport,\n }).extend(publicActions);\n};\n\nexport type Client = ReturnType<typeof getClientForChain>;\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 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 { InvalidParamsError } from '../../../errors';\nimport { ErrorReason } from '../../../types';\nimport type { ValidEvmTransferParams } from '../../../utils/evm/types/bridge';\nimport type { Config } from '../types/config';\n\ntype PartialTransferParams = Pick<ValidEvmTransferParams, 'sourceChain' | 'targetChain' | 'amount'> & {\n asset: Pick<ValidEvmTransferParams['asset'], 'symbol'>;\n};\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\nexport type CCTPTransferData = ReturnType<typeof getTransferData>;\n","import { type AssetFeeMap, type FeeParams } from '../../../types';\nimport { getClientForChain } from '../../../utils/evm/client';\nimport { TOKEN_ROUTER_ABI } from '../abis/token-router';\nimport type { Config } from '../types/config';\nimport { getTransferData } from '../utils/transfer-data';\n\nexport async function getFees(config: Config, params: FeeParams): Promise<AssetFeeMap> {\n const { sourceChain, targetChain, asset, amount } = params;\n\n const { sourceChainData, targetChainData, burnToken } = getTransferData(\n { sourceChain, targetChain, asset, amount },\n config,\n );\n\n const client = getClientForChain({ chain: sourceChain });\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 };\n}\n","import { type PublicClient } from 'viem';\nimport {\n ErrorReason,\n BridgeType,\n type Environment,\n type Hex,\n BridgeSignatureReason,\n isErc20Asset,\n type EvmSigner,\n type BridgeTransfer,\n} from '../../../types';\nimport { getClientForChain } from '../../../utils/evm/client';\nimport { ERC20_ABI } from '../../../abis/erc20';\nimport { getTransferData } from '../utils/transfer-data';\nimport { InvalidParamsError } from '../../../errors';\nimport { buildApprovalTxData, buildTransferTxData } from '../utils/build-tx';\nimport type { Config } from '../types/config';\nimport { getFees } from './get-fees';\nimport type { ValidEvmTransferParams } from '../../../utils/evm/types/bridge';\n\nconst approveAndTransfer = async (config: Config, params: ValidEvmTransferParams, signer: EvmSigner) => {\n const { sourceChain, targetChain, asset, amount, fromAddress, toAddress, onStepChange } = params;\n\n const { sourceChainData, targetChainData, burnToken } = getTransferData(\n { sourceChain, targetChain, asset, amount },\n config,\n );\n const client = getClientForChain({ chain: sourceChain });\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 const data = buildApprovalTxData({\n amount,\n sourceChainData,\n });\n const txHash = await signer.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 }\n\n onStepChange?.({\n currentSignature: isAllowanceApprovalRequired ? 2 : 1,\n currentSignatureReason: BridgeSignatureReason.TokensTransfer,\n requiredSignatures,\n });\n\n const data = buildTransferTxData({\n amount,\n burnToken,\n targetChainData,\n toAddress,\n });\n\n return signer.sign(\n {\n from: fromAddress,\n to: sourceChainData.tokenRouterAddress,\n data,\n },\n (signedTxHash: Hex) => client.sendRawTransaction({ serializedTransaction: signedTxHash }),\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 config: Config,\n params: ValidEvmTransferParams,\n environment: Environment,\n signer: EvmSigner,\n): Promise<BridgeTransfer> {\n const { minimumConfirmations: sourceRequiredConfirmationCount } =\n config.find((chainData) => chainData.chainId === params.sourceChain.chainId) ?? {};\n const { minimumConfirmations: targetRequiredConfirmationCount } =\n config.find((chainData) => chainData.chainId === params.targetChain.chainId) ?? {};\n\n if (!sourceRequiredConfirmationCount || !targetRequiredConfirmationCount) {\n throw new InvalidParamsError(ErrorReason.CONFIRMATION_COUNT_UNKNOWN);\n }\n\n const fees = await getFees(config, {\n asset: params.asset,\n amount: params.amount,\n sourceChain: params.sourceChain,\n targetChain: params.targetChain,\n });\n\n const bridgeFee = isErc20Asset(params.asset) ? fees[params.asset.address] ?? 0n : 0n;\n const txHash = await approveAndTransfer(config, params, signer);\n const sourceStartedAt = Date.now();\n const targetClient = getClientForChain({ chain: params.targetChain });\n const targetBlockNumber = await getStartBlockNumber(targetClient);\n\n return {\n type: BridgeType.CCTP,\n environment,\n fromAddress: params.fromAddress,\n toAddress: params.toAddress ?? params.fromAddress,\n amount: params.amount,\n asset: params.asset,\n\n bridgeFee,\n\n sourceChain: params.sourceChain,\n sourceStartedAt,\n sourceTxHash: txHash,\n sourceConfirmationCount: 0,\n sourceRequiredConfirmationCount,\n\n targetChain: params.targetChain,\n targetConfirmationCount: 0,\n targetRequiredConfirmationCount,\n\n targetStartBlockNumber: 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 {\n anonymous: false,\n inputs: [\n {\n indexed: false,\n internalType: 'address',\n name: 'to',\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: 'feeAddress',\n type: 'address',\n },\n {\n indexed: false,\n internalType: 'uint256',\n name: 'feeAmount',\n type: 'uint256',\n },\n {\n indexed: false,\n internalType: 'bytes32',\n name: 'originTxId',\n type: 'bytes32',\n },\n ],\n name: 'Mint',\n type: 'event',\n },\n] as const;\n","import { encodeFunctionData } from 'viem';\nimport type { ChainData, Token } from '../types/config';\nimport { TOKEN_ROUTER_ABI } from '../abis/token-router';\nimport { ERC20_ABI } from '../../../abis/erc20';\n\nexport function buildTransferTxData({\n amount,\n burnToken,\n targetChainData,\n toAddress,\n}: {\n targetChainData: ChainData;\n toAddress: `0x${string}`;\n burnToken: Token;\n amount: bigint;\n}) {\n return encodeFunctionData({\n abi: TOKEN_ROUTER_ABI,\n functionName: 'transferTokens',\n args: [amount, targetChainData.domain, toAddress, burnToken.address],\n });\n}\n\nexport function buildApprovalTxData({ amount, sourceChainData }: { amount: bigint; sourceChainData: ChainData }) {\n return encodeFunctionData({\n abi: ERC20_ABI,\n functionName: 'approve',\n args: [sourceChainData.tokenRouterAddress, amount],\n });\n}\n","import { isHash } from 'viem';\nimport { ErrorReason, type BridgeTransfer, type TrackingParams } from '../../../types';\nimport { getClientForChain } from '../../../utils/evm/client';\nimport { retryPromise } from '../../../utils/retry-promise';\nimport { getTrackingDelayByChainId } from '../utils/config';\n\nimport type { Config } from '../types/config';\nimport { createEvmSourceTracker, createEvmTargetTracker, DEFAULT_TRACKING_CONFIG } from '../../../utils/tracking';\n\nimport { checkMetadata, createGetMetadata, createGetTargetTxHash } from '../utils/cctp-tracking';\nimport { getTransferData } from '../utils/transfer-data';\nimport { InvalidParamsError } from '../../../errors';\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: Config, params: TrackingParams) => {\n const { bridgeTransfer } = params;\n const { asset, amount, sourceChain, targetChain } = bridgeTransfer;\n const transferData = getTransferData({ sourceChain, targetChain, asset, amount }, config);\n const { sourceChainData } = transferData;\n\n const sourceClient = getClientForChain({ chain: sourceChain });\n const targetClient = getClientForChain({ chain: targetChain });\n\n const getMetadata = createGetMetadata(transferData);\n\n const tracker = createEvmSourceTracker({\n sourceClient,\n targetClient,\n getMetadata,\n checkMetadata,\n trackingParams: params,\n trackingConfig: DEFAULT_TRACKING_CONFIG,\n });\n\n return retryPromise<BridgeTransfer>({\n promise: tracker,\n delay: getTrackingDelayByChainId(sourceChainData.chainId),\n startAfter: DEFAULT_TRACKING_CONFIG.initialDelayMs,\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: Config, params: TrackingParams) => {\n const { bridgeTransfer } = params;\n const { asset, amount, sourceChain, targetChain } = bridgeTransfer;\n const targetClient = getClientForChain({ chain: targetChain });\n const transferData = getTransferData(\n {\n sourceChain: sourceChain,\n targetChain: targetChain,\n asset: asset,\n amount: amount,\n },\n config,\n );\n\n const getTargetTxHash = createGetTargetTxHash({ targetClient, transferData });\n\n const tracker = createEvmTargetTracker({\n targetClient,\n getTargetTxHash,\n checkMetadata,\n trackingParams: params,\n trackingConfig: DEFAULT_TRACKING_CONFIG,\n });\n\n return retryPromise<BridgeTransfer>({\n promise: tracker,\n delay: getTrackingDelayByChainId(transferData.targetChainData.chainId),\n startAfter: DEFAULT_TRACKING_CONFIG.initialDelayMs,\n });\n};\n\nexport function trackTransfer(config: Config, params: TrackingParams) {\n if (\n !isHash(params.bridgeTransfer.sourceTxHash) ||\n (params.bridgeTransfer.targetTxHash && !isHash(params.bridgeTransfer.targetTxHash))\n ) {\n throw new InvalidParamsError(ErrorReason.INCORRECT_TXHASH_PROVIDED);\n }\n\n let abortFn: (() => void) | undefined;\n\n const cancel = () => {\n abortFn?.();\n };\n\n const executeTracking = async () => {\n const { updateListener, bridgeTransfer } = params;\n\n const { result: sourceTracker, cancel: cancelSourceTracking } = await trackSourceTx(config, {\n updateListener,\n bridgeTransfer,\n });\n abortFn = cancelSourceTracking;\n const transferAfterSourceFinished = await sourceTracker;\n const { result: targetTracker, cancel: cancelTargetTracking } = await trackTargetTx(config, {\n updateListener,\n bridgeTransfer: transferAfterSourceFinished,\n });\n abortFn = cancelTargetTracking;\n return targetTracker;\n };\n\n return {\n result: executeTracking(),\n cancel,\n };\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 = 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 { z } from 'zod';\nimport { ChainDomain } from './chain';\nimport type { Simplify } from 'type-fest';\nimport { caip2 } from '../../../utils';\nimport { evmAddressSchema } from '../../../utils/evm/evm-address-schema';\n\nexport type Token = typeof tokenSchema._output;\n\nconst tokenSchema = z.object({\n address: evmAddressSchema,\n name: z.string(),\n symbol: z.string(),\n decimals: z.number().positive(),\n});\n\nconst chainIdSchema = z.coerce.string().transform((numericString, ctx) => {\n const prefixedString = numericString.startsWith('eip155:') ? numericString : `eip155:${numericString}`;\n try {\n const parsed = caip2.toJSON(prefixedString);\n return caip2.toString(parsed);\n } catch (e) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'Invalid chain id, neither numeric nor caip2 compliant',\n });\n return z.NEVER;\n }\n});\n\nconst chainDataSchema = z.object({\n chainId: chainIdSchema,\n domain: z.nativeEnum(ChainDomain),\n tokenRouterAddress: evmAddressSchema,\n messageTransmitterAddress: evmAddressSchema,\n tokens: z.array(tokenSchema),\n minimumConfirmations: z.number().positive(),\n});\n\nexport type ChainData = Simplify<typeof chainDataSchema._output>;\nexport const configSchema = z.array(chainDataSchema);\nexport type Config = typeof configSchema._output;\n","export enum ChainDomain {\n Ethereum = 0,\n Avalanche = 1,\n}\n","import { z } from 'zod';\nimport { isAddress, type Address } from 'viem';\n\nexport const evmAddressSchema = z\n .string()\n .refine(\n (arg) => isAddress(arg),\n (arg) => ({ message: `Invalid EVM address '${arg}'` }),\n )\n .transform((a) => a as Address);\n","import { BridgeInitializationError } from '../../../errors';\nimport { AvalancheChainIds, ErrorReason } from '../../../types';\nimport { Environment } from '../../../types/environment';\nimport { configSchema, type Config } from '../types/config';\n\ntype SupportedEnvironments = Environment.PROD | Environment.TEST;\n\nconst isSupportedEnvironment = (env: Environment): env is SupportedEnvironments => {\n return env === Environment.PROD || env === Environment.TEST;\n};\n\nconst CONFIG_URLS: Record<SupportedEnvironments, 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 if (!isSupportedEnvironment(environment)) {\n throw new BridgeInitializationError(\n ErrorReason.ENVIRONMENT_NOT_SUPPORTED,\n `CCTP does not support ${environment} environment`,\n );\n }\n try {\n const response = await fetch(CONFIG_URLS[environment]);\n\n const json = await response.json();\n const config = configSchema.parse(json);\n\n return config;\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 { isHash, type TransactionReceipt } from 'viem';\nimport type { BridgeTransfer } from '../../types/transfer';\nimport type { Client } from '../evm/client';\nimport type { Done } from '../retry-promise';\nimport { type TrackingConfig, updateTransfer } from './utils';\nimport { getNetworkFeeEVM } from '../network-fee';\nimport { ErrorCode, type TrackingParams } from '../../types';\nimport { cloneDeep } from 'lodash';\n\nexport type CreateEvmSourceTrackerArgs = {\n trackingParams: TrackingParams;\n getMetadata: (txReceipt: TransactionReceipt) => BridgeTransfer['metadata'];\n checkMetadata: (metadata: BridgeTransfer['metadata']) => boolean;\n sourceClient: Client;\n targetClient: Client;\n trackingConfig: TrackingConfig;\n};\n\nexport const createEvmSourceTracker = ({\n targetClient,\n sourceClient,\n getMetadata,\n checkMetadata,\n trackingParams: { bridgeTransfer, updateListener },\n trackingConfig: { trackingLimitMs },\n}: CreateEvmSourceTrackerArgs) => {\n let updatableTransfer = cloneDeep(bridgeTransfer);\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 * - metadata is already set\n */\n if (updatableTransfer.completedAt || checkMetadata(updatableTransfer.metadata)) {\n return done(updatableTransfer);\n }\n\n /**\n * Check if the transaction has timed out\n */\n if (updatableTransfer.sourceStartedAt + trackingLimitMs <= Date.now()) {\n updatableTransfer = updateTransfer(\n updatableTransfer,\n { completedAt: Date.now(), errorCode: ErrorCode.TIMEOUT },\n updateListener,\n );\n return done(updatableTransfer);\n }\n\n if (!isHash(updatableTransfer.sourceTxHash)) {\n return;\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: updatableTransfer.sourceTxHash,\n });\n\n /**\n * Calculate the network fee if needed.\n */\n if (updatableTransfer.sourceNetworkFee === undefined) {\n const tx = await sourceClient.getTransaction({\n hash: updatableTransfer.sourceTxHash,\n });\n const networkFee = getNetworkFeeEVM(tx, txReceipt);\n\n if (networkFee) {\n updatableTransfer = updateTransfer(updatableTransfer, { 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 updatableTransfer = updateTransfer(\n updatableTransfer,\n { completedAt: Date.now(), errorCode: ErrorCode.TRANSACTION_REVERTED },\n updateListener,\n );\n return done(updatableTransfer);\n }\n if (!isHash(updatableTransfer.sourceTxHash)) {\n return;\n }\n /**\n * Check the confirmation count.\n * - update the sourceConfirmationCount if it increased\n * - update the targetStartBlockNumber if confirmation count increased but is not enough\n * - keeps polling until it's greater than sourceRequiredConfirmationCount\n */\n const confirmationCount = await sourceClient.getTransactionConfirmations({\n hash: updatableTransfer.sourceTxHash,\n });\n const hasMoreConfirmations = confirmationCount > updatableTransfer.sourceConfirmationCount;\n const hasRequiredConfirmations = confirmationCount >= updatableTransfer.sourceRequiredConfirmationCount;\n\n if (hasMoreConfirmations) {\n const changes = {} as Partial<BridgeTransfer>;\n changes.sourceConfirmationCount = Number(confirmationCount);\n\n if (!hasRequiredConfirmations) {\n changes.targetStartBlockNumber = await targetClient.getBlockNumber();\n }\n\n updatableTransfer = updateTransfer(updatableTransfer, changes, updateListener);\n }\n\n if (!hasRequiredConfirmations) {\n return;\n }\n\n if (!updatableTransfer.targetStartBlockNumber) {\n updatableTransfer = updateTransfer(\n updatableTransfer,\n { targetStartBlockNumber: await targetClient.getBlockNumber() },\n updateListener,\n );\n }\n\n const metadata = getMetadata(txReceipt);\n\n updatableTransfer = updateTransfer(updatableTransfer, { targetStartedAt: Date.now(), metadata }, updateListener);\n return done(updatableTransfer);\n };\n return tracker;\n};\n","import { cloneDeep, isNil, omitBy } from 'lodash';\nimport type { BridgeTransfer, TrackingParams } from '../../types';\n\nexport const updateTransfer = (\n initial: BridgeTransfer,\n updated: Partial<BridgeTransfer>,\n updateListener: TrackingParams['updateListener'],\n): BridgeTransfer => {\n const updatedNonNil = omitBy(updated, isNil);\n const nextTransfer = { ...cloneDeep(initial), ...cloneDeep(updatedNonNil) };\n updateListener(nextTransfer);\n return nextTransfer;\n};\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\nexport type TrackingConfig = {\n trackingLimitMs: number;\n maxBlocks: bigint;\n initialDelayMs: number;\n};\n\nexport const DEFAULT_TRACKING_CONFIG = {\n trackingLimitMs: TRACKING_LIMIT_MS,\n maxBlocks: MAX_BLOCKS,\n initialDelayMs: INITIAL_DELAY,\n} satisfies TrackingConfig;\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","import type { Client } from '../evm/client';\nimport type { Done } from '../retry-promise';\nimport { type TrackingConfig, updateTransfer } from './utils';\nimport { getNetworkFeeEVM } from '../network-fee';\nimport { ErrorCode, ErrorReason, type BridgeTransfer, type TrackingParams } from '../../types';\nimport { cloneDeep, isNil } from 'lodash';\nimport { InvalidParamsError } from '../../errors';\nimport { isHash } from 'viem';\n\ntype GetTargetTxHashParams = {\n fromBlock: bigint | 'earliest';\n toBlock: bigint | 'latest';\n metadata: BridgeTransfer['metadata'];\n};\n\nexport type CreateEvmTargetTrackerArgs = {\n trackingParams: TrackingParams;\n getTargetTxHash: (params: GetTargetTxHashParams) => Promise<`0x${string}` | undefined>;\n checkMetadata: (metadata: BridgeTransfer['metadata']) => boolean;\n targetClient: Client;\n trackingConfig: TrackingConfig;\n};\n\nexport const createEvmTargetTracker = ({\n targetClient,\n getTargetTxHash,\n checkMetadata,\n trackingParams: { bridgeTransfer, updateListener },\n trackingConfig: { trackingLimitMs, maxBlocks },\n}: CreateEvmTargetTrackerArgs) => {\n if (!bridgeTransfer.completedAt && !checkMetadata(bridgeTransfer.metadata)) {\n throw new InvalidParamsError(ErrorReason.INVALID_PARAMS, 'metadata is missing');\n }\n\n if (!bridgeTransfer.targetStartBlockNumber) {\n throw new InvalidParamsError(ErrorReason.INVALID_PARAMS, 'targetStartBlockNumber is missing');\n }\n let updatableTransfer = cloneDeep(bridgeTransfer);\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 (updatableTransfer.completedAt) {\n return done(updatableTransfer);\n }\n\n const hasTimedOut = updatableTransfer.sourceStartedAt + trackingLimitMs <= Date.now();\n /**\n * Check if the transaction has timed out\n */\n if (hasTimedOut) {\n updatableTransfer = updateTransfer(\n updatableTransfer,\n { completedAt: Date.now(), errorCode: ErrorCode.TIMEOUT },\n updateListener,\n );\n return done(updatableTransfer);\n }\n\n if (!updatableTransfer.targetStartBlockNumber) {\n // This is unreachable because we throw if this field is missing above\n // And we never unset this field, once it has already been set\n throw new Error('unreachable');\n }\n\n if (!updatableTransfer.targetTxHash) {\n const lastBlockNumber = await targetClient.getBlockNumber();\n const lowestBlockNumber = updatableTransfer.targetStartBlockNumber - maxBlocks;\n const fromBlock = lowestBlockNumber >= 0n ? lowestBlockNumber : 'earliest';\n const highestBlockNumber = updatableTransfer.targetStartBlockNumber + maxBlocks;\n const toBlock = highestBlockNumber < lastBlockNumber ? highestBlockNumber : 'latest';\n const targetTxHash = await getTargetTxHash({ fromBlock, toBlock, metadata: updatableTransfer.metadata });\n if (targetTxHash) {\n updatableTransfer = updateTransfer(updatableTransfer, { targetTxHash: targetTxHash }, updateListener);\n } else {\n updatableTransfer = updateTransfer(\n updatableTransfer,\n { targetStartBlockNumber: lastBlockNumber },\n updateListener,\n );\n return;\n }\n }\n\n if (isNil(updatableTransfer.targetTxHash) || !isHash(updatableTransfer.targetTxHash)) {\n return;\n }\n\n /**\n * Get the transaction's receipt.\n *\n */\n const txReceipt = await targetClient.getTransactionReceipt({\n hash: updatableTransfer.targetTxHash,\n });\n\n /**\n * Calculate the network fee if needed.\n */\n if (!updatableTransfer.targetNetworkFee) {\n const tx = await targetClient.getTransaction({\n hash: updatableTransfer.targetTxHash,\n });\n const networkFee = getNetworkFeeEVM(tx, txReceipt);\n\n if (networkFee) {\n updatableTransfer = updateTransfer(updatableTransfer, { targetNetworkFee: networkFee }, updateListener);\n }\n }\n\n /**\n * Update the state and terminate if the transaction was reverted.\n * Technically, it's possible to retry delivery of teleporter messages, but the current tracking implementation is naive.\n */\n if (txReceipt.status === 'reverted') {\n updatableTransfer = updateTransfer(\n updatableTransfer,\n { completedAt: Date.now(), errorCode: ErrorCode.TRANSACTION_REVERTED },\n updateListener,\n );\n return done(updatableTransfer);\n }\n if (isNil(updatableTransfer.targetTxHash) || !isHash(updatableTransfer.targetTxHash)) {\n return;\n }\n\n /**\n * Check the confirmation count.\n * - update the targetConfirmationCount if it increased\n * - keeps polling until it's greater than targetRequiredConfirmationCount\n */\n const confirmationCount = await targetClient.getTransactionConfirmations({\n hash: updatableTransfer.targetTxHash,\n });\n const hasMoreConfirmations = confirmationCount > updatableTransfer.targetConfirmationCount;\n const hasRequiredConfirmations = confirmationCount >= updatableTransfer.targetRequiredConfirmationCount;\n if (hasMoreConfirmations) {\n updatableTransfer = updateTransfer(\n updatableTransfer,\n { targetConfirmationCount: Number(confirmationCount) },\n updateListener,\n );\n }\n\n if (!hasRequiredConfirmations) {\n return;\n }\n\n updatableTransfer = updateTransfer(updatableTransfer, { completedAt: Date.now() }, updateListener);\n return done(updatableTransfer);\n };\n return tracker;\n};\n","import { isObject } from 'lodash';\nimport { type CreateEvmSourceTrackerArgs, type CreateEvmTargetTrackerArgs } from '../../../utils/tracking';\nimport { decodeEventLog, type AbiEvent } from 'viem';\nimport { TOKEN_ROUTER_ABI } from '../abis/token-router';\nimport { InvalidParamsError } from '../../../errors';\nimport { ErrorReason } from '../../../types';\nimport type { CCTPTransferData } from './transfer-data';\nimport type { Client } from '../../../utils/evm/client';\n\nexport const checkMetadata: CreateEvmSourceTrackerArgs['checkMetadata'] = (metadata): metadata is { nonce: bigint } => {\n return isObject(metadata) && typeof metadata.nonce === 'bigint';\n};\n\nexport const createGetMetadata = ({ sourceChainData }: CCTPTransferData): CreateEvmSourceTrackerArgs['getMetadata'] => {\n const getMetadata: CreateEvmSourceTrackerArgs['getMetadata'] = (txReceipt) => {\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 \"${txReceipt.transactionHash}\"`,\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 const nonce = transferEvent.args.nonce;\n return { nonce };\n };\n return getMetadata;\n};\n\nexport const MESSAGE_RECEIVED_EVENT_ABI = {\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} satisfies AbiEvent;\n\nexport const createGetTargetTxHash = ({\n targetClient,\n transferData: { targetChainData },\n}: {\n transferData: CCTPTransferData;\n targetClient: Client;\n}): CreateEvmTargetTrackerArgs['getTargetTxHash'] => {\n const getTargetTxHash: CreateEvmTargetTrackerArgs['getTargetTxHash'] = async ({ fromBlock, toBlock, metadata }) => {\n const targetLogs = await targetClient.getLogs({\n address: targetChainData.messageTransmitterAddress,\n event: MESSAGE_RECEIVED_EVENT_ABI,\n args: { nonce: metadata?.nonce as bigint },\n fromBlock,\n toBlock,\n });\n return targetLogs[0]?.transactionHash;\n };\n return getTargetTxHash;\n};\n","import { getClientForChain } from '../../../utils/evm/client';\nimport { ERC20_ABI } from '../../../abis/erc20';\nimport { getTransferData } from '../utils/transfer-data';\nimport { ChainDomain } from '../types/chain';\nimport type { Config } from '../types/config';\nimport type { ValidEvmGasEstimationParams } from '../../../utils/evm/types/bridge';\n\nconst ETH_APPROVAL_TX_GAS_ESTIMATE = 60_000n; // 55.5k gas on average (+/- 200 units)\nconst ETH_TRANSFER_TX_GAS_ESTIMATE = 175_000n; // 161.5k gas on average (+/- 200 units)\nconst AVAX_APPROVAL_TX_GAS_ESTIMATE = 60_000n; // 55.5k gas on average (+/- 200 units)\nconst AVAX_TRANSFER_TX_GAS_ESTIMATE = 215_000n; // 203k gas on average (+/- 200 units)\n/**\n * The CCTP bridging consists of up to two transactions:\n *\n * 1. Token spend approval (technically optional, but realistically performed basically every time)\n * 2. Token transfer (required)\n *\n * Since the 2nd one needs the first transaction to be complete, calling .estimateGas() is not possible.\n * The RPC call raises an error since it cannot execute the transfer transaction locally without\n * the allowance being set. For that reason, we're using hard-coded estimates here, with small buffers added.\n *\n * NOTE: These estimates are only supposed to be used to approximate the network fees in the UI.\n * DO NOT use them as `gasLimit` prop on the transactions!\n */\nexport async function estimateGas(config: Config, params: ValidEvmGasEstimationParams): Promise<bigint> {\n const { sourceChain, targetChain, asset, amount, fromAddress } = params;\n\n const { sourceChainData, burnToken } = getTransferData({ sourceChain, targetChain, asset, amount }, config);\n\n const client = getClientForChain({ chain: sourceChain });\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 isOffboarding = sourceChainData.domain === ChainDomain.Avalanche;\n\n if (allowance >= amount) {\n return isOffboarding ? AVAX_TRANSFER_TX_GAS_ESTIMATE : ETH_TRANSFER_TX_GAS_ESTIMATE;\n }\n\n return isOffboarding\n ? AVAX_APPROVAL_TX_GAS_ESTIMATE + AVAX_TRANSFER_TX_GAS_ESTIMATE\n : ETH_APPROVAL_TX_GAS_ESTIMATE + ETH_TRANSFER_TX_GAS_ESTIMATE;\n}\n","import { type FeeParams } from '../../../types';\nimport type { Config } from '../types/config';\nimport { getTransferData } from '../utils/transfer-data';\nimport { getFees } from './get-fees';\n\nexport async function getMinimumTransferAmount(config: Config, params: FeeParams) {\n const { sourceChain, targetChain, asset, amount } = params;\n\n const { burnToken } = getTransferData({ sourceChain, targetChain, asset, amount }, config);\n const fees = await getFees(config, params);\n return fees[burnToken.address] ?? 1n;\n}\n","import { type Asset, TokenType } from '../../../types';\nimport type { ValidEvmGasEstimationParams } from '../../../utils/evm/types/bridge';\n\nimport type { Config } from '../types/config';\nimport { getTransferData } from '../utils/transfer-data';\nimport { getFees } from './get-fees';\n\nexport async function estimateReceiveAmount(config: Config, params: ValidEvmGasEstimationParams) {\n const { mintToken, burnToken } = getTransferData(params, config);\n const targetAsset: Asset = { ...mintToken, type: TokenType.ERC20 };\n const fees = await getFees(config, params);\n return {\n asset: targetAsset,\n amount: params.amount - (fees[burnToken.address] ?? 0n),\n };\n}\n","import { isAddressEqual } from 'viem';\nimport { AvalancheChainIds, BridgeType, EthereumChainIds, type AnalyzeTxResult } from '../../../types';\nimport { ZERO_ADDRESS } from '../../../utils/consts';\nimport { ChainDomain } from '../types/chain';\nimport type { Config } from '../types/config';\nimport type { EvmAnalyzeTxParams } from '../../../utils/evm/types/bridge';\n\nexport function analyzeTx(config: Config, params: EvmAnalyzeTxParams): AnalyzeTxResult {\n for (const chainConfig of config) {\n if (chainConfig.chainId !== params.chainId) {\n continue;\n }\n\n const supportedTokenTransfer = params.tokenTransfers.find(({ symbol }) =>\n chainConfig.tokens.some(({ symbol: bridgeTokenSymbol }) => bridgeTokenSymbol === symbol),\n );\n if (!supportedTokenTransfer) {\n continue;\n }\n\n const isAvalanche = chainConfig.domain === ChainDomain.Avalanche;\n const isTestnet = params.chainId === AvalancheChainIds.FUJI || params.chainId === EthereumChainIds.SEPOLIA;\n const ethereumChain = isTestnet ? EthereumChainIds.SEPOLIA : EthereumChainIds.MAINNET;\n const avalancheChain = isTestnet ? AvalancheChainIds.FUJI : AvalancheChainIds.MAINNET;\n const isToTokenRouter =\n isAddressEqual(params.to, chainConfig.tokenRouterAddress) ||\n isAddressEqual(supportedTokenTransfer.to, chainConfig.tokenRouterAddress);\n if (isToTokenRouter) {\n return {\n isBridgeTx: true,\n bridgeType: BridgeType.CCTP,\n sourceChainId: params.chainId,\n // At the moment CCTP Bridge only supports briding between Avalanche and Ethereum,\n // so we can derive the target chain based on the source chain.\n targetChainId: isAvalanche ? ethereumChain : avalancheChain,\n };\n }\n\n const isFromMessageTransmitter = isAddressEqual(params.from, chainConfig.messageTransmitterAddress);\n const isMinted = isAddressEqual(supportedTokenTransfer.from, ZERO_ADDRESS);\n // The mint being recognized as bridging is a bold assumption here (USDC could also be bought, for example).\n if (isFromMessageTransmitter || isMinted) {\n // At the moment CCTP Bridge only supports briding between Avalanche and Ethereum,\n // so we can derive the source chain based on the target chain.\n return {\n isBridgeTx: true,\n bridgeType: BridgeType.CCTP,\n sourceChainId: isAvalanche ? ethereumChain : avalancheChain,\n targetChainId: params.chainId,\n };\n }\n }\n\n return {\n isBridgeTx: false,\n };\n}\n","import type { Address } from 'abitype';\n\nexport const ZERO_ADDRESS: Address = '0x0000000000000000000000000000000000000000';\n","import { isAddress, isHash } from 'viem';\nimport {\n ErrorReason,\n type AnalyzeTxParams,\n type BridgeTransfer,\n type GasEstimationParams,\n type TransferParams,\n} from '../../types';\nimport type { EvmAnalyzeTxParams, ValidEvmGasEstimationParams, ValidEvmTransferParams } from './types/bridge';\nimport { InvalidParamsError } from '../../errors';\nimport { isNil } from 'lodash';\nimport { validateEvmAddresses } from './validation';\n\nexport function toEvmAnalyzeTxParams(params: AnalyzeTxParams): EvmAnalyzeTxParams {\n const { chainId, from, to, tokenTransfers } = params;\n const { fromAddress, toAddress } = validateEvmAddresses({\n fromAddress: from,\n toAddress: to,\n });\n\n const evmTokenTransfer = tokenTransfers.map((tokenTransfer) => {\n const { from, to, symbol } = tokenTransfer;\n if (!from || !isAddress(from) || !to || !isAddress(to)) {\n throw new InvalidParamsError(ErrorReason.INCORRECT_ADDRESS_PROVIDED);\n }\n return {\n from,\n to,\n symbol,\n };\n });\n return {\n chainId,\n from: fromAddress,\n to: toAddress,\n tokenTransfers: evmTokenTransfer,\n };\n}\n\nexport function toEvmBridgeTransfer({\n sourceTxHash,\n targetTxHash,\n fromAddress: maybeFromAddress,\n toAddress: maybeToAddress,\n ...rest\n}: BridgeTransfer): BridgeTransfer {\n if (!isHash(sourceTxHash) || (!isNil(targetTxHash) && !isHash(targetTxHash))) {\n throw new InvalidParamsError(ErrorReason.INCORRECT_TXHASH_PROVIDED);\n }\n const { fromAddress, toAddress } = validateEvmAddresses({\n fromAddress: maybeFromAddress,\n toAddress: maybeToAddress,\n });\n\n return {\n sourceTxHash,\n targetTxHash,\n fromAddress,\n toAddress,\n ...rest,\n };\n}\n\nexport const toValidEvmGasEstimationParams = ({\n fromAddress,\n ...rest\n}: GasEstimationParams): ValidEvmGasEstimationParams => {\n if (!isAddress(fromAddress)) {\n throw new InvalidParamsError(ErrorReason.INCORRECT_ADDRESS_PROVIDED);\n }\n return { fromAddress, ...rest };\n};\n\nexport const toValidEvmTransferParams = ({\n fromAddress: maybeFromAddress,\n toAddress: maybeToAddress,\n ...rest\n}: TransferParams): ValidEvmTransferParams => {\n const { fromAddress, toAddress } = validateEvmAddresses({\n fromAddress: maybeFromAddress,\n toAddress: maybeToAddress,\n });\n return { fromAddress, toAddress, ...rest };\n};\n","import type { Address } from 'abitype';\nimport { type TransferParams, ErrorReason } from '../../types';\nimport { isAddress } from 'viem';\nimport { InvalidParamsError } from '../../errors';\nexport type AddressParams = Pick<TransferParams, 'fromAddress' | 'toAddress'>;\ntype EvmAddressParams = { fromAddress: Address; toAddress: Address };\n\nexport const validateEvmAddresses = (addressParams: AddressParams): EvmAddressParams => {\n const { fromAddress, toAddress } = addressParams;\n\n if (!isAddress(fromAddress) || !isAddress(toAddress)) {\n throw new InvalidParamsError(ErrorReason.INCORRECT_ADDRESS_PROVIDED);\n }\n return { fromAddress, toAddress };\n};\n","import { BridgeType } from '../../types/bridge';\nimport { getAssets } from './handlers/get-assets';\nimport { getFees } from './handlers/get-fees';\nimport { transferAsset } from './handlers/transfer-asset';\nimport { trackTransfer } from './handlers/track-transfer';\nimport { estimateGas } from './handlers/estimate-gas';\nimport { getConfig } from './utils/config';\n\nimport { getMinimumTransferAmount } from './handlers/get-minimum-transfer-amount';\nimport { estimateReceiveAmount } from './handlers/estimate-receive-amount';\nimport { analyzeTx } from './handlers/analyze-tx';\nimport type { EvmBridgeServiceFactory } from '../../utils/evm/types/bridge';\nimport { toEvmAnalyzeTxParams, toValidEvmGasEstimationParams, toValidEvmTransferParams } from '../../utils/evm/utils';\n\nexport const cctpBridgeFactory: EvmBridgeServiceFactory = async (environment, signer) => {\n const config = await getConfig(environment);\n return {\n type: BridgeType.CCTP,\n analyzeTx: (params) => analyzeTx(config, toEvmAnalyzeTxParams(params)),\n estimateGas: (params) => estimateGas(config, toValidEvmGasEstimationParams(params)),\n estimateReceiveAmount: (params) => estimateReceiveAmount(config, toValidEvmGasEstimationParams(params)),\n getAssets: () => getAssets(config),\n getFees: (params) => getFees(config, params),\n transferAsset: (params) => transferAsset(config, toValidEvmTransferParams(params), environment, signer),\n trackTransfer: (params) => trackTransfer(config, params),\n getMinimumTransferAmount: (params) => getMinimumTransferAmount(config, params),\n };\n};\n","import { InvalidParamsError } from '../../../errors';\nimport { ErrorReason, isErc20Asset, type Asset, type Erc20Asset } from '../../../types';\nimport type { ValidEvmTransferParams } from '../../../utils/evm/types/bridge';\nimport type { IcttErc20Erc20Config } from '../types/config';\n\ntype PartialTransferParams = Pick<ValidEvmTransferParams, 'sourceChain' | 'targetChain' | 'amount'> & { asset: Asset };\n\ntype PartialTransferParamsErc20 = Pick<ValidEvmTransferParams, 'sourceChain' | 'targetChain'> & { asset: Erc20Asset };\n\n/**\n * On-boards going from Home -> Remote are all registered in the Erc20Erc20TeleporterConfig.\n * @param param0\n * @param config\n * @returns\n */\nconst getHomeToRemoteConfig = (\n { sourceChain, targetChain, asset }: PartialTransferParamsErc20,\n config: IcttErc20Erc20Config,\n) => {\n const chainBridgeConfig = config.find(\n (chainBridgeConfig) => chainBridgeConfig.homeChain.chainId === sourceChain.chainId,\n );\n const tokenHomeConfig = chainBridgeConfig?.erc20Bridges.find(\n (erc20Bridge) =>\n erc20Bridge.baseToken.address === asset.address &&\n erc20Bridge.remotes.some(({ remoteChain }) => remoteChain.chainId === targetChain.chainId),\n );\n const tokenRemoteConfig = tokenHomeConfig?.remotes.find(\n (remoteConfig) => remoteConfig.remoteChain.chainId === targetChain.chainId,\n );\n return {\n chainBridgeConfig,\n tokenHomeConfig,\n tokenRemoteConfig,\n };\n};\n\n/**\n * The ERC20 Token Bridge automatically supports multi-hop transfers between TokenRemote instances.\n * But the current unified bridge implementation only supports single-hop transfers back to Home by default.\n * @param param0\n * @param config\n * @returns\n */\nconst getRemoteToHomeConfig = (\n { sourceChain, targetChain, asset }: PartialTransferParamsErc20,\n config: IcttErc20Erc20Config,\n) => {\n const chainBridgeConfig = config.find(\n (chainBridgeConfig) => chainBridgeConfig.homeChain.chainId === targetChain.chainId,\n );\n const tokenHomeConfig = chainBridgeConfig?.erc20Bridges.find((tokenHomeConfig) =>\n tokenHomeConfig.remotes.find(\n (remoteConfig) =>\n remoteConfig.tokenRemoteAddress === asset.address && remoteConfig.remoteChain.chainId === sourceChain.chainId,\n ),\n );\n const tokenRemoteConfig = tokenHomeConfig?.remotes.find(\n (remoteConfig) =>\n remoteConfig.tokenRemoteAddress === asset.address && remoteConfig.remoteChain.chainId === sourceChain.chainId,\n );\n\n return {\n chainBridgeConfig,\n tokenHomeConfig,\n tokenRemoteConfig,\n };\n};\n\nexport const getTransferData = (\n { sourceChain, targetChain, amount, asset }: PartialTransferParams,\n config: IcttErc20Erc20Config,\n) => {\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 if (!isErc20Asset(asset)) {\n throw new InvalidParamsError(ErrorReason.ASSET_NOT_SUPPORTED, 'Only ERC20 assets supported');\n }\n const homeToRemoteConfig = getHomeToRemoteConfig({ sourceChain, targetChain, asset }, config);\n const remoteToHomeConfig = getRemoteToHomeConfig({ sourceChain, targetChain, asset }, config);\n if (\n homeToRemoteConfig.chainBridgeConfig &&\n homeToRemoteConfig.tokenHomeConfig &&\n homeToRemoteConfig.tokenRemoteConfig\n ) {\n const { chainBridgeConfig, tokenHomeConfig, tokenRemoteConfig } = homeToRemoteConfig;\n return {\n homeToRemote: true,\n chainBridgeConfig,\n tokenHomeConfig,\n tokenRemoteConfig,\n };\n }\n if (\n remoteToHomeConfig.chainBridgeConfig &&\n remoteToHomeConfig.tokenHomeConfig &&\n remoteToHomeConfig.tokenRemoteConfig\n ) {\n const { chainBridgeConfig, tokenHomeConfig, tokenRemoteConfig } = remoteToHomeConfig;\n return {\n homeToRemote: false,\n chainBridgeConfig,\n tokenHomeConfig,\n tokenRemoteConfig,\n };\n }\n throw new InvalidParamsError(\n ErrorReason.ASSET_NOT_SUPPORTED,\n 'No Home->Remote or Remote->Home route exists for this asset',\n );\n};\n\nexport type TransferData = ReturnType<typeof getTransferData>;\n","import type { IcttErc20Erc20Config } from '../types/config';\nimport { getClientForChain } from '../../../utils/evm/client';\nimport { getTransferData } from '../utils/transfer-data';\nimport { ERC20_ABI } from '../../../abis/erc20';\nimport type { ValidEvmGasEstimationParams } from '../../../utils/evm/types/bridge';\n\nconst AVAX_APPROVAL_TX_GAS_ESTIMATE = 60_000n; // 55.5k gas on average (+/- 200 units)\nconst AVAX_TRANSFER_TX_GAS_ESTIMATE = 215_000n; // 203k gas on average (+/- 200 units)\n\nexport const estimateGas = async (\n config: IcttErc20Erc20Config,\n params: ValidEvmGasEstimationParams,\n): Promise<bigint> => {\n const { sourceChain, targetChain, asset, amount, fromAddress } = params;\n\n const { tokenHomeConfig, homeToRemote, tokenRemoteConfig } = getTransferData(\n { sourceChain, targetChain, asset, amount },\n config,\n );\n const client = getClientForChain({ chain: sourceChain });\n const allowance = await client.readContract({\n address: homeToRemote ? tokenHomeConfig.baseToken.address : tokenRemoteConfig.tokenRemoteAddress,\n abi: ERC20_ABI,\n functionName: 'allowance',\n args: [fromAddress, homeToRemote ? tokenHomeConfig.tokenHomeAddress : tokenRemoteConfig.tokenRemoteAddress],\n });\n return allowance >= amount\n ? AVAX_TRANSFER_TX_GAS_ESTIMATE\n : AVAX_APPROVAL_TX_GAS_ESTIMATE + AVAX_TRANSFER_TX_GAS_ESTIMATE;\n};\n","import type { IcttErc20Erc20Config } from '../types/config';\nimport type { ChainAssetMap, DestinationInfo } from '../../../types';\nimport { BridgeType } from '../../../types';\n\nexport const getAssets = (config: IcttErc20Erc20Config): ChainAssetMap => {\n const homeToRemote = config.reduce<ChainAssetMap>((assets, chainBridgeConfig) => {\n assets[chainBridgeConfig.homeChain.chainId] = chainBridgeConfig.erc20Bridges.map((tokenHomeConfig) => ({\n ...tokenHomeConfig.baseToken,\n destinations: tokenHomeConfig.remotes.reduce<DestinationInfo>((destinations, tokenRemoteConfig) => {\n destinations[tokenRemoteConfig.remoteChain.chainId] = [BridgeType.ICTT_ERC20_ERC20];\n return destinations;\n }, {}),\n }));\n\n return assets;\n }, {});\n\n const remoteToHome = config.reduce<ChainAssetMap>((assets, chainBridgeConfig) => {\n for (const tokenHomeConfig of chainBridgeConfig.erc20Bridges) {\n for (const tokenRemoteConfig of tokenHomeConfig.remotes) {\n const existingAssets = assets[tokenRemoteConfig.remoteChain.chainId] ?? [];\n assets[tokenRemoteConfig.remoteChain.chainId] = [\n ...existingAssets,\n {\n ...tokenHomeConfig.baseToken,\n address: tokenRemoteConfig.tokenRemoteAddress,\n destinations: {\n [chainBridgeConfig.homeChain.chainId]: [BridgeType.ICTT_ERC20_ERC20],\n },\n },\n ];\n }\n }\n\n return assets;\n }, {});\n\n return {\n ...homeToRemote,\n ...remoteToHome,\n };\n};\n","import type { AssetFeeMap, FeeParams } from '../../../types';\nimport type { IcttErc20Erc20Config } from '../types/config';\nimport { getTransferData } from '../utils/transfer-data';\n\n/**\n * No fees for now.\n * @param config\n * @param params\n * @returns\n */\nexport async function getFees(config: IcttErc20Erc20Config, params: FeeParams): Promise<AssetFeeMap> {\n getTransferData(params, config); // This validates the fee params\n return {};\n}\n","import { type PublicClient } from 'viem';\nimport {\n BridgeType,\n type Environment,\n type Hex,\n BridgeSignatureReason,\n isErc20Asset,\n type EvmSigner,\n type BridgeTransfer,\n} from '../../../types';\nimport { getClientForChain } from '../../../utils/evm/client';\nimport { ERC20_ABI } from '../../../abis/erc20';\nimport { getTransferData } from '../utils/transfer-data';\n\nimport { buildApprovalTxData, buildSendTxData } from '../utils/build-tx';\nimport type { IcttErc20Erc20Config } from '../types/config';\nimport { getFees } from './get-fees';\nimport type { ValidEvmTransferParams } from '../../../utils/evm/types/bridge';\n\ntype InternalTransferParams = {\n params: ValidEvmTransferParams;\n transferData: ReturnType<typeof getTransferData>;\n signer: EvmSigner;\n};\ntype AllowanceApproval = {\n isAllowanceApprovalRequired: boolean;\n requiredSignatures: number;\n};\n\nconst approveAndTransferWithSign = async ({\n params: { onStepChange, amount, fromAddress, sourceChain, toAddress },\n transferData,\n isAllowanceApprovalRequired,\n requiredSignatures,\n signer,\n}: InternalTransferParams & AllowanceApproval) => {\n const { tokenRemoteConfig, tokenHomeConfig, homeToRemote, chainBridgeConfig } = transferData;\n const client = getClientForChain({ chain: sourceChain });\n if (isAllowanceApprovalRequired) {\n onStepChange?.({\n currentSignature: 1,\n currentSignatureReason: BridgeSignatureReason.AllowanceApproval,\n requiredSignatures,\n });\n const data = buildApprovalTxData({\n amount,\n address: homeToRemote ? tokenHomeConfig.tokenHomeAddress : tokenRemoteConfig.tokenRemoteAddress,\n });\n const txHash = await signer.sign(\n {\n from: fromAddress,\n to: homeToRemote ? transferData.tokenHomeConfig.baseToken.address : tokenRemoteConfig.tokenRemoteAddress,\n data,\n },\n (signedTxHash: Hex) => client.sendRawTransaction({ serializedTransaction: signedTxHash }),\n );\n\n await client.waitForTransactionReceipt({\n hash: txHash,\n pollingInterval: 1_000,\n });\n }\n onStepChange?.({\n currentSignature: isAllowanceApprovalRequired ? 2 : 1,\n currentSignatureReason: BridgeSignatureReason.TokensTransfer,\n requiredSignatures,\n });\n const destinationBlockchainID = homeToRemote\n ? tokenRemoteConfig.remoteChain.blockchainId\n : chainBridgeConfig.homeChain.blockchainId;\n const destinationTokenTransferrerAddress = homeToRemote\n ? tokenRemoteConfig.tokenRemoteAddress\n : tokenHomeConfig.tokenHomeAddress;\n const data = buildSendTxData({\n amount,\n recipient: toAddress,\n destinationBlockchainID,\n destinationTokenTransferrerAddress,\n homeToRemote,\n });\n return signer.sign(\n {\n from: fromAddress,\n to: homeToRemote ? tokenHomeConfig.tokenHomeAddress : tokenRemoteConfig.tokenRemoteAddress,\n data,\n },\n (signedTxHash: Hex) => client.sendRawTransaction({ serializedTransaction: signedTxHash }),\n );\n};\n\n/**\n * This will issue the approval as well as the transfer, if necessary.\n * @param param0\n */\nconst approveAndTransferRouter = async ({ params, transferData, signer }: InternalTransferParams) => {\n const { sourceChain, fromAddress, amount } = params;\n const client = getClientForChain({ chain: sourceChain });\n const { homeToRemote, tokenHomeConfig, tokenRemoteConfig } = transferData;\n const allowance = await client.readContract({\n address: homeToRemote ? tokenHomeConfig.baseToken.address : tokenRemoteConfig.tokenRemoteAddress,\n abi: ERC20_ABI,\n functionName: 'allowance',\n args: [fromAddress, homeToRemote ? tokenHomeConfig.tokenHomeAddress : tokenRemoteConfig.tokenRemoteAddress],\n });\n\n const isAllowanceApprovalRequired = allowance < amount;\n const requiredSignatures = isAllowanceApprovalRequired ? 2 : 1; // if approval is required, we'll need 2 signatures\n return approveAndTransferWithSign({\n params,\n transferData,\n isAllowanceApprovalRequired,\n requiredSignatures,\n signer,\n });\n};\n\nconst approveAndTransfer = async (config: IcttErc20Erc20Config, params: ValidEvmTransferParams, signer: EvmSigner) => {\n const { sourceChain, targetChain, asset, amount } = params;\n\n const transferData = getTransferData({ sourceChain, targetChain, asset, amount }, config);\n return approveAndTransferRouter({ params, transferData, signer });\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 config: IcttErc20Erc20Config,\n params: ValidEvmTransferParams,\n environment: Environment,\n signer: EvmSigner,\n): Promise<BridgeTransfer> {\n const fees = await getFees(config, {\n asset: params.asset,\n amount: params.amount,\n sourceChain: params.sourceChain,\n targetChain: params.targetChain,\n });\n\n const bridgeFee = isErc20Asset(params.asset) ? fees[params.asset.address] ?? 0n : 0n;\n const txHash = await approveAndTransfer(config, params, signer);\n const sourceStartedAt = Date.now();\n const targetClient = getClientForChain({\n chain: params.targetChain,\n });\n const targetBlockNumber = await getStartBlockNumber(targetClient);\n\n return {\n type: BridgeType.ICTT_ERC20_ERC20,\n environment,\n fromAddress: params.fromAddress,\n toAddress: params.toAddress,\n amount: params.amount,\n asset: params.asset,\n\n bridgeFee,\n\n sourceChain: params.sourceChain,\n sourceStartedAt,\n sourceTxHash: txHash,\n sourceConfirmationCount: 0,\n sourceRequiredConfirmationCount: 1,\n\n targetChain: params.targetChain,\n targetConfirmationCount: 0,\n targetRequiredConfirmationCount: 1,\n\n targetStartBlockNumber: targetBlockNumber,\n };\n}\n","import { encodeFunctionData, type Address } from 'viem';\nimport { ERC20_TOKEN_HOME_ABI } from '../abis/erc20-token-home';\nimport { ERC20_ABI } from '../../../abis/erc20';\nimport { ZERO_ADDRESS } from '../../../utils/consts';\nimport { ERC20_TOKEN_REMOTE_ABI } from '../abis/erc20-token-remote';\n\nexport const REQUIRED_GAS_LIMIT = 85_000n;\n\nexport const buildSendTxData = ({\n homeToRemote,\n amount,\n destinationBlockchainID,\n destinationTokenTransferrerAddress,\n recipient,\n}: {\n amount: bigint;\n homeToRemote: boolean;\n destinationBlockchainID: Address;\n destinationTokenTransferrerAddress: Address;\n recipient: Address;\n}) => {\n return encodeFunctionData({\n abi: homeToRemote ? ERC20_TOKEN_HOME_ABI : ERC20_TOKEN_REMOTE_ABI,\n functionName: 'send',\n args: [\n {\n destinationBlockchainID,\n destinationTokenTransferrerAddress,\n recipient,\n primaryFeeTokenAddress: ZERO_ADDRESS,\n primaryFee: 0n,\n secondaryFee: 0n,\n requiredGasLimit: REQUIRED_GAS_LIMIT,\n multiHopFallback: ZERO_ADDRESS,\n },\n amount,\n ],\n });\n};\n\nexport function buildApprovalTxData({ amount, address }: { amount: bigint; address: Address }) {\n return encodeFunctionData({\n abi: ERC20_ABI,\n functionName: 'approve',\n args: [address, amount],\n });\n}\n","export const ERC20_TOKEN_HOME_ABI = [\n {\n type: 'constructor',\n inputs: [\n {\n name: 'teleporterRegistryAddress',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'teleporterManager',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'tokenAddress_',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'tokenDecimals_',\n type: 'uint8',\n internalType: 'uint8',\n },\n ],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n name: 'addCollateral',\n inputs: [\n {\n name: 'remoteBlockchainID',\n type: 'bytes32',\n internalType: 'bytes32',\n },\n {\n name: 'remoteTokenTransferrerAddress',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'amount',\n type: 'uint256',\n internalType: 'uint256',\n },\n ],\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n name: 'blockchainID',\n inputs: [],\n outputs: [\n {\n name: '',\n type: 'bytes32',\n internalType: 'bytes32',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getMinTeleporterVersion',\n inputs: [],\n outputs: [\n {\n name: '',\n type: 'uint256',\n internalType: 'uint256',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'isTeleporterAddressPaused',\n inputs: [\n {\n name: 'teleporterAddress',\n type: 'address',\n internalType: 'address',\n },\n ],\n outputs: [\n {\n name: '',\n type: 'bool',\n internalType: 'bool',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'owner',\n inputs: [],\n outputs: [\n {\n name: '',\n type: 'address',\n internalType: 'address',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'pauseTeleporterAddress',\n inputs: [\n {\n name: 'teleporterAddress',\n type: 'address',\n internalType: 'address',\n },\n ],\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n name: 'receiveTeleporterMessage',\n inputs: [\n {\n name: 'sourceBlockchainID',\n type: 'bytes32',\n internalType: 'bytes32',\n },\n {\n name: 'originSenderAddress',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'message',\n type: 'bytes',\n internalType: 'bytes',\n },\n ],\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n name: 'registeredRemotes',\n inputs: [\n {\n name: 'remoteBlockchainID',\n type: 'bytes32',\n internalType: 'bytes32',\n },\n {\n name: 'remoteTokenTransferrerAddress',\n type: 'address',\n internalType: 'address',\n },\n ],\n outputs: [\n {\n name: 'registered',\n type: 'bool',\n internalType: 'bool',\n },\n {\n name: 'collateralNeeded',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'tokenMultiplier',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'multiplyOnRemote',\n type: 'bool',\n internalType: 'bool',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'renounceOwnership',\n inputs: [],\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n name: 'send',\n inputs: [\n {\n name: 'input',\n type: 'tuple',\n internalType: 'struct SendTokensInput',\n components: [\n {\n name: 'destinationBlockchainID',\n type: 'bytes32',\n internalType: 'bytes32',\n },\n {\n name: 'destinationTokenTransferrerAddress',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'recipient',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'primaryFeeTokenAddress',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'primaryFee',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'secondaryFee',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'requiredGasLimit',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'multiHopFallback',\n type: 'address',\n internalType: 'address',\n },\n ],\n },\n {\n name: 'amount',\n type: 'uint256',\n internalType: 'uint256',\n },\n ],\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n name: 'sendAndCall',\n inputs: [\n {\n name: 'input',\n type: 'tuple',\n internalType: 'struct SendAndCallInput',\n components: [\n {\n name: 'destinationBlockchainID',\n type: 'bytes32',\n internalType: 'bytes32',\n },\n {\n name: 'destinationTokenTransferrerAddress',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'recipientContract',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'recipientPayload',\n type: 'bytes',\n internalType: 'bytes',\n },\n {\n name: 'requiredGasLimit',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'recipientGasLimit',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'multiHopFallback',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'fallbackRecipient',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'primaryFeeTokenAddress',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'primaryFee',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'secondaryFee',\n type: 'uint256',\n internalType: 'uint256',\n },\n ],\n },\n {\n name: 'amount',\n type: 'uint256',\n internalType: 'uint256',\n },\n ],\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n name: 'teleporterRegistry',\n inputs: [],\n outputs: [\n {\n name: '',\n type: 'address',\n internalType: 'contract TeleporterRegistry',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'token',\n inputs: [],\n outputs: [\n {\n name: '',\n type: 'address',\n internalType: 'contract IERC20',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'tokenAddress',\n inputs: [],\n outputs: [\n {\n name: '',\n type: 'address',\n internalType: 'address',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'tokenDecimals',\n inputs: [],\n outputs: [\n {\n name: '',\n type: 'uint8',\n internalType: 'uint8',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'transferOwnership',\n inputs: [\n {\n name: 'newOwner',\n type: 'address',\n internalType: 'address',\n },\n ],\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n name: 'transferredBalances',\n inputs: [\n {\n name: 'remoteBlockchainID',\n type: 'bytes32',\n internalType: 'bytes32',\n },\n {\n name: 'remoteTokenTransferrerAddress',\n type: 'address',\n internalType: 'address',\n },\n ],\n outputs: [\n {\n name: 'balance',\n type: 'uint256',\n internalType: 'uint256',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'unpauseTeleporterAddress',\n inputs: [\n {\n name: 'teleporterAddress',\n type: 'address',\n internalType: 'address',\n },\n ],\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n name: 'updateMinTeleporterVersion',\n inputs: [\n {\n name: 'version',\n type: 'uint256',\n internalType: 'uint256',\n },\n ],\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'event',\n name: 'CallFailed',\n inputs: [\n {\n name: 'recipientContract',\n type: 'address',\n indexed: true,\n internalType: 'address',\n },\n {\n name: 'amount',\n type: 'uint256',\n indexed: false,\n internalType: 'uint256',\n },\n ],\n anonymous: false,\n },\n {\n type: 'event',\n name: 'CallSucceeded',\n inputs: [\n {\n name: 'recipientContract',\n type: 'address',\n indexed: true,\n internalType: 'address',\n },\n {\n name: 'amount',\n type: 'uint256',\n indexed: false,\n internalType: 'uint256',\n },\n ],\n anonymous: false,\n },\n {\n type: 'event',\n name: 'CollateralAdded',\n inputs: [\n {\n name: 'remoteBlockchainID',\n type: 'bytes32',\n indexed: true,\n internalType: 'bytes32',\n },\n {\n name: 'remoteTokenTransferrerAddress',\n type: 'address',\n indexed: true,\n internalType: 'address',\n },\n {\n name: 'amount',\n type: 'uint256',\n indexed: false,\n internalType: 'uint256',\n },\n {\n name: 'remaining',\n type: 'uint256',\n indexed: false,\n internalType: 'uint256',\n },\n ],\n anonymous: false,\n },\n {\n type: 'event',\n name: 'MinTeleporterVersionUpdated',\n inputs: [\n {\n name: 'oldMinTeleporterVersion',\n type: 'uint256',\n indexed: true,\n internalType: 'uint256',\n },\n {\n name: 'newMinTeleporterVersion',\n type: 'uint256',\n indexed: true,\n internalType: 'uint256',\n },\n ],\n anonymous: false,\n },\n {\n type: 'event',\n name: 'OwnershipTransferred',\n inputs: [\n {\n name: 'previousOwner',\n type: 'address',\n indexed: true,\n internalType: 'address',\n },\n {\n name: 'newOwner',\n type: 'address',\n indexed: true,\n internalType: 'address',\n },\n ],\n anonymous: false,\n },\n {\n type: 'event',\n name: 'RemoteRegistered',\n inputs: [\n {\n name: 'remoteBlockchainID',\n type: 'bytes32',\n indexed: true,\n internalType: 'bytes32',\n },\n {\n name: 'remoteTokenTransferrerAddress',\n type: 'address',\n indexed: true,\n internalType: 'address',\n },\n {\n name: 'initialCollateralNeeded',\n type: 'uint256',\n indexed: false,\n internalType: 'uint256',\n },\n {\n name: 'tokenDecimals',\n type: 'uint8',\n indexed: false,\n internalType: 'uint8',\n },\n ],\n anonymous: false,\n },\n {\n type: 'event',\n name: 'TeleporterAddressPaused',\n inputs: [\n {\n name: 'teleporterAddress',\n type: 'address',\n indexed: true,\n internalType: 'address',\n },\n ],\n anonymous: false,\n },\n {\n type: 'event',\n name: 'TeleporterAddressUnpaused',\n inputs: [\n {\n name: 'teleporterAddress',\n type: 'address',\n indexed: true,\n internalType: 'address',\n },\n ],\n anonymous: false,\n },\n {\n type: 'event',\n name: 'TokensAndCallRouted',\n inputs: [\n {\n name: 'teleporterMessageID',\n type: 'bytes32',\n indexed: true,\n internalType: 'bytes32',\n },\n {\n name: 'input',\n type: 'tuple',\n indexed: false,\n internalType: 'struct SendAndCallInput',\n components: [\n {\n name: 'destinationBlockchainID',\n type: 'bytes32',\n internalType: 'bytes32',\n },\n {\n name: 'destinationTokenTransferrerAddress',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'recipientContract',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'recipientPayload',\n type: 'bytes',\n internalType: 'bytes',\n },\n {\n name: 'requiredGasLimit',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'recipientGasLimit',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'multiHopFallback',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'fallbackRecipient',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'primaryFeeTokenAddress',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'primaryFee',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'secondaryFee',\n type: 'uint256',\n internalType: 'uint256',\n },\n ],\n },\n {\n name: 'amount',\n type: 'uint256',\n indexed: false,\n internalType: 'uint256',\n },\n ],\n anonymous: false,\n },\n {\n type: 'event',\n name: 'TokensAndCallSent',\n inputs: [\n {\n name: 'teleporterMessageID',\n type: 'bytes32',\n indexed: true,\n internalType: 'bytes32',\n },\n {\n name: 'sender',\n type: 'address',\n indexed: true,\n internalType: 'address',\n },\n {\n name: 'input',\n type: 'tuple',\n indexed: false,\n internalType: 'struct SendAndCallInput',\n components: [\n {\n name: 'destinationBlockchainID',\n type: 'bytes32',\n internalType: 'bytes32',\n },\n {\n name: 'destinationTokenTransferrerAddress',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'recipientContract',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'recipientPayload',\n type: 'bytes',\n internalType: 'bytes',\n },\n {\n name: 'requiredGasLimit',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'recipientGasLimit',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'multiHopFallback',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'fallbackRecipient',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'primaryFeeTokenAddress',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'primaryFee',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'secondaryFee',\n type: 'uint256',\n internalType: 'uint256',\n },\n ],\n },\n {\n name: 'amount',\n type: 'uint256',\n indexed: false,\n internalType: 'uint256',\n },\n ],\n anonymous: false,\n },\n {\n type: 'event',\n name: 'TokensRouted',\n inputs: [\n {\n name: 'teleporterMessageID',\n type: 'bytes32',\n indexed: true,\n internalType: 'bytes32',\n },\n {\n name: 'input',\n type: 'tuple',\n indexed: false,\n internalType: 'struct SendTokensInput',\n components: [\n {\n name: 'destinationBlockchainID',\n type: 'bytes32',\n internalType: 'bytes32',\n },\n {\n name: 'destinationTokenTransferrerAddress',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'recipient',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'primaryFeeTokenAddress',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'primaryFee',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'secondaryFee',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'requiredGasLimit',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'multiHopFallback',\n type: 'address',\n internalType: 'address',\n },\n ],\n },\n {\n name: 'amount',\n type: 'uint256',\n indexed: false,\n internalType: 'uint256',\n },\n ],\n anonymous: false,\n },\n {\n type: 'event',\n name: 'TokensSent',\n inputs: [\n {\n name: 'teleporterMessageID',\n type: 'bytes32',\n indexed: true,\n internalType: 'bytes32',\n },\n {\n name: 'sender',\n type: 'address',\n indexed: true,\n internalType: 'address',\n },\n {\n name: 'input',\n type: 'tuple',\n indexed: false,\n internalType: 'struct SendTokensInput',\n components: [\n {\n name: 'destinationBlockchainID',\n type: 'bytes32',\n internalType: 'bytes32',\n },\n {\n name: 'destinationTokenTransferrerAddress',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'recipient',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'primaryFeeTokenAddress',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'primaryFee',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'secondaryFee',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'requiredGasLimit',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'multiHopFallback',\n type: 'address',\n internalType: 'address',\n },\n ],\n },\n {\n name: 'amount',\n type: 'uint256',\n indexed: false,\n internalType: 'uint256',\n },\n ],\n anonymous: false,\n },\n {\n type: 'event',\n name: 'TokensWithdrawn',\n inputs: [\n {\n name: 'recipient',\n type: 'address',\n indexed: true,\n internalType: 'address',\n },\n {\n name: 'amount',\n type: 'uint256',\n indexed: false,\n internalType: 'uint256',\n },\n ],\n anonymous: false,\n },\n] as const;\n","export const ERC20_TOKEN_REMOTE_ABI = [\n {\n type: 'constructor',\n inputs: [\n {\n name: 'settings',\n type: 'tuple',\n internalType: 'struct TokenRemoteSettings',\n components: [\n {\n name: 'teleporterRegistryAddress',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'teleporterManager',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'tokenHomeBlockchainID',\n type: 'bytes32',\n internalType: 'bytes32',\n },\n {\n name: 'tokenHomeAddress',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'tokenHomeDecimals',\n type: 'uint8',\n internalType: 'uint8',\n },\n ],\n },\n {\n name: 'tokenName',\n type: 'string',\n internalType: 'string',\n },\n {\n name: 'tokenSymbol',\n type: 'string',\n internalType: 'string',\n },\n {\n name: 'tokenDecimals_',\n type: 'uint8',\n internalType: 'uint8',\n },\n ],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n name: 'MULTI_HOP_CALL_GAS_PER_WORD',\n inputs: [],\n outputs: [\n {\n name: '',\n type: 'uint256',\n internalType: 'uint256',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'MULTI_HOP_CALL_REQUIRED_GAS',\n inputs: [],\n outputs: [\n {\n name: '',\n type: 'uint256',\n internalType: 'uint256',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'MULTI_HOP_SEND_REQUIRED_GAS',\n inputs: [],\n outputs: [\n {\n name: '',\n type: 'uint256',\n internalType: 'uint256',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'REGISTER_REMOTE_REQUIRED_GAS',\n inputs: [],\n outputs: [\n {\n name: '',\n type: 'uint256',\n internalType: 'uint256',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'allowance',\n inputs: [\n {\n name: 'owner',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'spender',\n type: 'address',\n internalType: 'address',\n },\n ],\n outputs: [\n {\n name: '',\n type: 'uint256',\n internalType: 'uint256',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'approve',\n inputs: [\n {\n name: 'spender',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'amount',\n type: 'uint256',\n internalType: 'uint256',\n },\n ],\n outputs: [\n {\n name: '',\n type: 'bool',\n internalType: 'bool',\n },\n ],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n name: 'balanceOf',\n inputs: [\n {\n name: 'account',\n type: 'address',\n internalType: 'address',\n },\n ],\n outputs: [\n {\n name: '',\n type: 'uint256',\n internalType: 'uint256',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'blockchainID',\n inputs: [],\n outputs: [\n {\n name: '',\n type: 'bytes32',\n internalType: 'bytes32',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'calculateNumWords',\n inputs: [\n {\n name: 'payloadSize',\n type: 'uint256',\n internalType: 'uint256',\n },\n ],\n outputs: [\n {\n name: '',\n type: 'uint256',\n internalType: 'uint256',\n },\n ],\n stateMutability: 'pure',\n },\n {\n type: 'function',\n name: 'decimals',\n inputs: [],\n outputs: [\n {\n name: '',\n type: 'uint8',\n internalType: 'uint8',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'decreaseAllowance',\n inputs: [\n {\n name: 'spender',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'subtractedValue',\n type: 'uint256',\n internalType: 'uint256',\n },\n ],\n outputs: [\n {\n name: '',\n type: 'bool',\n internalType: 'bool',\n },\n ],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n name: 'getMinTeleporterVersion',\n inputs: [],\n outputs: [\n {\n name: '',\n type: 'uint256',\n internalType: 'uint256',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'homeTokenDecimals',\n inputs: [],\n outputs: [\n {\n name: '',\n type: 'uint8',\n internalType: 'uint8',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'increaseAllowance',\n inputs: [\n {\n name: 'spender',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'addedValue',\n type: 'uint256',\n internalType: 'uint256',\n },\n ],\n outputs: [\n {\n name: '',\n type: 'bool',\n internalType: 'bool',\n },\n ],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n name: 'initialReserveImbalance',\n inputs: [],\n outputs: [\n {\n name: '',\n type: 'uint256',\n internalType: 'uint256',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'isCollateralized',\n inputs: [],\n outputs: [\n {\n name: '',\n type: 'bool',\n internalType: 'bool',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'isRegistered',\n inputs: [],\n outputs: [\n {\n name: '',\n type: 'bool',\n internalType: 'bool',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'isTeleporterAddressPaused',\n inputs: [\n {\n name: 'teleporterAddress',\n type: 'address',\n internalType: 'address',\n },\n ],\n outputs: [\n {\n name: '',\n type: 'bool',\n internalType: 'bool',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'multiplyOnRemote',\n inputs: [],\n outputs: [\n {\n name: '',\n type: 'bool',\n internalType: 'bool',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'name',\n inputs: [],\n outputs: [\n {\n name: '',\n type: 'string',\n internalType: 'string',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'owner',\n inputs: [],\n outputs: [\n {\n name: '',\n type: 'address',\n internalType: 'address',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'pauseTeleporterAddress',\n inputs: [\n {\n name: 'teleporterAddress',\n type: 'address',\n internalType: 'address',\n },\n ],\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n name: 'receiveTeleporterMessage',\n inputs: [\n {\n name: 'sourceBlockchainID',\n type: 'bytes32',\n internalType: 'bytes32',\n },\n {\n name: 'originSenderAddress',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'message',\n type: 'bytes',\n internalType: 'bytes',\n },\n ],\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n name: 'registerWithHome',\n inputs: [\n {\n name: 'feeInfo',\n type: 'tuple',\n internalType: 'struct TeleporterFeeInfo',\n components: [\n {\n name: 'feeTokenAddress',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'amount',\n type: 'uint256',\n internalType: 'uint256',\n },\n ],\n },\n ],\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n name: 'renounceOwnership',\n inputs: [],\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n name: 'send',\n inputs: [\n {\n name: 'input',\n type: 'tuple',\n internalType: 'struct SendTokensInput',\n components: [\n {\n name: 'destinationBlockchainID',\n type: 'bytes32',\n internalType: 'bytes32',\n },\n {\n name: 'destinationTokenTransferrerAddress',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'recipient',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'primaryFeeTokenAddress',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'primaryFee',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'secondaryFee',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'requiredGasLimit',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'multiHopFallback',\n type: 'address',\n internalType: 'address',\n },\n ],\n },\n {\n name: 'amount',\n type: 'uint256',\n internalType: 'uint256',\n },\n ],\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n name: 'sendAndCall',\n inputs: [\n {\n name: 'input',\n type: 'tuple',\n internalType: 'struct SendAndCallInput',\n components: [\n {\n name: 'destinationBlockchainID',\n type: 'bytes32',\n internalType: 'bytes32',\n },\n {\n name: 'destinationTokenTransferrerAddress',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'recipientContract',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'recipientPayload',\n type: 'bytes',\n internalType: 'bytes',\n },\n {\n name: 'requiredGasLimit',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'recipientGasLimit',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'multiHopFallback',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'fallbackRecipient',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'primaryFeeTokenAddress',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'primaryFee',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'secondaryFee',\n type: 'uint256',\n internalType: 'uint256',\n },\n ],\n },\n {\n name: 'amount',\n type: 'uint256',\n internalType: 'uint256',\n },\n ],\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n name: 'symbol',\n inputs: [],\n outputs: [\n {\n name: '',\n type: 'string',\n internalType: 'string',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'teleporterRegistry',\n inputs: [],\n outputs: [\n {\n name: '',\n type: 'address',\n internalType: 'contract TeleporterRegistry',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'tokenDecimals',\n inputs: [],\n outputs: [\n {\n name: '',\n type: 'uint8',\n internalType: 'uint8',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'tokenHomeAddress',\n inputs: [],\n outputs: [\n {\n name: '',\n type: 'address',\n internalType: 'address',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'tokenHomeBlockchainID',\n inputs: [],\n outputs: [\n {\n name: '',\n type: 'bytes32',\n internalType: 'bytes32',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'tokenMultiplier',\n inputs: [],\n outputs: [\n {\n name: '',\n type: 'uint256',\n internalType: 'uint256',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'totalSupply',\n inputs: [],\n outputs: [\n {\n name: '',\n type: 'uint256',\n internalType: 'uint256',\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'transfer',\n inputs: [\n {\n name: 'to',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'amount',\n type: 'uint256',\n internalType: 'uint256',\n },\n ],\n outputs: [\n {\n name: '',\n type: 'bool',\n internalType: 'bool',\n },\n ],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n name: 'transferFrom',\n inputs: [\n {\n name: 'from',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'to',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'amount',\n type: 'uint256',\n internalType: 'uint256',\n },\n ],\n outputs: [\n {\n name: '',\n type: 'bool',\n internalType: 'bool',\n },\n ],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n name: 'transferOwnership',\n inputs: [\n {\n name: 'newOwner',\n type: 'address',\n internalType: 'address',\n },\n ],\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n name: 'unpauseTeleporterAddress',\n inputs: [\n {\n name: 'teleporterAddress',\n type: 'address',\n internalType: 'address',\n },\n ],\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'function',\n name: 'updateMinTeleporterVersion',\n inputs: [\n {\n name: 'version',\n type: 'uint256',\n internalType: 'uint256',\n },\n ],\n outputs: [],\n stateMutability: 'nonpayable',\n },\n {\n type: 'event',\n name: 'Approval',\n inputs: [\n {\n name: 'owner',\n type: 'address',\n indexed: true,\n internalType: 'address',\n },\n {\n name: 'spender',\n type: 'address',\n indexed: true,\n internalType: 'address',\n },\n {\n name: 'value',\n type: 'uint256',\n indexed: false,\n internalType: 'uint256',\n },\n ],\n anonymous: false,\n },\n {\n type: 'event',\n name: 'CallFailed',\n inputs: [\n {\n name: 'recipientContract',\n type: 'address',\n indexed: true,\n internalType: 'address',\n },\n {\n name: 'amount',\n type: 'uint256',\n indexed: false,\n internalType: 'uint256',\n },\n ],\n anonymous: false,\n },\n {\n type: 'event',\n name: 'CallSucceeded',\n inputs: [\n {\n name: 'recipientContract',\n type: 'address',\n indexed: true,\n internalType: 'address',\n },\n {\n name: 'amount',\n type: 'uint256',\n indexed: false,\n internalType: 'uint256',\n },\n ],\n anonymous: false,\n },\n {\n type: 'event',\n name: 'MinTeleporterVersionUpdated',\n inputs: [\n {\n name: 'oldMinTeleporterVersion',\n type: 'uint256',\n indexed: true,\n internalType: 'uint256',\n },\n {\n name: 'newMinTeleporterVersion',\n type: 'uint256',\n indexed: true,\n internalType: 'uint256',\n },\n ],\n anonymous: false,\n },\n {\n type: 'event',\n name: 'OwnershipTransferred',\n inputs: [\n {\n name: 'previousOwner',\n type: 'address',\n indexed: true,\n internalType: 'address',\n },\n {\n name: 'newOwner',\n type: 'address',\n indexed: true,\n internalType: 'address',\n },\n ],\n anonymous: false,\n },\n {\n type: 'event',\n name: 'TeleporterAddressPaused',\n inputs: [\n {\n name: 'teleporterAddress',\n type: 'address',\n indexed: true,\n internalType: 'address',\n },\n ],\n anonymous: false,\n },\n {\n type: 'event',\n name: 'TeleporterAddressUnpaused',\n inputs: [\n {\n name: 'teleporterAddress',\n type: 'address',\n indexed: true,\n internalType: 'address',\n },\n ],\n anonymous: false,\n },\n {\n type: 'event',\n name: 'TokensAndCallSent',\n inputs: [\n {\n name: 'teleporterMessageID',\n type: 'bytes32',\n indexed: true,\n internalType: 'bytes32',\n },\n {\n name: 'sender',\n type: 'address',\n indexed: true,\n internalType: 'address',\n },\n {\n name: 'input',\n type: 'tuple',\n indexed: false,\n internalType: 'struct SendAndCallInput',\n components: [\n {\n name: 'destinationBlockchainID',\n type: 'bytes32',\n internalType: 'bytes32',\n },\n {\n name: 'destinationTokenTransferrerAddress',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'recipientContract',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'recipientPayload',\n type: 'bytes',\n internalType: 'bytes',\n },\n {\n name: 'requiredGasLimit',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'recipientGasLimit',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'multiHopFallback',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'fallbackRecipient',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'primaryFeeTokenAddress',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'primaryFee',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'secondaryFee',\n type: 'uint256',\n internalType: 'uint256',\n },\n ],\n },\n {\n name: 'amount',\n type: 'uint256',\n indexed: false,\n internalType: 'uint256',\n },\n ],\n anonymous: false,\n },\n {\n type: 'event',\n name: 'TokensSent',\n inputs: [\n {\n name: 'teleporterMessageID',\n type: 'bytes32',\n indexed: true,\n internalType: 'bytes32',\n },\n {\n name: 'sender',\n type: 'address',\n indexed: true,\n internalType: 'address',\n },\n {\n name: 'input',\n type: 'tuple',\n indexed: false,\n internalType: 'struct SendTokensInput',\n components: [\n {\n name: 'destinationBlockchainID',\n type: 'bytes32',\n internalType: 'bytes32',\n },\n {\n name: 'destinationTokenTransferrerAddress',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'recipient',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'primaryFeeTokenAddress',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'primaryFee',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'secondaryFee',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'requiredGasLimit',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'multiHopFallback',\n type: 'address',\n internalType: 'address',\n },\n ],\n },\n {\n name: 'amount',\n type: 'uint256',\n indexed: false,\n internalType: 'uint256',\n },\n ],\n anonymous: false,\n },\n {\n type: 'event',\n name: 'TokensWithdrawn',\n inputs: [\n {\n name: 'recipient',\n type: 'address',\n indexed: true,\n internalType: 'address',\n },\n {\n name: 'amount',\n type: 'uint256',\n indexed: false,\n internalType: 'uint256',\n },\n ],\n anonymous: false,\n },\n {\n type: 'event',\n name: 'Transfer',\n inputs: [\n {\n name: 'from',\n type: 'address',\n indexed: true,\n internalType: 'address',\n },\n {\n name: 'to',\n type: 'address',\n indexed: true,\n internalType: 'address',\n },\n {\n name: 'value',\n type: 'uint256',\n indexed: false,\n internalType: 'uint256',\n },\n ],\n anonymous: false,\n },\n] as const;\n","import { type CreateEvmSourceTrackerArgs, type CreateEvmTargetTrackerArgs } from '../../../utils/tracking';\nimport { ErrorReason, type BridgeTransfer } from '../../../types';\nimport { InvalidParamsError } from '../../../errors';\nimport { ERC20_TOKEN_HOME_ABI } from '../abis/erc20-token-home';\nimport { ERC20_TOKEN_REMOTE_ABI } from '../abis/erc20-token-remote';\nimport type { TransferData } from './transfer-data';\nimport { decodeEventLog, isHex, type AbiEvent, type Hex } from 'viem';\nimport type { Client } from '../../../utils/evm/client';\nimport { isNil, isObject } from 'lodash';\n\nexport const createGetMetadata =\n ({\n transferData: { homeToRemote, tokenHomeConfig, tokenRemoteConfig },\n }: {\n transferData: TransferData;\n }): CreateEvmSourceTrackerArgs['getMetadata'] =>\n (txReceipt) => {\n /**\n * Get the `TokensSent` event's log entry from the receipt\n */\n const contractAddress = homeToRemote ? tokenHomeConfig.tokenHomeAddress : tokenRemoteConfig.tokenRemoteAddress;\n const abi = homeToRemote ? ERC20_TOKEN_HOME_ABI : ERC20_TOKEN_REMOTE_ABI;\n const eventName = 'TokensSent';\n\n const transferEventLog = txReceipt.logs.find((log) => {\n if (log.address.toLowerCase() === contractAddress.toLowerCase()) {\n const event = decodeEventLog({\n abi,\n ...log,\n });\n\n return event.eventName === eventName;\n }\n\n return false;\n });\n\n if (!transferEventLog) {\n throw new InvalidParamsError(\n ErrorReason.INVALID_PARAMS,\n `unable to find a TokensSent event in source transaction \"${txReceipt.transactionHash}\"`,\n );\n }\n\n const transferEvent = decodeEventLog({\n abi,\n eventName,\n ...transferEventLog,\n });\n\n // save the teleporterMessageID and broadcast\n const teleporterMessageID = transferEvent.args.teleporterMessageID;\n return { teleporterMessageID };\n };\n\nexport const RECEIVE_CROSS_CHAIN_MESSAGE_EVENT = {\n name: 'ReceiveCrossChainMessage',\n type: 'event',\n inputs: [\n {\n name: 'messageID',\n type: 'bytes32',\n indexed: true,\n internalType: 'bytes32',\n },\n {\n name: 'sourceBlockchainID',\n type: 'bytes32',\n indexed: true,\n internalType: 'bytes32',\n },\n {\n name: 'deliverer',\n type: 'address',\n indexed: true,\n internalType: 'address',\n },\n {\n name: 'rewardRedeemer',\n type: 'address',\n indexed: false,\n internalType: 'address',\n },\n {\n name: 'message',\n type: 'tuple',\n indexed: false,\n internalType: 'struct TeleporterMessage',\n components: [\n {\n name: 'messageNonce',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'originSenderAddress',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'destinationBlockchainID',\n type: 'bytes32',\n internalType: 'bytes32',\n },\n {\n name: 'destinationAddress',\n type: 'address',\n internalType: 'address',\n },\n {\n name: 'requiredGasLimit',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'allowedRelayerAddresses',\n type: 'address[]',\n internalType: 'address[]',\n },\n {\n name: 'receipts',\n type: 'tuple[]',\n internalType: 'struct TeleporterMessageReceipt[]',\n components: [\n {\n name: 'receivedMessageNonce',\n type: 'uint256',\n internalType: 'uint256',\n },\n {\n name: 'relayerRewardAddress',\n type: 'address',\n internalType: 'address',\n },\n ],\n },\n {\n name: 'message',\n type: 'bytes',\n internalType: 'bytes',\n },\n ],\n },\n ],\n} satisfies AbiEvent;\n\nexport const createGetTargetTxHash =\n ({\n toAddress,\n transferData: { tokenHomeConfig, homeToRemote, tokenRemoteConfig },\n targetClient,\n }: {\n transferData: TransferData;\n targetClient: Client;\n toAddress: string;\n }): CreateEvmTargetTrackerArgs['getTargetTxHash'] =>\n async ({ fromBlock, toBlock, metadata }) => {\n if (!checkMetadata(metadata)) {\n throw new InvalidParamsError(ErrorReason.INVALID_PARAMS);\n }\n const receiveCrosschainMessageLogs = await targetClient.getLogs({\n address: tokenHomeConfig.teleporterAddress,\n event: RECEIVE_CROSS_CHAIN_MESSAGE_EVENT,\n args: {\n messageID: metadata.teleporterMessageID,\n },\n fromBlock,\n toBlock,\n });\n const lastLog = receiveCrosschainMessageLogs.at(-1);\n if (isNil(lastLog)) {\n return undefined;\n }\n const lastLogTxHash = lastLog.transactionHash;\n const txReceipt = await targetClient.getTransactionReceipt({\n hash: lastLogTxHash,\n });\n /**\n * It's not enough to monitor for the `ReceiveCrossChainMessage` event on the Teleporter Contract.\n * The message might still fail to execute on the Target side.\n * Additionally, if the recipient cannot receive funds, the ICTT contract may send the funds to a fallback address.\n * We must confirm that the `TokensWithdrawn` event was emitted from the same transaction as the `ReceiveCrossChainMessage` event,\n * with the expected recipient.\n */\n const abi = homeToRemote ? ERC20_TOKEN_REMOTE_ABI : ERC20_TOKEN_HOME_ABI;\n const contractAddress = homeToRemote ? tokenRemoteConfig.tokenRemoteAddress : tokenHomeConfig.tokenHomeAddress;\n const tokenWithdrawnEventLog = txReceipt.logs.find((log) => {\n if (log.address.toLowerCase() === contractAddress.toLowerCase()) {\n const event = decodeEventLog({\n abi,\n ...log,\n });\n\n return event.eventName === 'TokensWithdrawn';\n }\n\n return false;\n });\n\n if (isNil(tokenWithdrawnEventLog)) {\n return undefined;\n }\n const tokenWithdrawnEvent = decodeEventLog({\n abi,\n eventName: 'TokensWithdrawn',\n ...tokenWithdrawnEventLog,\n });\n\n if (tokenWithdrawnEvent.args.recipient.toLowerCase() === toAddress.toLowerCase()) {\n return lastLogTxHash;\n }\n return undefined;\n };\n\nexport const checkMetadata = (metadata: BridgeTransfer['metadata']): metadata is { teleporterMessageID: Hex } => {\n return isObject(metadata) && isHex(metadata.teleporterMessageID);\n};\n","import { getClientForChain } from '../../../utils/evm/client';\nimport { getTransferData } from '../utils/transfer-data';\nimport { retryPromise } from '../../../utils/retry-promise';\n\nimport { createEvmSourceTracker, createEvmTargetTracker, DEFAULT_TRACKING_CONFIG } from '../../../utils/tracking';\nimport { createGetMetadata, createGetTargetTxHash, checkMetadata } from '../utils/ictt-erc20-erc20-tracking';\nimport type { BridgeTransfer, TrackingParams } from '../../../types';\nimport type { IcttErc20Erc20Config } from '../types/config';\n\nconst trackSourceTx = async (config: IcttErc20Erc20Config, params: TrackingParams) => {\n const { bridgeTransfer } = params;\n const { asset, amount, sourceChain, targetChain } = bridgeTransfer;\n const transferData = getTransferData({ sourceChain, targetChain, asset, amount }, config);\n const sourceClient = getClientForChain({\n chain: bridgeTransfer.sourceChain,\n });\n\n const targetClient = getClientForChain({\n chain: bridgeTransfer.targetChain,\n });\n\n const getMetadata = createGetMetadata({ transferData });\n\n const tracker = createEvmSourceTracker({\n sourceClient,\n targetClient,\n getMetadata,\n checkMetadata,\n trackingParams: params,\n trackingConfig: DEFAULT_TRACKING_CONFIG,\n });\n\n return retryPromise<BridgeTransfer>({\n promise: tracker,\n delay: 2000,\n startAfter: DEFAULT_TRACKING_CONFIG.initialDelayMs,\n });\n};\n\n/**\n * Polls the target network until it finds the transaction that matches the message's teleporterMessageId\n * Updates the provided `BridgeTransfer` and broadcasts the changes via `updateListener`\n */\nexport const trackTargetTx = async (config: IcttErc20Erc20Config, params: TrackingParams) => {\n const { bridgeTransfer } = params;\n const { targetChain, sourceChain, asset, amount, toAddress } = bridgeTransfer;\n const transferData = getTransferData({ sourceChain, targetChain, asset, amount }, config);\n\n const targetClient = getClientForChain({\n chain: bridgeTransfer.targetChain,\n });\n\n const getTargetTxHash = createGetTargetTxHash({\n transferData,\n targetClient,\n toAddress,\n });\n\n const tracker = createEvmTargetTracker({\n targetClient,\n getTargetTxHash,\n checkMetadata,\n trackingParams: params,\n trackingConfig: DEFAULT_TRACKING_CONFIG,\n });\n\n return retryPromise<BridgeTransfer>({\n promise: tracker,\n delay: 2000,\n startAfter: DEFAULT_TRACKING_CONFIG.initialDelayMs,\n });\n};\n\nexport function trackTransfer(config: IcttErc20Erc20Config, params: TrackingParams) {\n let abortFn: (() => void) | undefined;\n\n const cancel = () => {\n abortFn?.();\n };\n\n const executeTracking = async () => {\n const { updateListener } = params;\n const { result: sourceTracker, cancel: cancelSourceTracking } = await trackSourceTx(config, params);\n abortFn = cancelSourceTracking;\n const transferAfterSourceFinished = await sourceTracker;\n\n const { result: targetTracker, cancel: cancelTargetTracking } = await trackTargetTx(config, {\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 FeeParams } from '../../../types';\nimport type { IcttErc20Erc20Config } from '../types/config';\nimport { getTransferData } from '../utils/transfer-data';\n\nexport async function getMinimumTransferAmount(config: IcttErc20Erc20Config, params: FeeParams) {\n getTransferData(params, config); // This validates the FeeParams\n return 1n;\n}\n","import { base58 } from '@scure/base';\nimport type { BytesCoder } from '@scure/base';\nimport { sha256 } from '@noble/hashes/sha256';\nimport { concatBytes } from '@noble/hashes/utils';\n\nexport const base58check: BytesCoder = {\n encode(data) {\n return base58.encode(concatBytes(data, sha256(data).subarray(-4)));\n },\n decode(string) {\n return base58.decode(string).subarray(0, -4);\n },\n};\n","import { z } from 'zod';\nimport type { Address } from 'abitype';\n\nimport { type Erc20Asset, type Hex } from '../../../types';\nimport { evmAddressSchema } from '../../../utils/evm/evm-address-schema';\n\nexport type ChainInfo = {\n chainId: string;\n blockchainId: Hex;\n};\n\n/**\n * Major assumption: remote ERC20 has same decimals as corresponding TokenHome.baseToken\n */\nexport type TokenRemoteConfig = {\n remoteChain: ChainInfo;\n tokenRemoteAddress: Address;\n};\n\nexport type TokenHomeConfig = {\n teleporterAddress: Address;\n tokenHomeAddress: Address;\n tokenHomeDecimals: number;\n baseToken: Erc20Asset;\n remotes: TokenRemoteConfig[];\n};\n\nexport type ChainBridgeConfig = {\n homeChain: ChainInfo;\n erc20Bridges: TokenHomeConfig[];\n};\n\nexport type IcttErc20Erc20Config = ChainBridgeConfig[];\n\nexport const chainApiSchema = z.object({\n subnetName: z.string(),\n subnetID: z.string(),\n blockchainID: z.string(),\n chainID: z.number(),\n network: z.string(),\n});\n\nexport const chainsApiSchema = z.array(chainApiSchema);\n\nexport const bridgeApiSchema = z.object({\n PKey: z.string(),\n SKey: z.string(),\n orgID: z.string(),\n bridgeID: z.string(),\n tokenAddress: evmAddressSchema,\n tokenSymbol: z.string(),\n tokenName: z.string(),\n tokenDecimals: z.number(),\n tokenHomeAddress: evmAddressSchema,\n tokenHomeChainID: z.number(),\n tokenRemoteAddress: evmAddressSchema,\n tokenRemoteChainID: z.number(),\n network: z.string(),\n isRegisteredInBridgeApp: z.enum(['Y', 'N']),\n createdAt: z.number(),\n updatedAt: z.number(),\n});\n\nexport const bridgesApiSchema = z.array(bridgeApiSchema);\n\nexport type ApiChain = typeof chainApiSchema._output;\nexport type ApiBridge = typeof bridgeApiSchema._output;\n","import type { Address } from 'abitype';\nimport { Environment } from '../../../types';\n\n/**\n * Major versions of teleporter have a fixed address across all chains.\n * Teleporter addresses must be identical for cross chain compatibility.\n * @see https://github.com/ava-labs/teleporter/tree/main?tab=readme-ov-file#deployed-addresses\n */\nexport const TELEPORTER_MESSENGER_ADDRESS_V1: Address = '0x253b2784c75e510dD0fF1da844684a1aC0aa5fcf';\n\nexport type SupportedEnvironment = Environment.PROD | Environment.TEST;\n\nexport const CONFIG_URLS: Record<SupportedEnvironment, string> = {\n [Environment.TEST]: 'https://ac-gateway-staging-us-east-1.avacloud-test.io/v1/bridge-app',\n [Environment.PROD]: 'https://ac-gateway-production-us-east-1.avacloud.io/v1/bridge-app',\n};\n\nexport const MainnetCChain = {\n chainID: 43114,\n blockchainID: '2q9e4r6Mu3U68nU1fYjgbR6JvwrRx36CohpAX5UQxse55x1Q5',\n} as const;\n\nexport const TestnetCChain = {\n chainID: 43113,\n blockchainID: 'yH8D7ThNJkxmtkuv2jgBa4P1Rn3Qpr4pPr7QYNfcdoS6k6HWp',\n} as const;\n","import { BridgeInitializationError } from '../../../errors';\nimport { ErrorReason, TokenType } from '../../../types';\nimport { Environment } from '../../../types/environment';\nimport { base58check } from '../../../utils/base58check';\nimport { bridgesApiSchema, chainsApiSchema, type ApiBridge, type IcttErc20Erc20Config } from '../types/config';\nimport { caip2 } from '../../../utils';\nimport {\n CONFIG_URLS,\n MainnetCChain,\n TELEPORTER_MESSENGER_ADDRESS_V1,\n TestnetCChain,\n type SupportedEnvironment,\n} from './consts';\nimport { toHex } from 'viem';\nimport { retrieveJson } from './retrieve-json';\n\nconst isSupportedEnvironment = (env: Environment): env is SupportedEnvironment => {\n return env === Environment.PROD || env === Environment.TEST;\n};\n\nconst isFulfilled = <T>(result: PromiseSettledResult<T>): result is PromiseFulfilledResult<T> =>\n result.status === 'fulfilled';\n\nconst getChains = async (baseUrl: string, env: Environment) => {\n const chainsJson = await retrieveJson(`${baseUrl}/chains`);\n // Include respective C-Chain info, `/chains` endpoint does not return it\n return [env === Environment.PROD ? MainnetCChain : TestnetCChain, ...chainsApiSchema.parse(chainsJson)];\n};\n\nconst getBridges = async (baseUrl: string, chains: { chainID: number }[]): Promise<ApiBridge[]> => {\n const bridgesResults = await Promise.allSettled(\n chains.map(async (chain) => {\n const chainBridgesJson = await retrieveJson(`${baseUrl}/chains/${chain.chainID}/bridges`);\n return bridgesApiSchema.parse(chainBridgesJson);\n }),\n );\n return bridgesResults.filter(isFulfilled).flatMap((b) => b.value);\n};\n\nexport const getConfig = async (environment: Environment): Promise<IcttErc20Erc20Config> => {\n if (!isSupportedEnvironment(environment)) {\n throw new BridgeInitializationError(\n ErrorReason.ENVIRONMENT_NOT_SUPPORTED,\n `ICTT does not support ${environment} environment`,\n );\n }\n\n try {\n const baseUrl = CONFIG_URLS[environment];\n const chains = await getChains(baseUrl, environment);\n const bridges = await getBridges(baseUrl, chains);\n const config: IcttErc20Erc20Config = [];\n\n bridges.forEach((bridge) => {\n const homeChainInfo = chains.find(({ chainID }) => chainID === bridge.tokenHomeChainID);\n\n if (!homeChainInfo) {\n // No info about the home chain for some reason, skip adding the home chain config\n return;\n }\n\n let homeChainConfig = config.find(\n ({ homeChain }) =>\n homeChain.chainId === caip2.toString({ namespace: 'eip155', reference: String(homeChainInfo.chainID) }),\n );\n if (!homeChainConfig) {\n homeChainConfig = {\n homeChain: {\n chainId: caip2.toString({ namespace: 'eip155', reference: String(homeChainInfo.chainID) }),\n blockchainId: toHex(base58check.decode(homeChainInfo.blockchainID)),\n },\n erc20Bridges: [],\n };\n config.push(homeChainConfig);\n }\n\n let tokenBridge = homeChainConfig.erc20Bridges.find(\n ({ tokenHomeAddress }) => tokenHomeAddress === bridge.tokenHomeAddress,\n );\n if (!tokenBridge) {\n tokenBridge = {\n baseToken: {\n address: bridge.tokenAddress,\n decimals: bridge.tokenDecimals,\n name: bridge.tokenName || bridge.tokenSymbol, // some tokens have the name empty\n symbol: bridge.tokenSymbol,\n type: TokenType.ERC20,\n },\n remotes: [],\n teleporterAddress: TELEPORTER_MESSENGER_ADDRESS_V1,\n tokenHomeAddress: bridge.tokenHomeAddress,\n tokenHomeDecimals: bridge.tokenDecimals,\n };\n homeChainConfig.erc20Bridges.push(tokenBridge);\n }\n\n const remoteChain = chains.find(({ chainID }) => chainID === bridge.tokenRemoteChainID);\n\n if (!remoteChain) {\n // No info about the remote chain for some reason, skip adding the remote config\n return;\n }\n\n const blockchainIdAsHex = toHex(base58check.decode(remoteChain.blockchainID));\n const caipId = caip2.toString({ namespace: 'eip155', reference: String(bridge.tokenRemoteChainID) });\n const existingRemote = tokenBridge.remotes.find(\n ({ tokenRemoteAddress, remoteChain: { chainId } }) =>\n tokenRemoteAddress === bridge.tokenRemoteAddress && chainId === caipId,\n );\n if (!existingRemote) {\n tokenBridge.remotes.push({\n remoteChain: {\n chainId: caipId,\n blockchainId: blockchainIdAsHex,\n },\n tokenRemoteAddress: bridge.tokenRemoteAddress,\n });\n }\n });\n\n // Filter out the home chain configs which do not have any matching remote configs\n return config\n .map((chainConfig) => ({\n ...chainConfig,\n erc20Bridges: chainConfig.erc20Bridges.filter((bridgeConfig) => bridgeConfig.remotes.length > 0),\n }))\n .filter((chainConfig) => chainConfig.erc20Bridges.length > 0);\n } catch (err) {\n throw new BridgeInitializationError(\n ErrorReason.CONFIG_NOT_AVAILABLE,\n `Error while fetching ICTT-ERC20-ERC20 config: ${(err as unknown as Error).message}`,\n );\n }\n};\n","export const retrieveJson = async (url: string) => {\n const response = await fetch(url);\n return await response.json();\n};\n","import { getFees } from './get-fees';\nimport { getTransferData } from '../utils/transfer-data';\nimport type { IcttErc20Erc20Config } from '../types/config';\nimport type { Asset } from '../../../types';\nimport type { ValidEvmGasEstimationParams } from '../../../utils/evm/types/bridge';\n\nexport const estimateReceiveAmount = async (config: IcttErc20Erc20Config, params: ValidEvmGasEstimationParams) => {\n const {\n homeToRemote,\n tokenHomeConfig: { baseToken },\n tokenRemoteConfig: { tokenRemoteAddress },\n } = getTransferData(params, config);\n const targetAsset: Asset = { ...baseToken, address: homeToRemote ? tokenRemoteAddress : baseToken.address };\n const fees = await getFees(config, params);\n return {\n amount: params.amount - (fees[baseToken.address] ?? 0n),\n asset: targetAsset,\n };\n};\n","import { isAddressEqual } from 'viem';\nimport { BridgeType, type AnalyzeTxResult } from '../../../types';\nimport { ZERO_ADDRESS } from '../../../utils/consts';\nimport type { IcttErc20Erc20Config } from '../types/config';\nimport type { EvmAnalyzeTxParams } from '../../../utils/evm/types/bridge';\n\nexport function analyzeTx(config: IcttErc20Erc20Config, params: EvmAnalyzeTxParams): AnalyzeTxResult {\n for (const chainConfig of config) {\n for (const bridge of chainConfig.erc20Bridges) {\n const supportedTokenTransfer = params.tokenTransfers.find(({ symbol }) => symbol === bridge.baseToken.symbol);\n\n if (!supportedTokenTransfer) {\n continue;\n }\n\n const isTeleporterInvolved = isAddressEqual(bridge.teleporterAddress, params.to);\n const isFromTokenHome =\n isAddressEqual(params.from, bridge.tokenHomeAddress) ||\n isAddressEqual(supportedTokenTransfer.from, bridge.tokenHomeAddress);\n const isMinted =\n isAddressEqual(params.from, ZERO_ADDRESS) || isAddressEqual(supportedTokenTransfer.from, ZERO_ADDRESS);\n\n // If Token Home sent tokens to the user, or if the transaction sent towards Teleporter resulted\n // in tokens being transfered to the user, the funds were being transfered ONTO the analyzed chain\n if (isTeleporterInvolved && (isFromTokenHome || isMinted)) {\n return {\n isBridgeTx: true,\n // We can only be sure of the source chain if there is only one remote it could have came from\n sourceChainId: bridge.remotes.length === 1 ? bridge.remotes[0]!.remoteChain.chainId : undefined,\n targetChainId: params.chainId,\n bridgeType: BridgeType.ICTT_ERC20_ERC20,\n };\n }\n\n // If Token Home is the target address, the funds were being transfered OUT OF the analyzed chain\n const isToTokenHome =\n isAddressEqual(params.to, bridge.tokenHomeAddress) ||\n isAddressEqual(supportedTokenTransfer.to, bridge.tokenHomeAddress);\n\n if (isToTokenHome) {\n return {\n isBridgeTx: true,\n sourceChainId: params.chainId,\n // We can only be sure of the target chain if there is only one remote it could have went towards\n targetChainId: bridge.remotes.length === 1 ? bridge.remotes[0]!.remoteChain.chainId : undefined,\n bridgeType: BridgeType.ICTT_ERC20_ERC20,\n };\n }\n }\n }\n\n return {\n isBridgeTx: false,\n };\n}\n","import { estimateGas } from './handlers/estimate-gas';\nimport { getAssets } from './handlers/get-assets';\nimport { getFees } from './handlers/get-fees';\nimport { transferAsset } from './handlers/transfer-asset';\nimport { trackTransfer } from './handlers/track-transfer';\nimport { getMinimumTransferAmount } from './handlers/get-minimum-transfer-amount';\nimport { getConfig } from './utils/config';\nimport { estimateReceiveAmount } from './handlers/estimate-receive-amount';\nimport { analyzeTx } from './handlers/analyze-tx';\nimport { BridgeType, type AnalyzeTxParams, type GasEstimationParams } from '../../types';\nimport type { EvmBridgeServiceFactory } from '../../utils/evm/types/bridge';\nimport { toEvmAnalyzeTxParams, toValidEvmGasEstimationParams, toValidEvmTransferParams } from '../../utils/evm/utils';\n\nexport const icttErc20Erc20BridgeFactory: EvmBridgeServiceFactory = async (environment, signer) => {\n const config = await getConfig(environment);\n return {\n type: BridgeType.ICTT_ERC20_ERC20,\n analyzeTx: (params: AnalyzeTxParams) => analyzeTx(config, toEvmAnalyzeTxParams(params)),\n estimateGas: (params: GasEstimationParams) => estimateGas(config, toValidEvmGasEstimationParams(params)),\n estimateReceiveAmount: (params: GasEstimationParams) =>\n estimateReceiveAmount(config, toValidEvmGasEstimationParams(params)),\n getAssets: () => getAssets(config),\n getFees: (params) => getFees(config, params),\n getMinimumTransferAmount: (params) => getMinimumTransferAmount(config, params),\n transferAsset: (params) => transferAsset(config, toValidEvmTransferParams(params), environment, signer),\n trackTransfer: (params) => trackTransfer(config, params),\n };\n};\n","import { cctpBridgeFactory } from '../bridges/cctp/factory';\nimport { icttErc20Erc20BridgeFactory } from '../bridges/ictt-erc20-erc20';\nimport { BridgeUnavailableError } from '../errors';\nimport type { BridgeAsset } from '../types/asset';\nimport {\n type BridgeInitializer,\n type BridgeService,\n BridgeType,\n isAvaToBtcBridgeInitializer,\n isBtcToAvaBridgeInitializer,\n} from '../types/bridge';\nimport type { Environment } from '../types/environment';\nimport type { BridgeServicesMap } from '../types/config';\n\nimport { compact } from 'lodash';\nimport { avalancheEvmBridgeFactory } from '../bridges/avalanche/evm/factory';\nimport { avalancheBtcToAvaBridgeFactory } from '../bridges/avalanche/bitcoin/btc-ava/factory';\nimport { avalancheAvaToBtcBridgeFactory } from '../bridges/avalanche/bitcoin/ava-btc/factory';\n\nexport const supportedBridges = {\n [BridgeType.AVALANCHE_BTC_AVA]: avalancheBtcToAvaBridgeFactory,\n [BridgeType.AVALANCHE_AVA_BTC]: avalancheAvaToBtcBridgeFactory,\n [BridgeType.AVALANCHE_EVM]: avalancheEvmBridgeFactory,\n [BridgeType.CCTP]: cctpBridgeFactory,\n [BridgeType.ICTT_ERC20_ERC20]: icttErc20Erc20BridgeFactory,\n} as const satisfies Record<BridgeType, object>;\n\nexport const getEnabledBridgeServices = async (\n environment: Environment,\n enabledBridgeInitializers: BridgeInitializer[],\n): Promise<BridgeServicesMap> => {\n const bridgePromisesResults = await Promise.allSettled(\n enabledBridgeInitializers.map(async (initializer): Promise<[BridgeType, BridgeService]> => {\n if (isAvaToBtcBridgeInitializer(initializer)) {\n const factory = supportedBridges[initializer.type];\n return [initializer.type, await factory(environment, initializer.signer, initializer.bitcoinFunctions)];\n }\n\n if (isBtcToAvaBridgeInitializer(initializer)) {\n const factory = supportedBridges[initializer.type];\n return [initializer.type, await factory(environment, initializer.signer, initializer.bitcoinFunctions)];\n }\n\n const factory = supportedBridges[initializer.type];\n return [initializer.type, await factory(environment, initializer.signer)];\n }),\n );\n\n return new Map(\n compact(bridgePromisesResults.map((result) => (result.status === 'fulfilled' ? result.value : undefined))),\n );\n};\n\nexport const getBridgeForTransfer = (\n enabledBridgeServices: Map<BridgeType, BridgeService>,\n asset: BridgeAsset,\n targetChainId: string,\n) => {\n const destinations = asset.destinations[targetChainId];\n for (const bridgeType of destinations ?? []) {\n const bridge = enabledBridgeServices.get(bridgeType);\n if (bridge) {\n return { bridge, type: bridgeType };\n }\n }\n throw new BridgeUnavailableError();\n};\n","import { encodeFunctionData, isAddress } from 'viem';\nimport { InvalidParamsError } from '../../../../errors';\nimport type { EvmConfig } from '../types/config';\nimport { ERC20_ABI } from '../../../../abis/erc20';\nimport { ErrorReason, isNativeAsset } from '../../../../types';\nimport { getClientForChain } from '../../../../utils/evm/client';\nimport { WAVAX_ABI } from '../abis/wavax-abi';\nimport { WETH_ABI } from '../abis/weth-abi';\nimport { getTransferData } from '../utils/transfer-data';\nimport type { ValidEvmGasEstimationParams } from '../../../../utils/evm/types/bridge';\n\nexport async function estimateGas(config: EvmConfig, params: ValidEvmGasEstimationParams): Promise<bigint> {\n const { sourceChain, targetChain, asset, amount, fromAddress } = params;\n\n if (!isAddress(fromAddress)) {\n throw new InvalidParamsError(ErrorReason.INVALID_PARAMS, `Invalid fromAddress: ${fromAddress}`);\n }\n\n const ethereumWalletAddress = config.walletAddresses.ethereum;\n\n const { source, ethToAva } = getTransferData({ sourceChain, targetChain, asset, amount }, config);\n const client = getClientForChain({ chain: sourceChain });\n\n let estimate = 0n;\n if (isNativeAsset(asset) && ethToAva) {\n // ETH -> WETH\n estimate += await client.estimateContractGas({\n address: source.token.address,\n abi: WETH_ABI,\n functionName: 'deposit',\n account: fromAddress,\n });\n // Ethereum -> Avalanche\n try {\n estimate += await client.estimateContractGas({\n address: source.token.address,\n abi: ERC20_ABI,\n functionName: 'transfer',\n account: fromAddress,\n args: [ethereumWalletAddress, amount],\n });\n } catch {\n // When estimating the gas before performing the transfer asset, the WETH balance might be too low to perform the estimation.\n // This is a backup way to estimate the gas. But the result usually comes out a bit lower than estimateContractGas.\n const transferData = encodeFunctionData({\n abi: ERC20_ABI,\n functionName: 'transfer',\n args: [ethereumWalletAddress, amount],\n });\n\n estimate += await client.estimateGas({\n data: transferData,\n account: fromAddress,\n to: ethereumWalletAddress,\n value: amount,\n });\n }\n } else {\n estimate = await client.estimateContractGas({\n address: source.token.address,\n abi: ethToAva ? ERC20_ABI : WAVAX_ABI,\n functionName: ethToAva ? 'transfer' : 'unwrap',\n account: fromAddress,\n args: ethToAva ? [ethereumWalletAddress, amount] : [amount, 0],\n });\n }\n\n return estimate;\n}\n","export const WAVAX_ABI = [\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n internalType: 'address',\n name: 'src',\n type: 'address',\n },\n {\n indexed: true,\n internalType: 'address',\n name: 'guy',\n type: 'address',\n },\n {\n indexed: false,\n internalType: 'uint256',\n name: 'wad',\n type: 'uint256',\n },\n ],\n name: 'Approval',\n type: 'event',\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n internalType: 'address',\n name: 'dst',\n type: 'address',\n },\n {\n indexed: false,\n internalType: 'uint256',\n name: 'wad',\n type: 'uint256',\n },\n ],\n name: 'Deposit',\n type: 'event',\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n internalType: 'address',\n name: 'src',\n type: 'address',\n },\n {\n indexed: true,\n internalType: 'address',\n name: 'dst',\n type: 'address',\n },\n {\n indexed: false,\n internalType: 'uint256',\n name: 'wad',\n type: 'uint256',\n },\n ],\n name: 'Transfer',\n type: 'event',\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n internalType: 'address',\n name: 'src',\n type: 'address',\n },\n {\n indexed: false,\n internalType: 'uint256',\n name: 'wad',\n type: 'uint256',\n },\n ],\n name: 'Withdrawal',\n type: 'event',\n },\n {\n payable: true,\n stateMutability: 'payable',\n type: 'fallback',\n },\n {\n constant: true,\n inputs: [\n {\n internalType: 'address',\n name: '',\n type: 'address',\n },\n {\n internalType: 'address',\n name: '',\n type: 'address',\n },\n ],\n name: 'allowance',\n outputs: [\n {\n internalType: 'uint256',\n name: '',\n type: 'uint256',\n },\n ],\n payable: false,\n stateMutability: 'view',\n type: 'function',\n },\n {\n constant: false,\n inputs: [\n {\n internalType: 'address',\n name: 'guy',\n type: 'address',\n },\n {\n internalType: 'uint256',\n name: 'wad',\n type: 'uint256',\n },\n ],\n name: 'approve',\n outputs: [\n {\n internalType: 'bool',\n name: '',\n type: 'bool',\n },\n ],\n payable: false,\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n constant: true,\n inputs: [\n {\n internalType: 'address',\n name: '',\n type: 'address',\n },\n ],\n name: 'balanceOf',\n outputs: [\n {\n internalType: 'uint256',\n name: '',\n type: 'uint256',\n },\n ],\n payable: false,\n stateMutability: 'view',\n type: 'function',\n },\n {\n constant: true,\n inputs: [],\n name: 'decimals',\n outputs: [\n {\n internalType: 'uint8',\n name: '',\n type: 'uint8',\n },\n ],\n payable: false,\n stateMutability: 'view',\n type: 'function',\n },\n {\n constant: false,\n inputs: [],\n name: 'deposit',\n outputs: [],\n payable: true,\n stateMutability: 'payable',\n type: 'function',\n },\n {\n constant: true,\n inputs: [],\n name: 'name',\n outputs: [\n {\n internalType: 'string',\n name: '',\n type: 'string',\n },\n ],\n payable: false,\n stateMutability: 'view',\n type: 'function',\n },\n {\n constant: true,\n inputs: [],\n name: 'symbol',\n outputs: [\n {\n internalType: 'string',\n name: '',\n type: 'string',\n },\n ],\n payable: false,\n stateMutability: 'view',\n type: 'function',\n },\n {\n constant: false,\n inputs: [\n {\n internalType: 'address',\n name: 'dst',\n type: 'address',\n },\n {\n internalType: 'uint256',\n name: 'wad',\n type: 'uint256',\n },\n ],\n name: 'transfer',\n outputs: [\n {\n internalType: 'bool',\n name: '',\n type: 'bool',\n },\n ],\n payable: false,\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n constant: false,\n inputs: [\n {\n internalType: 'address',\n name: 'src',\n type: 'address',\n },\n {\n internalType: 'address',\n name: 'dst',\n type: 'address',\n },\n {\n internalType: 'uint256',\n name: 'wad',\n type: 'uint256',\n },\n ],\n name: 'transferFrom',\n outputs: [\n {\n internalType: 'bool',\n name: '',\n type: 'bool',\n },\n ],\n payable: false,\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n constant: false,\n inputs: [\n {\n internalType: 'uint256',\n name: 'wad',\n type: 'uint256',\n },\n ],\n name: 'withdraw',\n outputs: [],\n payable: false,\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n constant: false,\n inputs: [\n {\n internalType: 'uint256',\n name: 'value',\n type: 'uint256',\n },\n {\n internalType: 'uint256',\n name: 'chain_id',\n type: 'uint256',\n },\n ],\n name: 'unwrap',\n outputs: [],\n payable: false,\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n constant: true,\n inputs: [],\n name: 'totalSupply',\n outputs: [\n {\n name: '',\n type: 'uint256',\n },\n ],\n payable: false,\n stateMutability: 'view',\n type: 'function',\n },\n {\n constant: false,\n inputs: [\n {\n internalType: 'address',\n name: 'token',\n type: 'address',\n },\n {\n internalType: 'uint256',\n name: 'amount',\n type: 'uint256',\n },\n ],\n name: 'swap',\n outputs: [\n {\n internalType: 'bool',\n name: '',\n type: 'bool',\n },\n ],\n payable: false,\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n constant: true,\n inputs: [\n {\n internalType: 'address',\n name: '',\n type: 'address',\n },\n ],\n name: 'swapSupply',\n outputs: [\n {\n internalType: 'uint256',\n name: '',\n type: 'uint256',\n },\n ],\n payable: false,\n stateMutability: 'view',\n type: 'function',\n },\n] as const;\n","export const WETH_ABI = [\n {\n constant: true,\n inputs: [],\n name: 'name',\n outputs: [\n {\n name: '',\n type: 'string',\n },\n ],\n payable: false,\n stateMutability: 'view',\n type: 'function',\n },\n {\n constant: false,\n inputs: [\n {\n name: 'guy',\n type: 'address',\n },\n {\n name: 'wad',\n type: 'uint256',\n },\n ],\n name: 'approve',\n outputs: [\n {\n name: '',\n type: 'bool',\n },\n ],\n payable: false,\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n constant: true,\n inputs: [],\n name: 'totalSupply',\n outputs: [\n {\n name: '',\n type: 'uint256',\n },\n ],\n payable: false,\n stateMutability: 'view',\n type: 'function',\n },\n {\n constant: false,\n inputs: [\n {\n name: 'src',\n type: 'address',\n },\n {\n name: 'dst',\n type: 'address',\n },\n {\n name: 'wad',\n type: 'uint256',\n },\n ],\n name: 'transferFrom',\n outputs: [\n {\n name: '',\n type: 'bool',\n },\n ],\n payable: false,\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n constant: false,\n inputs: [\n {\n name: 'wad',\n type: 'uint256',\n },\n ],\n name: 'withdraw',\n outputs: [],\n payable: false,\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n constant: true,\n inputs: [],\n name: 'decimals',\n outputs: [\n {\n name: '',\n type: 'uint8',\n },\n ],\n payable: false,\n stateMutability: 'view',\n type: 'function',\n },\n {\n constant: true,\n inputs: [\n {\n name: '',\n type: 'address',\n },\n ],\n name: 'balanceOf',\n outputs: [\n {\n name: '',\n type: 'uint256',\n },\n ],\n payable: false,\n stateMutability: 'view',\n type: 'function',\n },\n {\n constant: true,\n inputs: [],\n name: 'symbol',\n outputs: [\n {\n name: '',\n type: 'string',\n },\n ],\n payable: false,\n stateMutability: 'view',\n type: 'function',\n },\n {\n constant: false,\n inputs: [\n {\n name: 'dst',\n type: 'address',\n },\n {\n name: 'wad',\n type: 'uint256',\n },\n ],\n name: 'transfer',\n outputs: [\n {\n name: '',\n type: 'bool',\n },\n ],\n payable: false,\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n constant: false,\n inputs: [],\n name: 'deposit',\n outputs: [],\n payable: true,\n stateMutability: 'payable',\n type: 'function',\n },\n {\n constant: true,\n inputs: [\n {\n name: '',\n type: 'address',\n },\n {\n name: '',\n type: 'address',\n },\n ],\n name: 'allowance',\n outputs: [\n {\n name: '',\n type: 'uint256',\n },\n ],\n payable: false,\n stateMutability: 'view',\n type: 'function',\n },\n {\n payable: true,\n stateMutability: 'payable',\n type: 'fallback',\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n name: 'src',\n type: 'address',\n },\n {\n indexed: true,\n name: 'guy',\n type: 'address',\n },\n {\n indexed: false,\n name: 'wad',\n type: 'uint256',\n },\n ],\n name: 'Approval',\n type: 'event',\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n name: 'src',\n type: 'address',\n },\n {\n indexed: true,\n name: 'dst',\n type: 'address',\n },\n {\n indexed: false,\n name: 'wad',\n type: 'uint256',\n },\n ],\n name: 'Transfer',\n type: 'event',\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n name: 'dst',\n type: 'address',\n },\n {\n indexed: false,\n name: 'wad',\n type: 'uint256',\n },\n ],\n name: 'Deposit',\n type: 'event',\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n name: 'src',\n type: 'address',\n },\n {\n indexed: false,\n name: 'wad',\n type: 'uint256',\n },\n ],\n name: 'Withdrawal',\n type: 'event',\n },\n];\n","import { isAddress, type Address } from 'viem';\nimport { z } from 'zod';\nimport type { Environment } from '../../../types';\nimport { isBech32Address } from '../bitcoin/utils/address';\n\nconst evmAddressSchema = z\n .string()\n .refine(\n (arg: string) => isAddress(arg),\n (arg: string) => ({ message: `Invalid EVM address '${arg}'` }),\n )\n .transform((a: string) => a as Address);\n\nconst btcAddressSchema = z.string().refine(\n (arg: string) => {\n return isBech32Address(arg);\n },\n (arg: string) => ({ message: `Invalid BTC address '${arg}'` }),\n);\n\nexport enum Blockchain {\n AVALANCHE = 'avalanche',\n ETHEREUM = 'ethereum',\n BITCOIN = 'bitcoin',\n UNKNOWN = '',\n}\n\nconst BlockchainEnum = z.nativeEnum(Blockchain);\ntype BlockchainEnum = z.infer<typeof BlockchainEnum>;\n\nexport interface RuntimeConfig {\n environment: Environment;\n tokenInfoUrl: string;\n configMismatchThreshold: number;\n wardenConfigURLs: string[];\n disabledTokensOnNetwork: Partial<Record<Blockchain, string[]>>;\n}\n\nconst AssetBase = z.object({\n tokenName: z.string(),\n nativeNetwork: BlockchainEnum,\n denomination: z.number(),\n});\n\nconst EthereumAssetConfig = AssetBase.extend({\n nativeContractAddress: evmAddressSchema,\n wrappedContractAddress: evmAddressSchema,\n wrappedNetwork: BlockchainEnum,\n});\n\nconst CriticalConfigBase = z.object({\n disableFrontend: z.boolean(),\n addressBlocklist: z.array(z.string()),\n});\n\nconst EthereumCriticalConfig = CriticalConfigBase.extend({\n assets: z.record(z.string(), EthereumAssetConfig), // key is token symbol\n networks: z.record(BlockchainEnum, z.union([z.number(), z.undefined()])),\n walletAddresses: z.record(BlockchainEnum, evmAddressSchema),\n});\n\nconst EthereumNonCriticalConfigBase = z.object({\n minimumConfirmations: z.record(BlockchainEnum, z.optional(z.number())),\n});\n\nconst EthereumStaticFeeNonCriticalConfig = EthereumNonCriticalConfigBase.extend({\n unwrapFeeApproximation: z.record(z.string(), z.string()),\n wrapFeeApproximation: z.record(z.string(), z.string()),\n});\n\nexport const DynamicFeeEstimation = z.object({\n minimumFeeAmount: z.string(),\n maximumFeeAmount: z.string(),\n feePercentage: z.number(),\n feePercentageDecimals: z.number(),\n});\n\nconst EthereumDynamicFeeNonCriticalConfig = EthereumNonCriticalConfigBase.extend({\n unwrapFeeApproximation: z.record(z.string(), DynamicFeeEstimation),\n wrapFeeApproximation: z.record(z.string(), DynamicFeeEstimation),\n});\n\nconst EthereumStaticFeeConfig = z.object({\n critical: EthereumCriticalConfig,\n nonCritical: EthereumStaticFeeNonCriticalConfig,\n});\n\nconst EthereumDynamicFeeConfig = z.object({\n critical: EthereumCriticalConfig,\n nonCritical: EthereumDynamicFeeNonCriticalConfig,\n});\n\nexport type EvmDynamicNonCriticalConfig = typeof EthereumDynamicFeeNonCriticalConfig._output;\n\nconst BitcoinAssetConfig = z.object({\n tokenName: z.string(),\n bech32AddressPrefix: z.union([z.literal('tb'), z.literal('bc')]),\n wrappedContractAddress: evmAddressSchema,\n wrappedNetwork: BlockchainEnum,\n});\n\nconst BitcoinCritical = CriticalConfigBase.extend({\n addressBlocklist: z.array(z.string()),\n avalancheChainId: z.number(),\n bitcoinAssets: z.record(z.string(), BitcoinAssetConfig), // key is token symbol\n walletAddresses: z.object({\n btc: btcAddressSchema,\n avalanche: evmAddressSchema,\n }),\n});\n\nconst BitcoinCurrentBridgeFeeEstimateDynamic = z.object({\n dustThreshold: z.number(),\n wrapFeeEstimate: z.object({\n minimumFeeAmount: z.string(),\n maximumFeeAmount: z.string(),\n feePercentage: z.number(),\n feePercentageDecimals: z.number(),\n }),\n unwrapFeeEstimate: z.object({\n bridgeToll: z.object({\n minimumFeeAmount: z.string(),\n maximumFeeAmount: z.string(),\n feePercentage: z.number(),\n feePercentageDecimals: z.number(),\n }),\n estimatedTxFee: z.object({\n constAmount: z.number(),\n numeratorPerSat: z.number(),\n denominatorPerSat: z.number(),\n }),\n }),\n});\nexport type BitcoinCurrentBridgeFeeEstimateDynamic = typeof BitcoinCurrentBridgeFeeEstimateDynamic._output;\n\nconst BitcoinCurrentBridgeFeeEstimateStatic = z.object({\n wrapFeeAmount: z.number(),\n constUnwrapFeeAmount: z.number(),\n unwrapFeeNumerator: z.number(),\n unwrapFeeDenominator: z.number(),\n dustThreshold: z.number(),\n});\nexport type BitcoinCurrentBridgeFeeEstimateStatic = typeof BitcoinCurrentBridgeFeeEstimateStatic._output;\n\nconst BitcoinNetworkInfo = z.object({\n minimumConfirmations: z.number(),\n minimumOnboardSize: z.number(),\n currentBridgeFeeEstimate: z.union([BitcoinCurrentBridgeFeeEstimateDynamic, BitcoinCurrentBridgeFeeEstimateStatic]),\n});\n\nconst BitcoinNonCritical = z.object({\n networkInfo: z.record(z.string(), BitcoinNetworkInfo),\n});\n\n// BitcoinConfig supports both dynamic and static\nconst BitcoinConfig = z.object({\n criticalBitcoin: BitcoinCritical,\n nonCriticalBitcoin: BitcoinNonCritical,\n});\n\nconst ConfigWithDynamicEthereum = z.intersection(EthereumDynamicFeeConfig, BitcoinConfig);\nconst ConfigWithStaticEthereum = z.intersection(EthereumStaticFeeConfig, BitcoinConfig);\n\nexport const WardenConfigSchema = z.union([ConfigWithDynamicEthereum, ConfigWithStaticEthereum]);\n\nexport type WardenConfig = typeof WardenConfigSchema._output;\n","import { bech32 } from '@scure/base';\n\nfunction isBech32Format(btcAddress: string): btcAddress is `${string}1${string}` {\n return btcAddress.toLowerCase().startsWith('tb1') || btcAddress.toLowerCase().startsWith('bc1');\n}\n\nexport function isBech32Address(btcAddress: string): boolean {\n if (!isBech32Format(btcAddress)) {\n return false;\n }\n try {\n // This function throws an exception if the address is not valid.\n bech32.decode(btcAddress);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function isBech32AddressInNetwork(btcAddress: string, isMainnet: boolean) {\n if (isBech32Address(btcAddress)) {\n return btcAddress.toLowerCase().startsWith(isMainnet ? 'bc' : 'tb');\n }\n return false;\n}\n","import { AvalancheChainIds, BitcoinChainIds, EthereumChainIds, type Chain } from '../../../types/chain';\nimport caip2 from '../../../utils/caip2';\nimport { ChainId } from '../types/chain';\nimport { Blockchain } from '../types/config';\n\n// EVM\nexport const isEthereumChainId = (chainId: number) => {\n return chainId === ChainId.ETHEREUM_HOMESTEAD || chainId === ChainId.ETHEREUM_TEST_SEPOLIA;\n};\n\nexport const isCaip2EthereumChainId = (caip2ChainId: string) => {\n return EthereumChainIds.MAINNET === caip2ChainId || EthereumChainIds.SEPOLIA === caip2ChainId;\n};\n\nexport const isEthereumChain = (chain: Chain) => {\n return isCaip2EthereumChainId(chain.chainId);\n};\n\nexport const isAvalancheChainId = (chainId: number) => {\n return chainId === ChainId.AVALANCHE_MAINNET || chainId === ChainId.AVALANCHE_TESTNET;\n};\n\nexport const isCaip2AvalancheChainId = (caip2ChainId: string) => {\n return AvalancheChainIds.FUJI === caip2ChainId || AvalancheChainIds.MAINNET === caip2ChainId;\n};\n\nexport const isAvalancheChain = (chain: Chain) => {\n return isCaip2AvalancheChainId(chain.chainId);\n};\n\nexport const chainIdToBlockchain = (chainId: number) => {\n switch (chainId) {\n case ChainId.AVALANCHE_MAINNET:\n case ChainId.AVALANCHE_TESTNET:\n return Blockchain.AVALANCHE;\n case ChainId.ETHEREUM_HOMESTEAD:\n case ChainId.ETHEREUM_TEST_SEPOLIA:\n return Blockchain.ETHEREUM;\n }\n};\n\n// Bitcoin\nexport const isBitcoinChainId = (chainId: number) => {\n return chainId === ChainId.BITCOIN || chainId === ChainId.BITCOIN_TESTNET;\n};\n\nexport const isCaip2BitcoinChainId = (caip2ChainId: string) => {\n return caip2ChainId === BitcoinChainIds.MAINNET || caip2ChainId === BitcoinChainIds.TESTNET;\n};\n\nexport const isBitcoinChain = (chain: Chain) => {\n return isCaip2BitcoinChainId(chain.chainId);\n};\n\n// All Networks\nexport const caip2ChainIdToBlockchain = (caip2ChainId: string) => {\n if (isCaip2BitcoinChainId(caip2ChainId)) {\n return Blockchain.BITCOIN;\n }\n const { reference: chainId } = caip2.toJSON(caip2ChainId);\n return chainIdToBlockchain(Number(chainId));\n};\n\nexport const isMainnetCaip2ChainId = (chainId: string) => {\n return (\n chainId === EthereumChainIds.MAINNET || chainId === AvalancheChainIds.MAINNET || chainId === BitcoinChainIds.MAINNET\n );\n};\n\nexport const isTestnetCaip2ChainId = (chainId: string) => {\n return !isMainnetCaip2ChainId(chainId);\n};\n\nexport const isMainnetChain = (chain: Chain) => {\n return isMainnetCaip2ChainId(chain.chainId);\n};\n\nexport const isTestnetChain = (chain: Chain) => {\n return !isMainnetChain(chain);\n};\n\nexport const isMainnetChainId = (chainId: number) => {\n return chainId === ChainId.AVALANCHE_MAINNET || chainId === ChainId.ETHEREUM_HOMESTEAD || chainId === ChainId.BITCOIN;\n};\n\nexport const isTestnetChainId = (chainId: number) => {\n return !isMainnetChainId(chainId);\n};\n","import { TokenType, type NativeAsset } from '../../../../types';\n\nexport const ETH_TOKEN = {\n type: TokenType.NATIVE,\n name: 'Ether',\n symbol: 'ETH',\n decimals: 18,\n} satisfies NativeAsset;\n","import { isEthereumChain } from '../../utils/chain';\nimport { InvalidParamsError } from '../../../../errors/invalid-params-error';\nimport { isErc20Asset, isNativeAsset, type Asset, type BridgeAsset, type Chain } from '../../../../types';\nimport { ErrorReason } from '../../../../types/error';\n\nimport { ETH_TOKEN } from './consts';\nimport { isEqual } from 'lodash';\nimport type { EvmConfig, EthToAvaTransferData, AvaToEthTransferData, TransferData } from '../types/config';\nimport { caip2 } from '../../../../utils';\nimport { ChainId } from '../../types/chain';\nimport { convertBridgeAssetToAsset } from '../../utils/asset';\nimport type { ValidEvmTransferParams } from '../../../../utils/evm/types/bridge';\ntype PartialTransferParams = Pick<ValidEvmTransferParams, 'sourceChain' | 'targetChain' | 'amount' | 'asset'>;\n\nconst ethHandler = (config: EvmConfig) => {\n return {\n source: config.nativeTokenConfig.ethereumToken,\n target: config.nativeTokenConfig.avalancheToken,\n ethToAva: true,\n };\n};\n\nconst assetsMatch = (asset: Asset, bridgeAsset: BridgeAsset) => {\n if (!isErc20Asset(bridgeAsset)) {\n throw new InvalidParamsError(ErrorReason.ASSET_NOT_SUPPORTED, `Wrong token type: ${bridgeAsset.type}`);\n }\n return isEqual(asset, convertBridgeAssetToAsset(bridgeAsset));\n};\n\nconst prepEthToAvaTransferData = (config: EvmConfig, asset: BridgeAsset): EthToAvaTransferData => {\n if (!isErc20Asset(asset)) {\n throw new InvalidParamsError(ErrorReason.ASSET_NOT_SUPPORTED, `Wrong token type: ${asset.type}`);\n }\n const ethToken = config.ethereumTokens[asset.address];\n if (!ethToken || !assetsMatch(ethToken.token, asset)) {\n throw new InvalidParamsError(\n ErrorReason.ASSET_NOT_SUPPORTED,\n `Unable to find matching ethereum token in config: ${asset.symbol}`,\n );\n }\n\n const avaToken = config.avalancheTokens[ethToken.target.tokenAddress];\n\n if (!avaToken) {\n throw new InvalidParamsError(\n ErrorReason.ASSET_NOT_SUPPORTED,\n `Unable to get avalanche token in config: ${asset.symbol}`,\n );\n }\n\n return {\n source: ethToken,\n target: avaToken,\n ethToAva: true,\n };\n};\n\nconst prepAvaToEthTransferData = (config: EvmConfig, asset: BridgeAsset): AvaToEthTransferData => {\n if (!isErc20Asset(asset)) {\n throw new InvalidParamsError(ErrorReason.ASSET_NOT_SUPPORTED, `Wrong token type: ${asset.type}`);\n }\n const avaToken = config.avalancheTokens[asset.address];\n if (!avaToken || !assetsMatch(avaToken.token, asset)) {\n throw new InvalidParamsError(\n ErrorReason.ASSET_NOT_SUPPORTED,\n `Unable to find matching avalanche token in config: ${asset.symbol}`,\n );\n }\n\n const ethToken = config.ethereumTokens[avaToken.target.tokenAddress];\n\n if (!ethToken) {\n throw new InvalidParamsError(\n ErrorReason.ASSET_NOT_SUPPORTED,\n `Unable to get ethereum token in config: ${asset.symbol}`,\n );\n }\n\n return {\n source: avaToken,\n target: ethToken,\n ethToAva: false,\n };\n};\n\nconst isValidChainCombination = (sourceChain: Chain, targetChain: Chain) => {\n const { reference: sourceChainId } = caip2.toJSON(sourceChain.chainId);\n const { reference: targetChainId } = caip2.toJSON(targetChain.chainId);\n\n const validRoutes = [\n { source: ChainId.ETHEREUM_HOMESTEAD, target: ChainId.AVALANCHE_MAINNET },\n { source: ChainId.AVALANCHE_MAINNET, target: ChainId.ETHEREUM_HOMESTEAD },\n { source: ChainId.ETHEREUM_TEST_SEPOLIA, target: ChainId.AVALANCHE_TESTNET },\n { source: ChainId.AVALANCHE_TESTNET, target: ChainId.ETHEREUM_TEST_SEPOLIA },\n ];\n return validRoutes.some(\n ({ source, target }) => source.toString() === sourceChainId && target.toString() === targetChainId,\n );\n};\n\nexport const getTransferData = (\n { sourceChain, targetChain, amount, asset }: PartialTransferParams,\n config: EvmConfig,\n): TransferData => {\n if (sourceChain.chainId === targetChain.chainId) {\n throw new InvalidParamsError(\n ErrorReason.IDENTICAL_CHAINS_PROVIDED,\n `SourceChain and TargetChain need to be different network. But found the same chainId: ${sourceChain.chainId}`,\n );\n }\n\n if (!isValidChainCombination(sourceChain, targetChain)) {\n throw new InvalidParamsError(\n ErrorReason.INVALID_PARAMS,\n `SourceChain and TargetChain combination is not correct or the chains provided are not supported`,\n );\n }\n\n if (amount <= 0n) {\n throw new InvalidParamsError(ErrorReason.INCORRECT_AMOUNT_PROVIDED, 'Amount must be greater than zero');\n }\n\n if (isNativeAsset(asset) && asset.symbol === ETH_TOKEN.symbol && isEthereumChain(sourceChain)) {\n return ethHandler(config);\n }\n\n if (isEthereumChain(sourceChain)) {\n return prepEthToAvaTransferData(config, asset);\n } else {\n return prepAvaToEthTransferData(config, asset);\n }\n};\n","import { type Asset, type BridgeAsset } from '../../../types';\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport const convertBridgeAssetToAsset = ({ destinations, ...rest }: BridgeAsset): Asset => rest;\n","import { DynamicFeeEstimation } from '../../types/config';\nimport { type FeeApproximation } from '../types/config';\n\nexport const isDynamicFee = (\n feeApproximation: FeeApproximation | string | bigint | undefined,\n): feeApproximation is FeeApproximation => {\n try {\n DynamicFeeEstimation.parse(feeApproximation);\n return true;\n } catch {\n return false;\n }\n};\n","import type { FeeApproximation } from '../evm/types/config';\nconst capped = (value: bigint, { max, min }: { max: bigint; min: bigint }): bigint => {\n if (value > max) {\n return max;\n }\n if (value < min) {\n return min;\n }\n return value;\n};\n\nexport const getDynamicFeeAmount = (amount: bigint, feeApproximation: FeeApproximation) => {\n const { minimumFeeAmount, maximumFeeAmount, feePercentage, feePercentageDecimals } = feeApproximation;\n const minimumFee = BigInt(minimumFeeAmount);\n const maximumFee = BigInt(maximumFeeAmount);\n const percentage = feePercentage / 10 ** feePercentageDecimals / 100; // divide by 100 since it's supposed to represent percentage\n const fee = Number(amount) * percentage;\n const bigintFee = BigInt(Math.ceil(fee));\n const cost = capped(bigintFee, { min: minimumFee, max: maximumFee });\n\n return cost;\n};\n","import type { FeeParams } from '../../../../types/bridge';\nimport { getTransferData } from '../utils/transfer-data';\nimport type { AssetFeeMap } from '../../../../types/asset';\nimport { isDynamicFee } from '../utils/fee';\nimport type { EvmConfig } from '../types/config';\nimport { getDynamicFeeAmount } from '../../utils/fees';\n\nexport async function getFees(config: EvmConfig, params: FeeParams): Promise<AssetFeeMap> {\n const { sourceChain, targetChain, asset, amount } = params;\n const { source, target, ethToAva } = getTransferData({ sourceChain, targetChain, asset, amount }, config);\n const feeApproximation = ethToAva ? source.wrapFeeApproximation : source.unwrapFeeApproximation;\n\n if (isDynamicFee(feeApproximation)) {\n const cost = getDynamicFeeAmount(amount, feeApproximation);\n return {\n [target.token.address]: cost,\n };\n }\n const cost = feeApproximation ?? 0n;\n return {\n [target.token.address]: cost,\n };\n}\n","import { getTransferData } from '../utils/transfer-data';\nimport type { EvmConfig } from '../types/config';\nimport { getFees } from './get-fees';\nimport type { ValidEvmGasEstimationParams } from '../../../../utils/evm/types/bridge';\n\nexport async function estimateReceiveAmount(config: EvmConfig, params: ValidEvmGasEstimationParams) {\n const { target } = getTransferData(params, config);\n const fees = await getFees(config, params);\n return {\n asset: target.token,\n amount: params.amount - (fees[target.token.address] ?? 0n),\n };\n}\n","import type { ChainAssetMap } from '../../../../types/asset';\nimport { BridgeType } from '../../../../types/bridge';\nimport { ChainId } from '../../types/chain';\nimport type { EvmConfig } from '../types/config';\n\nimport { ETH_TOKEN } from '../utils/consts';\n\nexport function getAssets(config: EvmConfig): ChainAssetMap {\n const assetsWithEthTokens = Object.values(config.ethereumTokens).reduce((list, tokenConfig) => {\n //USDC is being supported by CCTP. (USDC.e in avalancheTokens will be supported by avalanche evm)\n if (tokenConfig.token.symbol === 'USDC') {\n return list;\n }\n const ethChainId = tokenConfig.chainId;\n const avaChainId = tokenConfig.target.chainId;\n\n const bridgeAsset = {\n ...tokenConfig.token,\n destinations: { [avaChainId]: [BridgeType.AVALANCHE_EVM] },\n };\n\n const currentList = list[ethChainId] ?? [];\n currentList.push(bridgeAsset);\n list[ethChainId] = currentList;\n\n return list;\n }, {} as ChainAssetMap);\n\n const allAssets = Object.values(config.avalancheTokens).reduce((list, tokenConfig) => {\n const avaChainId = tokenConfig.chainId;\n const ethChainId = tokenConfig.target.chainId;\n\n const bridgeAsset = {\n ...tokenConfig.token,\n destinations: { [ethChainId]: [BridgeType.AVALANCHE_EVM] },\n };\n\n const currentList = list[avaChainId] ?? [];\n currentList.push(bridgeAsset);\n list[avaChainId] = currentList;\n\n return list;\n }, assetsWithEthTokens);\n\n const homesteadKey = `eip155:${ChainId.ETHEREUM_HOMESTEAD}`;\n if (allAssets[homesteadKey]) {\n allAssets[homesteadKey].push({\n ...ETH_TOKEN,\n destinations: { [`eip155:${ChainId.AVALANCHE_MAINNET}`]: [BridgeType.AVALANCHE_EVM] },\n });\n }\n\n const sepoliaKey = `eip155:${ChainId.ETHEREUM_TEST_SEPOLIA}`;\n if (allAssets[sepoliaKey]) {\n allAssets[sepoliaKey].push({\n ...ETH_TOKEN,\n destinations: { [`eip155:${ChainId.AVALANCHE_TESTNET}`]: [BridgeType.AVALANCHE_EVM] },\n });\n }\n\n return allAssets;\n}\n","import type { Address } from 'viem';\nimport { InvalidParamsError } from '../../../../errors';\nimport { ErrorReason, type FeeParams } from '../../../../types';\nimport type { EvmConfig } from '../types/config';\nimport { isDynamicFee } from '../utils/fee';\nimport { getTransferData } from '../utils/transfer-data';\nimport { getFees } from './get-fees';\n\n/**\n * The fee charged is calculated at the time that the transfer is processed.\n * Given that the fee calculation depends on the current asset prices,\n * and that there is a time gap between when the transaction is sent by\n * the user and when it is processed by the bridge (~19 minutes for Ethereum, 1 hrs for bitcoin, etc),\n * the fee estimations made before the bridge Tx is submitted could be stale/off compared to the actual fee charged.\n *\n * This is a somewhat arbitrary multiplier to account for this possible discrepancy in fee estimations.\n */\nexport const FEE_ESTIMATION_MULTIPLIER = 3n;\n\nexport async function getMinimumTransferAmount(config: EvmConfig, params: FeeParams) {\n const { sourceChain, targetChain, asset, amount } = params;\n\n const { source, target, ethToAva } = getTransferData({ sourceChain, targetChain, asset, amount }, config);\n\n const feeApproximation = ethToAva ? source.wrapFeeApproximation : source.unwrapFeeApproximation;\n\n if (isDynamicFee(feeApproximation)) {\n const minimumFeeAmount = feeApproximation.minimumFeeAmount;\n\n return BigInt(minimumFeeAmount) * FEE_ESTIMATION_MULTIPLIER;\n }\n\n //Static fee\n const staticFee = await getFees(config, params);\n const feeResult = staticFee[target.token.address as Address];\n if (feeResult === undefined) {\n throw new InvalidParamsError(ErrorReason.INVALID_PARAMS, `Unable to get static fee for ${asset.symbol}`);\n }\n\n return feeResult * FEE_ESTIMATION_MULTIPLIER;\n}\n","import type { CreateEvmSourceTrackerArgs, CreateEvmTargetTrackerArgs } from '../../../../utils/tracking';\nimport type { Client } from '../../../../utils/evm/client';\nimport { isNil, isObject } from 'lodash';\nimport type { BridgeTransfer, TrackingParams } from '../../../../types';\nimport { isHex, type AbiEvent, type Log } from 'viem';\nimport { ZERO_ADDRESS } from '../../../../utils/consts';\nimport type { EvmConfig, TransferData } from '../types/config';\nimport type { TransferLog, MintLog } from '../types/tracking';\n\nexport const createGetMetadata = (): CreateEvmSourceTrackerArgs['getMetadata'] => (txReceipt) => {\n return { transactionHash: txReceipt.transactionHash };\n};\n\nexport const createGetTargetTxHash =\n ({\n params: {\n bridgeTransfer: { fromAddress },\n },\n transferData: { target, ethToAva },\n targetClient,\n config,\n }: {\n params: TrackingParams;\n transferData: TransferData;\n targetClient: Client;\n config: EvmConfig;\n }): CreateEvmTargetTrackerArgs['getTargetTxHash'] =>\n async ({ fromBlock, toBlock, metadata }) => {\n if (!fromBlock) {\n return undefined;\n }\n const contractAddress = target.token.address;\n const from = ethToAva ? ZERO_ADDRESS : config.walletAddresses.ethereum;\n const args = ethToAva ? undefined : { src: from, dst: fromAddress };\n\n const event = ethToAva\n ? ({\n inputs: [\n {\n indexed: false,\n name: 'to',\n type: 'address',\n },\n {\n indexed: false,\n name: 'amount',\n type: 'uint256',\n },\n {\n indexed: false,\n name: 'feeAddress',\n type: 'address',\n },\n {\n indexed: false,\n name: 'feeAmount',\n type: 'uint256',\n },\n {\n indexed: false,\n name: 'originTxId',\n type: 'bytes32',\n },\n ],\n name: 'Mint',\n type: 'event',\n } satisfies AbiEvent)\n : ({\n inputs: [\n {\n indexed: true,\n name: 'src',\n type: 'address',\n },\n {\n indexed: true,\n name: 'dst',\n type: 'address',\n },\n {\n indexed: false,\n name: 'wad',\n type: 'uint256',\n },\n ],\n name: 'Transfer',\n type: 'event',\n } satisfies AbiEvent);\n\n const logs = await targetClient.getLogs({\n address: contractAddress,\n event,\n args,\n fromBlock,\n toBlock,\n });\n // Forr ethToAva, originTxId is not indexed. So it cannot be a part of the filter. We manually do this to ensure that we are getting the correct log\n const foundLog = ethToAva\n ? logs.find((log) => includesOriginTxId(log) && log.args.originTxId === metadata?.transactionHash)\n : logs.at(-1);\n\n if (isNil(foundLog)) {\n return undefined;\n }\n\n return foundLog.transactionHash;\n };\n\nexport const includesOriginTxId = (log: MintLog | TransferLog | Log): log is MintLog => {\n if (isMintLogOrTransferLog(log)) {\n return Object.keys(log.args).includes('originTxId');\n }\n return false;\n};\n\nconst isMintLogOrTransferLog = (log: MintLog | TransferLog | Log): log is MintLog | TransferLog => {\n return Object.keys(log).includes('args');\n};\n\nexport const checkMetadata = (metadata: BridgeTransfer['metadata']): metadata is { transactionHash: `0x${string}` } => {\n return isObject(metadata) && isHex(metadata.transactionHash);\n};\n","import { DEFAULT_TRACKING_CONFIG } from './../../../../utils/tracking/utils';\nimport { getTransferData } from '../utils/transfer-data';\nimport { getClientForChain } from '../../../../utils/evm/client';\nimport { checkMetadata, createGetMetadata, createGetTargetTxHash } from '../utils/tracking';\nimport { createEvmSourceTracker, createEvmTargetTracker } from '../../../../utils/tracking';\nimport { retryPromise } from '../../../../utils/retry-promise';\nimport type { EvmConfig } from '../types/config';\nimport type { BridgeTransfer, TrackingParams } from '../../../../types';\n\nconst trackTargetTx = async (config: EvmConfig, params: TrackingParams) => {\n const { bridgeTransfer } = params;\n const { targetChain, sourceChain, asset, amount } = bridgeTransfer;\n const transferData = getTransferData({ sourceChain, targetChain, asset, amount }, config);\n\n const targetClient = getClientForChain({\n chain: bridgeTransfer.targetChain,\n });\n\n const getTargetTxHash = createGetTargetTxHash({\n params,\n transferData,\n targetClient,\n config,\n });\n\n const tracker = createEvmTargetTracker({\n targetClient,\n getTargetTxHash,\n checkMetadata,\n trackingParams: params,\n trackingConfig: DEFAULT_TRACKING_CONFIG,\n });\n\n return retryPromise<BridgeTransfer>({\n promise: tracker,\n delay: 1000 * 30, // 30s since ETH confirmations happen slower\n startAfter: DEFAULT_TRACKING_CONFIG.initialDelayMs,\n });\n};\n\nconst trackSourceTx = async (params: TrackingParams) => {\n const { sourceChain, targetChain } = params.bridgeTransfer;\n\n const sourceClient = getClientForChain({ chain: sourceChain });\n const targetClient = getClientForChain({ chain: targetChain });\n\n const getMetadata = createGetMetadata();\n\n const tracker = createEvmSourceTracker({\n sourceClient,\n targetClient,\n getMetadata,\n checkMetadata,\n trackingParams: params,\n trackingConfig: DEFAULT_TRACKING_CONFIG,\n });\n return retryPromise<BridgeTransfer>({\n promise: tracker,\n delay: 1000 * 30, // 30s since ETH confirmations happen slower\n startAfter: DEFAULT_TRACKING_CONFIG.initialDelayMs,\n });\n};\n\nexport function trackTransfer(config: EvmConfig, params: TrackingParams) {\n let abortFn: (() => void) | undefined;\n\n const cancel = () => {\n abortFn?.();\n };\n\n const executeTracking = async () => {\n const { bridgeTransfer, updateListener } = params;\n const { result: sourceTracker, cancel: cancelSourceTracking } = await trackSourceTx({\n bridgeTransfer,\n updateListener,\n });\n abortFn = cancelSourceTracking;\n const transferAfterSourceFinished = await sourceTracker;\n\n const { result: targetTracker, cancel: cancelTargetTracking } = await trackTargetTx(config, {\n updateListener,\n bridgeTransfer: transferAfterSourceFinished,\n });\n\n abortFn = cancelTargetTracking;\n\n return targetTracker;\n };\n\n return {\n result: executeTracking(),\n cancel,\n };\n}\n","import { encodeFunctionData, type Address } from 'viem';\nimport type { Chain } from '../../../types/chain';\nimport { getClientForChain } from '../../../utils/evm/client';\nimport { BridgeSignatureReason, type BridgeStepDetails } from '../../../types/bridge';\nimport type { Hex, EvmSign } from '../../../types/signer';\nimport { WAVAX_ABI } from '../evm/abis/wavax-abi';\nimport type { TokenData } from '../evm/types/config';\n\nexport const transferAssetFromAvaToHome = async ({\n amount,\n source,\n sourceChain,\n fromAddress,\n sign,\n onStepChange,\n}: {\n amount: bigint;\n source: TokenData; // Wrapped asset\n sourceChain: Chain; // Avalanche\n fromAddress: Address;\n sign: EvmSign;\n onStepChange?: (stepDetails: BridgeStepDetails) => void;\n}): Promise<`0x${string}`> => {\n const client = getClientForChain({ chain: sourceChain });\n\n onStepChange?.({\n currentSignature: 1,\n currentSignatureReason: BridgeSignatureReason.TokensTransfer,\n requiredSignatures: 1,\n });\n\n const data = encodeFunctionData({\n abi: WAVAX_ABI,\n functionName: 'unwrap',\n args: [amount, 0n], // Passing 0n instead of the actual chain ID since we get unsupported chain ID error when we pass the valid ID\n });\n\n const txHash = await sign(\n {\n from: fromAddress,\n to: source.token.address,\n data,\n },\n (signedTxHash: Hex) => client.sendRawTransaction({ serializedTransaction: signedTxHash }),\n );\n await client.waitForTransactionReceipt({ hash: txHash, pollingInterval: 1_000 });\n return txHash;\n};\n","import { encodeFunctionData, type Address, type Hex } from 'viem';\nimport {\n type EvmSign,\n type Chain,\n type BridgeStepDetails,\n ErrorReason,\n BridgeSignatureReason,\n Environment,\n type BridgeAsset,\n isNativeAsset,\n} from '../../../../types';\nimport { InvalidParamsError } from '../../../../errors';\nimport { getClientForChain } from '../../../../utils/evm/client';\nimport { isAvalancheChain, isMainnetChain } from '../../utils/chain';\nimport { WETH_ABI } from '../abis/weth-abi';\nimport { ERC20_ABI } from '../../../../abis/erc20';\nimport { type EvmConfig, type TokenData } from '../types/config';\nimport { Blockchain } from '../../types/config';\n\nexport const VulnerableRouterAddresses = {\n [Blockchain.ETHEREUM]: '0x6b7a87899490EcE95443e979cA9485CBE7E71522',\n [Blockchain.AVALANCHE]: '0x9b17bAADf0f21F03e35249e0e59723F34994F806',\n};\n\nconst wrapERC20Asset = async ({\n amount,\n config,\n source,\n sourceChain,\n fromAddress,\n sign,\n onStepChange,\n}: {\n amount: bigint;\n config: EvmConfig;\n source: TokenData;\n sourceChain: Chain;\n fromAddress: Address;\n sign: EvmSign;\n onStepChange?: (stepDetails: BridgeStepDetails) => void;\n}) => {\n const ethereumWalletAddress = config.walletAddresses.ethereum;\n\n const client = getClientForChain({ chain: sourceChain });\n\n onStepChange?.({\n currentSignature: 1,\n currentSignatureReason: BridgeSignatureReason.TokensTransfer,\n requiredSignatures: 1,\n });\n\n const data = encodeFunctionData({\n abi: ERC20_ABI,\n functionName: 'transfer',\n args: [ethereumWalletAddress, amount],\n });\n\n const txHash = await sign(\n {\n from: fromAddress,\n to: source.token.address,\n data,\n },\n (signedTxHash: Hex) => client.sendRawTransaction({ serializedTransaction: signedTxHash }),\n );\n\n await client.waitForTransactionReceipt({ hash: txHash, pollingInterval: 1_000 });\n\n return txHash;\n};\n\n/**\n * Checks if the address has token approvals for addresses involved in the\n * multichain incident:\n * https://medium.com/multichainorg/action-required-critical-vulnerability-for-six-tokens-6b3cbd22bfc0\n *\n * Due to the approval, attackers can drain the assets from the users account\n * immediately after a transaction like wrapping ETH or transferring the asset\n * across the bridge.\n */\nconst hasAddressVulnerableMultichainApproval = async ({\n config,\n fromAddress,\n sourceChain,\n targetChain,\n}: {\n config: EvmConfig;\n fromAddress: Address;\n sourceChain: Chain; // Should be Ethereum\n targetChain: Chain; // Should be Avalanche\n}) => {\n if (config.environment !== Environment.PROD && !isMainnetChain(sourceChain) && !isMainnetChain(targetChain)) {\n return false;\n }\n\n const ethWethConfig = config.nativeTokenConfig.ethereumToken;\n const avaWethConfig = config.nativeTokenConfig.avalancheToken;\n\n try {\n const ethClient = getClientForChain({ chain: sourceChain });\n const ethWethAllowance = await ethClient.readContract({\n address: ethWethConfig.token.address,\n abi: ERC20_ABI,\n functionName: 'allowance',\n args: [fromAddress, VulnerableRouterAddresses[Blockchain.ETHEREUM]],\n });\n\n if (ethWethAllowance !== 0n) {\n return true;\n }\n const avaClient = getClientForChain({ chain: targetChain });\n const avaWethAllowance = await avaClient.readContract({\n address: avaWethConfig.token.address,\n abi: ERC20_ABI,\n functionName: 'allowance',\n args: [fromAddress, VulnerableRouterAddresses[Blockchain.AVALANCHE]],\n });\n\n return avaWethAllowance !== 0n;\n } catch (e) {\n return false;\n }\n};\n\nconst wrapNativeAsset = async ({\n amount,\n config,\n fromAddress,\n source,\n sourceChain,\n targetChain,\n sign,\n onStepChange,\n}: {\n amount: bigint;\n config: EvmConfig;\n fromAddress: Address;\n source: TokenData;\n sourceChain: Chain;\n targetChain: Chain;\n sign: EvmSign;\n onStepChange?: (stepDetails: BridgeStepDetails) => void;\n}) => {\n const ethereumWalletAddress = config.walletAddresses.ethereum;\n\n const client = getClientForChain({ chain: sourceChain });\n\n if (!isAvalancheChain(targetChain)) {\n throw new InvalidParamsError(ErrorReason.INVALID_PARAMS, 'Invalid chain combinations');\n }\n // Checks if the address has token approvals for addresses involved in the multi-chain incident\n const isAddressVulnerable = await hasAddressVulnerableMultichainApproval({\n config,\n fromAddress,\n sourceChain,\n targetChain,\n });\n\n if (isAddressVulnerable) {\n throw new InvalidParamsError(\n ErrorReason.VULNERABLE_TOKEN_APPROVAL_ADDRESS,\n 'Address has vulnerable token approvals',\n );\n }\n\n onStepChange?.({\n currentSignature: 1,\n currentSignatureReason: BridgeSignatureReason.WrapToken,\n requiredSignatures: 2,\n });\n\n const wrapData = encodeFunctionData({\n abi: WETH_ABI,\n functionName: 'deposit',\n });\n\n const wrapTxHash = await sign(\n {\n from: fromAddress,\n to: source.token.address,\n value: amount,\n data: wrapData,\n },\n (signedTxHash: Hex) => client.sendRawTransaction({ serializedTransaction: signedTxHash }),\n );\n\n await client.waitForTransactionReceipt({ hash: wrapTxHash, pollingInterval: 1_000 });\n\n onStepChange?.({\n currentSignature: 2,\n currentSignatureReason: BridgeSignatureReason.TokensTransfer,\n requiredSignatures: 2,\n });\n\n const transferData = encodeFunctionData({\n abi: ERC20_ABI,\n functionName: 'transfer',\n args: [ethereumWalletAddress, amount],\n });\n\n const txHash = await sign(\n {\n from: fromAddress,\n to: source.token.address,\n data: transferData,\n },\n (signedTxHash: Hex) => client.sendRawTransaction({ serializedTransaction: signedTxHash }),\n );\n await client.waitForTransactionReceipt({ hash: txHash, pollingInterval: 1_000 });\n\n return txHash;\n};\n\nexport const transferAssetFromEthToAva = async ({\n amount,\n asset,\n config,\n fromAddress,\n source,\n sourceChain,\n targetChain,\n sign,\n onStepChange,\n}: {\n amount: bigint;\n asset: BridgeAsset;\n config: EvmConfig;\n fromAddress: Address;\n source: TokenData;\n sourceChain: Chain;\n targetChain: Chain;\n sign: EvmSign;\n onStepChange?: (stepDetails: BridgeStepDetails) => void;\n}) => {\n if (isNativeAsset(asset)) {\n return wrapNativeAsset({\n amount,\n config,\n fromAddress,\n source,\n sourceChain,\n targetChain,\n sign,\n onStepChange,\n });\n }\n\n return wrapERC20Asset({ amount, config, source, sourceChain, fromAddress, sign, onStepChange });\n};\n","import { isAvalancheChain } from './../../utils/chain';\nimport { InvalidParamsError } from '../../../../errors/invalid-params-error';\nimport { BridgeType } from '../../../../types/bridge';\nimport { ErrorReason } from '../../../../types/error';\nimport { getTransferData } from '../utils/transfer-data';\nimport { transferAssetFromAvaToHome } from '../../utils/unwrapping';\nimport { transferAssetFromEthToAva } from '../utils/wrapping';\nimport { getFees } from './get-fees';\nimport { getClientForChain } from '../../../../utils/evm/client';\nimport { getMinimumTransferAmount } from './get-minimum-transfer-amount';\nimport type { EvmConfig } from '../types/config';\nimport type { BridgeTransfer, EvmSigner, Hex } from '../../../../types';\nimport type { ValidEvmTransferParams } from '../../../../utils/evm/types/bridge';\n\nexport async function transferAsset(\n config: EvmConfig,\n params: ValidEvmTransferParams,\n signer: EvmSigner,\n): Promise<BridgeTransfer> {\n const { sourceChain, targetChain, asset, amount, fromAddress, toAddress, onStepChange } = params;\n\n if (fromAddress !== toAddress) {\n throw new InvalidParamsError(ErrorReason.INVALID_PARAMS, 'fromAddress and toAddress do not match');\n }\n\n const fees = await getFees(config, { asset, amount, sourceChain, targetChain });\n const { source, target, ethToAva } = getTransferData({ sourceChain, targetChain, asset, amount }, config);\n\n const minimumAmount = await getMinimumTransferAmount(config, { asset, amount, sourceChain, targetChain });\n if (amount < minimumAmount) {\n throw new InvalidParamsError(ErrorReason.INVALID_PARAMS, `Minimum transfer amount is ${minimumAmount.toString()}`);\n }\n\n const sourceRequiredConfirmationCount = isAvalancheChain(sourceChain)\n ? config.minimumConfirmations.avalanche\n : config.minimumConfirmations.ethereum;\n\n const bridgeFee = fees[target.token.address] ?? 0n;\n\n let txHash: Hex;\n\n if (ethToAva) {\n // wrap asset (Ethereum -> Avalanche)\n txHash = await transferAssetFromEthToAva({\n amount,\n asset,\n config,\n fromAddress,\n source,\n sourceChain,\n targetChain,\n sign: signer.sign,\n onStepChange,\n });\n } else {\n // unwrap asset (Avalanche -> Ethereum)\n txHash = await transferAssetFromAvaToHome({\n amount,\n fromAddress,\n source,\n sourceChain,\n sign: signer.sign,\n onStepChange,\n });\n }\n\n const sourceStartedAt = Date.now();\n const targetClient = getClientForChain({ chain: params.targetChain });\n\n let targetStartBlockNumber: bigint | undefined;\n try {\n targetStartBlockNumber = await targetClient.getBlockNumber();\n } catch (e) {\n console.error(e);\n }\n\n return {\n type: BridgeType.AVALANCHE_EVM,\n environment: config.environment,\n fromAddress: params.fromAddress,\n toAddress: params.toAddress,\n amount: params.amount,\n asset,\n bridgeFee,\n sourceChain: params.sourceChain,\n sourceStartedAt,\n sourceTxHash: txHash,\n sourceConfirmationCount: 0,\n sourceRequiredConfirmationCount,\n targetChain: params.targetChain,\n targetConfirmationCount: 0,\n targetRequiredConfirmationCount: 1, // EVM transactions need 1 confirmation\n targetStartBlockNumber,\n };\n}\n","import { BridgeInitializationError } from '../../../../errors/bridge-initialization-error';\nimport type { Environment } from '../../../../types';\nimport { TokenType, type Erc20Asset } from '../../../../types/asset';\nimport { ErrorReason } from '../../../../types/error';\nimport type { WardenConfig } from '../../types/config';\nimport type { EvmConfig, EthereumTokens, AvalancheTokens } from '../types/config';\nimport { isDynamicFee } from './fee';\n\nexport const convertToConfig = (wardenConfig: WardenConfig, environment: Environment): EvmConfig => {\n const wardenTokenList = wardenConfig.critical.assets;\n //Chain IDs for ethereum and avalanche\n const { ethereum, avalanche } = wardenConfig.critical.networks;\n\n if (ethereum === undefined || avalanche === undefined) {\n throw new BridgeInitializationError(\n ErrorReason.WARDEN_CONFIG_MISSING_NETWORK,\n 'Critical networks info is missing from wardenConfig',\n );\n }\n\n // If the wallet addresses are missing, we cannot perform bridge.\n const avalancheWalletAddress = wardenConfig.critical.walletAddresses.avalanche;\n const ethereumWalletAddress = wardenConfig.critical.walletAddresses.ethereum;\n\n if (!avalancheWalletAddress || !ethereumWalletAddress) {\n throw new BridgeInitializationError(\n ErrorReason.CONFIG_NOT_AVAILABLE,\n 'Wallet address is missing from the critical config.',\n );\n }\n\n // EVM tokens from Ethereum\n const homeTokens = Object.entries(wardenTokenList).reduce((assetList, [symbol, wardenAsset]) => {\n const nativeNetworkToken = {\n type: TokenType.ERC20,\n address: wardenAsset.nativeContractAddress,\n name: wardenAsset.tokenName,\n symbol: symbol,\n decimals: wardenAsset.denomination,\n } satisfies Erc20Asset;\n\n const wrapFee = wardenConfig.nonCritical.wrapFeeApproximation[symbol];\n\n assetList[wardenAsset.nativeContractAddress] = {\n chainId: `eip155:${ethereum}`,\n token: nativeNetworkToken,\n target: {\n chainId: `eip155:${avalanche}`,\n tokenAddress: wardenAsset.wrappedContractAddress,\n },\n wrapFeeApproximation: isDynamicFee(wrapFee) ? wrapFee : wrapFee ? BigInt(wrapFee) : undefined,\n };\n\n return assetList;\n }, {} as EthereumTokens);\n\n const wethHomeToken = Object.values(homeTokens).find((homeToken) => homeToken.token.symbol === 'WETH');\n\n if (!wethHomeToken) {\n throw new BridgeInitializationError(ErrorReason.CONFIG_NOT_AVAILABLE, 'WETH info is missing from config');\n }\n\n // EVM wrapped tokens from Avalanhce\n const avaTokens = Object.entries(wardenTokenList).reduce((assetList, [symbol, wardenAsset]) => {\n const avaNetworkToken = {\n type: TokenType.ERC20,\n address: wardenAsset.wrappedContractAddress,\n name: wardenAsset.tokenName,\n symbol: `${symbol}.e`,\n decimals: wardenAsset.denomination,\n } satisfies Erc20Asset;\n\n const unwrapFee = wardenConfig.nonCritical.unwrapFeeApproximation[symbol];\n\n assetList[wardenAsset.wrappedContractAddress] = {\n chainId: `eip155:${avalanche}`,\n token: avaNetworkToken,\n target: {\n chainId: `eip155:${ethereum}`,\n tokenAddress: wardenAsset.nativeContractAddress,\n },\n unwrapFeeApproximation: isDynamicFee(unwrapFee) ? unwrapFee : unwrapFee ? BigInt(unwrapFee) : undefined,\n };\n\n return assetList;\n }, {} as AvalancheTokens);\n\n const wethAvaToken = avaTokens[wethHomeToken.target.tokenAddress];\n\n if (!wethAvaToken) {\n throw new BridgeInitializationError(ErrorReason.CONFIG_NOT_AVAILABLE, 'WETH.e info is missing from config');\n }\n\n const avalancheMinimumConfirmation = wardenConfig.nonCritical.minimumConfirmations.avalanche;\n const ethereumMinimumConfirmation = wardenConfig.nonCritical.minimumConfirmations.ethereum;\n\n if (!avalancheMinimumConfirmation || !ethereumMinimumConfirmation) {\n throw new BridgeInitializationError(ErrorReason.CONFIG_NOT_AVAILABLE, 'Minimum confirmation info is missing');\n }\n\n const evmConfig: EvmConfig = {\n addressBlocklist: wardenConfig.critical.addressBlocklist,\n ethereumTokens: homeTokens,\n avalancheTokens: avaTokens,\n minimumConfirmations: {\n avalanche: avalancheMinimumConfirmation,\n ethereum: ethereumMinimumConfirmation,\n },\n environment,\n walletAddresses: {\n avalanche: avalancheWalletAddress,\n ethereum: ethereumWalletAddress,\n },\n nativeTokenConfig: {\n ethereumToken: wethHomeToken,\n avalancheToken: wethAvaToken,\n },\n };\n\n return evmConfig;\n};\n","import { Environment } from '../../../types/environment';\nimport { Blockchain, type RuntimeConfig } from '../types/config';\n\nconst devConfig: RuntimeConfig = {\n environment: Environment.DEV,\n tokenInfoUrl: 'https://raw.githubusercontent.com/ava-labs/avalanche-bridge-resources/main/token_list.test.json',\n configMismatchThreshold: 1, // 2 of the 3 must match\n wardenConfigURLs: [\n 'https://warden1-avax-dev-storage.s3.amazonaws.com/bridge_settings.json',\n 'https://warden2-avax-dev-storage.s3.amazonaws.com/bridge_settings.json',\n 'https://warden3-avax-dev-storage.s3.amazonaws.com/bridge_settings.json',\n ],\n disabledTokensOnNetwork: {\n [Blockchain.AVALANCHE]: [],\n [Blockchain.ETHEREUM]: ['FAU'],\n },\n};\n\nconst stageConfig = {\n ...devConfig,\n environment: Environment.STAGING,\n};\n\nconst testConfig = {\n ...stageConfig,\n environment: Environment.TEST,\n configMismatchThreshold: 2, // 6 of the 8 must match\n wardenConfigURLs: [\n 'https://ava-warden-bucket.s3.eu-central-1.amazonaws.com/bridge_settings.json',\n 'https://ava-warden-testnet.s3.us-west-1.amazonaws.com/bridge_settings.json',\n 'https://avalabs-testnet-cce1-testnet-warden-bucket.s3.ca-central-1.amazonaws.com/bridge_settings.json',\n 'https://avalabs-warden-test-blob.s3.amazonaws.com/bridge_settings.json',\n 'https://avawarden.s3.amazonaws.com/bridge_settings.json',\n 'https://blob-storage-testnet.warden-avascan.info/bridge_settings.json',\n 'https://chainstack-ava-warden-testnet.s3.us-west-2.amazonaws.com/bridge_settings.json',\n 'https://s3.amazonaws.com/warden-mgmt-prod-testnet.blockdaemon.com/bridge_settings.json',\n ],\n};\n\nconst prodConfig = {\n ...testConfig,\n environment: Environment.PROD,\n tokenInfoUrl: 'https://raw.githubusercontent.com/ava-labs/avalanche-bridge-resources/main/token_list.json',\n wardenConfigURLs: [\n 'https://ava-warden-bucket-prod.s3.eu-central-1.amazonaws.com/bridge_settings.json',\n 'https://ava-warden-mainnet.s3.us-west-1.amazonaws.com/bridge_settings.json',\n 'https://avalabs-mainnet-cce1-mainnet-warden-bucket.s3.ca-central-1.amazonaws.com/bridge_settings.json',\n 'https://avawarden-prod.s3.amazonaws.com/bridge_settings.json',\n 'https://blob-storage-mainnet.warden-avascan.info/bridge_settings.json',\n 'https://chainstack-ava-warden-mainnet.s3.us-west-2.amazonaws.com/bridge_settings.json',\n 'https://s3.amazonaws.com/warden-mgmt-prod-mainnet.blockdaemon.com/bridge_settings.json',\n 'https://warden-avax-storage.s3.amazonaws.com/bridge_settings.json',\n ],\n disabledTokensOnNetwork: {\n [Blockchain.AVALANCHE]: [],\n [Blockchain.ETHEREUM]: ['CRV'],\n },\n};\n\nexport const RUNTIME_CONFIGS = {\n [Environment.PROD]: prodConfig,\n [Environment.STAGING]: stageConfig,\n [Environment.TEST]: testConfig,\n [Environment.DEV]: devConfig,\n};\n\nexport const getRuntimeConfig = (environment: Environment): RuntimeConfig => {\n return RUNTIME_CONFIGS[environment];\n};\n","import { isEqual, maxBy, memoize } from 'lodash';\nimport { BridgeInitializationError } from '../../../errors/bridge-initialization-error';\nimport { ErrorReason } from '../../../types/error';\nimport { WardenConfigSchema, type RuntimeConfig, type WardenConfig } from '../types/config';\n\nconst fetchConfigs = async (wardenConfigUrls: string[]) => {\n const promises: Promise<Response>[] = [];\n wardenConfigUrls.forEach((url) => promises.push(fetch(url)));\n const responses = await Promise.allSettled(promises);\n const configs: WardenConfig[] = [];\n for (const response of responses) {\n if (response.status === 'rejected' || !response.value || !response.value.ok) {\n continue;\n }\n\n try {\n const responseJson = await response.value.json();\n const parsedConfig = WardenConfigSchema.parse(responseJson);\n configs.push(parsedConfig);\n } catch (e) {\n console.error(e);\n }\n }\n return configs;\n};\n\n// Figuring out how many fetched warden configs share the same values in critical and to verify that the mismatch count is not going over configMismatchThreshold,\n// Non-critical configs seem to change often. And comparing the whole config will cause the WARDEN_CONFIG_MISMATCH error.\n// So currently we only use critical to compare.\nconst consolidateByCriticalConfig = (configs: WardenConfig[]) => {\n return configs.map((config) => {\n if (config.critical.disableFrontend) {\n throw new BridgeInitializationError(ErrorReason.CONFIG_NOT_AVAILABLE, 'Disable frontend');\n }\n\n const count = configs.reduce(\n (count, otherConfig) => count + (isEqual(config.critical, otherConfig.critical) ? 1 : 0),\n 0,\n );\n return { config, count };\n });\n};\n\nexport const getWardenConfig = memoize(async (runtimeConfig: RuntimeConfig): Promise<WardenConfig> => {\n const wardenConfigUrls = runtimeConfig.wardenConfigURLs;\n const configs = await fetchConfigs(wardenConfigUrls);\n const consolidatedConfigs = consolidateByCriticalConfig(configs);\n const mostFrequentConfig = maxBy(consolidatedConfigs, (consolidatedConfig) => consolidatedConfig.count);\n if (\n !mostFrequentConfig ||\n mostFrequentConfig.count < runtimeConfig.wardenConfigURLs.length - runtimeConfig.configMismatchThreshold\n ) {\n throw new BridgeInitializationError(ErrorReason.WARDEN_CONFIG_MISMATCH, 'Warden config mismatch');\n }\n return mostFrequentConfig.config;\n});\n\nexport const clearWardenConfig = () => getWardenConfig.cache.clear?.();\n","import { Environment } from '../../../../types/environment';\nimport { convertToConfig } from './convert-config';\nimport { getRuntimeConfig } from '../../utils/runtime-config';\nimport { getWardenConfig } from '../../utils/warden-config';\nimport type { EvmConfig } from '../types/config';\n\nexport const getConfig = async (environment: Environment): Promise<EvmConfig> => {\n const runtimeConfig = getRuntimeConfig(environment);\n const wardenConfig = await getWardenConfig(runtimeConfig);\n const bridgeConfig = convertToConfig(wardenConfig, environment);\n return bridgeConfig;\n};\n","import { isAddressEqual } from 'viem';\nimport { AvalancheChainIds, BridgeType, EthereumChainIds, type AnalyzeTxResult } from '../../../../types';\nimport type { EvmConfig } from '../types/config';\nimport type { EvmAnalyzeTxParams } from '../../../../utils/evm/types/bridge';\n\nexport function analyzeTx(config: EvmConfig, params: EvmAnalyzeTxParams): AnalyzeTxResult {\n const isTestnet = AvalancheChainIds.FUJI === params.chainId || EthereumChainIds.SEPOLIA === params.chainId;\n const avalancheChain = isTestnet ? AvalancheChainIds.FUJI : AvalancheChainIds.MAINNET;\n const ethereumChain = isTestnet ? EthereumChainIds.SEPOLIA : EthereumChainIds.MAINNET;\n\n if (\n isAddressEqual(params.from, config.walletAddresses.ethereum) ||\n isAddressEqual(params.to, config.walletAddresses.avalanche)\n ) {\n // If tokens were transfered FROM Ethereum wallet address,\n // then it was received on Ethereum, and therefore came from Avalanche\n return {\n isBridgeTx: true,\n sourceChainId: avalancheChain,\n targetChainId: ethereumChain,\n bridgeType: BridgeType.AVALANCHE_EVM,\n };\n }\n\n // If tokens were transfered FROM the Avalanche wallet address,\n // then it was received on Avalanche, and therefore came from Ethereum\n if (\n isAddressEqual(params.from, config.walletAddresses.avalanche) ||\n isAddressEqual(params.to, config.walletAddresses.ethereum)\n ) {\n return {\n isBridgeTx: true,\n sourceChainId: ethereumChain,\n targetChainId: avalancheChain,\n bridgeType: BridgeType.AVALANCHE_EVM,\n };\n }\n\n return {\n isBridgeTx: false,\n };\n}\n","import { BridgeType } from '../../../types/bridge';\nimport { estimateGas } from './handlers/estimate-gas';\nimport { estimateReceiveAmount } from './handlers/estimate-receive-amount';\nimport { getAssets } from './handlers/get-assets';\nimport { getFees } from './handlers/get-fees';\nimport { getMinimumTransferAmount } from './handlers/get-minimum-transfer-amount';\nimport { trackTransfer } from './handlers/track-transfer';\nimport { transferAsset } from './handlers/transfer-asset';\nimport { getConfig } from './utils/config';\nimport { analyzeTx } from './handlers/analyze-tx';\nimport type { EvmBridgeServiceFactory } from '../../../utils/evm/types/bridge';\nimport {\n toEvmAnalyzeTxParams,\n toValidEvmGasEstimationParams,\n toValidEvmTransferParams,\n} from '../../../utils/evm/utils';\n\nexport const avalancheEvmBridgeFactory: EvmBridgeServiceFactory = async (environment, signer) => {\n const config = await getConfig(environment);\n return {\n type: BridgeType.AVALANCHE_EVM,\n analyzeTx: (params) => analyzeTx(config, toEvmAnalyzeTxParams(params)),\n estimateGas: (params) => estimateGas(config, toValidEvmGasEstimationParams(params)),\n estimateReceiveAmount: (params) => estimateReceiveAmount(config, toValidEvmGasEstimationParams(params)),\n getAssets: () => getAssets(config),\n getFees: (params) => getFees(config, params),\n transferAsset: (params) => transferAsset(config, toValidEvmTransferParams(params), signer),\n trackTransfer: (params) => trackTransfer(config, params),\n getMinimumTransferAmount: (params) => getMinimumTransferAmount(config, params),\n };\n};\n","import type { BitcoinCurrentBridgeFeeEstimateDynamic, BitcoinCurrentBridgeFeeEstimateStatic } from '../../types/config';\nimport type {\n BtcUnwrappingFeeEstimateDynamic,\n BtcUnwrappingFeeEstimateStatic,\n BtcWrappingFeeEstimateDynamic,\n BtcWrappingFeeEstimateStatic,\n} from '../types/config';\n\nexport const isNetworkInfoDynamic = (\n currentBridgeFeeEstimate: BitcoinCurrentBridgeFeeEstimateDynamic | BitcoinCurrentBridgeFeeEstimateStatic,\n): currentBridgeFeeEstimate is BitcoinCurrentBridgeFeeEstimateDynamic => {\n return 'wrapFeeEstimate' in currentBridgeFeeEstimate;\n};\n\nexport const isDynamicFee = (\n bridgeFeeEstimate:\n | BtcWrappingFeeEstimateDynamic\n | BtcWrappingFeeEstimateStatic\n | BtcUnwrappingFeeEstimateDynamic\n | BtcUnwrappingFeeEstimateStatic,\n): bridgeFeeEstimate is BtcWrappingFeeEstimateDynamic | BtcUnwrappingFeeEstimateDynamic => {\n return 'wrapFeeEstimate' in bridgeFeeEstimate || 'unwrapFeeEstimate' in bridgeFeeEstimate;\n};\n","import { BridgeInitializationError } from '../../../../errors';\nimport { BitcoinChainIds, ErrorReason, TokenType, type Environment } from '../../../../types';\nimport type { WardenConfig } from '../../types/config';\nimport type { BtcConfig, BitcoinBtcToken, AvaBtcToken } from '../types/config';\nimport { isNetworkInfoDynamic } from './fee';\n\nexport const convertToConfig = (wardenConfig: WardenConfig, environment: Environment): BtcConfig => {\n // Bitcoin config\n const criticalBitcoin = wardenConfig.criticalBitcoin;\n\n const btcAsset = criticalBitcoin.bitcoinAssets.btc;\n if (!btcAsset) {\n throw new BridgeInitializationError(ErrorReason.CONFIG_NOT_AVAILABLE, 'Bitcoin asset info is missing from config');\n }\n\n const bitcoinNetworkInfo = wardenConfig.nonCriticalBitcoin.networkInfo.btc;\n\n if (!bitcoinNetworkInfo) {\n throw new BridgeInitializationError(ErrorReason.CONFIG_NOT_AVAILABLE, 'Bitcoin network info was not found.');\n }\n const currentBridgeFeeEstimate = bitcoinNetworkInfo.currentBridgeFeeEstimate;\n\n const bridgeFeeEstimateHome = isNetworkInfoDynamic(currentBridgeFeeEstimate)\n ? {\n wrapFeeEstimate: currentBridgeFeeEstimate.wrapFeeEstimate,\n }\n : {\n wrapFeeAmount: currentBridgeFeeEstimate.wrapFeeAmount,\n };\n const bitcoinCaip2 = btcAsset.bech32AddressPrefix === 'bc' ? BitcoinChainIds.MAINNET : BitcoinChainIds.TESTNET; // bc === mainnet. tb === testnet\n const btcHomeToken: BitcoinBtcToken = {\n chainId: bitcoinCaip2,\n token: {\n name: btcAsset.tokenName,\n symbol: 'BTC',\n decimals: 8,\n type: TokenType.NATIVE,\n },\n target: {\n networkId: `eip155:${criticalBitcoin.avalancheChainId}`,\n tokenAddress: btcAsset.wrappedContractAddress,\n },\n bridgeFeeEstimate: bridgeFeeEstimateHome,\n };\n\n const bridgeFeeEstimateRemote = isNetworkInfoDynamic(currentBridgeFeeEstimate)\n ? {\n unwrapFeeEstimate: currentBridgeFeeEstimate.unwrapFeeEstimate,\n }\n : {\n constUnwrapFeeAmount: currentBridgeFeeEstimate.constUnwrapFeeAmount,\n unwrapFeeNumerator: currentBridgeFeeEstimate.unwrapFeeNumerator,\n unwrapFeeDenominator: currentBridgeFeeEstimate.unwrapFeeDenominator,\n };\n\n const btcRemoteToken: AvaBtcToken = {\n chainId: `eip155:${criticalBitcoin.avalancheChainId}`,\n token: {\n name: btcAsset.tokenName,\n symbol: 'BTC.b',\n decimals: 8,\n type: TokenType.ERC20,\n address: btcAsset.wrappedContractAddress,\n },\n target: {\n networkId: bitcoinCaip2,\n },\n bridgeFeeEstimate: bridgeFeeEstimateRemote,\n };\n\n const btcConfig: BtcConfig = {\n addressBlocklist: wardenConfig.criticalBitcoin.addressBlocklist,\n environment,\n dustThreshold: currentBridgeFeeEstimate.dustThreshold,\n minimumOnboardSize: bitcoinNetworkInfo.minimumOnboardSize,\n minimumConfirmations: {\n bitcoin: bitcoinNetworkInfo.minimumConfirmations,\n avalanche: wardenConfig.nonCritical.minimumConfirmations.avalanche ?? 1,\n },\n nativeTokenConfig: {\n bitcoinToken: btcHomeToken,\n avalancheToken: btcRemoteToken,\n },\n walletAddresses: {\n bitcoin: criticalBitcoin.walletAddresses.btc,\n avalanche: criticalBitcoin.walletAddresses.avalanche,\n },\n };\n\n return btcConfig;\n};\n","import { BridgeInitializationError } from '../../../../errors';\nimport { ErrorReason, type Environment } from '../../../../types';\nimport { getRuntimeConfig } from '../../utils/runtime-config';\nimport { getWardenConfig } from '../../utils/warden-config';\nimport type { BtcConfig } from '../types/config';\nimport { convertToConfig } from './convert-config';\n\nexport const getConfig = async (environment: Environment): Promise<BtcConfig> => {\n try {\n const runtimeConfig = getRuntimeConfig(environment);\n const wardenConfig = await getWardenConfig(runtimeConfig);\n const bridgeConfig = convertToConfig(wardenConfig, environment);\n return bridgeConfig;\n } catch (err) {\n throw new BridgeInitializationError(ErrorReason.CONFIG_NOT_AVAILABLE);\n }\n};\n","import { isCaip2AvalancheChainId, isCaip2BitcoinChainId, isTestnetCaip2ChainId } from './../../../utils/chain';\nimport {\n AvalancheChainIds,\n BitcoinChainIds,\n BridgeType,\n type AnalyzeTxParams,\n type AnalyzeTxResult,\n} from '../../../../../types';\nimport type { BtcConfig } from '../../types/config';\nimport { isEqual } from 'lodash';\nimport { ZERO_ADDRESS } from '../../../../../utils/consts';\n\nexport function analyzeTx(config: BtcConfig, params: AnalyzeTxParams): AnalyzeTxResult {\n const { chainId, from, to, tokenTransfers } = params;\n\n const isAvalanche = isCaip2AvalancheChainId(chainId);\n const isBitcoin = isCaip2BitcoinChainId(chainId);\n if (!isAvalanche && !isBitcoin) {\n return {\n isBridgeTx: false,\n };\n }\n const isTestnet = isTestnetCaip2ChainId(chainId);\n const avalancheChain = isTestnet ? AvalancheChainIds.FUJI : AvalancheChainIds.MAINNET;\n const bitcoinChain = isTestnet ? BitcoinChainIds.TESTNET : BitcoinChainIds.MAINNET;\n\n const isSourceTx =\n isBitcoin &&\n isEqual(to.toLowerCase(), config.walletAddresses.bitcoin.toLowerCase()) &&\n tokenTransfers.some((tokenTransfer) => tokenTransfer.symbol === 'BTC');\n\n const isTargetTx =\n isAvalanche &&\n isEqual(from, config.walletAddresses.avalanche) &&\n tokenTransfers.some((tokenTransfer) => tokenTransfer.symbol === 'BTC.b' && tokenTransfer.from === ZERO_ADDRESS);\n\n if (isTargetTx || isSourceTx) {\n return {\n isBridgeTx: true,\n sourceChainId: bitcoinChain,\n targetChainId: avalancheChain,\n bridgeType: BridgeType.AVALANCHE_BTC_AVA,\n };\n }\n\n return {\n isBridgeTx: false,\n };\n}\n","/**\n * Custom Bitcoin UTXO interface.\n */\n\nimport { z } from 'zod';\n\nconst BitcoinInputUTXO = z.object({\n txHash: z.string(),\n txHex: z.optional(z.string()),\n index: z.number(),\n value: z.number(),\n script: z.string(),\n blockHeight: z.number(),\n confirmations: z.number(),\n});\n\nexport const BitcoinInputUTXOArray = z.array(BitcoinInputUTXO);\n\nexport type BitcoinInputUTXO = typeof BitcoinInputUTXO._output;\n\nconst BitcoinInputUTXOWithOptionalScript = BitcoinInputUTXO.extend({\n script: z.optional(z.string()),\n});\nexport type BitcoinInputUTXOWithOptionalScript = typeof BitcoinInputUTXOWithOptionalScript._output;\n/**\n * Used for defining outputs when creating a transaction.\n */\n\nconst BitcoinOutputUTXO = z.object({\n address: z.string(),\n value: z.number(),\n});\nexport const BitcoinOutputUTXOArray = z.array(BitcoinOutputUTXO);\n\nexport type BitcoinOutputUTXO = typeof BitcoinOutputUTXO._output;\n\nexport interface BitcoinTx {\n hash: string;\n fees: number;\n block: number;\n amount: number;\n confirmations: number;\n blockTime: number;\n addresses: string[];\n inputs: {\n txid: string;\n vout: number;\n sequence: number;\n n: number;\n addresses: string[];\n isAddress: boolean;\n value: number;\n }[];\n outputs: {\n addresses: string[];\n value: number;\n n: number;\n spent: boolean;\n hex: string;\n isAddress: boolean;\n }[];\n}\n","import { BitcoinInputUTXOArray, BitcoinOutputUTXOArray } from './../../types/utxo';\nimport coinSelect from 'coinselect';\nimport type { BitcoinInputUTXO, BitcoinInputUTXOWithOptionalScript } from '../../types/utxo';\nimport { InvalidParamsError } from '../../../../../errors';\nimport { ErrorReason } from '../../../../../types';\n\nfunction filterDuplicateUTXOs<\n InputUtxo extends BitcoinInputUTXO | BitcoinInputUTXOWithOptionalScript = BitcoinInputUTXO,\n>(utxos: InputUtxo[]) {\n const seen: string[] = [];\n return utxos.filter((utxo) => {\n const key = utxo.txHash + utxo.index.toString();\n if (seen.includes(key)) return false;\n seen.push(key);\n return true;\n });\n}\n\n/**\n * Uses coinselect to select the input and output utxos for the given information.\n * Returns undefined if the transaction can not be completed.\n * @param to Destination address.\n * @param changeAddress Change address.\n * @param amount Amount to send in satoshis.\n * @param feeRate Satoshis per byte.\n * @param sourceUtxos UTXOs to pick from to construct the transaction.\n */\nexport function selectUtxos(\n to: string,\n changeAddress: string,\n amount: bigint,\n feeRate: number,\n sourceUtxos: BitcoinInputUTXO[],\n) {\n const filtered = filterDuplicateUTXOs(sourceUtxos);\n const targets = [{ address: to, value: Number(amount) }];\n\n /**\n * Note: Each algorithm will add a change output if the input - output - fee\n * value difference is over a dust threshold. This is calculated independently\n * by utils.finalize, irrespective of the algorithm chosen, for the purposes\n * of safety.\n */\n const { inputs, outputs, fee } = coinSelect(filtered, targets, feeRate);\n\n // Should not get here but we need to check the returned value types\n if (typeof fee !== 'number') {\n throw new InvalidParamsError(ErrorReason.UNKNOWN, 'Unable to choose utxo properly');\n }\n\n // If inputs or outputs is not defined then we can not complete this transaction\n if (!inputs || !outputs || !outputs.length) return { fee };\n const validatedInput = BitcoinInputUTXOArray.parse(inputs);\n\n // Change is only returned if it's above the dust threshold\n // address is missing in change. So assigning it before validation to keep force the address to be required.\n const finalOuts = [outputs[0]];\n const change = outputs[1];\n if (change) {\n finalOuts.push({\n address: changeAddress,\n value: change.value,\n });\n }\n\n const validatedOutput = BitcoinOutputUTXOArray.parse(finalOuts);\n\n return {\n inputs: validatedInput,\n outputs: validatedOutput,\n fee: fee,\n };\n}\n","import { isEqual } from 'lodash';\nimport { BitcoinChainIds, ErrorReason, type Asset, type BridgeAsset, type Chain } from '../../../../../types';\nimport { ChainId } from '../../../types/chain';\nimport { convertBridgeAssetToAsset } from '../../../utils/asset';\nimport { InvalidParamsError } from '../../../../../errors';\nimport type { BtcConfig } from '../../types/config';\nimport type { ValidBtcToAvaTransferParams } from '../types/bridge';\nimport type { BtcToAvaTransferData } from '../types/transfer-data';\n\ntype PartialTransferParams = Pick<ValidBtcToAvaTransferParams, 'sourceChain' | 'targetChain' | 'amount' | 'asset'>;\n\nconst isValidChainCombination = (sourceChain: Chain, targetChain: Chain) => {\n const validRoutes = [\n { source: BitcoinChainIds.MAINNET, target: `eip155:${ChainId.AVALANCHE_MAINNET}` },\n { source: BitcoinChainIds.TESTNET, target: `eip155:${ChainId.AVALANCHE_TESTNET}` },\n ];\n return validRoutes.some(({ source, target }) => source === sourceChain.chainId && target === targetChain.chainId);\n};\n\nconst assetsMatch = (asset: Asset, bridgeAsset: BridgeAsset) => {\n return isEqual(asset, convertBridgeAssetToAsset(bridgeAsset));\n};\n\nexport const getTransferData = (params: PartialTransferParams, config: BtcConfig): BtcToAvaTransferData => {\n const { sourceChain, targetChain, amount, asset } = params;\n\n if (!isValidChainCombination(sourceChain, targetChain)) {\n throw new InvalidParamsError(ErrorReason.INVALID_PARAMS, 'SourceChain and TargetChain combination is not valid');\n }\n\n if (amount <= 0n) {\n throw new InvalidParamsError(ErrorReason.INCORRECT_AMOUNT_PROVIDED, 'Amount must be greater than zero');\n }\n\n const source = config.nativeTokenConfig.bitcoinToken;\n\n if (!assetsMatch(source.token, asset)) {\n throw new InvalidParamsError(ErrorReason.ASSET_NOT_SUPPORTED, 'Incorrect Asset was provided');\n }\n\n return {\n source,\n target: config.nativeTokenConfig.avalancheToken,\n btcToAva: true,\n };\n};\n","import type { BtcConfig } from '../../types/config';\nimport { selectUtxos } from '../utils/utxo';\nimport type { ValidBtcToAvaGasEstimationParams } from '../types/bridge';\nimport { getTransferData } from '../utils/transfer-data';\nimport type { BitcoinFunctions } from '../../../../../types/bitcoin-functions';\n\nexport async function estimateGas(\n config: BtcConfig,\n params: ValidBtcToAvaGasEstimationParams,\n bitcoinFunctions: BitcoinFunctions,\n): Promise<bigint> {\n const { fromAddress, sourceChain, targetChain, asset, amount } = params;\n\n getTransferData(\n {\n sourceChain,\n targetChain,\n asset,\n amount,\n },\n config,\n );\n\n //BTC from Bitcoin to Avalanche\n const bridgeAddress = config.walletAddresses.bitcoin;\n // Bitcoin's formula for fee is `transactionByteLength * feeRate`.\n // By setting the feeRate here to 1, we'll receive the transaction's byte length,\n // which is what we need to have the dynamic fee calculations in the UI.\n // Think of the byteLength as gasLimit for EVM transactions.\n const feeRate = 1;\n const { utxos } = await bitcoinFunctions.getUtxoBalance(fromAddress, false);\n const uxtoWithScripts = await bitcoinFunctions.getScriptsForUtxos(utxos);\n\n //getTransferTxDetails\n // Check for duplicate inputs\n // Select UTXOs for the transaction\n const { fee } = selectUtxos(bridgeAddress, fromAddress, amount, feeRate, uxtoWithScripts);\n return BigInt(fee);\n}\n","import type { AssetFeeMap, FeeParams } from '../../../../../types';\nimport { getDynamicFeeAmount } from '../../../utils/fees';\nimport type { BtcConfig } from '../../types/config';\nimport { isDynamicFee } from '../../utils/fee';\nimport { getTransferData } from '../utils/transfer-data';\n\nexport async function getFees(config: BtcConfig, params: FeeParams): Promise<AssetFeeMap> {\n const { sourceChain, targetChain, amount, asset } = params;\n const { source, target } = getTransferData({ sourceChain, targetChain, amount, asset }, config);\n if (isDynamicFee(source.bridgeFeeEstimate)) {\n const cost = getDynamicFeeAmount(amount, source.bridgeFeeEstimate.wrapFeeEstimate);\n return {\n [target.token.address]: cost,\n };\n }\n\n return {\n [target.token.address]: BigInt(source.bridgeFeeEstimate.wrapFeeAmount),\n };\n}\n","import type { BtcConfig } from '../../types/config';\nimport type { ValidBtcToAvaGasEstimationParams } from '../types/bridge';\nimport { getTransferData } from '../utils/transfer-data';\nimport { getFees } from './get-fees';\n\nexport async function estimateReceiveAmount(config: BtcConfig, params: ValidBtcToAvaGasEstimationParams) {\n const { sourceChain, targetChain, asset, amount } = params;\n\n const { target } = getTransferData(\n {\n sourceChain,\n targetChain,\n asset,\n amount,\n },\n config,\n );\n const fees = await getFees(config, params);\n\n return {\n asset: target.token,\n amount: params.amount - (fees[target.token.address] ?? 0n),\n };\n}\n","import { BridgeType, type BridgeAsset, type ChainAssetMap } from '../../../../../types';\nimport type { BtcConfig } from '../../types/config';\n\nexport function getAssets(config: BtcConfig): ChainAssetMap {\n const bitcoinAsset = config.nativeTokenConfig.bitcoinToken;\n const bitcoinBridgeAsset: BridgeAsset = {\n ...bitcoinAsset.token,\n destinations: { [bitcoinAsset.target.networkId]: [BridgeType.AVALANCHE_BTC_AVA] },\n };\n\n return {\n [bitcoinAsset.chainId]: [bitcoinBridgeAsset],\n };\n}\n","import type { FeeParams } from '../../../../../types';\nimport type { BtcConfig } from '../../types/config';\nimport { isDynamicFee } from '../../utils/fee';\nimport type { BtcToAvaTransferData } from '../types/transfer-data';\nimport { getTransferData } from '../utils/transfer-data';\nimport { getFees } from './get-fees';\n\nexport async function getMinimumTransferAmount(config: BtcConfig, params: FeeParams) {\n const { sourceChain, targetChain, amount, asset } = params;\n\n const transferData = getTransferData({ sourceChain, targetChain, amount, asset }, config);\n\n const baseFee = await getBaseFee(config, params, transferData);\n const minimumOnboardSize = config.minimumOnboardSize;\n return BigInt(Math.max(baseFee * 4, minimumOnboardSize));\n}\n\nasync function getBaseFee(config: BtcConfig, params: FeeParams, { source, target }: BtcToAvaTransferData) {\n if (isDynamicFee(source.bridgeFeeEstimate)) {\n return Number(source.bridgeFeeEstimate.wrapFeeEstimate.minimumFeeAmount);\n } else {\n const bridgeFee = await getFees(config, params);\n return Number(bridgeFee[target.token.address]);\n }\n}\n","import type { Client } from '../../../../../utils/evm/client';\nimport { ErrorCode, type BridgeTransfer, type TrackingParams } from '../../../../../types';\nimport type { Done } from '../../../../../utils/retry-promise';\nimport { updateTransfer, type TrackingConfig } from '../../../../../utils/tracking/utils';\nimport { cloneDeep } from 'lodash';\nimport type { BitcoinFunctions } from '../../../../../types/bitcoin-functions';\n\nexport type CreateBtcSourceTrackerArgs = {\n trackingParams: TrackingParams;\n checkMetadata: (metadata: BridgeTransfer['metadata']) => boolean;\n targetClient: Client;\n trackingConfig: TrackingConfig;\n bitcoinFunctions: BitcoinFunctions;\n};\n\nexport const createBtcToAvaSourceTracker = ({\n targetClient,\n checkMetadata,\n trackingParams: { bridgeTransfer, updateListener },\n trackingConfig: { trackingLimitMs },\n bitcoinFunctions,\n}: CreateBtcSourceTrackerArgs) => {\n let updatableTransfer = cloneDeep(bridgeTransfer);\n\n const tracker = async (done: Done<BridgeTransfer>) => {\n const { sourceTxHash } = bridgeTransfer;\n /**\n * Return early if:\n * - transfer has already completed successfully or due to some error\n * - metadata is already set\n */\n if (updatableTransfer.completedAt || checkMetadata(updatableTransfer.metadata)) {\n return done(updatableTransfer);\n }\n\n /**\n * Check if the transaction has timed out\n */\n if (updatableTransfer.sourceStartedAt + trackingLimitMs <= Date.now()) {\n updatableTransfer = updateTransfer(\n updatableTransfer,\n { completedAt: Date.now(), errorCode: ErrorCode.TIMEOUT },\n updateListener,\n );\n return done(updatableTransfer);\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 { confirmations: confirmationCount, fees } = await bitcoinFunctions.getTransaction(sourceTxHash);\n\n /**\n * Calculate the network fee if needed.\n */\n if (!updatableTransfer.sourceNetworkFee) {\n const roundedFee = BigInt(Math.ceil(fees));\n updatableTransfer = updateTransfer(updatableTransfer, { sourceNetworkFee: roundedFee }, updateListener);\n }\n\n /**\n * Check the confirmation count.\n * - update the sourceConfirmationCount if it increased\n * - update the targetStartBlockNumber if confirmation count increased but is not enough\n * - keeps polling until it's greater than sourceRequiredConfirmationCount\n */\n const hasMoreConfirmations = confirmationCount > updatableTransfer.sourceConfirmationCount;\n const hasRequiredConfirmations = confirmationCount >= updatableTransfer.sourceRequiredConfirmationCount;\n\n if (hasMoreConfirmations) {\n const changes = {} as Partial<BridgeTransfer>;\n changes.sourceConfirmationCount = Number(confirmationCount);\n\n if (!hasRequiredConfirmations) {\n changes.targetStartBlockNumber = await targetClient.getBlockNumber();\n }\n\n updatableTransfer = updateTransfer(updatableTransfer, changes, updateListener);\n }\n\n if (!hasRequiredConfirmations) {\n return;\n }\n\n if (!updatableTransfer.targetStartBlockNumber) {\n updatableTransfer = updateTransfer(\n updatableTransfer,\n { targetStartBlockNumber: await targetClient.getBlockNumber() },\n updateListener,\n );\n }\n\n updatableTransfer = updateTransfer(\n updatableTransfer,\n { targetStartedAt: Date.now(), metadata: { transactionHash: sourceTxHash } },\n updateListener,\n );\n\n return done(updatableTransfer);\n };\n return tracker;\n};\n","import type { Client } from '../../../../../utils/evm/client';\nimport type { Done } from '../../../../../utils/retry-promise';\nimport { getNetworkFeeEVM } from '../../../../../utils/network-fee';\nimport { ErrorCode, ErrorReason, type BridgeTransfer, type TrackingParams } from '../../../../../types';\nimport { cloneDeep, isNil } from 'lodash';\nimport { InvalidParamsError } from '../../../../../errors';\nimport { updateTransfer, type TrackingConfig } from '../../../../../utils/tracking/utils';\nimport { isHash } from 'viem';\n\ntype GetTargetTxHashParams = {\n fromBlock: bigint | 'earliest';\n toBlock: bigint | 'latest';\n metadata: BridgeTransfer['metadata'];\n};\n\nexport type CreateBtcToAvaTargetTrackerArgs = {\n trackingParams: TrackingParams;\n getTargetTxHash: (params: GetTargetTxHashParams) => Promise<`0x${string}` | undefined>;\n checkMetadata: (metadata: BridgeTransfer['metadata']) => boolean;\n targetClient: Client;\n trackingConfig: TrackingConfig;\n};\n\nexport const createBtcToAvaTargetTracker = ({\n targetClient,\n getTargetTxHash,\n checkMetadata,\n trackingParams: { bridgeTransfer, updateListener },\n trackingConfig: { trackingLimitMs, maxBlocks },\n}: CreateBtcToAvaTargetTrackerArgs) => {\n if (!bridgeTransfer.completedAt && !checkMetadata(bridgeTransfer.metadata)) {\n throw new InvalidParamsError(ErrorReason.INVALID_PARAMS, 'metadata is missing');\n }\n\n if (!bridgeTransfer.targetStartBlockNumber) {\n throw new InvalidParamsError(ErrorReason.INVALID_PARAMS, 'targetStartBlockNumber is missing');\n }\n let updatableTransfer = cloneDeep(bridgeTransfer);\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 (updatableTransfer.completedAt) {\n return done(updatableTransfer);\n }\n\n /**\n * Check if the transaction has timed out\n */\n if (updatableTransfer.sourceStartedAt + trackingLimitMs <= Date.now()) {\n updatableTransfer = updateTransfer(\n updatableTransfer,\n { completedAt: Date.now(), errorCode: ErrorCode.TIMEOUT },\n updateListener,\n );\n return done(updatableTransfer);\n }\n\n if (!updatableTransfer.targetStartBlockNumber) {\n // This is unreachable because we throw if this field is missing above\n // And we never unset this field, once it has already been set\n throw new Error('unreachable');\n }\n\n if (!updatableTransfer.targetTxHash) {\n const lastBlockNumber = await targetClient.getBlockNumber();\n const lowestBlockNumber = updatableTransfer.targetStartBlockNumber - maxBlocks;\n const fromBlock = lowestBlockNumber >= 0n ? lowestBlockNumber : 'earliest';\n const highestBlockNumber = updatableTransfer.targetStartBlockNumber + maxBlocks;\n const toBlock = highestBlockNumber < lastBlockNumber ? highestBlockNumber : 'latest';\n const targetTxHash = await getTargetTxHash({ fromBlock, toBlock, metadata: updatableTransfer.metadata });\n if (targetTxHash) {\n updatableTransfer = updateTransfer(updatableTransfer, { targetTxHash }, updateListener);\n } else {\n updatableTransfer = updateTransfer(\n updatableTransfer,\n { targetStartBlockNumber: lastBlockNumber },\n updateListener,\n );\n return;\n }\n }\n\n if (isNil(updatableTransfer.targetTxHash) || !isHash(updatableTransfer.targetTxHash)) {\n return;\n }\n\n /**\n * Get the transaction's receipt.\n *\n */\n const txReceipt = await targetClient.getTransactionReceipt({\n hash: updatableTransfer.targetTxHash,\n });\n\n /**\n * Calculate the network fee if needed.\n */\n if (!updatableTransfer.targetNetworkFee) {\n const tx = await targetClient.getTransaction({\n hash: updatableTransfer.targetTxHash,\n });\n\n const networkFee = getNetworkFeeEVM(tx, txReceipt);\n\n if (networkFee) {\n updatableTransfer = updateTransfer(updatableTransfer, { targetNetworkFee: networkFee }, updateListener);\n }\n }\n\n /**\n * Update the state and terminate if the transaction was reverted.\n * Technically, it's possible to retry delivery of teleporter messages, but the current tracking implementation is naive.\n */\n if (txReceipt.status === 'reverted') {\n updatableTransfer = updateTransfer(\n updatableTransfer,\n { completedAt: Date.now(), errorCode: ErrorCode.TRANSACTION_REVERTED },\n updateListener,\n );\n return done(updatableTransfer);\n }\n\n if (isNil(updatableTransfer.targetTxHash) || !isHash(updatableTransfer.targetTxHash)) {\n return;\n }\n\n /**\n * Check the confirmation count.\n * - update the targetConfirmationCount if it increased\n * - keeps polling until it's greater than targetRequiredConfirmationCount\n */\n const confirmationCount = await targetClient.getTransactionConfirmations({\n hash: updatableTransfer.targetTxHash,\n });\n\n const hasMoreConfirmations = confirmationCount > updatableTransfer.targetConfirmationCount;\n const hasRequiredConfirmations = confirmationCount >= updatableTransfer.targetRequiredConfirmationCount;\n if (hasMoreConfirmations) {\n updatableTransfer = updateTransfer(\n updatableTransfer,\n { targetConfirmationCount: Number(confirmationCount) },\n updateListener,\n );\n }\n\n if (!hasRequiredConfirmations) {\n return;\n }\n\n updatableTransfer = updateTransfer(updatableTransfer, { completedAt: Date.now() }, updateListener);\n\n return done(updatableTransfer);\n };\n return tracker;\n};\n","import type { AbiEvent } from 'viem';\nimport type { Client } from '../../../../../utils/evm/client';\nimport type { CreateBtcToAvaTargetTrackerArgs } from './btc-to-ava-target-tracker';\nimport { includesOriginTxId } from '../../../evm/utils/tracking';\nimport { isNil, isObject } from 'lodash';\nimport type { BridgeTransfer } from '../../../../../types';\nimport type { BtcToAvaTransferData } from '../types/transfer-data';\n\nexport const checkMetadata = (metadata: BridgeTransfer['metadata']): metadata is { transactionHash: string } => {\n return isObject(metadata) && !!metadata.transactionHash;\n};\n\nexport const createGetTargetTxHash =\n ({\n transferData: { target },\n targetClient,\n }: {\n transferData: BtcToAvaTransferData;\n targetClient: Client;\n }): CreateBtcToAvaTargetTrackerArgs['getTargetTxHash'] =>\n async ({ fromBlock, toBlock, metadata }) => {\n if (!fromBlock) {\n return undefined;\n }\n const contractAddress = target.token.address;\n\n const event = {\n inputs: [\n {\n indexed: false,\n name: 'to',\n type: 'address',\n },\n {\n indexed: false,\n name: 'amount',\n type: 'uint256',\n },\n {\n indexed: false,\n name: 'feeAddress',\n type: 'address',\n },\n {\n indexed: false,\n name: 'feeAmount',\n type: 'uint256',\n },\n {\n indexed: false,\n name: 'originTxId',\n type: 'bytes32',\n },\n {\n indexed: false,\n name: 'originOutputIndex',\n type: 'uint256',\n },\n ],\n name: 'Mint',\n type: 'event',\n } satisfies AbiEvent;\n const logs = await targetClient.getLogs({\n address: contractAddress,\n event,\n fromBlock,\n toBlock,\n });\n\n // originTxId is not indexed. So it cannot be a part of the filter. We manually do this to ensure that we are getting the correct log\n const foundLog = logs.find(\n (log) => includesOriginTxId(log) && log.args.originTxId === `0x${metadata?.transactionHash}`,\n );\n\n if (isNil(foundLog)) {\n return undefined;\n }\n\n return foundLog.transactionHash;\n };\n","import type { BridgeTransfer, TrackingParams } from '../../../../../types';\nimport type { BitcoinFunctions } from '../../../../../types/bitcoin-functions';\nimport { getClientForChain } from '../../../../../utils/evm/client';\nimport { retryPromise } from '../../../../../utils/retry-promise';\nimport { DEFAULT_TRACKING_CONFIG } from '../../../../../utils/tracking';\nimport type { BtcConfig } from '../../types/config';\nimport type { BtcToAvaTransferData } from '../types/transfer-data';\nimport { createBtcToAvaSourceTracker } from '../utils/btc-to-ava-source-tracker';\nimport { createBtcToAvaTargetTracker } from '../utils/btc-to-ava-target-tracker';\nimport { checkMetadata, createGetTargetTxHash } from '../utils/tracking';\nimport { getTransferData } from '../utils/transfer-data';\n\nconst trackBtcSourceTx = async (params: TrackingParams, bitcoinFunctions: BitcoinFunctions) => {\n const { targetChain } = params.bridgeTransfer;\n\n const targetClient = getClientForChain({ chain: targetChain });\n\n const tracker = createBtcToAvaSourceTracker({\n targetClient,\n trackingParams: params,\n trackingConfig: DEFAULT_TRACKING_CONFIG,\n checkMetadata,\n bitcoinFunctions,\n });\n\n return retryPromise<BridgeTransfer>({\n promise: tracker,\n delay: 1000 * 60, // 60s since BTC confirmations happen slow\n startAfter: DEFAULT_TRACKING_CONFIG.initialDelayMs,\n });\n};\n\nconst trackAvaTargetTx = async (params: TrackingParams, transferData: BtcToAvaTransferData) => {\n const { bridgeTransfer } = params;\n\n const targetClient = getClientForChain({\n chain: bridgeTransfer.targetChain,\n });\n\n const getTargetTxHash = createGetTargetTxHash({\n transferData,\n targetClient,\n });\n\n const tracker = createBtcToAvaTargetTracker({\n targetClient,\n getTargetTxHash,\n checkMetadata,\n trackingParams: params,\n trackingConfig: DEFAULT_TRACKING_CONFIG,\n });\n\n return retryPromise<BridgeTransfer>({\n promise: tracker,\n delay: 2000,\n startAfter: DEFAULT_TRACKING_CONFIG.initialDelayMs,\n });\n};\n\nexport function trackTransfer(config: BtcConfig, params: TrackingParams, bitcoinFunctions: BitcoinFunctions) {\n let abortFn: (() => void) | undefined;\n\n const cancel = () => {\n abortFn?.();\n };\n\n const executeTracking = async () => {\n const { bridgeTransfer } = params;\n const { targetChain, sourceChain, asset, amount } = bridgeTransfer;\n\n const transferData = getTransferData(\n {\n sourceChain,\n targetChain,\n asset,\n amount,\n },\n config,\n );\n\n const { result: sourceTracker, cancel: cancelSourceTracking } = await trackBtcSourceTx(params, bitcoinFunctions);\n abortFn = cancelSourceTracking;\n const transferAfterSourceFinished = await sourceTracker;\n\n const { result: targetTracker, cancel: cancelTargetTracking } = await trackAvaTargetTx(\n {\n ...params,\n bridgeTransfer: transferAfterSourceFinished,\n },\n transferData,\n );\n\n abortFn = cancelTargetTracking;\n\n return targetTracker;\n };\n\n return {\n result: executeTracking(),\n cancel,\n };\n}\n","import type { BtcConfig } from '../../types/config';\nimport {\n ErrorReason,\n type BridgeStepDetails,\n type BtcSign,\n BridgeSignatureReason,\n Environment,\n} from '../../../../../types';\nimport { selectUtxos } from './utxo';\nimport { InvalidParamsError } from '../../../../../errors';\nimport type { BitcoinFunctions } from '../../../../../types/bitcoin-functions';\n\nexport const transferAssetFromBtcToAva = async ({\n config,\n amount,\n fromAddress,\n sign,\n onStepChange,\n bitcoinFunctions,\n}: {\n config: BtcConfig;\n amount: bigint;\n fromAddress: string;\n sign: BtcSign;\n onStepChange?: (stepDetails: BridgeStepDetails) => void;\n bitcoinFunctions: BitcoinFunctions;\n}) => {\n const { low, high } = await bitcoinFunctions.getFeeRates();\n\n // Because BTC testnet fees are super high recently,\n // defaulting to cheaper preset makes testing easier.\n const feeRate = config.environment === Environment.PROD ? high : low;\n const { utxos } = await bitcoinFunctions.getUtxoBalance(fromAddress, false);\n\n const uxtoWithScripts = await bitcoinFunctions.getScriptsForUtxos(utxos);\n const bridgeAddress = config.walletAddresses.bitcoin;\n\n const { inputs, outputs } = selectUtxos(bridgeAddress, fromAddress, amount, feeRate, uxtoWithScripts);\n\n if (!inputs || !outputs) {\n throw new InvalidParamsError(ErrorReason.INVALID_PARAMS, 'Unable to create transaction');\n }\n\n onStepChange?.({\n currentSignature: 1,\n currentSignatureReason: BridgeSignatureReason.TokensTransfer,\n requiredSignatures: 1,\n });\n\n const txHash = await sign({ inputs, outputs }, bitcoinFunctions.issueRawTx);\n return txHash;\n};\n","import { BridgeType, type BridgeTransfer, type BtcSigner } from '../../../../../types';\nimport { getClientForChain } from '../../../../../utils/evm/client';\nimport type { BtcConfig } from '../../types/config';\nimport { transferAssetFromBtcToAva } from '../utils/wrapping';\nimport { getTransferData } from '../utils/transfer-data';\nimport { getFees } from './get-fees';\nimport type { ValidBtcToAvaTransferParams } from '../types/bridge';\nimport type { BitcoinFunctions } from '../../../../../types/bitcoin-functions';\n\nexport async function transferAsset(\n config: BtcConfig,\n params: ValidBtcToAvaTransferParams,\n signer: BtcSigner,\n bitcoinFunctions: BitcoinFunctions,\n): Promise<BridgeTransfer> {\n const { fromAddress, toAddress, sourceChain, targetChain, asset, amount, onStepChange } = params;\n\n const { target } = getTransferData(\n {\n sourceChain,\n targetChain,\n asset,\n amount,\n },\n config,\n );\n\n const sourceStartedAt = Date.now();\n const fees = await getFees(config, { asset, amount, sourceChain, targetChain });\n const bridgeFee = fees[target.token.address] ?? 0n;\n\n const sourceRequiredConfirmationCount = config.minimumConfirmations.bitcoin;\n\n const txHash = await transferAssetFromBtcToAva({\n config,\n amount,\n sign: signer.sign,\n onStepChange,\n fromAddress,\n bitcoinFunctions,\n });\n const targetClient = getClientForChain({ chain: targetChain });\n\n let targetStartBlockNumber: bigint | undefined = undefined;\n try {\n targetStartBlockNumber = await targetClient.getBlockNumber();\n } catch (e) {\n console.error(e);\n }\n\n const bridgeTransfer: BridgeTransfer = {\n type: BridgeType.AVALANCHE_BTC_AVA,\n environment: config.environment,\n fromAddress,\n toAddress,\n amount: params.amount,\n asset,\n bridgeFee,\n sourceChain: sourceChain,\n sourceStartedAt,\n sourceTxHash: txHash,\n sourceConfirmationCount: 0,\n sourceRequiredConfirmationCount,\n targetChain: params.targetChain,\n targetConfirmationCount: 0,\n targetRequiredConfirmationCount: 1, // EVM transactions need 1 confirmation\n targetStartBlockNumber,\n };\n return bridgeTransfer;\n}\n","import type { Address } from 'abitype';\n\nimport { isMainnetChain } from '../../../utils/chain';\nimport { isAddress } from 'viem';\nimport { InvalidParamsError } from '../../../../../errors';\nimport { isBech32AddressInNetwork } from '../../utils/address';\nimport type { BitcoinFunctions } from '../../../../../types/bitcoin-functions';\nimport {\n ErrorReason,\n type BridgeService,\n type BtcSigner,\n type Environment,\n type GasEstimationParams,\n type TransferParams,\n} from '../../../../../types';\n\nexport type ValidBtcToAvaTransferParams = TransferParams & {\n fromAddress: string; // Bitcoin address\n toAddress: Address; // Avalanche address\n};\n\nexport type ValidBtcToAvaGasEstimationParams = Omit<ValidBtcToAvaTransferParams, 'onStepChange' | 'toAddress'>;\n\nexport const toValidBtcToAvaTransferParams = ({\n fromAddress,\n toAddress,\n sourceChain,\n ...rest\n}: TransferParams): ValidBtcToAvaTransferParams => {\n if (!isAddress(toAddress)) {\n throw new InvalidParamsError(ErrorReason.INCORRECT_ADDRESS_PROVIDED, 'Invalid toAddress was provided');\n }\n\n const mainnet = isMainnetChain(sourceChain);\n if (!isBech32AddressInNetwork(fromAddress, mainnet)) {\n throw new InvalidParamsError(\n ErrorReason.INCORRECT_ADDRESS_PROVIDED,\n 'Invalid fromAddress was provided: Make sure it is Btc Address from correct environment',\n );\n }\n return { fromAddress, toAddress, sourceChain, ...rest };\n};\n\nexport const toValidBtcToAvaGasEstimationParams = ({\n fromAddress,\n sourceChain,\n ...rest\n}: GasEstimationParams): ValidBtcToAvaGasEstimationParams => {\n const mainnet = isMainnetChain(sourceChain);\n if (!isBech32AddressInNetwork(fromAddress, mainnet)) {\n throw new InvalidParamsError(\n ErrorReason.INCORRECT_ADDRESS_PROVIDED,\n 'Invalid fromAddress was provided: Make sure it is Btc Address from correct environment',\n );\n }\n return { fromAddress, sourceChain, ...rest };\n};\n\nexport type BtcToAvaBridgeServiceFactory = (\n environment: Environment,\n signer: BtcSigner,\n bitcoinFunctions: BitcoinFunctions,\n) => Promise<BridgeService>;\n","import { BridgeType } from '../../../../types';\nimport { getConfig } from '../utils/config';\nimport { analyzeTx } from './handlers/analyze-tx';\nimport { estimateGas } from './handlers/estimate-gas';\nimport { estimateReceiveAmount } from './handlers/estimate-receive-amount';\nimport { getAssets } from './handlers/get-assets';\nimport { getFees } from './handlers/get-fees';\nimport { getMinimumTransferAmount } from './handlers/get-minimum-transfer-amount';\nimport { trackTransfer } from './handlers/track-transfer';\nimport { transferAsset } from './handlers/transfer-asset';\nimport {\n toValidBtcToAvaGasEstimationParams,\n toValidBtcToAvaTransferParams,\n type BtcToAvaBridgeServiceFactory,\n} from './types/bridge';\n\nexport const avalancheBtcToAvaBridgeFactory: BtcToAvaBridgeServiceFactory = async (\n environment,\n signer,\n bitcoinFunctions,\n) => {\n const config = await getConfig(environment);\n\n return {\n type: BridgeType.AVALANCHE_BTC_AVA,\n analyzeTx: (params) => analyzeTx(config, params),\n estimateGas: (params) => estimateGas(config, toValidBtcToAvaGasEstimationParams(params), bitcoinFunctions),\n estimateReceiveAmount: (params) => estimateReceiveAmount(config, toValidBtcToAvaGasEstimationParams(params)),\n getAssets: () => getAssets(config),\n getFees: (params) => getFees(config, params),\n transferAsset: (params) => transferAsset(config, toValidBtcToAvaTransferParams(params), signer, bitcoinFunctions),\n trackTransfer: (params) => trackTransfer(config, params, bitcoinFunctions),\n getMinimumTransferAmount: (params) => getMinimumTransferAmount(config, params),\n };\n};\n","import { isCaip2AvalancheChainId, isCaip2BitcoinChainId, isTestnetCaip2ChainId } from './../../../utils/chain';\nimport {\n AvalancheChainIds,\n BitcoinChainIds,\n BridgeType,\n type AnalyzeTxParams,\n type AnalyzeTxResult,\n} from '../../../../../types';\nimport type { BtcConfig } from '../../types/config';\nimport { isEqual } from 'lodash';\nimport { ZERO_ADDRESS } from '../../../../../utils/consts';\n\nexport function analyzeTx(config: BtcConfig, params: AnalyzeTxParams): AnalyzeTxResult {\n const { chainId, from, to, tokenTransfers } = params;\n\n const isAvalanche = isCaip2AvalancheChainId(chainId);\n const isBitcoin = isCaip2BitcoinChainId(chainId);\n if (!isAvalanche && !isBitcoin) {\n return {\n isBridgeTx: false,\n };\n }\n const isTestnet = isTestnetCaip2ChainId(chainId);\n const avalancheChain = isTestnet ? AvalancheChainIds.FUJI : AvalancheChainIds.MAINNET;\n const bitcoinChain = isTestnet ? BitcoinChainIds.TESTNET : BitcoinChainIds.MAINNET;\n\n const isSourceTx =\n isAvalanche &&\n isEqual(to.toLowerCase(), config.nativeTokenConfig.avalancheToken.token.address.toLowerCase()) &&\n tokenTransfers.some(\n (tokenTransfer) =>\n tokenTransfer.to?.toLowerCase() === ZERO_ADDRESS.toLowerCase() && tokenTransfer.symbol === 'BTC.b',\n );\n\n const isTargetTx =\n isBitcoin &&\n isEqual(from.toLowerCase(), config.walletAddresses.bitcoin.toLowerCase()) &&\n tokenTransfers.some((tokenTransfer) => tokenTransfer.symbol === 'BTC');\n\n if (isSourceTx || isTargetTx) {\n return {\n isBridgeTx: true,\n sourceChainId: avalancheChain,\n targetChainId: bitcoinChain,\n bridgeType: BridgeType.AVALANCHE_AVA_BTC,\n };\n }\n\n return {\n isBridgeTx: false,\n };\n}\n","import { isEqual } from 'lodash';\nimport { convertBridgeAssetToAsset } from '../../../utils/asset';\nimport { BitcoinChainIds, ErrorReason, type Asset, type BridgeAsset, type Chain } from '../../../../../types';\n\nimport { InvalidParamsError } from '../../../../../errors';\nimport type { BtcConfig } from '../../types/config';\nimport { ChainId } from '../../../types/chain';\nimport type { AvaToBtcTransferData } from '../types/transfer-data';\nimport type { ValidAvaToBtcTransferParams } from '../types/bridge';\n\ntype PartialTransferParams = Pick<ValidAvaToBtcTransferParams, 'sourceChain' | 'targetChain' | 'amount' | 'asset'>;\n\nconst isValidChainCombination = (sourceChain: Chain, targetChain: Chain) => {\n const validRoutes = [\n { source: `eip155:${ChainId.AVALANCHE_MAINNET}`, target: BitcoinChainIds.MAINNET },\n { source: `eip155:${ChainId.AVALANCHE_TESTNET}`, target: BitcoinChainIds.TESTNET },\n ];\n return validRoutes.some(({ source, target }) => source === sourceChain.chainId && target === targetChain.chainId);\n};\n\nconst assetsMatch = (asset: Asset, bridgeAsset: BridgeAsset) => {\n return isEqual(asset, convertBridgeAssetToAsset(bridgeAsset));\n};\n\nexport const getTransferData = (params: PartialTransferParams, config: BtcConfig): AvaToBtcTransferData => {\n const { sourceChain, targetChain, amount, asset } = params;\n\n if (!isValidChainCombination(sourceChain, targetChain)) {\n throw new InvalidParamsError(ErrorReason.INVALID_PARAMS, 'SourceChain and TargetChain combination is not valid');\n }\n\n if (amount <= 0n) {\n throw new InvalidParamsError(ErrorReason.INCORRECT_AMOUNT_PROVIDED, 'Amount must be greater than zero');\n }\n\n const source = config.nativeTokenConfig.avalancheToken;\n\n if (!assetsMatch(source.token, asset)) {\n throw new InvalidParamsError(ErrorReason.ASSET_NOT_SUPPORTED, 'Incorrect Asset was provided');\n }\n\n return {\n source,\n target: config.nativeTokenConfig.bitcoinToken,\n btcToAva: false,\n };\n};\n","import { getClientForChain } from '../../../../../utils/evm/client';\nimport { WAVAX_ABI } from '../../../evm/abis/wavax-abi';\nimport type { BtcConfig } from '../../types/config';\nimport type { ValidAvaToBtcGasEstimationParams } from '../types/bridge';\nimport { getTransferData } from '../utils/transfer-data';\n\nexport async function estimateGas(config: BtcConfig, params: ValidAvaToBtcGasEstimationParams): Promise<bigint> {\n const { sourceChain, targetChain, asset, amount, fromAddress } = params;\n\n const { source } = getTransferData(\n {\n sourceChain,\n targetChain,\n asset,\n amount,\n },\n config,\n );\n\n const client = getClientForChain({ chain: sourceChain });\n const estimate = await client.estimateContractGas({\n address: source.token.address,\n abi: WAVAX_ABI,\n functionName: 'unwrap',\n account: fromAddress,\n args: [amount, 0],\n });\n\n return estimate;\n}\n","import type { AssetFeeMap, FeeParams } from '../../../../../types';\nimport { getDynamicFeeAmount } from '../../../utils/fees';\nimport type { BtcConfig } from '../../types/config';\nimport { isDynamicFee } from '../../utils/fee';\nimport { getTransferData } from '../utils/transfer-data';\n\nexport async function getFees(config: BtcConfig, params: FeeParams): Promise<AssetFeeMap> {\n const { sourceChain, targetChain, amount, asset } = params;\n const { source } = getTransferData({ sourceChain, targetChain, amount, asset }, config);\n if (isDynamicFee(source.bridgeFeeEstimate)) {\n const { constAmount, numeratorPerSat, denominatorPerSat } =\n source.bridgeFeeEstimate.unwrapFeeEstimate.estimatedTxFee;\n\n const txFee = constAmount + (numeratorPerSat / denominatorPerSat) * Number(amount);\n const bridgeFee = getDynamicFeeAmount(amount, source.bridgeFeeEstimate.unwrapFeeEstimate.bridgeToll);\n const cost = BigInt(Math.ceil(txFee)) + bridgeFee;\n return {\n NATIVE: BigInt(cost),\n };\n } else {\n const { constUnwrapFeeAmount, unwrapFeeNumerator, unwrapFeeDenominator } = source.bridgeFeeEstimate;\n const costInNumber = constUnwrapFeeAmount + (unwrapFeeNumerator / unwrapFeeDenominator) * Number(amount);\n const cost = BigInt(Math.ceil(costInNumber));\n\n return {\n NATIVE: BigInt(cost),\n };\n }\n}\n","import type { BtcConfig } from '../../types/config';\nimport type { ValidAvaToBtcGasEstimationParams } from '../types/bridge';\nimport { getTransferData } from '../utils/transfer-data';\n\nimport { getFees } from './get-fees';\n\nexport async function estimateReceiveAmount(config: BtcConfig, params: ValidAvaToBtcGasEstimationParams) {\n const { sourceChain, targetChain, asset, amount } = params;\n\n const { target } = getTransferData(\n {\n sourceChain,\n targetChain,\n asset,\n amount,\n },\n config,\n );\n const fees = await getFees(config, { sourceChain, targetChain, amount, asset });\n\n return {\n asset: target.token,\n amount: params.amount - (fees['NATIVE'] ?? 0n),\n };\n}\n","import { BridgeType, type BridgeAsset, type ChainAssetMap } from '../../../../../types';\nimport type { BtcConfig } from '../../types/config';\n\nexport function getAssets(config: BtcConfig): ChainAssetMap {\n const avaBitcoinAsset = config.nativeTokenConfig.avalancheToken;\n const avaBitcoinBridgeAsset: BridgeAsset = {\n ...avaBitcoinAsset.token,\n destinations: { [avaBitcoinAsset.target.networkId]: [BridgeType.AVALANCHE_AVA_BTC] },\n };\n\n return {\n [avaBitcoinAsset.chainId]: [avaBitcoinBridgeAsset],\n };\n}\n","import type { FeeParams } from '../../../../../types';\nimport type { BtcConfig } from '../../types/config';\nimport { isDynamicFee } from '../../utils/fee';\nimport type { AvaToBtcTransferData } from '../types/transfer-data';\nimport { getTransferData } from '../utils/transfer-data';\nimport { getFees } from './get-fees';\n\nexport async function getMinimumTransferAmount(config: BtcConfig, params: FeeParams) {\n const { sourceChain, targetChain, amount, asset } = params;\n\n const transferData = getTransferData({ sourceChain, targetChain, amount, asset }, config);\n const baseFee = await getBaseFee(config, params, transferData);\n const dustThreshold = config.dustThreshold;\n\n return BigInt(Math.ceil((baseFee + dustThreshold) * 2));\n}\n\nasync function getBaseFee(config: BtcConfig, params: FeeParams, { source }: AvaToBtcTransferData) {\n if (isDynamicFee(source.bridgeFeeEstimate)) {\n const { constAmount, numeratorPerSat, denominatorPerSat } =\n source.bridgeFeeEstimate.unwrapFeeEstimate.estimatedTxFee;\n const txFee = constAmount + (numeratorPerSat / denominatorPerSat) * Number(params.amount);\n return Number(source.bridgeFeeEstimate.unwrapFeeEstimate.bridgeToll.minimumFeeAmount) + txFee;\n } else {\n const bridgeFee = await getFees(config, params);\n return Number(bridgeFee['NATIVE']);\n }\n}\n","import { isHash, type TransactionReceipt } from 'viem';\nimport type { BridgeTransfer } from '../../../../../types/transfer';\nimport type { Client } from '../../../../../utils/evm/client';\nimport type { Done } from '../../../../../utils/retry-promise';\nimport { getNetworkFeeEVM } from '../../../../../utils/network-fee';\nimport { ErrorCode, type TrackingParams } from '../../../../../types';\nimport { cloneDeep } from 'lodash';\nimport { updateTransfer, type TrackingConfig } from '../../../../../utils/tracking/utils';\nimport type { BitcoinFunctions } from '../../../../../types/bitcoin-functions';\n\nexport type CreateAvaToBtcSourceTrackerArgs = {\n trackingParams: TrackingParams;\n getMetadata: (txReceipt: TransactionReceipt) => BridgeTransfer['metadata'];\n checkMetadata: (metadata: BridgeTransfer['metadata']) => boolean;\n sourceClient: Client;\n trackingConfig: TrackingConfig;\n bitcoinFunctions: BitcoinFunctions;\n};\n\nexport const createAvaToBtcSourceTracker = ({\n sourceClient,\n getMetadata,\n checkMetadata,\n trackingParams: { bridgeTransfer, updateListener },\n trackingConfig: { trackingLimitMs },\n bitcoinFunctions,\n}: CreateAvaToBtcSourceTrackerArgs) => {\n let updateableTransfer = cloneDeep(bridgeTransfer);\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 * - metadata is already set\n */\n if (updateableTransfer.completedAt || checkMetadata(updateableTransfer.metadata)) {\n return done(updateableTransfer);\n }\n\n /**\n * Check if the transaction has timed out\n */\n if (updateableTransfer.sourceStartedAt + trackingLimitMs <= Date.now()) {\n updateableTransfer = updateTransfer(\n updateableTransfer,\n { completedAt: Date.now(), errorCode: ErrorCode.TIMEOUT },\n updateListener,\n );\n return done(updateableTransfer);\n }\n if (!isHash(updateableTransfer.sourceTxHash)) {\n return;\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,\n });\n\n /**\n * Calculate the network fee if needed.\n */\n if (!updateableTransfer.sourceNetworkFee) {\n const tx = await sourceClient.getTransaction({\n hash: updateableTransfer.sourceTxHash,\n });\n const networkFee = getNetworkFeeEVM(tx, txReceipt);\n\n if (networkFee) {\n updateableTransfer = 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 updateableTransfer = updateTransfer(\n updateableTransfer,\n { completedAt: Date.now(), errorCode: ErrorCode.TRANSACTION_REVERTED },\n updateListener,\n );\n return done(updateableTransfer);\n }\n if (!isHash(updateableTransfer.sourceTxHash)) {\n return;\n }\n /**\n * Check the confirmation count.\n * - update the sourceConfirmationCount if it increased\n * - update the targetStartBlockNumber if confirmation count increased but is not enough\n * - keeps polling until it's greater than sourceRequiredConfirmationCount\n */\n const confirmationCount = await sourceClient.getTransactionConfirmations({\n hash: updateableTransfer.sourceTxHash,\n });\n const hasMoreConfirmations = confirmationCount > updateableTransfer.sourceConfirmationCount;\n const hasRequiredConfirmations = confirmationCount >= updateableTransfer.sourceRequiredConfirmationCount;\n\n if (hasMoreConfirmations) {\n const changes = {} as Partial<BridgeTransfer>;\n changes.sourceConfirmationCount = Number(confirmationCount);\n\n if (!hasRequiredConfirmations) {\n changes.targetStartBlockNumber = BigInt(await bitcoinFunctions.getChainHeight());\n }\n\n updateableTransfer = updateTransfer(updateableTransfer, changes, updateListener);\n }\n\n if (!hasRequiredConfirmations) {\n return;\n }\n\n if (!updateableTransfer.targetStartBlockNumber) {\n updateableTransfer = updateTransfer(\n updateableTransfer,\n { targetStartBlockNumber: BigInt(await bitcoinFunctions.getChainHeight()) },\n updateListener,\n );\n }\n\n const metadata = getMetadata(txReceipt);\n\n updateableTransfer = updateTransfer(updateableTransfer, { targetStartedAt: Date.now(), metadata }, updateListener);\n return done(updateableTransfer);\n };\n return tracker;\n};\n","import { type Done } from '../../../../../utils/retry-promise';\nimport { ErrorCode, ErrorReason, type BridgeTransfer, type TrackingParams } from '../../../../../types';\nimport { InvalidParamsError } from '../../../../../errors';\nimport type { BtcConfig } from '../../types/config';\nimport { cloneDeep } from 'lodash';\nimport { updateTransfer, type TrackingConfig } from '../../../../../utils/tracking/utils';\nimport type { BitcoinTx } from '../../types/utxo';\nimport type { BitcoinFunctions } from '../../../../../types/bitcoin-functions';\n\nexport type CreateAvaToBtcTargetTrackerArgs = {\n trackingParams: TrackingParams;\n trackingConfig: TrackingConfig;\n config: BtcConfig;\n bitcoinFunctions: BitcoinFunctions;\n};\n\nexport const createAvaToBtcTargetTracker = ({\n trackingParams: { bridgeTransfer, updateListener },\n trackingConfig: { trackingLimitMs },\n config,\n bitcoinFunctions,\n}: CreateAvaToBtcTargetTrackerArgs) => {\n const { toAddress, targetStartBlockNumber, amount } = bridgeTransfer;\n\n if (!bridgeTransfer.targetStartBlockNumber) {\n throw new InvalidParamsError(ErrorReason.INVALID_PARAMS, 'targetStartBlockNumber is missing');\n }\n let updateableTransfer = cloneDeep(bridgeTransfer);\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 the transaction has timed out\n */\n if (updateableTransfer.sourceStartedAt + trackingLimitMs <= Date.now()) {\n updateableTransfer = updateTransfer(\n updateableTransfer,\n { completedAt: Date.now(), errorCode: ErrorCode.TIMEOUT },\n updateListener,\n );\n return done(updateableTransfer);\n }\n\n if (!updateableTransfer.targetStartBlockNumber) {\n // This is unreachable because we throw if this field is missing above\n // And we never unset this field, once it has already been set\n throw new Error('unreachable');\n }\n\n let tx: BitcoinTx | undefined = undefined;\n if (!updateableTransfer.targetTxHash) {\n const { confirmed, unconfirmed } = await bitcoinFunctions.getUTXOs(toAddress, false);\n\n // Filter to blocks from the startBlockNumber\n // and sort by height asc\n const filteredUTXOs = confirmed\n .filter((utxo) => !targetStartBlockNumber || utxo.blockHeight >= targetStartBlockNumber)\n .sort((a, b) => a.blockHeight - b.blockHeight);\n\n const utxos = [...filteredUTXOs, ...unconfirmed];\n // Find the first UTXO from the bridge\n for (const utxo of utxos) {\n tx = await bitcoinFunctions.getTransaction(utxo.txHash);\n if (!tx) {\n return;\n }\n const isFromBridge = tx.addresses.includes(config.walletAddresses.bitcoin);\n if (isFromBridge) {\n updateableTransfer = updateTransfer(\n updateableTransfer,\n { targetTxHash: tx.hash, targetNetworkFee: BigInt(tx.fees), targetConfirmationCount: tx.confirmations },\n updateListener,\n );\n\n const txOutput = tx.outputs.find((o) => o.addresses?.length === 1 && o.addresses[0] === toAddress);\n const bridgeFee = txOutput && BigInt(Math.ceil(Number(amount) - txOutput.value));\n if (bridgeFee) {\n updateableTransfer = updateTransfer(updateableTransfer, { bridgeFee }, updateListener);\n }\n break;\n }\n }\n\n if (!updateableTransfer.targetTxHash) {\n return;\n }\n }\n\n if (!tx) {\n tx = await bitcoinFunctions.getTransaction(updateableTransfer.targetTxHash);\n }\n if (!tx) {\n return;\n }\n const isConfirmed = tx.confirmations >= updateableTransfer.targetRequiredConfirmationCount;\n\n if (isConfirmed) {\n updateableTransfer = updateTransfer(\n updateableTransfer,\n { completedAt: Date.now(), targetConfirmationCount: tx.confirmations },\n updateListener,\n );\n return done(updateableTransfer);\n }\n };\n return tracker;\n};\n","import type { BridgeTransfer, TrackingParams } from '../../../../../types';\nimport type { BitcoinFunctions } from '../../../../../types/bitcoin-functions';\nimport { getClientForChain } from '../../../../../utils/evm/client';\nimport { retryPromise } from '../../../../../utils/retry-promise';\nimport { DEFAULT_TRACKING_CONFIG } from '../../../../../utils/tracking';\nimport { checkMetadata, createGetMetadata } from '../../../evm/utils/tracking';\nimport type { BtcConfig } from '../../types/config';\nimport { createAvaToBtcSourceTracker } from '../utils/ava-to-btc-source-tracker';\nimport { createAvaToBtcTargetTracker } from '../utils/ava-to-btc-target-tracker';\nimport { getTransferData } from '../utils/transfer-data';\n\nconst trackAvaSourceTx = async (params: TrackingParams, bitcoinFunctions: BitcoinFunctions) => {\n const { sourceChain } = params.bridgeTransfer;\n\n const sourceClient = getClientForChain({ chain: sourceChain });\n\n const getMetadata = createGetMetadata();\n\n const tracker = createAvaToBtcSourceTracker({\n sourceClient,\n getMetadata,\n checkMetadata,\n trackingParams: params,\n trackingConfig: DEFAULT_TRACKING_CONFIG,\n bitcoinFunctions,\n });\n return retryPromise<BridgeTransfer>({\n promise: tracker,\n delay: 2000,\n startAfter: DEFAULT_TRACKING_CONFIG.initialDelayMs,\n });\n};\n\nconst trackBtcTargetTx = async (config: BtcConfig, params: TrackingParams, bitcoinFunctions: BitcoinFunctions) => {\n const tracker = createAvaToBtcTargetTracker({\n trackingParams: params,\n trackingConfig: DEFAULT_TRACKING_CONFIG,\n config,\n bitcoinFunctions,\n });\n\n return retryPromise<BridgeTransfer>({\n promise: tracker,\n delay: 1000 * 60, // 60s since BTC confirmations happen slow\n startAfter: DEFAULT_TRACKING_CONFIG.initialDelayMs,\n });\n};\n\nexport function trackTransfer(config: BtcConfig, params: TrackingParams, bitcoinFunctions: BitcoinFunctions) {\n let abortFn: (() => void) | undefined;\n\n const cancel = () => {\n abortFn?.();\n };\n\n const executeTracking = async () => {\n const { bridgeTransfer } = params;\n const { targetChain, sourceChain, asset, amount } = bridgeTransfer;\n\n //Vailidating\n getTransferData(\n {\n sourceChain,\n targetChain,\n asset,\n amount,\n },\n config,\n );\n\n const { result: sourceTracker, cancel: cancelSourceTracking } = await trackAvaSourceTx(params, bitcoinFunctions);\n abortFn = cancelSourceTracking;\n const transferAfterSourceFinished = await sourceTracker;\n\n const { result: targetTracker, cancel: cancelTargetTracking } = await trackBtcTargetTx(\n config,\n {\n ...params,\n bridgeTransfer: transferAfterSourceFinished,\n },\n bitcoinFunctions,\n );\n\n abortFn = cancelTargetTracking;\n\n return targetTracker;\n };\n\n return {\n result: executeTracking(),\n cancel,\n };\n}\n","import { BridgeType, type BridgeTransfer, type EvmSigner } from '../../../../../types';\nimport type { BitcoinFunctions } from '../../../../../types/bitcoin-functions';\nimport { transferAssetFromAvaToHome } from '../../../utils/unwrapping';\nimport type { BtcConfig } from '../../types/config';\nimport type { ValidAvaToBtcTransferParams } from '../types/bridge';\nimport { getTransferData } from '../utils/transfer-data';\nimport { getFees } from './get-fees';\n\nexport async function transferAsset(\n config: BtcConfig,\n params: ValidAvaToBtcTransferParams,\n signer: EvmSigner,\n bitcoinFunctions: BitcoinFunctions,\n): Promise<BridgeTransfer> {\n const { sourceChain, targetChain, asset, amount, fromAddress, toAddress, onStepChange } = params;\n\n const { source } = getTransferData(\n {\n sourceChain,\n targetChain,\n asset,\n amount,\n },\n config,\n );\n\n const sourceStartedAt = Date.now();\n const fees = await getFees(config, { asset, amount, sourceChain, targetChain });\n const bridgeFee = fees['NATIVE'] ?? 0n;\n\n const sourceRequiredConfirmationCount = config.minimumConfirmations.avalanche;\n\n const txHash = await transferAssetFromAvaToHome({\n amount,\n source,\n sourceChain,\n fromAddress,\n sign: signer.sign,\n onStepChange,\n });\n\n const targetStartBlockNumber = BigInt(await bitcoinFunctions.getChainHeight());\n\n const bridgeTransfer: BridgeTransfer = {\n type: BridgeType.AVALANCHE_AVA_BTC,\n environment: config.environment,\n fromAddress: fromAddress,\n toAddress: toAddress,\n amount: params.amount,\n asset,\n bridgeFee,\n sourceChain: sourceChain,\n sourceStartedAt,\n sourceTxHash: txHash,\n sourceConfirmationCount: 0,\n sourceRequiredConfirmationCount,\n targetChain: params.targetChain,\n targetConfirmationCount: 0,\n targetRequiredConfirmationCount: 1, // BTC transactions need 1 confirmation\n targetStartBlockNumber,\n };\n return bridgeTransfer;\n}\n","import type { Address } from 'abitype';\nimport {\n ErrorReason,\n type BridgeService,\n type Environment,\n type EvmSigner,\n type GasEstimationParams,\n type TransferParams,\n} from '../../../../../types';\nimport { isMainnetChain } from '../../../utils/chain';\nimport { isAddress } from 'viem';\nimport { InvalidParamsError } from '../../../../../errors';\nimport { isBech32AddressInNetwork } from '../../utils/address';\nimport type { BitcoinFunctions } from '../../../../../types/bitcoin-functions';\n\nexport type ValidAvaToBtcTransferParams = TransferParams & {\n fromAddress: Address; // Avalanche addressC\n toAddress: string; // Bitcoin address\n};\n\nexport type ValidAvaToBtcGasEstimationParams = Omit<ValidAvaToBtcTransferParams, 'onStepChange' | 'toAddress'>;\n\nexport const toValidAvaToBtcTransferParams = ({\n fromAddress,\n toAddress,\n targetChain,\n ...rest\n}: TransferParams): ValidAvaToBtcTransferParams => {\n if (!isAddress(fromAddress)) {\n throw new InvalidParamsError(ErrorReason.INCORRECT_ADDRESS_PROVIDED, 'Invalid fromAddress was provided');\n }\n\n const mainnet = isMainnetChain(targetChain);\n if (!isBech32AddressInNetwork(toAddress, mainnet)) {\n throw new InvalidParamsError(\n ErrorReason.INCORRECT_ADDRESS_PROVIDED,\n 'Invalid toAddress was provided: Make sure it is Btc Address from correct environment',\n );\n }\n return { fromAddress, toAddress, targetChain, ...rest };\n};\nexport const toValidAvaToBtcGasEstimationParams = ({\n fromAddress,\n targetChain,\n ...rest\n}: GasEstimationParams): ValidAvaToBtcGasEstimationParams => {\n if (!isAddress(fromAddress)) {\n throw new InvalidParamsError(ErrorReason.INCORRECT_ADDRESS_PROVIDED, 'Invalid fromAddress was provided');\n }\n return { fromAddress, targetChain, ...rest };\n};\n\nexport type AvaToBtcBridgeServiceFactory = (\n environment: Environment,\n signer: EvmSigner,\n bitcoinFunctions: BitcoinFunctions,\n) => Promise<BridgeService>;\n","import { BridgeType } from '../../../../types';\nimport { getConfig } from '../utils/config';\nimport { analyzeTx } from './handlers/analyze-tx';\nimport { estimateGas } from './handlers/estimate-gas';\nimport { estimateReceiveAmount } from './handlers/estimate-receive-amount';\nimport { getAssets } from './handlers/get-assets';\nimport { getFees } from './handlers/get-fees';\nimport { getMinimumTransferAmount } from './handlers/get-minimum-transfer-amount';\nimport { trackTransfer } from './handlers/track-transfer';\nimport { transferAsset } from './handlers/transfer-asset';\nimport {\n toValidAvaToBtcGasEstimationParams,\n toValidAvaToBtcTransferParams,\n type AvaToBtcBridgeServiceFactory,\n} from './types/bridge';\n\nexport const avalancheAvaToBtcBridgeFactory: AvaToBtcBridgeServiceFactory = async (\n environment,\n signer,\n bitcoinFunctions,\n) => {\n const config = await getConfig(environment);\n\n return {\n type: BridgeType.AVALANCHE_AVA_BTC,\n analyzeTx: (params) => analyzeTx(config, params),\n estimateGas: (params) => estimateGas(config, toValidAvaToBtcGasEstimationParams(params)),\n estimateReceiveAmount: (params) => estimateReceiveAmount(config, toValidAvaToBtcGasEstimationParams(params)),\n getAssets: () => getAssets(config),\n getFees: (params) => getFees(config, params),\n transferAsset: (params) => transferAsset(config, toValidAvaToBtcTransferParams(params), signer, bitcoinFunctions),\n trackTransfer: (params) => trackTransfer(config, params, bitcoinFunctions),\n getMinimumTransferAmount: (params) => getMinimumTransferAmount(config, params),\n };\n};\n"]}