@avalabs/bridge-unified 1.0.1 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/.turbo/turbo-build.log +10 -10
  2. package/.turbo/turbo-lint.log +1 -1
  3. package/.turbo/turbo-test.log +25 -0
  4. package/CHANGELOG.md +18 -0
  5. package/README.md +137 -71
  6. package/dist/index.cjs +11 -3
  7. package/dist/index.cjs.map +1 -1
  8. package/dist/index.d.cts +207 -34
  9. package/dist/index.d.ts +207 -34
  10. package/dist/index.js +4 -3
  11. package/dist/index.js.map +1 -1
  12. package/jest.config.js +9 -0
  13. package/package.json +15 -9
  14. package/src/bridges/cctp/__mocks__/asset.mock.ts +15 -0
  15. package/src/bridges/cctp/__mocks__/bridge-transfer.mock.ts +48 -0
  16. package/src/bridges/cctp/__mocks__/chain.mocks.ts +31 -0
  17. package/src/bridges/cctp/__mocks__/config.mock.ts +45 -0
  18. package/src/bridges/cctp/abis/erc20.ts +117 -0
  19. package/src/bridges/cctp/abis/message-transmitter.ts +318 -0
  20. package/src/bridges/cctp/abis/token-router.ts +843 -0
  21. package/src/bridges/cctp/factory.test.ts +73 -0
  22. package/src/bridges/cctp/factory.ts +32 -0
  23. package/src/bridges/cctp/handlers/get-assets.test.ts +47 -0
  24. package/src/bridges/cctp/handlers/get-assets.ts +27 -0
  25. package/src/bridges/cctp/handlers/get-fees.test.ts +61 -0
  26. package/src/bridges/cctp/handlers/get-fees.ts +26 -0
  27. package/src/bridges/cctp/handlers/track-transfer.test.ts +779 -0
  28. package/src/bridges/cctp/handlers/track-transfer.ts +365 -0
  29. package/src/bridges/cctp/handlers/transfer-asset.test.ts +429 -0
  30. package/src/bridges/cctp/handlers/transfer-asset.ts +179 -0
  31. package/src/bridges/cctp/index.ts +1 -0
  32. package/src/bridges/cctp/types/chain.ts +4 -0
  33. package/src/bridges/cctp/types/config.ts +19 -0
  34. package/src/bridges/cctp/utils/config.test.ts +49 -0
  35. package/src/bridges/cctp/utils/config.ts +36 -0
  36. package/src/bridges/cctp/utils/transfer-data.test.ts +83 -0
  37. package/src/bridges/cctp/utils/transfer-data.ts +48 -0
  38. package/src/errors/bridge-error.ts +11 -0
  39. package/src/errors/bridge-initialization-error.ts +9 -0
  40. package/src/errors/bridge-unavailable-error.ts +9 -0
  41. package/src/errors/index.ts +4 -20
  42. package/src/errors/invalid-params-error.ts +9 -0
  43. package/src/index.ts +3 -1
  44. package/src/types/asset.ts +26 -0
  45. package/src/types/bridge.ts +63 -0
  46. package/src/types/chain.ts +10 -0
  47. package/src/types/config.ts +10 -0
  48. package/src/types/environment.ts +4 -0
  49. package/src/types/error.ts +19 -0
  50. package/src/types/index.ts +9 -0
  51. package/src/types/provider.ts +12 -0
  52. package/src/types/signer.ts +18 -0
  53. package/src/types/transfer.ts +35 -0
  54. package/src/unified-bridge-service.test.ts +208 -0
  55. package/src/unified-bridge-service.ts +90 -0
  56. package/src/utils/bridge-types.test.ts +103 -0
  57. package/src/utils/bridge-types.ts +32 -0
  58. package/src/utils/caip2.test.ts +44 -0
  59. package/src/utils/caip2.ts +41 -0
  60. package/src/utils/client.test.ts +97 -0
  61. package/src/utils/client.ts +44 -0
  62. package/src/utils/ensure-config.test.ts +43 -0
  63. package/src/utils/ensure-config.ts +12 -0
  64. package/src/utils/index.ts +2 -0
  65. package/src/utils/network-fee.test.ts +24 -0
  66. package/src/utils/network-fee.ts +6 -0
  67. package/src/utils/retry-promise.test.ts +115 -0
  68. package/src/utils/retry-promise.ts +72 -0
  69. package/src/utils/wait.test.ts +33 -0
  70. package/src/utils/wait.ts +4 -0
  71. package/tsconfig.jest.json +7 -0
  72. package/tsconfig.json +2 -1
  73. package/src/bridge-service.ts +0 -18
  74. package/src/handlers/get-bridge-router.ts +0 -25
  75. package/src/handlers/submit-and-watch-bridge-transaction.ts +0 -1
  76. package/src/handlers/submit-bridge-transaction-step.ts +0 -22
@@ -1,5 +1,5 @@
1
1
 
2
- > @avalabs/bridge-unified@1.0.1 build /home/runner/work/consumer-sdks/consumer-sdks/packages/bridge-unified
2
+ > @avalabs/bridge-unified@2.0.1 build /home/runner/work/consumer-sdks/consumer-sdks/packages/bridge-unified
3
3
  > tsup
4
4
 
5
5
  CLI Building entry: ./src/index.ts
@@ -10,13 +10,13 @@
10
10
  CLI Cleaning output folder
11
11
  CJS Build start
12
12
  ESM Build start
13
- CJS dist/index.cjs 473.00 B
14
- CJS dist/index.cjs.map 3.67 KB
15
- CJS ⚡️ Build success in 464ms
16
- ESM dist/index.js 459.00 B
17
- ESM dist/index.js.map 3.67 KB
18
- ESM ⚡️ Build success in 464ms
13
+ ESM dist/index.js 23.02 KB
14
+ ESM dist/index.js.map 83.10 KB
15
+ ESM ⚡️ Build success in 1337ms
16
+ CJS dist/index.cjs 23.04 KB
17
+ CJS dist/index.cjs.map 83.10 KB
18
+ CJS ⚡️ Build success in 1337ms
19
19
  DTS Build start
20
- DTS ⚡️ Build success in 7247ms
21
- DTS dist/index.d.cts 1.23 KB
22
- DTS dist/index.d.ts 1.23 KB
20
+ DTS ⚡️ Build success in 8990ms
21
+ DTS dist/index.d.cts 5.90 KB
22
+ DTS dist/index.d.ts 5.90 KB
@@ -1,4 +1,4 @@
1
1
 
2
- > @avalabs/bridge-unified@1.0.1 lint /home/runner/work/consumer-sdks/consumer-sdks/packages/bridge-unified
2
+ > @avalabs/bridge-unified@2.0.1 lint /home/runner/work/consumer-sdks/consumer-sdks/packages/bridge-unified
3
3
  > eslint "src/**/*.ts"
4
4
 
@@ -0,0 +1,25 @@
1
+
2
+ > @avalabs/bridge-unified@2.0.1 test /home/runner/work/consumer-sdks/consumer-sdks/packages/bridge-unified
3
+ > jest
4
+
5
+ PASS src/bridges/cctp/handlers/track-transfer.test.ts (10.844 s)
6
+ PASS src/bridges/cctp/handlers/transfer-asset.test.ts
7
+ PASS src/unified-bridge-service.test.ts
8
+ PASS src/utils/retry-promise.test.ts
9
+ PASS src/bridges/cctp/utils/transfer-data.test.ts
10
+ PASS src/utils/bridge-types.test.ts
11
+ PASS src/utils/client.test.ts
12
+ PASS src/bridges/cctp/factory.test.ts
13
+ PASS src/bridges/cctp/handlers/get-fees.test.ts
14
+ PASS src/bridges/cctp/utils/config.test.ts
15
+ PASS src/utils/ensure-config.test.ts
16
+ PASS src/utils/caip2.test.ts
17
+ PASS src/bridges/cctp/handlers/get-assets.test.ts
18
+ PASS src/utils/network-fee.test.ts
19
+ PASS src/utils/wait.test.ts
20
+
21
+ Test Suites: 15 passed, 15 total
22
+ Tests: 82 passed, 82 total
23
+ Snapshots: 0 total
24
+ Time: 18.859 s
25
+ Ran all test suites.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @avalabs/unified-bridge
2
2
 
3
+ ## 2.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 672c0e8: fix: lowercase addresses for comparison
8
+
9
+ ## 2.0.0
10
+
11
+ ### Major Changes
12
+
13
+ - 7df7ca0: CCTP integration
14
+
15
+ ### Minor Changes
16
+
17
+ - 7df7ca0: use caip2 chain ids
18
+ - 54757d4: Make sourceProvider optional, add bridged asset denomination info
19
+ - b8f102b: update and validate startBlockNumber while tracking
20
+
3
21
  ## 1.0.1
4
22
 
5
23
  ### Patch Changes
package/README.md CHANGED
@@ -1,92 +1,158 @@
1
- <br/>
2
-
3
1
  <p align="center">
4
2
  <a href="https://subnets.avax.network/">
5
3
  <picture>
6
4
  <img alt="Avalanche Logo" src="https://images.ctfassets.net/gcj8jwzm6086/Gse8dqDEnJtT87RsbbEf4/1609daeb09e9db4a6617d44623028356/Avalanche_Horizontal_White.svg" width="auto" height="60">
7
5
  </picture>
8
- </a>
6
+ </a>
9
7
  </p>
10
8
 
11
9
  <p align="center">
12
- Parse arbitrary VM data for display in the Avalanche Subnet Explorer.
10
+ A package for routing tokens from Chain A to Chain B, and unifying multiple bridge tools into one.
13
11
  <p>
14
12
 
15
- <br>
13
+ ## What is this?
14
+
15
+ The bridging ecosystem is complex. There are often multiple tools that can be used to bridge tokens from one chain to another, and sometimes to get a token from chain A to C you need to use multiple bridging tools and route through chain B first. This package simplifies that process by creating the _Unified Bridge API_, a standard interface for bridging tokens from one chain to another without having to worry about the underlying tools or the underlying intermediary chains.
16
+
17
+ These are the bridges we currently support:
18
+
19
+ - **CCTP** - preferred for brdiging USDC between Ethereum and Avalanche C-Chain. See the `bridges/cctp` folder.
16
20
 
17
- ## Supported VMs
21
+ Future bridges we plan to support:
18
22
 
19
- - MoveVM
23
+ - **Avalanche Bridge** - is capable of transferring a fixed list of tokens between Ethereum and Avalanche C-Chain.
24
+ - **Teleporter** - for moving tokens between subnets.
25
+ - **Cross-Chain Transfer** - for moving tokens between the three Avalanche Primary Network chains (X-Chain, C-Chain, and P-Chain).
20
26
 
21
27
  ## Getting Started
22
28
 
23
29
  ```sh
24
- npm install @avalabs/vm-parser
30
+ npm install @avalabs/bridge-unified
25
31
  # or
26
- yarn add @avalabs/vm-parser
32
+ yarn add @avalabs/bridge-unified
27
33
  # or
28
- pnpm add @avalabs/vm-parser
34
+ pnpm add @avalabs/bridge-unified
29
35
  ```
30
36
 
31
- ## Overview
32
-
33
- ```tsx
34
- // 1. Import modules.
35
- import { createMoveVmConfig, DataDisplayFormat } from '@avalabs/vm-parser';
36
- import {
37
- Card,
38
- CardTitle,
39
- CardContent,
40
- Chip,
41
- TableContainer,
42
- Table,
43
- TableBody,
44
- TableRow,
45
- TableCell,
46
- } from 'some-ui-library';
47
- import useSWR from 'swr'; // Or your preferred data fetching library
48
-
49
- const MOVE_RPC_URL =
50
- 'https://seed-node1-rpc.movementlabs.xyz/ext/bc/2gLyawqthdiyrJktJmdnDAb1XVc6xwJXU6iJKu3Uwj21F2mXAK/rpc';
51
- // 2. Set up your config
52
- const moveVmConfig = createMoveVmConfig(MOVE_RPC_URL);
53
-
54
- const TransactionDetails = ({ txId }: { txId: string }) => {
55
- // 2. Get the data from the config's `getPageData` function
56
- const { data } = useSWR(txId, moveVmConfig.transactionDetails.getPageData);
57
-
58
- // 3. Display the data dynamically based on the config's displayFormat.
59
- return (
60
- <>
61
- {moveVmConfig.displayFormat.map(({ sectionTitle, fields }) => (
62
- <Card>
63
- <CardTitle>{sectionTitle}</CardTitle>
64
- <CardContent>
65
- <TableContainer>
66
- <Table>
67
- <TableBody>
68
- {fields.map(({ name, displayValue, displayFormat }) => (
69
- <TableRow>
70
- <TableCell>{field.name}</TableCell>
71
- <TableCell>
72
- /* Display the field differently depending on its display formatter */
73
- {field.displayFormat === DataDisplayFormat.CHIP ? (
74
- <Chip>{field.displayValue}</Chip>
75
- ) : field.displayFormat === DataDisplayFormat.DATETIME ? (
76
- new Date(field.displayValue).toLocaleString()
77
- ) : (
78
- fields.displayValue
79
- )}
80
- </TableCell>
81
- </TableRow>
82
- ))}
83
- </TableBody>
84
- </Table>
85
- </TableContainer>
86
- </CardContent>
87
- </Card>
88
- ))}
89
- </>
90
- );
91
- };
37
+ ## Usage
38
+
39
+ ```js
40
+ import { createUnifiedBridgeService, Environment, BridgeTransfer } from '@avalabs/bridge-unified';
41
+
42
+ // create a new service for an environment
43
+ const unifiedService = createUnifiedBridgeService({
44
+ environment: Environment.TEST,
45
+ });
46
+
47
+ // init the service, fetch and setup its configs
48
+ await unifiedService.init();
49
+
50
+ // get the list of supported assets, grouped by caip2 (https://chainagnostic.org/CAIPs/caip-2) chain IDs
51
+ const assets = await unifiedService.getAssets()
52
+
53
+ // get the bridge fee(s) of the provided transfer
54
+ const fees = await unifiedService.getFees({...})
55
+
56
+ // start a new bridge transfer and store its state
57
+ const bridgeTransfer = await unifiedService.transferAsset({...})
58
+
59
+ // create an update listener for tracking
60
+ const updateListener = (transfer: BridgeTransfer) => {
61
+ console.log(transfer)
62
+ }
63
+
64
+ // start tracking the transfer's state. whenever the state changes, it will call the provided `updateListener`
65
+ const { cancel, result } = await unifiedService.trackTransfer({bridgeTransfer, updateListener, ...})
66
+
67
+ // immediatelly stops tracking and rejects the tracker's promise
68
+ // cancel()
69
+
70
+ // wait for the transfer to finish and get its final state
71
+ const finalizedBridgeTransfer = await result
92
72
  ```
73
+
74
+ ## API
75
+
76
+ ### createUnifiedBridgeService({ environment, disabledBridgeTypes? })
77
+
78
+ Returns a new `unifiedBridgeService` for the given `environment`, using all supported bridge integrations by default. Individual bridges can be turned off via the `disabledBridgeTypes` array.
79
+
80
+ #### environment
81
+
82
+ Type: `Environment`
83
+
84
+ Defines if the bridge service should use `testnet` or `mainnet`.
85
+
86
+ #### disabledBridgeTypes
87
+
88
+ Type: `BridgeType[] | undefined`
89
+
90
+ Disables the integration of the provided `BridgeType`s.
91
+
92
+ ### unifiedBridgeService
93
+
94
+ Contains all the required properties and methods to prepare, initiate or track a bridge transfer.
95
+ Automatically picks the right (enabled) bridge integration to use based on the provided params.
96
+
97
+ ```js
98
+ {
99
+ environment, // the provided Environment during initialization
100
+ bridges, // the list of enabled bridge integrations
101
+ init,
102
+ updateConfigs,
103
+ getAssets,
104
+ getFees,
105
+ transferAsset,
106
+ trackTransfer,
107
+ }
108
+ ```
109
+
110
+ #### init
111
+
112
+ Type: `() => Promise<void>`
113
+
114
+ Initializes the unified service by attempting to fetch the configurations of the enabled bridges.
115
+
116
+ #### updateConfigs
117
+
118
+ Type: `() => Promise<void>`
119
+
120
+ Attempts to fetch the configurations of the enabled bridges.
121
+
122
+ #### getAssets
123
+
124
+ Type: `() => Promise<ChainAssetMap>`
125
+
126
+ Returns the aggregated list of assets supported by the enabled bridges grouped by [caip2](https://chainagnostic.org/CAIPs/caip-2) chain IDs.
127
+
128
+ #### getFees
129
+
130
+ Type: `(params: FeeParams) => Promise<AssetFeeMap>`
131
+
132
+ Calculates and returns the bridge fees in `tokenAddress` - `amount` pairs for a given bridge transfer.
133
+
134
+ #### transferAsset
135
+
136
+ Type: `(params: TransferParams) => Promise<BridgeTransfer>`
137
+
138
+ Starts a new bridge transfer, executing every required step in a single call.
139
+ Transactions signing is done by either the provided `sourceProvider` or a custom `sign` callback. Clients using their custom `sign` implementation may use their own solution or the default `dispatch` callback to submit the transaction to the network.
140
+ Returns a `BridgeTransfer` containing all the (known) initial values such as: environment, addresses, amount, fee, transaction hash, required and actual block confirmation counts, etc.
141
+
142
+ #### trackTransfer
143
+
144
+ Type: `(params: TrackingParams) => ({cancel, result})`
145
+
146
+ Tracks the given `BridgeTransfer`'s progress and invokes the provided listener callback whenever a change happens.
147
+
148
+ ###### cancel
149
+
150
+ Type: `() => void`
151
+
152
+ If it's still pending, rejects the tracker's promise (`result`) immediatelly and breaks its loop under the hood.
153
+
154
+ ###### result
155
+
156
+ Type: `Promise<BridgeTransfer>`
157
+
158
+ Resolves with the finalized `BridgeTransfer` (if not canceled before).
package/dist/index.cjs CHANGED
@@ -1,9 +1,17 @@
1
1
  'use strict';
2
2
 
3
- require('viem');
3
+ var viem = require('viem');
4
+ var lodash = require('lodash');
4
5
 
5
- var t=class extends Error{constructor(a,m){super(a);this.code=m;this.code=m;}},e=class extends t{constructor(o="Not implemented"){super(o,5001),this.name="NotImplementedError";}};var n=async r=>{throw new e};var i=r=>{throw new e};var s=()=>{};var v=r=>({getBridgeRouter:i,submitBridgeTransactionStep:n,submitAndWatchBridgeTransaction:s});
6
+ var H=(r=>(r.NATIVE="native",r.ERC20="erc20",r))(H||{});var E=(t=>(t.CCTP="cctp",t))(E||{}),V=(r=>(r.AllowanceApproval="allowance-approval",r.TokensTransfer="tokens-transfer",r))(V||{});var K=(r=>(r.PROD="production",r.TEST="test",r))(K||{});var R=(n=>(n[n.BRIDGE_NOT_AVAILABLE=5001]="BRIDGE_NOT_AVAILABLE",n[n.INITIALIZATION_FAILED=5002]="INITIALIZATION_FAILED",n[n.INVALID_PARAMS=5003]="INVALID_PARAMS",n[n.TIMEOUT=5004]="TIMEOUT",n[n.TRANSACTION_REVERTED=5005]="TRANSACTION_REVERTED",n))(R||{}),v=(i=>(i.UNKNOWN="UNKNOWN",i.CONFIG_NOT_AVAILABLE="CONFIG_NOT_AVAILABLE",i.INVALID_PARAMS="INVALID_PARAMS",i.IDENTICAL_CHAINS_PROVIDED="IDENTICAL_CHAINS_PROVIDED",i.INCORRECT_AMOUNT_PROVIDED="INCORRECT_AMOUNT_PROVIDED",i.INCORRECT_ADDRESS_PROVIDED="INCORRECT_ADDRESS_PROVIDED",i.CHAIN_NOT_SUPPORTED="CHAIN_NOT_SUPPORTED",i.ASSET_NOT_SUPPORTED="ASSET_NOT_SUPPORTED",i.CONFIRMATION_COUNT_UNKNOWN="CONFIRMATION_COUNT_UNKNOWN",i))(v||{});var N=class extends Error{constructor(r,a,p){super(r);this.code=a;this.details=p;}};var P=class extends N{constructor(t="UNKNOWN",r){super(t,5001,r),this.name="BridgeUnavailableError";}};var B=class extends N{constructor(t="UNKNOWN",r){super(t,5002,r),this.name="BridgeInitializationError";}};var T=class extends N{constructor(t="INVALID_PARAMS",r){super(t,5003,r),this.name="InvalidParamsError";}};var ae={test:"https://raw.githubusercontent.com/ava-labs/avalanche-bridge-resources/main/cctp/cctp_config.test.json",production:"https://raw.githubusercontent.com/ava-labs/avalanche-bridge-resources/main/cctp/cctp_config.json"},q=async e=>{try{return (await(await fetch(ae[e])).json()).map(a=>({...a,chainId:`eip155:${a.chainId}`}))}catch(t){throw new B("CONFIG_NOT_AVAILABLE",`Error while fetching CCTP config: ${t.message}`)}},M=e=>{switch(e){case"eip155:43114":case"eip155:43113":return 1e3;default:return 2e4}};async function $(e){await e.ensureHasConfig();let t=e.config.map(r=>r.chainId);return e.config.reduce((r,a)=>(r[a.chainId]=a.tokens.map(p=>({...p,type:"erc20",destinations:t.reduce((n,o)=>(a.chainId!==o&&(n[o]||(n[o]=[]),n[o]?.push("cctp")),n),{})})),r),{})}var se="^[-a-z0-9]{3,8}$",ie="^[-_a-zA-Z0-9]{1,50}$",G=":",oe=e=>{let[t,r]=e.split(G);if(!t||!r)throw new Error("Invalid identifier provided.");if(!new RegExp(se).test(t))throw new Error("Invalid namespace provided.");if(!new RegExp(ie).test(r))throw new Error("Invalid reference provided.");return {namespace:t,reference:r}},pe=({namespace:e,reference:t})=>`${e}${G}${t}`,S={toJSON:oe,toString:pe};var le=e=>{let{reference:t}=S.toJSON(e.chainId);return {id:Number(t),name:e.chainName,nativeCurrency:{decimals:e.networkToken.decimals,symbol:e.networkToken.symbol,name:e.networkToken.name},network:e.chainName,rpcUrls:{default:{http:[e.rpcUrl]},public:{http:[e.rpcUrl]}},...e.utilityAddresses?.multicall&&{contracts:{multicall3:{address:e.utilityAddresses.multicall}}}}},I=({chain:e,provider:t})=>{let r=le(e),a=t?viem.custom(t):viem.http(e.rpcUrl,{batch:!0,retryCount:0});return viem.createWalletClient({chain:r,transport:a}).extend(viem.publicActions)};var x=[{inputs:[{internalType:"address",name:"circleTokenMessenger_",type:"address"},{internalType:"address",name:"burnToken_",type:"address"}],stateMutability:"nonpayable",type:"constructor"},{inputs:[],name:"AlreadyAdmin",type:"error"},{inputs:[],name:"AlreadyFeeCollector",type:"error"},{inputs:[],name:"AlreadySupportedBurnToken",type:"error"},{inputs:[],name:"AmountLessThanFee",type:"error"},{inputs:[],name:"BalanceNotIncreased",type:"error"},{inputs:[],name:"CannotRemoveLastAdmin",type:"error"},{inputs:[],name:"FeePercentageGreaterThanMax",type:"error"},{inputs:[],name:"InvalidAdminAddress",type:"error"},{inputs:[],name:"InvalidFeeCollector",type:"error"},{inputs:[],name:"InvalidMintRecipientAddress",type:"error"},{inputs:[],name:"InvalidTokenAddress",type:"error"},{inputs:[],name:"InvalidTokenMessengerAddress",type:"error"},{inputs:[],name:"MaxFeeLessThanMinFee",type:"error"},{inputs:[],name:"NotAdmin",type:"error"},{inputs:[],name:"NotFeeCollector",type:"error"},{inputs:[],name:"UnSupportedBurnToken",type:"error"},{inputs:[],name:"UnsupportedDomain",type:"error"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"admin",type:"address"}],name:"AdminAdded",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"admin",type:"address"}],name:"AdminRemoved",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"token",type:"address"}],name:"BurnTokenAdded",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"token",type:"address"}],name:"BurnTokenRemoved",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"feeCollector",type:"address"}],name:"FeeCollectorAdded",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"feeCollector",type:"address"}],name:"FeeCollectorRemoved",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"uint32",name:"domain",type:"uint32"},{components:[{internalType:"uint256",name:"maxFee",type:"uint256"},{internalType:"uint256",name:"minFee",type:"uint256"},{internalType:"uint32",name:"feePercentage",type:"uint32"},{internalType:"uint256",name:"txnFee",type:"uint256"},{internalType:"bool",name:"supported",type:"bool"}],indexed:!1,internalType:"struct FeeCalculator.FeeConfiguration",name:"feeConfiguration",type:"tuple"}],name:"FeeConfigurationUpdated",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"previousOwner",type:"address"},{indexed:!0,internalType:"address",name:"newOwner",type:"address"}],name:"OwnershipTransferred",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"account",type:"address"}],name:"Paused",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"uint64",name:"nonce",type:"uint64"},{indexed:!1,internalType:"address",name:"burnToken",type:"address"},{indexed:!1,internalType:"uint256",name:"amount",type:"uint256"},{indexed:!1,internalType:"address",name:"depositor",type:"address"},{indexed:!1,internalType:"address",name:"mintRecipient",type:"address"},{indexed:!1,internalType:"uint32",name:"destinationDomain",type:"uint32"},{indexed:!1,internalType:"uint256",name:"totalFee",type:"uint256"}],name:"TransferTokens",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"address",name:"account",type:"address"}],name:"Unpaused",type:"event"},{inputs:[{internalType:"address",name:"account",type:"address"}],name:"addAdmin",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"feeCollector",type:"address"}],name:"addFeeCollector",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"token",type:"address"}],name:"addSupportedBurnToken",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"uint256",name:"amount",type:"uint256"},{internalType:"uint32",name:"destinationDomain",type:"uint32"}],name:"calculateFee",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[],name:"circleTokenMessenger",outputs:[{internalType:"contract ICircleTokenMessenger",name:"",type:"address"}],stateMutability:"view",type:"function"},{inputs:[],name:"circleTokenMessengerAddress",outputs:[{internalType:"address",name:"",type:"address"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"token",type:"address"}],name:"collectFees",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"token",type:"address"}],name:"getFeeAmounts",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"}],name:"getFeeConfiguration",outputs:[{components:[{internalType:"uint256",name:"maxFee",type:"uint256"},{internalType:"uint256",name:"minFee",type:"uint256"},{internalType:"uint32",name:"feePercentage",type:"uint32"},{internalType:"uint256",name:"txnFee",type:"uint256"},{internalType:"bool",name:"supported",type:"bool"}],internalType:"struct FeeCalculator.FeeConfiguration",name:"",type:"tuple"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"}],name:"getFeePercentage",outputs:[{internalType:"uint32",name:"",type:"uint32"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"}],name:"getMaxFee",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"}],name:"getMinFee",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"}],name:"getTxnFee",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"account",type:"address"}],name:"isAdmin",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"account",type:"address"}],name:"isFeeCollector",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"token",type:"address"}],name:"isSupportedBurnToken",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"}],name:"isSupportedDomain",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[],name:"owner",outputs:[{internalType:"address",name:"",type:"address"}],stateMutability:"view",type:"function"},{inputs:[],name:"pause",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[],name:"paused",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"account",type:"address"}],name:"removeAdmin",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"feeCollector",type:"address"}],name:"removeFeeCollector",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"token",type:"address"}],name:"removeSupportedBurnToken",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[],name:"renounceOwnership",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"uint32",name:"domain",type:"uint32"},{components:[{internalType:"uint256",name:"maxFee",type:"uint256"},{internalType:"uint256",name:"minFee",type:"uint256"},{internalType:"uint32",name:"feePercentage",type:"uint32"},{internalType:"uint256",name:"txnFee",type:"uint256"},{internalType:"bool",name:"supported",type:"bool"}],internalType:"struct FeeCalculator.FeeConfiguration",name:"feeConfiguration",type:"tuple"}],name:"setFeeConfiguration",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"",type:"address"}],name:"supportedBurnTokens",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"newOwner",type:"address"}],name:"transferOwnership",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"uint256",name:"amount",type:"uint256"},{internalType:"uint32",name:"destinationDomain",type:"uint32"},{internalType:"address",name:"mintRecipient",type:"address"},{internalType:"address",name:"burnToken",type:"address"}],name:"transferTokens",outputs:[{internalType:"uint64",name:"nonce",type:"uint64"}],stateMutability:"nonpayable",type:"function"},{inputs:[],name:"unpause",outputs:[],stateMutability:"nonpayable",type:"function"}];var _=({sourceChain:e,targetChain:t,amount:r,asset:a},p)=>{if(e.chainId===t.chainId)throw new T("IDENTICAL_CHAINS_PROVIDED");if(r<=0n)throw new T("INCORRECT_AMOUNT_PROVIDED","Amount must be greater than zero");let n=p.find(i=>i.chainId===e.chainId);if(!n)throw new T("CHAIN_NOT_SUPPORTED",`Not supported on source chain "${e.chainId}"`);let o=p.find(i=>i.chainId===t.chainId);if(!o)throw new T("CHAIN_NOT_SUPPORTED",`Not supported on target chain "${t.chainId}"`);let d=n.tokens.find(i=>i.symbol===a.symbol),y=o.tokens.find(i=>i.symbol===a.symbol);if(!d||!y)throw new T("ASSET_NOT_SUPPORTED");return {sourceChainData:n,targetChainData:o,burnToken:d,mintToken:y}};async function W(e,t){await e.ensureHasConfig();let{sourceChain:r,targetChain:a,asset:p,amount:n,provider:o}=t,{sourceChainData:d,targetChainData:y,burnToken:i}=_({sourceChain:r,targetChain:a,asset:p,amount:n},e.config),u=await I({chain:r,provider:o}).readContract({address:d.tokenRouterAddress,abi:x,functionName:"calculateFee",args:[n,y.domain]});return {[i.address]:u}}var D=[{constant:!0,inputs:[],name:"name",outputs:[{name:"",type:"string"}],payable:!1,stateMutability:"view",type:"function"},{constant:!1,inputs:[{name:"_spender",type:"address"},{name:"_value",type:"uint256"}],name:"approve",outputs:[{name:"",type:"bool"}],payable:!1,stateMutability:"nonpayable",type:"function"},{constant:!0,inputs:[],name:"totalSupply",outputs:[{name:"",type:"uint256"}],payable:!1,stateMutability:"view",type:"function"},{constant:!1,inputs:[{name:"_from",type:"address"},{name:"_to",type:"address"},{name:"_value",type:"uint256"}],name:"transferFrom",outputs:[{name:"",type:"bool"}],payable:!1,stateMutability:"nonpayable",type:"function"},{constant:!0,inputs:[],name:"decimals",outputs:[{name:"",type:"uint8"}],payable:!1,stateMutability:"view",type:"function"},{constant:!0,inputs:[{name:"_owner",type:"address"}],name:"balanceOf",outputs:[{name:"balance",type:"uint256"}],payable:!1,stateMutability:"view",type:"function"},{constant:!0,inputs:[],name:"symbol",outputs:[{name:"",type:"string"}],payable:!1,stateMutability:"view",type:"function"},{constant:!1,inputs:[{name:"_to",type:"address"},{name:"_value",type:"uint256"}],name:"transfer",outputs:[{name:"",type:"bool"}],payable:!1,stateMutability:"nonpayable",type:"function"},{constant:!0,inputs:[{name:"_owner",type:"address"},{name:"_spender",type:"address"}],name:"allowance",outputs:[{name:"",type:"uint256"}],payable:!1,stateMutability:"view",type:"function"},{payable:!0,stateMutability:"payable",type:"fallback"},{anonymous:!1,inputs:[{indexed:!0,name:"owner",type:"address"},{indexed:!0,name:"spender",type:"address"},{indexed:!1,name:"value",type:"uint256"}],name:"Approval",type:"event"},{anonymous:!1,inputs:[{indexed:!0,name:"from",type:"address"},{indexed:!0,name:"to",type:"address"},{indexed:!1,name:"value",type:"uint256"}],name:"Transfer",type:"event"}];var ye=async(e,t)=>{let{sourceChain:r,targetChain:a,asset:p,amount:n,fromAddress:o,toAddress:d,sourceProvider:y,onStepChange:i,sign:s}=t,u=d??o;if(!viem.isAddress(o)||!viem.isAddress(u))throw new T("INCORRECT_ADDRESS_PROVIDED");let{sourceChainData:c,targetChainData:f,burnToken:l}=_({sourceChain:r,targetChain:a,asset:p,amount:n},e.config),m=I({chain:r,provider:y}),b=await m.readContract({address:l.address,abi:D,functionName:"allowance",args:[o,c.tokenRouterAddress]})<n,h=b?2:1;if(b)if(i?.({currentSignature:1,currentSignatureReason:"allowance-approval",requiredSignatures:h}),s){let g=viem.encodeFunctionData({abi:D,functionName:"approve",args:[c.tokenRouterAddress,n]}),A=await s({from:o,to:l.address,data:g},k=>m.sendRawTransaction({serializedTransaction:k}));await m.waitForTransactionReceipt({hash:A,pollingInterval:1e3});}else {let{request:g}=await m.simulateContract({account:o,address:l.address,abi:D,functionName:"approve",args:[c.tokenRouterAddress,n]}),A=await m.writeContract(g);await m.waitForTransactionReceipt({hash:A,pollingInterval:1e3});}if(i?.({currentSignature:b?2:1,currentSignatureReason:"tokens-transfer",requiredSignatures:h}),s){let g=viem.encodeFunctionData({abi:x,functionName:"transferTokens",args:[n,f.domain,u,l.address]});return s({from:o,to:c.tokenRouterAddress,data:g},A=>m.sendRawTransaction({serializedTransaction:A}))}else {let{request:g}=await m.simulateContract({account:o,address:c.tokenRouterAddress,abi:x,functionName:"transferTokens",args:[n,f.domain,u,l.address]});return m.writeContract(g)}},fe=async e=>{try{return await e.getBlockNumber()}catch{return}};async function J(e,t,r){await e.ensureHasConfig();let{minimumConfirmations:a}=e.config.find(u=>u.chainId===t.sourceChain.chainId)??{},{minimumConfirmations:p}=e.config.find(u=>u.chainId===t.targetChain.chainId)??{};if(!a||!p)throw new T("CONFIRMATION_COUNT_UNKNOWN");let n=await e.getFees({...t,provider:t.sourceProvider}),o=(t.asset.address&&n[t.asset.address])??0n,d=await ye(e,t),y=Date.now(),i=I({chain:t.targetChain,provider:t.targetProvider}),s=await fe(i);return {type:e.type,environment:r,fromAddress:t.fromAddress,toAddress:t.toAddress??t.fromAddress,amount:t.amount,amountDecimals:t.asset.decimals,symbol:t.asset.symbol,bridgeFee:o,sourceChain:t.sourceChain,sourceStartedAt:y,sourceTxHash:d,sourceConfirmationCount:0,requiredSourceConfirmationCount:a,targetChain:t.targetChain,targetConfirmationCount:0,requiredTargetConfirmationCount:p,startBlockNumber:s}}async function Z(e){if(!e.config&&(await e.updateConfig(),!e.config))throw new B("CONFIG_NOT_AVAILABLE")}var O=(e,t)=>e.gasPrice&&BigInt(e.gasPrice*t.gasUsed);var L=async e=>new Promise(t=>{setTimeout(t,e);});var U=({promise:e,delay:t,startAfter:r})=>{let a=!1,p=!1,n=0,o,d,y=u=>{o&&a&&(a=!1,o(u));},i=()=>{p=!0,d&&a&&(a=!1,d("cancelled"));};return {result:new Promise((u,c)=>{a=!0,o=u,d=c;let f=async()=>{if(!(!a||p)){try{if(await e(y),!a||p)return;await L(t);}catch(l){console.error(l.message),n+=1,await L(2**n*t);}await f();}};r?setTimeout(f,r):f();}),cancel:i}};var Q=1e3*60*60*3,Y=1024n,ee=5e3,C=(e,t,r)=>{Object.assign(e,Object.fromEntries(Object.entries(t).filter(([,a])=>a!==void 0))),r({...e});},Te=async(e,t)=>{let{sourceProvider:r,targetProvider:a,updateListener:p,bridgeTransfer:n}=t,o=I({chain:n.sourceChain,provider:r}),d=e.find(c=>c.chainId===n.sourceChain.chainId),y=I({chain:n.targetChain,provider:a}),i=e.find(c=>c.chainId===n.targetChain.chainId),s={...n};if(!d||!i)throw new T("CHAIN_NOT_SUPPORTED");return U({promise:async c=>{if(s.completedAt||s.metadata?.nonce)return c(s);if(s.sourceStartedAt+Q<=Date.now())return C(s,{completedAt:Date.now(),errorCode:5004},p),c(s);let f=await o.getTransactionReceipt({hash:s.sourceTxHash});if(!s.sourceNetworkFee){let A=await o.getTransaction({hash:s.sourceTxHash}),k=O(A,f);k&&C(s,{sourceNetworkFee:k},p);}if(f.status==="reverted")return C(s,{completedAt:Date.now(),errorCode:5005},p),c(s);let l=await o.getTransactionConfirmations({hash:s.sourceTxHash}),m=l>s.sourceConfirmationCount,w=l>=s.requiredSourceConfirmationCount;if(m){let A={};A.sourceConfirmationCount=Number(l),w||(A.startBlockNumber=await y.getBlockNumber()),C(s,A,p);}if(!w)return;s.startBlockNumber||C(s,{startBlockNumber:await y.getBlockNumber()},p);let b=f.logs.find(A=>A.address.toLowerCase()===d.tokenRouterAddress.toLowerCase()?viem.decodeEventLog({abi:x,...A}).eventName==="TransferTokens":!1);if(!b)throw new T("INVALID_PARAMS",`unable to find a TransferTokens event in source transaction "${s.sourceTxHash}"`);let g=viem.decodeEventLog({abi:x,eventName:"TransferTokens",...b}).args.nonce;return C(s,{targetStartedAt:Date.now(),metadata:{nonce:g}},p),c(s)},delay:M(d.chainId),startAfter:ee})},ge=async(e,t)=>{let{targetProvider:r,updateListener:a,bridgeTransfer:p}=t,n={...p};if(!p.completedAt&&!p.metadata?.nonce)throw new T("INVALID_PARAMS","nonce is missing");if(!p.startBlockNumber)throw new T("INVALID_PARAMS","startBlockNumber is missing");let o=I({chain:p.targetChain,provider:r}),d=e.find(i=>i.chainId===p.targetChain.chainId);if(!d)throw new T("INVALID_PARAMS",`unknown target chain "${p.targetChain.chainId}"`);return U({promise:async i=>{if(n.completedAt)return i(n);if(!n.startBlockNumber)return C(n,{completedAt:Date.now(),errorCode:5003},a),i(n);if(n.sourceStartedAt+Q<=Date.now())return C(n,{completedAt:Date.now(),errorCode:5004},a),i(n);if(!n.targetTxHash){let l=await o.getBlockNumber(),m=n.startBlockNumber-Y,w=m>=0n?m:"earliest",b=n.startBlockNumber+Y,h=b<l?b:"latest",g=await o.getLogs({address:d.messageTransmitterAddress,event:{name:"MessageReceived",type:"event",inputs:[{indexed:!0,internalType:"address",name:"caller",type:"address"},{indexed:!1,internalType:"uint32",name:"sourceDomain",type:"uint32"},{indexed:!0,internalType:"uint64",name:"nonce",type:"uint64"},{indexed:!1,internalType:"bytes32",name:"sender",type:"bytes32"},{indexed:!1,internalType:"bytes",name:"messageBody",type:"bytes"}]},args:{nonce:n.metadata.nonce},fromBlock:w,toBlock:h});if(g[0]?.transactionHash)C(n,{targetTxHash:g[0].transactionHash},a);else {C(n,{startBlockNumber:l},a);return}}let s=await o.getTransactionReceipt({hash:n.targetTxHash});if(!n.targetNetworkFee){let l=await o.getTransaction({hash:n.targetTxHash}),m=O(l,s);m&&C(n,{targetNetworkFee:m},a);}if(s.status==="reverted")return C(n,{completedAt:Date.now(),errorCode:5005},a),i(n);let u=await o.getTransactionConfirmations({hash:n.targetTxHash}),c=u>n.targetConfirmationCount,f=u>=n.requiredTargetConfirmationCount;if(c&&C(n,{targetConfirmationCount:Number(u)},a),!!f)return C(n,{completedAt:Date.now()},a),i(n)},delay:M(d.chainId),startAfter:ee})};function te(e,t){let r,a=()=>{r?.();};return {result:(async()=>{await e.ensureHasConfig();let{sourceProvider:n,targetProvider:o,updateListener:d,bridgeTransfer:y}=t,{result:i,cancel:s}=await Te(e.config,{sourceProvider:n,targetProvider:o,updateListener:d,bridgeTransfer:y});r=s;let u=await i,{result:c,cancel:f}=await ge(e.config,{sourceProvider:n,targetProvider:o,updateListener:d,bridgeTransfer:u});return r=f,c})(),cancel:a}}var ne=e=>({type:"cctp",config:null,updateConfig:async function(){this.config=await q(e);},ensureHasConfig:async function(){return Z(this)},getAssets:async function(){return $(this)},getFees:async function(t){return W(this,t)},transferAsset:async function(t){return J(this,t,e)},trackTransfer:function(t){return te(this,t)}});var Ae=new Map([["cctp",ne]]),re=(e,t)=>new Map([...Ae].filter(([r])=>!t?.includes(r)).map(([r,a])=>[r,a(e)])),F=(e,t,r)=>{let a=t.destinations[r]?.find(p=>e.has(p));if(!a)throw new P;return {type:a,bridge:e.get(a)}};var dn=({environment:e,disabledBridgeTypes:t})=>{let r=re(e,t),a=async()=>{await Promise.allSettled(Array.from(r).map(([,s])=>s.updateConfig()));};return {environment:e,bridges:r,init:async()=>{await a();},updateConfigs:a,getAssets:async()=>(await Promise.all(Array.from(r).map(([,u])=>u.getAssets()))).reduce((u,c)=>{for(let[f,l]of Object.entries(c)){let m=u[f];if(m)for(let w of l){let b=m.findIndex(({symbol:h})=>h===w.symbol);b===-1?m.push(w):lodash.mergeWith(m[b],w,(h,g)=>{if(lodash.isArray(h))return [...new Set(h.concat(g))]});}else u[f]=l;}return u},{}),getFees:async s=>{let{bridge:u}=F(r,s.asset,s.targetChain.chainId);return u.getFees(s)},canTransferAsset:(s,u)=>{try{return F(r,s,u),!0}catch{return !1}},transferAsset:async s=>{let{bridge:u}=F(r,s.asset,s.targetChain.chainId);return u.transferAsset(s)},trackTransfer:s=>{let u=r.get(s.bridgeTransfer.type);if(!u)throw new P;return u.trackTransfer(s)}}};
6
7
 
7
- exports.createBridgeService = v;
8
+ exports.BridgeSignatureReason = V;
9
+ exports.BridgeType = E;
10
+ exports.Environment = K;
11
+ exports.ErrorCode = R;
12
+ exports.ErrorReason = v;
13
+ exports.TokenType = H;
14
+ exports.caip2 = S;
15
+ exports.createUnifiedBridgeService = dn;
8
16
  //# sourceMappingURL=out.js.map
9
17
  //# sourceMappingURL=index.cjs.map