@circle-fin/provider-cctp-v2 0.0.2-alpha.7 → 1.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.
- package/README.md +28 -124
- package/index.cjs.js +120 -91
- package/index.d.ts +47 -65
- package/index.mjs +120 -91
- package/package.json +20 -6
package/README.md
CHANGED
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
[](https://badge.fury.io/js/@circle-fin%2Fprovider-cctp-v2)
|
|
6
6
|
[](https://www.typescriptlang.org/)
|
|
7
7
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
8
|
+
[](https://discord.com/invite/buildoncircle)
|
|
8
9
|
|
|
9
|
-
**Circle's Cross-Chain Transfer Protocol v2 provider for
|
|
10
|
+
**Circle's Cross-Chain Transfer Protocol v2 provider for Bridge Kit**
|
|
10
11
|
|
|
11
12
|
_Native USDC bridging across 34 chains using Circle's battle-tested protocols._
|
|
12
13
|
|
|
@@ -20,19 +21,19 @@ _Native USDC bridging across 34 chains using Circle's battle-tested protocols._
|
|
|
20
21
|
- [Why CCTPv2 Provider?](#why-cctpv2-provider)
|
|
21
22
|
- [Installation](#installation)
|
|
22
23
|
- [Quick Start](#quick-start)
|
|
23
|
-
- [Option 1: With
|
|
24
|
+
- [Option 1: With Bridge Kit (Recommended)](#option-1-with-bridge-kit-recommended)
|
|
24
25
|
- [Option 2: Direct Provider Usage](#option-2-direct-provider-usage)
|
|
25
26
|
- [Features](#features)
|
|
26
27
|
- [Supported Chains \& Routes](#supported-chains--routes)
|
|
27
|
-
- [Mainnet Chains
|
|
28
|
-
- [Testnet Chains
|
|
28
|
+
- [Mainnet Chains](#mainnet-chains)
|
|
29
|
+
- [Testnet Chains](#testnet-chains)
|
|
29
30
|
- [Usage Examples](#usage-examples)
|
|
30
31
|
- [Basic Bridge Operation](#basic-bridge-operation)
|
|
31
32
|
- [Route Validation](#route-validation)
|
|
32
33
|
- [Bridge Configurations](#bridge-configurations)
|
|
33
34
|
- [Error Handling](#error-handling)
|
|
34
35
|
- [Bridge Process](#bridge-process)
|
|
35
|
-
- [Integration with
|
|
36
|
+
- [Integration with Bridge Kit](#integration-with-bridge-kit)
|
|
36
37
|
- [API Reference](#api-reference)
|
|
37
38
|
- [Core Methods](#core-methods)
|
|
38
39
|
- [Transfer Parameters](#transfer-parameters)
|
|
@@ -42,9 +43,9 @@ _Native USDC bridging across 34 chains using Circle's battle-tested protocols._
|
|
|
42
43
|
|
|
43
44
|
## Overview
|
|
44
45
|
|
|
45
|
-
The CCTPv2 Bridging Provider is a strongly-typed implementation of Circle's Cross-Chain Transfer Protocol (CCTP) version 2 that enables **native USDC bridging** between
|
|
46
|
+
The CCTPv2 Bridging Provider is a strongly-typed implementation of Circle's Cross-Chain Transfer Protocol (CCTP) version 2 that enables **native USDC bridging** between 34+ supported blockchain networks.
|
|
46
47
|
|
|
47
|
-
While primarily designed to power the [
|
|
48
|
+
While primarily designed to power the [Bridge Kit](https://www.npmjs.com/package/@circle-fin/bridge-kit), this provider can also be used **directly in applications** that need fine-grained control over the CCTP transfer process or want to integrate CCTP without the full Stablecoin Kits framework.
|
|
48
49
|
|
|
49
50
|
### Why CCTPv2 Provider?
|
|
50
51
|
|
|
@@ -62,21 +63,21 @@ npm install @circle-fin/provider-cctp-v2
|
|
|
62
63
|
yarn add @circle-fin/provider-cctp-v2
|
|
63
64
|
```
|
|
64
65
|
|
|
65
|
-
> **Note**: This provider is included by default with the [
|
|
66
|
+
> **Note**: This provider is included by default with the [Bridge Kit](https://www.npmjs.com/package/@circle-fin/bridge-kit). You can import this provider if you need to do a custom CCTP integration.
|
|
66
67
|
|
|
67
68
|
## Quick Start
|
|
68
69
|
|
|
69
|
-
### Option 1: With
|
|
70
|
+
### Option 1: With Bridge Kit (Recommended)
|
|
70
71
|
|
|
71
72
|
```typescript
|
|
72
|
-
import {
|
|
73
|
+
import { BridgeKit } from '@circle-fin/bridge-kit'
|
|
73
74
|
|
|
74
75
|
// Provider included by default
|
|
75
|
-
const kit = new
|
|
76
|
+
const kit = new BridgeKit()
|
|
76
77
|
|
|
77
78
|
const result = await kit.bridge({
|
|
78
|
-
|
|
79
|
-
|
|
79
|
+
from: { adapter: sourceAdapter, chain: 'Ethereum' },
|
|
80
|
+
to: { adapter: destAdapter, chain: 'Base' },
|
|
80
81
|
amount: '100.50',
|
|
81
82
|
})
|
|
82
83
|
```
|
|
@@ -113,16 +114,16 @@ const isSupported = provider.supportsRoute('Ethereum', 'Base', 'USDC')
|
|
|
113
114
|
|
|
114
115
|
// Get bridge estimate
|
|
115
116
|
const estimate = await provider.estimate({
|
|
116
|
-
|
|
117
|
-
|
|
117
|
+
from: { adapter: sourceAdapter, chain: 'Ethereum' },
|
|
118
|
+
to: { adapter: destAdapter, chain: 'Base' },
|
|
118
119
|
amount: '100.50',
|
|
119
120
|
config: { transferSpeed: 'FAST' },
|
|
120
121
|
})
|
|
121
122
|
|
|
122
123
|
// Execute bridge operation with custom logic
|
|
123
124
|
const result = await provider.bridge({
|
|
124
|
-
|
|
125
|
-
|
|
125
|
+
from: { adapter: sourceAdapter, chain: 'Ethereum' },
|
|
126
|
+
to: { adapter: destAdapter, chain: 'Base' },
|
|
126
127
|
amount: '100.50',
|
|
127
128
|
config: { transferSpeed: 'FAST' },
|
|
128
129
|
})
|
|
@@ -141,92 +142,14 @@ const result = await provider.bridge({
|
|
|
141
142
|
|
|
142
143
|
The provider supports **544 total bridge routes** across these chains:
|
|
143
144
|
|
|
144
|
-
### Mainnet Chains
|
|
145
|
+
### Mainnet Chains
|
|
145
146
|
|
|
146
147
|
**Arbitrum**, **Avalanche**, **Base**, **Codex**, **Ethereum**, **HyperEVM**, **Ink**, **Linea**, **OP Mainnet**, **Plume**, **Polygon PoS**, **Sei**, **Solana**, **Sonic**, **Unichain**, **World Chain**, **XDC**
|
|
147
148
|
|
|
148
|
-
### Testnet Chains
|
|
149
|
+
### Testnet Chains
|
|
149
150
|
|
|
150
151
|
**Arbitrum Sepolia**, **Avalanche Fuji**, **Base Sepolia**, **Codex Testnet**, **Ethereum Sepolia**, **HyperEVM Testnet**, **Ink Testnet**, **Linea Sepolia**, **OP Sepolia**, **Plume Testnet**, **Polygon PoS Amoy**, **Sei Testnet**, **Solana Devnet**, **Sonic Testnet**, **Unichain Sepolia**, **World Chain Sepolia**, **XDC Apothem**
|
|
151
152
|
|
|
152
|
-
## Usage Examples
|
|
153
|
-
|
|
154
|
-
### Basic Bridge Operation
|
|
155
|
-
|
|
156
|
-
```typescript
|
|
157
|
-
import { BridgingKit } from '@circle-fin/bridging-kit'
|
|
158
|
-
import { ViemAdapter } from '@circle-fin/adapter-viem-v2'
|
|
159
|
-
import { createPublicClient, createWalletClient, http } from 'viem'
|
|
160
|
-
import { mainnet, base } from 'viem/chains'
|
|
161
|
-
import { privateKeyToAccount } from 'viem/accounts'
|
|
162
|
-
|
|
163
|
-
const account = privateKeyToAccount(process.env.PRIVATE_KEY)
|
|
164
|
-
const kit = new BridgingKit() // CCTPv2 provider included by default
|
|
165
|
-
|
|
166
|
-
const ethereumAdapter = new ViemAdapter({
|
|
167
|
-
publicClient: createPublicClient({ chain: mainnet, transport: http() }),
|
|
168
|
-
walletClient: createWalletClient({
|
|
169
|
-
account,
|
|
170
|
-
chain: mainnet,
|
|
171
|
-
transport: http(),
|
|
172
|
-
}),
|
|
173
|
-
})
|
|
174
|
-
|
|
175
|
-
const baseAdapter = new ViemAdapter({
|
|
176
|
-
publicClient: createPublicClient({ chain: base, transport: http() }),
|
|
177
|
-
walletClient: createWalletClient({ account, chain: base, transport: http() }),
|
|
178
|
-
})
|
|
179
|
-
|
|
180
|
-
const result = await kit.bridge({
|
|
181
|
-
source: { adapter: ethereumAdapter },
|
|
182
|
-
destination: { adapter: baseAdapter },
|
|
183
|
-
amount: '100.50',
|
|
184
|
-
config: { transferSpeed: 'FAST' },
|
|
185
|
-
})
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
### Route Validation
|
|
189
|
-
|
|
190
|
-
```typescript
|
|
191
|
-
import { CCTPV2BridgingProvider } from '@circle-fin/provider-cctp-v2'
|
|
192
|
-
import { BridgingKit } from '@circle-fin/bridging-kit'
|
|
193
|
-
|
|
194
|
-
const provider = new CCTPV2BridgingProvider()
|
|
195
|
-
const kit = new BridgingKit()
|
|
196
|
-
|
|
197
|
-
// Check if a route is supported
|
|
198
|
-
const isSupported = provider.supportsRoute('Ethereum', 'Base', 'USDC')
|
|
199
|
-
console.log('Ethereum → Base:', isSupported ? '✅' : '❌')
|
|
200
|
-
|
|
201
|
-
// Validate before bridging
|
|
202
|
-
const sourceChain = 'Ethereum'
|
|
203
|
-
const destChain = 'Base'
|
|
204
|
-
if (!kit.supportsRoute(sourceChain, destChain, 'USDC')) {
|
|
205
|
-
throw new Error('Route not supported')
|
|
206
|
-
}
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
### Bridge Configurations
|
|
210
|
-
|
|
211
|
-
```typescript
|
|
212
|
-
// Using the same kit and adapters from the examples above
|
|
213
|
-
// Fast bridge (higher fees, faster processing)
|
|
214
|
-
const fastResult = await kit.bridge({
|
|
215
|
-
source: { adapter: ethereumAdapter },
|
|
216
|
-
destination: { adapter: baseAdapter },
|
|
217
|
-
amount: '50.0',
|
|
218
|
-
config: { transferSpeed: 'FAST' },
|
|
219
|
-
})
|
|
220
|
-
|
|
221
|
-
// Slow bridge (lower fees, longer processing)
|
|
222
|
-
const slowResult = await kit.bridge({
|
|
223
|
-
source: { adapter: ethereumAdapter },
|
|
224
|
-
destination: { adapter: baseAdapter },
|
|
225
|
-
amount: '50.0',
|
|
226
|
-
config: { transferSpeed: 'SLOW' },
|
|
227
|
-
})
|
|
228
|
-
```
|
|
229
|
-
|
|
230
153
|
## Error Handling
|
|
231
154
|
|
|
232
155
|
The provider implements thoughtful error handling for different scenarios:
|
|
@@ -234,8 +157,8 @@ The provider implements thoughtful error handling for different scenarios:
|
|
|
234
157
|
```typescript
|
|
235
158
|
// Using the same kit and adapters from the examples above
|
|
236
159
|
const params = {
|
|
237
|
-
|
|
238
|
-
|
|
160
|
+
from: { adapter: sourceAdapter, chain: 'Ethereum' },
|
|
161
|
+
to: { adapter: destAdapter, chain: 'Base' },
|
|
239
162
|
amount: '100.50',
|
|
240
163
|
}
|
|
241
164
|
|
|
@@ -276,12 +199,12 @@ The CCTPv2 provider handles the complete cross-chain bridging flow:
|
|
|
276
199
|
|
|
277
200
|
Each step is tracked and can be monitored through the Provider's event system. Transaction details for each step include explorer URLs for easy verification on block explorers.
|
|
278
201
|
|
|
279
|
-
## Integration with
|
|
202
|
+
## Integration with Bridge Kit
|
|
280
203
|
|
|
281
|
-
This provider is designed specifically for the [
|
|
204
|
+
This provider is designed specifically for the [Bridge Kit](https://www.npmjs.com/package/@circle-fin/bridge-kit):
|
|
282
205
|
|
|
283
206
|
```typescript
|
|
284
|
-
import {
|
|
207
|
+
import { BridgeKit } from '@circle-fin/bridge-kit'
|
|
285
208
|
import { ViemAdapter } from '@circle-fin/adapter-viem-v2'
|
|
286
209
|
import { createPublicClient, createWalletClient, http } from 'viem'
|
|
287
210
|
import { mainnet, base } from 'viem/chains'
|
|
@@ -290,7 +213,7 @@ import { privateKeyToAccount } from 'viem/accounts'
|
|
|
290
213
|
const account = privateKeyToAccount(process.env.PRIVATE_KEY)
|
|
291
214
|
|
|
292
215
|
// Provider is included by default
|
|
293
|
-
const kit = new
|
|
216
|
+
const kit = new BridgeKit()
|
|
294
217
|
|
|
295
218
|
const sourceAdapter = new ViemAdapter({
|
|
296
219
|
publicClient: createPublicClient({ chain: mainnet, transport: http() }),
|
|
@@ -315,31 +238,12 @@ kit.on('mint', (event) => console.log('Mint:', event.values.txHash))
|
|
|
315
238
|
|
|
316
239
|
// Execute transfer
|
|
317
240
|
const result = await kit.bridge({
|
|
318
|
-
|
|
319
|
-
|
|
241
|
+
from: { adapter: sourceAdapter, chain: 'Ethereum' },
|
|
242
|
+
to: { adapter: destAdapter, chain: 'Base' },
|
|
320
243
|
amount: '25.0',
|
|
321
244
|
})
|
|
322
245
|
```
|
|
323
246
|
|
|
324
|
-
## API Reference
|
|
325
|
-
|
|
326
|
-
### Core Methods
|
|
327
|
-
|
|
328
|
-
- `supportsRoute(source, destination, token)` - Check if transfer route is supported
|
|
329
|
-
- `bridge(params)` - Execute cross-chain bridge operation
|
|
330
|
-
- `estimate(params)` - Get cost estimates for transfer
|
|
331
|
-
|
|
332
|
-
### Transfer Parameters
|
|
333
|
-
|
|
334
|
-
```typescript
|
|
335
|
-
interface BridgeParams {
|
|
336
|
-
source: WalletContextWithFlexibleChain
|
|
337
|
-
destination: WalletContextWithFlexibleChain
|
|
338
|
-
amount: string
|
|
339
|
-
config?: BridgeConfig
|
|
340
|
-
}
|
|
341
|
-
```
|
|
342
|
-
|
|
343
247
|
## Development
|
|
344
248
|
|
|
345
249
|
This package is part of the Stablecoin Kits monorepo.
|
package/index.cjs.js
CHANGED
|
@@ -18,6 +18,17 @@
|
|
|
18
18
|
|
|
19
19
|
'use strict';
|
|
20
20
|
|
|
21
|
+
// Buffer polyfill setup - executes before any other code
|
|
22
|
+
// Ensures globalThis.Buffer is available for @solana/spl-token and other Solana libraries
|
|
23
|
+
import { Buffer } from 'buffer';
|
|
24
|
+
if (typeof globalThis !== 'undefined' && typeof globalThis.Buffer === 'undefined') {
|
|
25
|
+
globalThis.Buffer = Buffer;
|
|
26
|
+
}
|
|
27
|
+
if (typeof window !== 'undefined' && typeof window.Buffer === 'undefined') {
|
|
28
|
+
window.Buffer = Buffer;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
21
32
|
var zod = require('zod');
|
|
22
33
|
var bytes = require('@ethersproject/bytes');
|
|
23
34
|
var address = require('@ethersproject/address');
|
|
@@ -2152,7 +2163,7 @@ var Chains = {
|
|
|
2152
2163
|
*
|
|
2153
2164
|
* @example
|
|
2154
2165
|
* ```typescript
|
|
2155
|
-
* import { isCCTPV2Supported } from '@circle-fin/
|
|
2166
|
+
* import { isCCTPV2Supported } from '@circle-fin/bridge-kit'
|
|
2156
2167
|
*
|
|
2157
2168
|
* const isSupported = isCCTPV2Supported(ethChainDefinition)
|
|
2158
2169
|
* console.log(isSupported) // true
|
|
@@ -2244,6 +2255,11 @@ const baseChainDefinitionSchema = zod.z.object({
|
|
|
2244
2255
|
eurcAddress: zod.z.string().nullable(),
|
|
2245
2256
|
usdcAddress: zod.z.string().nullable(),
|
|
2246
2257
|
cctp: zod.z.any().nullable(), // We'll accept any CCTP config structure
|
|
2258
|
+
kitContracts: zod.z
|
|
2259
|
+
.object({
|
|
2260
|
+
bridge: zod.z.string().optional(),
|
|
2261
|
+
})
|
|
2262
|
+
.optional(),
|
|
2247
2263
|
});
|
|
2248
2264
|
/**
|
|
2249
2265
|
* Zod schema for validating EVM chain definitions specifically.
|
|
@@ -2275,13 +2291,15 @@ const baseChainDefinitionSchema = zod.z.object({
|
|
|
2275
2291
|
* }
|
|
2276
2292
|
* ```
|
|
2277
2293
|
*/
|
|
2278
|
-
const evmChainDefinitionSchema = baseChainDefinitionSchema
|
|
2294
|
+
const evmChainDefinitionSchema = baseChainDefinitionSchema
|
|
2295
|
+
.extend({
|
|
2279
2296
|
type: zod.z.literal('evm'),
|
|
2280
2297
|
chainId: zod.z.number({
|
|
2281
2298
|
required_error: 'EVM chains must have a chainId. Please provide a valid EVM chain ID.',
|
|
2282
2299
|
invalid_type_error: 'EVM chain ID must be a number.',
|
|
2283
2300
|
}),
|
|
2284
|
-
})
|
|
2301
|
+
})
|
|
2302
|
+
.strict(); //// Reject any additional properties not defined in the schema
|
|
2285
2303
|
/**
|
|
2286
2304
|
* Zod schema for validating non-EVM chain definitions.
|
|
2287
2305
|
* This schema extends the base schema with non-EVM specific properties.
|
|
@@ -2301,7 +2319,7 @@ const nonEvmChainDefinitionSchema = baseChainDefinitionSchema
|
|
|
2301
2319
|
'polkadot',
|
|
2302
2320
|
]),
|
|
2303
2321
|
})
|
|
2304
|
-
.strict(); // Reject additional properties
|
|
2322
|
+
.strict(); // Reject any additional properties not defined in the schema
|
|
2305
2323
|
/**
|
|
2306
2324
|
* Discriminated union schema for all chain definitions.
|
|
2307
2325
|
* This schema validates different chain types based on their 'type' field.
|
|
@@ -2574,8 +2592,8 @@ class BridgingProvider {
|
|
|
2574
2592
|
*
|
|
2575
2593
|
* @example
|
|
2576
2594
|
* ```typescript
|
|
2577
|
-
* setKitIdentifier('
|
|
2578
|
-
* getUserAgent() // "
|
|
2595
|
+
* setKitIdentifier('bridge-kit', '1.2.3')
|
|
2596
|
+
* getUserAgent() // "bridge-kit/1.2.3 (node/18.16.0)"
|
|
2579
2597
|
* ```
|
|
2580
2598
|
*
|
|
2581
2599
|
* @returns The Stablecoin Kits SDK user agent string.
|
|
@@ -2610,7 +2628,7 @@ function getRuntime() {
|
|
|
2610
2628
|
/**
|
|
2611
2629
|
* Get the user agent string for Stablecoin Kits SDK (universal, sync).
|
|
2612
2630
|
*
|
|
2613
|
-
* @returns The user agent string, e.g., "
|
|
2631
|
+
* @returns The user agent string, e.g., "bridge-kit/1.2.3 (node/18.16.0)"
|
|
2614
2632
|
*/
|
|
2615
2633
|
function getUserAgent() {
|
|
2616
2634
|
if (cachedUserAgent !== undefined)
|
|
@@ -4188,67 +4206,48 @@ class KitError extends Error {
|
|
|
4188
4206
|
}
|
|
4189
4207
|
|
|
4190
4208
|
/**
|
|
4191
|
-
* Standardized error
|
|
4209
|
+
* Standardized error definitions for INPUT type errors.
|
|
4210
|
+
*
|
|
4211
|
+
* Each entry combines the numeric error code with its corresponding
|
|
4212
|
+
* string name to ensure consistency when creating error instances.
|
|
4192
4213
|
*
|
|
4193
4214
|
* Error codes follow a hierarchical numbering scheme where the first digit
|
|
4194
4215
|
* indicates the error category (1 = INPUT) and subsequent digits provide
|
|
4195
4216
|
* specific error identification within that category.
|
|
4196
4217
|
*
|
|
4218
|
+
*
|
|
4197
4219
|
* @example
|
|
4198
4220
|
* ```typescript
|
|
4199
|
-
* import {
|
|
4221
|
+
* import { InputError } from '@core/errors'
|
|
4200
4222
|
*
|
|
4201
4223
|
* const error = new KitError({
|
|
4202
|
-
*
|
|
4203
|
-
* name: InputErrorName.NETWORK_MISMATCH,
|
|
4224
|
+
* ...InputError.NETWORK_MISMATCH,
|
|
4204
4225
|
* recoverability: 'FATAL',
|
|
4205
4226
|
* message: 'Source and destination networks must be different'
|
|
4206
4227
|
* })
|
|
4228
|
+
*
|
|
4229
|
+
* // Access code and name individually if needed
|
|
4230
|
+
* console.log(InputError.NETWORK_MISMATCH.code) // 1001
|
|
4231
|
+
* console.log(InputError.NETWORK_MISMATCH.name) // 'INPUT_NETWORK_MISMATCH'
|
|
4207
4232
|
* ```
|
|
4208
4233
|
*/
|
|
4209
|
-
|
|
4210
|
-
(function (InputErrorCode) {
|
|
4234
|
+
const InputError = {
|
|
4211
4235
|
/** Network type mismatch between chains (mainnet vs testnet) */
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4236
|
+
NETWORK_MISMATCH: {
|
|
4237
|
+
code: 1001,
|
|
4238
|
+
name: 'INPUT_NETWORK_MISMATCH',
|
|
4239
|
+
},
|
|
4215
4240
|
/** Unsupported or invalid bridge route configuration */
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
InputErrorCode[InputErrorCode["INVALID_CHAIN"] = 1005] = "INVALID_CHAIN";
|
|
4241
|
+
UNSUPPORTED_ROUTE: {
|
|
4242
|
+
code: 1003,
|
|
4243
|
+
name: 'INPUT_UNSUPPORTED_ROUTE',
|
|
4244
|
+
},
|
|
4221
4245
|
/** General validation failure for complex validation rules */
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
* These names correspond 1:1 with InputErrorCode and should always
|
|
4228
|
-
* be used together to ensure consistency across error instances.
|
|
4229
|
-
*
|
|
4230
|
-
* @example
|
|
4231
|
-
* ```typescript
|
|
4232
|
-
* import { InputErrorCode, InputErrorName } from '@core/errors'
|
|
4233
|
-
*
|
|
4234
|
-
* // Use matching code and name enums
|
|
4235
|
-
* const error = new KitError({
|
|
4236
|
-
* code: InputErrorCode.NETWORK_MISMATCH,
|
|
4237
|
-
* name: InputErrorName.NETWORK_MISMATCH,
|
|
4238
|
-
* recoverability: 'FATAL',
|
|
4239
|
-
* message: 'Network mismatch detected'
|
|
4240
|
-
* })
|
|
4241
|
-
* ```
|
|
4242
|
-
*/
|
|
4243
|
-
var InputErrorName;
|
|
4244
|
-
(function (InputErrorName) {
|
|
4245
|
-
InputErrorName["NETWORK_MISMATCH"] = "INPUT_NETWORK_MISMATCH";
|
|
4246
|
-
InputErrorName["INVALID_AMOUNT"] = "INPUT_INVALID_AMOUNT";
|
|
4247
|
-
InputErrorName["UNSUPPORTED_ROUTE"] = "INPUT_UNSUPPORTED_ROUTE";
|
|
4248
|
-
InputErrorName["INVALID_ADDRESS"] = "INPUT_INVALID_ADDRESS";
|
|
4249
|
-
InputErrorName["INVALID_CHAIN"] = "INPUT_INVALID_CHAIN";
|
|
4250
|
-
InputErrorName["VALIDATION_FAILED"] = "INPUT_VALIDATION_FAILED";
|
|
4251
|
-
})(InputErrorName || (InputErrorName = {}));
|
|
4246
|
+
VALIDATION_FAILED: {
|
|
4247
|
+
code: 1098,
|
|
4248
|
+
name: 'INPUT_VALIDATION_FAILED',
|
|
4249
|
+
},
|
|
4250
|
+
};
|
|
4252
4251
|
|
|
4253
4252
|
/**
|
|
4254
4253
|
* Creates error for network type mismatch between source and destination.
|
|
@@ -4275,8 +4274,7 @@ function createNetworkMismatchError(sourceChain, destChain) {
|
|
|
4275
4274
|
const sourceNetworkType = sourceChain.isTestnet ? 'testnet' : 'mainnet';
|
|
4276
4275
|
const destNetworkType = destChain.isTestnet ? 'testnet' : 'mainnet';
|
|
4277
4276
|
const errorDetails = {
|
|
4278
|
-
|
|
4279
|
-
name: InputErrorName.NETWORK_MISMATCH,
|
|
4277
|
+
...InputError.NETWORK_MISMATCH,
|
|
4280
4278
|
recoverability: 'FATAL',
|
|
4281
4279
|
message: `Cannot bridge between ${sourceChain.name} (${sourceNetworkType}) and ${destChain.name} (${destNetworkType}). Source and destination networks must both be testnet or both be mainnet.`,
|
|
4282
4280
|
cause: {
|
|
@@ -4305,8 +4303,7 @@ function createNetworkMismatchError(sourceChain, destChain) {
|
|
|
4305
4303
|
*/
|
|
4306
4304
|
function createUnsupportedRouteError(source, destination) {
|
|
4307
4305
|
const errorDetails = {
|
|
4308
|
-
|
|
4309
|
-
name: InputErrorName.UNSUPPORTED_ROUTE,
|
|
4306
|
+
...InputError.UNSUPPORTED_ROUTE,
|
|
4310
4307
|
recoverability: 'FATAL',
|
|
4311
4308
|
message: `Route from ${source} to ${destination} is not supported.`,
|
|
4312
4309
|
cause: {
|
|
@@ -4353,8 +4350,7 @@ function createValidationFailedError(field, value, reason) {
|
|
|
4353
4350
|
valueString = String(value);
|
|
4354
4351
|
}
|
|
4355
4352
|
const errorDetails = {
|
|
4356
|
-
|
|
4357
|
-
name: InputErrorName.VALIDATION_FAILED,
|
|
4353
|
+
...InputError.VALIDATION_FAILED,
|
|
4358
4354
|
recoverability: 'FATAL',
|
|
4359
4355
|
message: `Validation failed for '${field}': ${valueString} - ${reason}.`,
|
|
4360
4356
|
cause: {
|
|
@@ -4518,15 +4514,21 @@ mintAddress) => {
|
|
|
4518
4514
|
return rawAddress;
|
|
4519
4515
|
}
|
|
4520
4516
|
else {
|
|
4521
|
-
const [{ getAssociatedTokenAddress }, { PublicKey }] = await Promise.all([
|
|
4522
|
-
import('@solana/spl-token'),
|
|
4523
|
-
import('@solana/web3.js'),
|
|
4524
|
-
]);
|
|
4525
4517
|
// Solana: derive the associated token account
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4518
|
+
// Use dynamic import to avoid loading Solana dependencies for EVM-only users
|
|
4519
|
+
try {
|
|
4520
|
+
const [{ PublicKey }, { getAssociatedTokenAddressSync }] = await Promise.all([
|
|
4521
|
+
import('@solana/web3.js'),
|
|
4522
|
+
import('@solana/spl-token'),
|
|
4523
|
+
]);
|
|
4524
|
+
const owner = new PublicKey(rawAddress);
|
|
4525
|
+
const mintPub = new PublicKey(mintAddress);
|
|
4526
|
+
const ata = getAssociatedTokenAddressSync(mintPub, owner);
|
|
4527
|
+
return ata.toBase58();
|
|
4528
|
+
}
|
|
4529
|
+
catch {
|
|
4530
|
+
throw new Error('Failed to derive Solana token account. Please ensure @solana/web3.js and @solana/spl-token are installed: npm install @solana/web3.js @solana/spl-token');
|
|
4531
|
+
}
|
|
4530
4532
|
}
|
|
4531
4533
|
};
|
|
4532
4534
|
|
|
@@ -4764,6 +4766,7 @@ async function bridgeFetchAttestation({ params, provider, }, txHash) {
|
|
|
4764
4766
|
...step,
|
|
4765
4767
|
state: 'error',
|
|
4766
4768
|
error: err,
|
|
4769
|
+
data: undefined,
|
|
4767
4770
|
};
|
|
4768
4771
|
}
|
|
4769
4772
|
return step;
|
|
@@ -4946,12 +4949,29 @@ async function bridge(params, provider) {
|
|
|
4946
4949
|
throw new Error(`${name} step failed: ${errorDetails}`);
|
|
4947
4950
|
}
|
|
4948
4951
|
context = updateContext?.(step);
|
|
4949
|
-
|
|
4952
|
+
const actionValues = {
|
|
4950
4953
|
protocol: 'cctp',
|
|
4951
4954
|
version: 'v2',
|
|
4952
|
-
|
|
4953
|
-
|
|
4954
|
-
|
|
4955
|
+
values: step,
|
|
4956
|
+
};
|
|
4957
|
+
// use a switch statement for type safety to separate the different step types
|
|
4958
|
+
switch (name) {
|
|
4959
|
+
case 'approve':
|
|
4960
|
+
case 'burn':
|
|
4961
|
+
case 'mint':
|
|
4962
|
+
provider.actionDispatcher?.dispatch(name, {
|
|
4963
|
+
...actionValues,
|
|
4964
|
+
method: name,
|
|
4965
|
+
});
|
|
4966
|
+
break;
|
|
4967
|
+
case 'fetchAttestation':
|
|
4968
|
+
provider.actionDispatcher?.dispatch(name, {
|
|
4969
|
+
...actionValues,
|
|
4970
|
+
method: name,
|
|
4971
|
+
values: step,
|
|
4972
|
+
});
|
|
4973
|
+
break;
|
|
4974
|
+
}
|
|
4955
4975
|
result.steps.push(step);
|
|
4956
4976
|
}
|
|
4957
4977
|
catch (error) {
|
|
@@ -5207,7 +5227,6 @@ base58StringSchema.refine((value) => value.length >= 86 && value.length <= 88, '
|
|
|
5207
5227
|
zod.z.object({
|
|
5208
5228
|
prepare: zod.z.function(),
|
|
5209
5229
|
waitForTransaction: zod.z.function(),
|
|
5210
|
-
getChain: zod.z.function(),
|
|
5211
5230
|
getAddress: zod.z.function(),
|
|
5212
5231
|
});
|
|
5213
5232
|
|
|
@@ -5730,9 +5749,9 @@ class CCTPV2BridgingProvider extends BridgingProvider {
|
|
|
5730
5749
|
*
|
|
5731
5750
|
* @param params - The bridge parameters containing source, destination, amount, and optional config.
|
|
5732
5751
|
* @returns A promise resolving to the bridge result, including transaction details, step states, and explorer URLs.
|
|
5733
|
-
* @throws {ValidationError}
|
|
5734
|
-
* @throws {BridgeError}
|
|
5735
|
-
* @throws {UnsupportedRouteError}
|
|
5752
|
+
* @throws {ValidationError} When the parameters are invalid.
|
|
5753
|
+
* @throws {BridgeError} When the bridge operation fails.
|
|
5754
|
+
* @throws {UnsupportedRouteError} When the route is not supported.
|
|
5736
5755
|
*
|
|
5737
5756
|
* @example
|
|
5738
5757
|
* ```typescript
|
|
@@ -5794,9 +5813,14 @@ class CCTPV2BridgingProvider extends BridgingProvider {
|
|
|
5794
5813
|
* chains, as well as any applicable protocol fees.
|
|
5795
5814
|
*
|
|
5796
5815
|
* @param params - The bridge parameters containing source, destination, amount, and optional config.
|
|
5797
|
-
* @returns Promise resolving to detailed cost breakdown including
|
|
5798
|
-
*
|
|
5799
|
-
*
|
|
5816
|
+
* @returns Promise resolving to detailed cost breakdown including:
|
|
5817
|
+
* - `gasFees`: Array of gas estimates for each step (Approve, Burn, Mint)
|
|
5818
|
+
* - Gas amounts in native token smallest units (wei for ETH, lamports for SOL, etc.)
|
|
5819
|
+
* - `fees`: Array of protocol and kit fees
|
|
5820
|
+
* - Provider fees in USDC decimal units (e.g., "0.1" USDC)
|
|
5821
|
+
* - Kit fees in USDC decimal units if configured
|
|
5822
|
+
* @throws {ValidationError} When the parameters are invalid.
|
|
5823
|
+
* @throws {UnsupportedRouteError} When the route is not supported.
|
|
5800
5824
|
*
|
|
5801
5825
|
* @example
|
|
5802
5826
|
* ```typescript
|
|
@@ -6063,6 +6087,7 @@ class CCTPV2BridgingProvider extends BridgingProvider {
|
|
|
6063
6087
|
message: attestation.message,
|
|
6064
6088
|
attestation: attestation.attestation,
|
|
6065
6089
|
eventNonce: attestation.eventNonce,
|
|
6090
|
+
destinationAddress: destination.address,
|
|
6066
6091
|
};
|
|
6067
6092
|
// Single call with or without context
|
|
6068
6093
|
if (resolvedContext) {
|
|
@@ -6176,28 +6201,29 @@ class CCTPV2BridgingProvider extends BridgingProvider {
|
|
|
6176
6201
|
return false;
|
|
6177
6202
|
}
|
|
6178
6203
|
/**
|
|
6179
|
-
*
|
|
6180
|
-
* based on the configured bridge speed and chain requirements.
|
|
6204
|
+
* Determines the appropriate maximum fee for a cross-chain bridge operation.
|
|
6181
6205
|
*
|
|
6182
6206
|
* For FAST bridge operations, it calculates a dynamic fee based on the bridge amount
|
|
6183
6207
|
* and fast bridge burn fee, or uses a provided maxFee if specified.
|
|
6184
6208
|
*
|
|
6185
6209
|
* For SLOW bridge operations, it returns 0 as there are no additional fees.
|
|
6186
6210
|
*
|
|
6187
|
-
* @param
|
|
6188
|
-
*
|
|
6189
|
-
*
|
|
6190
|
-
*
|
|
6191
|
-
*
|
|
6211
|
+
* @param params - The bridge parameters object containing:
|
|
6212
|
+
* - `source`: The source wallet context with chain definition and adapter
|
|
6213
|
+
* - `destination`: The destination wallet context with chain definition and adapter
|
|
6214
|
+
* - `amount`: The bridge amount in minor units (e.g., "1000000" for 1 USDC)
|
|
6215
|
+
* - `config`: Optional bridge configuration including transferSpeed and maxFee settings
|
|
6216
|
+
* @returns The maximum fee to be used for the bridge operation in minor units
|
|
6192
6217
|
*
|
|
6193
6218
|
* @example
|
|
6194
6219
|
* ```typescript
|
|
6195
|
-
* const maxFee = await provider.getMaxFee(
|
|
6196
|
-
*
|
|
6197
|
-
*
|
|
6198
|
-
* '1000000', // 1 USDC
|
|
6199
|
-
*
|
|
6200
|
-
*
|
|
6220
|
+
* const maxFee = await provider.getMaxFee({
|
|
6221
|
+
* source: { adapter: sourceAdapter, chain: Chains.Ethereum, address: '0x...' },
|
|
6222
|
+
* destination: { adapter: destAdapter, chain: Chains.Base, address: '0x...' },
|
|
6223
|
+
* amount: '1000000', // 1 USDC
|
|
6224
|
+
* token: 'USDC',
|
|
6225
|
+
* config: { transferSpeed: TransferSpeed.FAST }
|
|
6226
|
+
* })
|
|
6201
6227
|
* console.log('Max fee:', maxFee)
|
|
6202
6228
|
* ```
|
|
6203
6229
|
*/
|
|
@@ -6264,8 +6290,11 @@ class CCTPV2BridgingProvider extends BridgingProvider {
|
|
|
6264
6290
|
// Get the min finality threshold based on the transfer speed
|
|
6265
6291
|
const minFinalityThreshold = CCTPv2MinFinalityThreshold[transferSpeed];
|
|
6266
6292
|
// Calculate the max fee
|
|
6267
|
-
const maxFee = await
|
|
6268
|
-
|
|
6293
|
+
const [maxFee, mintRecipient] = await Promise.all([
|
|
6294
|
+
this.getMaxFee(params),
|
|
6295
|
+
getMintRecipientAccount(destination.chain.type, destination.address ??
|
|
6296
|
+
(await destination.adapter.getAddress(destination.chain)), destination.chain.usdcAddress),
|
|
6297
|
+
]);
|
|
6269
6298
|
const actionParams = {
|
|
6270
6299
|
fromChain: source.chain,
|
|
6271
6300
|
toChain: destination.chain,
|
package/index.d.ts
CHANGED
|
@@ -1167,6 +1167,14 @@ interface CCTPv2ActionMap {
|
|
|
1167
1167
|
* Destination chain definition where tokens will be minted.
|
|
1168
1168
|
*/
|
|
1169
1169
|
readonly toChain: ChainDefinitionWithCCTPv2;
|
|
1170
|
+
/**
|
|
1171
|
+
* Optional destination wallet address on the destination chain to receive minted USDC.
|
|
1172
|
+
*
|
|
1173
|
+
* When provided (e.g., for Solana), the mint instruction will derive the
|
|
1174
|
+
* recipient's Associated Token Account (ATA) from this address instead of
|
|
1175
|
+
* the adapter's default address.
|
|
1176
|
+
*/
|
|
1177
|
+
readonly destinationAddress?: string;
|
|
1170
1178
|
};
|
|
1171
1179
|
/**
|
|
1172
1180
|
* Initiate a cross-chain USDC transfer using a custom bridge contract with preapproval funnel.
|
|
@@ -1524,7 +1532,7 @@ interface USDCActionMap {
|
|
|
1524
1532
|
/**
|
|
1525
1533
|
* Central registry of all available action namespaces and their operations.
|
|
1526
1534
|
*
|
|
1527
|
-
* Define the complete action map structure used throughout the
|
|
1535
|
+
* Define the complete action map structure used throughout the bridge kit.
|
|
1528
1536
|
* Each top-level key represents a namespace (e.g., 'token', 'usdc') containing
|
|
1529
1537
|
* related operations. The structure supports arbitrary nesting depth through
|
|
1530
1538
|
* the recursive utility types provided in this module.
|
|
@@ -1617,7 +1625,7 @@ type NestedValue<T, K extends string> = K extends `${infer First}.${infer Rest}`
|
|
|
1617
1625
|
*
|
|
1618
1626
|
* @remarks
|
|
1619
1627
|
* This type serves as the canonical source for all valid action identifiers
|
|
1620
|
-
* in the
|
|
1628
|
+
* in the bridge kit. It ensures compile-time validation of action keys
|
|
1621
1629
|
* and enables type-safe action dispatching throughout the application.
|
|
1622
1630
|
*
|
|
1623
1631
|
* @see {@link ActionPayload} for extracting parameter types
|
|
@@ -1986,26 +1994,6 @@ declare abstract class Adapter<TAdapterCapabilities extends AdapterCapabilities
|
|
|
1986
1994
|
* ```
|
|
1987
1995
|
*/
|
|
1988
1996
|
capabilities?: TAdapterCapabilities;
|
|
1989
|
-
/**
|
|
1990
|
-
* Default chain for operations when none is explicitly provided.
|
|
1991
|
-
*
|
|
1992
|
-
* This allows adapters to have sensible defaults for chain operations,
|
|
1993
|
-
* reducing the need for explicit chain specification in every call.
|
|
1994
|
-
*
|
|
1995
|
-
* @remarks
|
|
1996
|
-
* This is optional for backward compatibility and because some adapter types
|
|
1997
|
-
* (like developer-controlled adapters) may not have meaningful defaults.
|
|
1998
|
-
*
|
|
1999
|
-
* @example
|
|
2000
|
-
* ```typescript
|
|
2001
|
-
* // User-controlled adapter with default chain
|
|
2002
|
-
* defaultChain = Ethereum
|
|
2003
|
-
*
|
|
2004
|
-
* // Developer-controlled adapter (no default)
|
|
2005
|
-
* defaultChain = undefined
|
|
2006
|
-
* ```
|
|
2007
|
-
*/
|
|
2008
|
-
defaultChain?: ChainDefinition;
|
|
2009
1997
|
/**
|
|
2010
1998
|
* Registry of available actions for this adapter.
|
|
2011
1999
|
*
|
|
@@ -2119,16 +2107,6 @@ declare abstract class Adapter<TAdapterCapabilities extends AdapterCapabilities
|
|
|
2119
2107
|
* @returns A promise that resolves to the blockchain address as a string.
|
|
2120
2108
|
*/
|
|
2121
2109
|
abstract getAddress(chain?: ChainDefinition): Promise<string>;
|
|
2122
|
-
/**
|
|
2123
|
-
* Retrieves the {@link ChainDefinition} object that describes the blockchain
|
|
2124
|
-
* this adapter is configured to interact with.
|
|
2125
|
-
*
|
|
2126
|
-
* This includes information such as the chain ID, name, native currency, etc.,
|
|
2127
|
-
* as defined by the `ChainDefinition` type.
|
|
2128
|
-
*
|
|
2129
|
-
* @returns A promise that resolves to the {@link ChainDefinition} for the current chain.
|
|
2130
|
-
*/
|
|
2131
|
-
abstract getChain(): Promise<ChainDefinition>;
|
|
2132
2110
|
/**
|
|
2133
2111
|
* Switches the adapter to operate on the specified chain.
|
|
2134
2112
|
*
|
|
@@ -2173,17 +2151,14 @@ declare abstract class Adapter<TAdapterCapabilities extends AdapterCapabilities
|
|
|
2173
2151
|
* - **Browser wallet adapters**: Request chain switch via EIP-1193 or equivalent
|
|
2174
2152
|
* - **Multi-entity adapters**: Validate chain support (operations are contextual)
|
|
2175
2153
|
*
|
|
2176
|
-
* @param chain - The target chain for operations.
|
|
2154
|
+
* @param chain - The target chain for operations.
|
|
2177
2155
|
* @returns A promise that resolves when the adapter is operating on the specified chain.
|
|
2178
2156
|
* @throws When the target chain is not supported or chain switching fails.
|
|
2179
2157
|
*
|
|
2180
2158
|
* @remarks
|
|
2181
|
-
* This method
|
|
2182
|
-
*
|
|
2183
|
-
*
|
|
2184
|
-
* **Backward Compatibility**: The default implementation provides basic validation but
|
|
2185
|
-
* doesn't perform actual chain switching. Concrete adapter implementations should override
|
|
2186
|
-
* this method to provide proper chain switching logic.
|
|
2159
|
+
* This method always calls `switchToChain()` to ensure consistency across all adapter types.
|
|
2160
|
+
* The underlying implementations handle idempotent switching efficiently (e.g., browser wallets
|
|
2161
|
+
* gracefully handle switching to the current chain, private key adapters recreate lightweight clients).
|
|
2187
2162
|
*
|
|
2188
2163
|
* @example
|
|
2189
2164
|
* ```typescript
|
|
@@ -2197,7 +2172,7 @@ declare abstract class Adapter<TAdapterCapabilities extends AdapterCapabilities
|
|
|
2197
2172
|
* await circleWalletsAdapter.ensureChain(Ethereum)
|
|
2198
2173
|
* ```
|
|
2199
2174
|
*/
|
|
2200
|
-
ensureChain(
|
|
2175
|
+
ensureChain(targetChain: ChainDefinition): Promise<void>;
|
|
2201
2176
|
/**
|
|
2202
2177
|
* Validate that the target chain is supported by this adapter.
|
|
2203
2178
|
*
|
|
@@ -2264,7 +2239,7 @@ interface ApiPollingConfig {
|
|
|
2264
2239
|
*
|
|
2265
2240
|
* @example
|
|
2266
2241
|
* ```typescript
|
|
2267
|
-
* import { Actionable } from '@circle/
|
|
2242
|
+
* import { Actionable } from '@circle-fin/bridge-kit/utils';
|
|
2268
2243
|
*
|
|
2269
2244
|
* // Define your action types
|
|
2270
2245
|
* type TransferActions = {
|
|
@@ -2584,7 +2559,7 @@ interface EstimateResult {
|
|
|
2584
2559
|
}[];
|
|
2585
2560
|
/** Array of protocol and service fees for the transfer */
|
|
2586
2561
|
fees: {
|
|
2587
|
-
/** The type of fee - either from the
|
|
2562
|
+
/** The type of fee - either from the bridge kit or the underlying provider */
|
|
2588
2563
|
type: 'kit' | 'provider';
|
|
2589
2564
|
/** The token in which the fee is charged (currently only USDC) */
|
|
2590
2565
|
token: 'USDC';
|
|
@@ -2647,10 +2622,9 @@ interface BridgeConfig {
|
|
|
2647
2622
|
interface CustomFee {
|
|
2648
2623
|
/**
|
|
2649
2624
|
* The absolute fee to charge for the transfer.
|
|
2650
|
-
* Provide the amount
|
|
2651
|
-
*
|
|
2652
|
-
*
|
|
2653
|
-
* For example: to charge 1 USDC, pass `'1000000'`.
|
|
2625
|
+
* Provide the amount as a base-10 numeric string representing the integer amount of the token (not in smallest units).
|
|
2626
|
+
* For example: to charge 1 USDC or 1 USDC, pass `'1'`.
|
|
2627
|
+
* This is not a percentage.
|
|
2654
2628
|
*
|
|
2655
2629
|
* Note: passing `'0'` results in no fee being charged.
|
|
2656
2630
|
*/
|
|
@@ -3125,6 +3099,7 @@ type BridgeFetchAttestationStep = BridgeStep &
|
|
|
3125
3099
|
| {
|
|
3126
3100
|
state: 'pending';
|
|
3127
3101
|
txHash?: string;
|
|
3102
|
+
data?: undefined;
|
|
3128
3103
|
}
|
|
3129
3104
|
/**
|
|
3130
3105
|
* The error state of the fetch attestation step.
|
|
@@ -3132,6 +3107,7 @@ type BridgeFetchAttestationStep = BridgeStep &
|
|
|
3132
3107
|
| {
|
|
3133
3108
|
state: 'error';
|
|
3134
3109
|
error: unknown;
|
|
3110
|
+
data?: undefined;
|
|
3135
3111
|
});
|
|
3136
3112
|
|
|
3137
3113
|
/**
|
|
@@ -3349,9 +3325,9 @@ declare class CCTPV2BridgingProvider extends BridgingProvider<CCTPV2Actions> imp
|
|
|
3349
3325
|
*
|
|
3350
3326
|
* @param params - The bridge parameters containing source, destination, amount, and optional config.
|
|
3351
3327
|
* @returns A promise resolving to the bridge result, including transaction details, step states, and explorer URLs.
|
|
3352
|
-
* @throws {ValidationError}
|
|
3353
|
-
* @throws {BridgeError}
|
|
3354
|
-
* @throws {UnsupportedRouteError}
|
|
3328
|
+
* @throws {ValidationError} When the parameters are invalid.
|
|
3329
|
+
* @throws {BridgeError} When the bridge operation fails.
|
|
3330
|
+
* @throws {UnsupportedRouteError} When the route is not supported.
|
|
3355
3331
|
*
|
|
3356
3332
|
* @example
|
|
3357
3333
|
* ```typescript
|
|
@@ -3396,9 +3372,14 @@ declare class CCTPV2BridgingProvider extends BridgingProvider<CCTPV2Actions> imp
|
|
|
3396
3372
|
* chains, as well as any applicable protocol fees.
|
|
3397
3373
|
*
|
|
3398
3374
|
* @param params - The bridge parameters containing source, destination, amount, and optional config.
|
|
3399
|
-
* @returns Promise resolving to detailed cost breakdown including
|
|
3400
|
-
*
|
|
3401
|
-
*
|
|
3375
|
+
* @returns Promise resolving to detailed cost breakdown including:
|
|
3376
|
+
* - `gasFees`: Array of gas estimates for each step (Approve, Burn, Mint)
|
|
3377
|
+
* - Gas amounts in native token smallest units (wei for ETH, lamports for SOL, etc.)
|
|
3378
|
+
* - `fees`: Array of protocol and kit fees
|
|
3379
|
+
* - Provider fees in USDC decimal units (e.g., "0.1" USDC)
|
|
3380
|
+
* - Kit fees in USDC decimal units if configured
|
|
3381
|
+
* @throws {ValidationError} When the parameters are invalid.
|
|
3382
|
+
* @throws {UnsupportedRouteError} When the route is not supported.
|
|
3402
3383
|
*
|
|
3403
3384
|
* @example
|
|
3404
3385
|
* ```typescript
|
|
@@ -3576,28 +3557,29 @@ declare class CCTPV2BridgingProvider extends BridgingProvider<CCTPV2Actions> imp
|
|
|
3576
3557
|
*/
|
|
3577
3558
|
supportsRoute(source: ChainDefinition, destination: ChainDefinition, token: 'USDC'): boolean;
|
|
3578
3559
|
/**
|
|
3579
|
-
*
|
|
3580
|
-
* based on the configured bridge speed and chain requirements.
|
|
3560
|
+
* Determines the appropriate maximum fee for a cross-chain bridge operation.
|
|
3581
3561
|
*
|
|
3582
3562
|
* For FAST bridge operations, it calculates a dynamic fee based on the bridge amount
|
|
3583
3563
|
* and fast bridge burn fee, or uses a provided maxFee if specified.
|
|
3584
3564
|
*
|
|
3585
3565
|
* For SLOW bridge operations, it returns 0 as there are no additional fees.
|
|
3586
3566
|
*
|
|
3587
|
-
* @param
|
|
3588
|
-
*
|
|
3589
|
-
*
|
|
3590
|
-
*
|
|
3591
|
-
*
|
|
3567
|
+
* @param params - The bridge parameters object containing:
|
|
3568
|
+
* - `source`: The source wallet context with chain definition and adapter
|
|
3569
|
+
* - `destination`: The destination wallet context with chain definition and adapter
|
|
3570
|
+
* - `amount`: The bridge amount in minor units (e.g., "1000000" for 1 USDC)
|
|
3571
|
+
* - `config`: Optional bridge configuration including transferSpeed and maxFee settings
|
|
3572
|
+
* @returns The maximum fee to be used for the bridge operation in minor units
|
|
3592
3573
|
*
|
|
3593
3574
|
* @example
|
|
3594
3575
|
* ```typescript
|
|
3595
|
-
* const maxFee = await provider.getMaxFee(
|
|
3596
|
-
*
|
|
3597
|
-
*
|
|
3598
|
-
* '1000000', // 1 USDC
|
|
3599
|
-
*
|
|
3600
|
-
*
|
|
3576
|
+
* const maxFee = await provider.getMaxFee({
|
|
3577
|
+
* source: { adapter: sourceAdapter, chain: Chains.Ethereum, address: '0x...' },
|
|
3578
|
+
* destination: { adapter: destAdapter, chain: Chains.Base, address: '0x...' },
|
|
3579
|
+
* amount: '1000000', // 1 USDC
|
|
3580
|
+
* token: 'USDC',
|
|
3581
|
+
* config: { transferSpeed: TransferSpeed.FAST }
|
|
3582
|
+
* })
|
|
3601
3583
|
* console.log('Max fee:', maxFee)
|
|
3602
3584
|
* ```
|
|
3603
3585
|
*/
|
package/index.mjs
CHANGED
|
@@ -16,6 +16,17 @@
|
|
|
16
16
|
* limitations under the License.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
+
// Buffer polyfill setup - executes before any other code
|
|
20
|
+
// Ensures globalThis.Buffer is available for @solana/spl-token and other Solana libraries
|
|
21
|
+
import { Buffer } from 'buffer';
|
|
22
|
+
if (typeof globalThis !== 'undefined' && typeof globalThis.Buffer === 'undefined') {
|
|
23
|
+
globalThis.Buffer = Buffer;
|
|
24
|
+
}
|
|
25
|
+
if (typeof window !== 'undefined' && typeof window.Buffer === 'undefined') {
|
|
26
|
+
window.Buffer = Buffer;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
|
|
19
30
|
import { z } from 'zod';
|
|
20
31
|
import { hexlify, hexZeroPad } from '@ethersproject/bytes';
|
|
21
32
|
import { getAddress } from '@ethersproject/address';
|
|
@@ -2146,7 +2157,7 @@ var Chains = /*#__PURE__*/Object.freeze({
|
|
|
2146
2157
|
*
|
|
2147
2158
|
* @example
|
|
2148
2159
|
* ```typescript
|
|
2149
|
-
* import { isCCTPV2Supported } from '@circle-fin/
|
|
2160
|
+
* import { isCCTPV2Supported } from '@circle-fin/bridge-kit'
|
|
2150
2161
|
*
|
|
2151
2162
|
* const isSupported = isCCTPV2Supported(ethChainDefinition)
|
|
2152
2163
|
* console.log(isSupported) // true
|
|
@@ -2238,6 +2249,11 @@ const baseChainDefinitionSchema = z.object({
|
|
|
2238
2249
|
eurcAddress: z.string().nullable(),
|
|
2239
2250
|
usdcAddress: z.string().nullable(),
|
|
2240
2251
|
cctp: z.any().nullable(), // We'll accept any CCTP config structure
|
|
2252
|
+
kitContracts: z
|
|
2253
|
+
.object({
|
|
2254
|
+
bridge: z.string().optional(),
|
|
2255
|
+
})
|
|
2256
|
+
.optional(),
|
|
2241
2257
|
});
|
|
2242
2258
|
/**
|
|
2243
2259
|
* Zod schema for validating EVM chain definitions specifically.
|
|
@@ -2269,13 +2285,15 @@ const baseChainDefinitionSchema = z.object({
|
|
|
2269
2285
|
* }
|
|
2270
2286
|
* ```
|
|
2271
2287
|
*/
|
|
2272
|
-
const evmChainDefinitionSchema = baseChainDefinitionSchema
|
|
2288
|
+
const evmChainDefinitionSchema = baseChainDefinitionSchema
|
|
2289
|
+
.extend({
|
|
2273
2290
|
type: z.literal('evm'),
|
|
2274
2291
|
chainId: z.number({
|
|
2275
2292
|
required_error: 'EVM chains must have a chainId. Please provide a valid EVM chain ID.',
|
|
2276
2293
|
invalid_type_error: 'EVM chain ID must be a number.',
|
|
2277
2294
|
}),
|
|
2278
|
-
})
|
|
2295
|
+
})
|
|
2296
|
+
.strict(); //// Reject any additional properties not defined in the schema
|
|
2279
2297
|
/**
|
|
2280
2298
|
* Zod schema for validating non-EVM chain definitions.
|
|
2281
2299
|
* This schema extends the base schema with non-EVM specific properties.
|
|
@@ -2295,7 +2313,7 @@ const nonEvmChainDefinitionSchema = baseChainDefinitionSchema
|
|
|
2295
2313
|
'polkadot',
|
|
2296
2314
|
]),
|
|
2297
2315
|
})
|
|
2298
|
-
.strict(); // Reject additional properties
|
|
2316
|
+
.strict(); // Reject any additional properties not defined in the schema
|
|
2299
2317
|
/**
|
|
2300
2318
|
* Discriminated union schema for all chain definitions.
|
|
2301
2319
|
* This schema validates different chain types based on their 'type' field.
|
|
@@ -2568,8 +2586,8 @@ class BridgingProvider {
|
|
|
2568
2586
|
*
|
|
2569
2587
|
* @example
|
|
2570
2588
|
* ```typescript
|
|
2571
|
-
* setKitIdentifier('
|
|
2572
|
-
* getUserAgent() // "
|
|
2589
|
+
* setKitIdentifier('bridge-kit', '1.2.3')
|
|
2590
|
+
* getUserAgent() // "bridge-kit/1.2.3 (node/18.16.0)"
|
|
2573
2591
|
* ```
|
|
2574
2592
|
*
|
|
2575
2593
|
* @returns The Stablecoin Kits SDK user agent string.
|
|
@@ -2604,7 +2622,7 @@ function getRuntime() {
|
|
|
2604
2622
|
/**
|
|
2605
2623
|
* Get the user agent string for Stablecoin Kits SDK (universal, sync).
|
|
2606
2624
|
*
|
|
2607
|
-
* @returns The user agent string, e.g., "
|
|
2625
|
+
* @returns The user agent string, e.g., "bridge-kit/1.2.3 (node/18.16.0)"
|
|
2608
2626
|
*/
|
|
2609
2627
|
function getUserAgent() {
|
|
2610
2628
|
if (cachedUserAgent !== undefined)
|
|
@@ -4182,67 +4200,48 @@ class KitError extends Error {
|
|
|
4182
4200
|
}
|
|
4183
4201
|
|
|
4184
4202
|
/**
|
|
4185
|
-
* Standardized error
|
|
4203
|
+
* Standardized error definitions for INPUT type errors.
|
|
4204
|
+
*
|
|
4205
|
+
* Each entry combines the numeric error code with its corresponding
|
|
4206
|
+
* string name to ensure consistency when creating error instances.
|
|
4186
4207
|
*
|
|
4187
4208
|
* Error codes follow a hierarchical numbering scheme where the first digit
|
|
4188
4209
|
* indicates the error category (1 = INPUT) and subsequent digits provide
|
|
4189
4210
|
* specific error identification within that category.
|
|
4190
4211
|
*
|
|
4212
|
+
*
|
|
4191
4213
|
* @example
|
|
4192
4214
|
* ```typescript
|
|
4193
|
-
* import {
|
|
4215
|
+
* import { InputError } from '@core/errors'
|
|
4194
4216
|
*
|
|
4195
4217
|
* const error = new KitError({
|
|
4196
|
-
*
|
|
4197
|
-
* name: InputErrorName.NETWORK_MISMATCH,
|
|
4218
|
+
* ...InputError.NETWORK_MISMATCH,
|
|
4198
4219
|
* recoverability: 'FATAL',
|
|
4199
4220
|
* message: 'Source and destination networks must be different'
|
|
4200
4221
|
* })
|
|
4222
|
+
*
|
|
4223
|
+
* // Access code and name individually if needed
|
|
4224
|
+
* console.log(InputError.NETWORK_MISMATCH.code) // 1001
|
|
4225
|
+
* console.log(InputError.NETWORK_MISMATCH.name) // 'INPUT_NETWORK_MISMATCH'
|
|
4201
4226
|
* ```
|
|
4202
4227
|
*/
|
|
4203
|
-
|
|
4204
|
-
(function (InputErrorCode) {
|
|
4228
|
+
const InputError = {
|
|
4205
4229
|
/** Network type mismatch between chains (mainnet vs testnet) */
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4230
|
+
NETWORK_MISMATCH: {
|
|
4231
|
+
code: 1001,
|
|
4232
|
+
name: 'INPUT_NETWORK_MISMATCH',
|
|
4233
|
+
},
|
|
4209
4234
|
/** Unsupported or invalid bridge route configuration */
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
InputErrorCode[InputErrorCode["INVALID_CHAIN"] = 1005] = "INVALID_CHAIN";
|
|
4235
|
+
UNSUPPORTED_ROUTE: {
|
|
4236
|
+
code: 1003,
|
|
4237
|
+
name: 'INPUT_UNSUPPORTED_ROUTE',
|
|
4238
|
+
},
|
|
4215
4239
|
/** General validation failure for complex validation rules */
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
|
|
4221
|
-
* These names correspond 1:1 with InputErrorCode and should always
|
|
4222
|
-
* be used together to ensure consistency across error instances.
|
|
4223
|
-
*
|
|
4224
|
-
* @example
|
|
4225
|
-
* ```typescript
|
|
4226
|
-
* import { InputErrorCode, InputErrorName } from '@core/errors'
|
|
4227
|
-
*
|
|
4228
|
-
* // Use matching code and name enums
|
|
4229
|
-
* const error = new KitError({
|
|
4230
|
-
* code: InputErrorCode.NETWORK_MISMATCH,
|
|
4231
|
-
* name: InputErrorName.NETWORK_MISMATCH,
|
|
4232
|
-
* recoverability: 'FATAL',
|
|
4233
|
-
* message: 'Network mismatch detected'
|
|
4234
|
-
* })
|
|
4235
|
-
* ```
|
|
4236
|
-
*/
|
|
4237
|
-
var InputErrorName;
|
|
4238
|
-
(function (InputErrorName) {
|
|
4239
|
-
InputErrorName["NETWORK_MISMATCH"] = "INPUT_NETWORK_MISMATCH";
|
|
4240
|
-
InputErrorName["INVALID_AMOUNT"] = "INPUT_INVALID_AMOUNT";
|
|
4241
|
-
InputErrorName["UNSUPPORTED_ROUTE"] = "INPUT_UNSUPPORTED_ROUTE";
|
|
4242
|
-
InputErrorName["INVALID_ADDRESS"] = "INPUT_INVALID_ADDRESS";
|
|
4243
|
-
InputErrorName["INVALID_CHAIN"] = "INPUT_INVALID_CHAIN";
|
|
4244
|
-
InputErrorName["VALIDATION_FAILED"] = "INPUT_VALIDATION_FAILED";
|
|
4245
|
-
})(InputErrorName || (InputErrorName = {}));
|
|
4240
|
+
VALIDATION_FAILED: {
|
|
4241
|
+
code: 1098,
|
|
4242
|
+
name: 'INPUT_VALIDATION_FAILED',
|
|
4243
|
+
},
|
|
4244
|
+
};
|
|
4246
4245
|
|
|
4247
4246
|
/**
|
|
4248
4247
|
* Creates error for network type mismatch between source and destination.
|
|
@@ -4269,8 +4268,7 @@ function createNetworkMismatchError(sourceChain, destChain) {
|
|
|
4269
4268
|
const sourceNetworkType = sourceChain.isTestnet ? 'testnet' : 'mainnet';
|
|
4270
4269
|
const destNetworkType = destChain.isTestnet ? 'testnet' : 'mainnet';
|
|
4271
4270
|
const errorDetails = {
|
|
4272
|
-
|
|
4273
|
-
name: InputErrorName.NETWORK_MISMATCH,
|
|
4271
|
+
...InputError.NETWORK_MISMATCH,
|
|
4274
4272
|
recoverability: 'FATAL',
|
|
4275
4273
|
message: `Cannot bridge between ${sourceChain.name} (${sourceNetworkType}) and ${destChain.name} (${destNetworkType}). Source and destination networks must both be testnet or both be mainnet.`,
|
|
4276
4274
|
cause: {
|
|
@@ -4299,8 +4297,7 @@ function createNetworkMismatchError(sourceChain, destChain) {
|
|
|
4299
4297
|
*/
|
|
4300
4298
|
function createUnsupportedRouteError(source, destination) {
|
|
4301
4299
|
const errorDetails = {
|
|
4302
|
-
|
|
4303
|
-
name: InputErrorName.UNSUPPORTED_ROUTE,
|
|
4300
|
+
...InputError.UNSUPPORTED_ROUTE,
|
|
4304
4301
|
recoverability: 'FATAL',
|
|
4305
4302
|
message: `Route from ${source} to ${destination} is not supported.`,
|
|
4306
4303
|
cause: {
|
|
@@ -4347,8 +4344,7 @@ function createValidationFailedError(field, value, reason) {
|
|
|
4347
4344
|
valueString = String(value);
|
|
4348
4345
|
}
|
|
4349
4346
|
const errorDetails = {
|
|
4350
|
-
|
|
4351
|
-
name: InputErrorName.VALIDATION_FAILED,
|
|
4347
|
+
...InputError.VALIDATION_FAILED,
|
|
4352
4348
|
recoverability: 'FATAL',
|
|
4353
4349
|
message: `Validation failed for '${field}': ${valueString} - ${reason}.`,
|
|
4354
4350
|
cause: {
|
|
@@ -4512,15 +4508,21 @@ mintAddress) => {
|
|
|
4512
4508
|
return rawAddress;
|
|
4513
4509
|
}
|
|
4514
4510
|
else {
|
|
4515
|
-
const [{ getAssociatedTokenAddress }, { PublicKey }] = await Promise.all([
|
|
4516
|
-
import('@solana/spl-token'),
|
|
4517
|
-
import('@solana/web3.js'),
|
|
4518
|
-
]);
|
|
4519
4511
|
// Solana: derive the associated token account
|
|
4520
|
-
|
|
4521
|
-
|
|
4522
|
-
|
|
4523
|
-
|
|
4512
|
+
// Use dynamic import to avoid loading Solana dependencies for EVM-only users
|
|
4513
|
+
try {
|
|
4514
|
+
const [{ PublicKey }, { getAssociatedTokenAddressSync }] = await Promise.all([
|
|
4515
|
+
import('@solana/web3.js'),
|
|
4516
|
+
import('@solana/spl-token'),
|
|
4517
|
+
]);
|
|
4518
|
+
const owner = new PublicKey(rawAddress);
|
|
4519
|
+
const mintPub = new PublicKey(mintAddress);
|
|
4520
|
+
const ata = getAssociatedTokenAddressSync(mintPub, owner);
|
|
4521
|
+
return ata.toBase58();
|
|
4522
|
+
}
|
|
4523
|
+
catch {
|
|
4524
|
+
throw new Error('Failed to derive Solana token account. Please ensure @solana/web3.js and @solana/spl-token are installed: npm install @solana/web3.js @solana/spl-token');
|
|
4525
|
+
}
|
|
4524
4526
|
}
|
|
4525
4527
|
};
|
|
4526
4528
|
|
|
@@ -4758,6 +4760,7 @@ async function bridgeFetchAttestation({ params, provider, }, txHash) {
|
|
|
4758
4760
|
...step,
|
|
4759
4761
|
state: 'error',
|
|
4760
4762
|
error: err,
|
|
4763
|
+
data: undefined,
|
|
4761
4764
|
};
|
|
4762
4765
|
}
|
|
4763
4766
|
return step;
|
|
@@ -4940,12 +4943,29 @@ async function bridge(params, provider) {
|
|
|
4940
4943
|
throw new Error(`${name} step failed: ${errorDetails}`);
|
|
4941
4944
|
}
|
|
4942
4945
|
context = updateContext?.(step);
|
|
4943
|
-
|
|
4946
|
+
const actionValues = {
|
|
4944
4947
|
protocol: 'cctp',
|
|
4945
4948
|
version: 'v2',
|
|
4946
|
-
|
|
4947
|
-
|
|
4948
|
-
|
|
4949
|
+
values: step,
|
|
4950
|
+
};
|
|
4951
|
+
// use a switch statement for type safety to separate the different step types
|
|
4952
|
+
switch (name) {
|
|
4953
|
+
case 'approve':
|
|
4954
|
+
case 'burn':
|
|
4955
|
+
case 'mint':
|
|
4956
|
+
provider.actionDispatcher?.dispatch(name, {
|
|
4957
|
+
...actionValues,
|
|
4958
|
+
method: name,
|
|
4959
|
+
});
|
|
4960
|
+
break;
|
|
4961
|
+
case 'fetchAttestation':
|
|
4962
|
+
provider.actionDispatcher?.dispatch(name, {
|
|
4963
|
+
...actionValues,
|
|
4964
|
+
method: name,
|
|
4965
|
+
values: step,
|
|
4966
|
+
});
|
|
4967
|
+
break;
|
|
4968
|
+
}
|
|
4949
4969
|
result.steps.push(step);
|
|
4950
4970
|
}
|
|
4951
4971
|
catch (error) {
|
|
@@ -5201,7 +5221,6 @@ base58StringSchema.refine((value) => value.length >= 86 && value.length <= 88, '
|
|
|
5201
5221
|
z.object({
|
|
5202
5222
|
prepare: z.function(),
|
|
5203
5223
|
waitForTransaction: z.function(),
|
|
5204
|
-
getChain: z.function(),
|
|
5205
5224
|
getAddress: z.function(),
|
|
5206
5225
|
});
|
|
5207
5226
|
|
|
@@ -5724,9 +5743,9 @@ class CCTPV2BridgingProvider extends BridgingProvider {
|
|
|
5724
5743
|
*
|
|
5725
5744
|
* @param params - The bridge parameters containing source, destination, amount, and optional config.
|
|
5726
5745
|
* @returns A promise resolving to the bridge result, including transaction details, step states, and explorer URLs.
|
|
5727
|
-
* @throws {ValidationError}
|
|
5728
|
-
* @throws {BridgeError}
|
|
5729
|
-
* @throws {UnsupportedRouteError}
|
|
5746
|
+
* @throws {ValidationError} When the parameters are invalid.
|
|
5747
|
+
* @throws {BridgeError} When the bridge operation fails.
|
|
5748
|
+
* @throws {UnsupportedRouteError} When the route is not supported.
|
|
5730
5749
|
*
|
|
5731
5750
|
* @example
|
|
5732
5751
|
* ```typescript
|
|
@@ -5788,9 +5807,14 @@ class CCTPV2BridgingProvider extends BridgingProvider {
|
|
|
5788
5807
|
* chains, as well as any applicable protocol fees.
|
|
5789
5808
|
*
|
|
5790
5809
|
* @param params - The bridge parameters containing source, destination, amount, and optional config.
|
|
5791
|
-
* @returns Promise resolving to detailed cost breakdown including
|
|
5792
|
-
*
|
|
5793
|
-
*
|
|
5810
|
+
* @returns Promise resolving to detailed cost breakdown including:
|
|
5811
|
+
* - `gasFees`: Array of gas estimates for each step (Approve, Burn, Mint)
|
|
5812
|
+
* - Gas amounts in native token smallest units (wei for ETH, lamports for SOL, etc.)
|
|
5813
|
+
* - `fees`: Array of protocol and kit fees
|
|
5814
|
+
* - Provider fees in USDC decimal units (e.g., "0.1" USDC)
|
|
5815
|
+
* - Kit fees in USDC decimal units if configured
|
|
5816
|
+
* @throws {ValidationError} When the parameters are invalid.
|
|
5817
|
+
* @throws {UnsupportedRouteError} When the route is not supported.
|
|
5794
5818
|
*
|
|
5795
5819
|
* @example
|
|
5796
5820
|
* ```typescript
|
|
@@ -6057,6 +6081,7 @@ class CCTPV2BridgingProvider extends BridgingProvider {
|
|
|
6057
6081
|
message: attestation.message,
|
|
6058
6082
|
attestation: attestation.attestation,
|
|
6059
6083
|
eventNonce: attestation.eventNonce,
|
|
6084
|
+
destinationAddress: destination.address,
|
|
6060
6085
|
};
|
|
6061
6086
|
// Single call with or without context
|
|
6062
6087
|
if (resolvedContext) {
|
|
@@ -6170,28 +6195,29 @@ class CCTPV2BridgingProvider extends BridgingProvider {
|
|
|
6170
6195
|
return false;
|
|
6171
6196
|
}
|
|
6172
6197
|
/**
|
|
6173
|
-
*
|
|
6174
|
-
* based on the configured bridge speed and chain requirements.
|
|
6198
|
+
* Determines the appropriate maximum fee for a cross-chain bridge operation.
|
|
6175
6199
|
*
|
|
6176
6200
|
* For FAST bridge operations, it calculates a dynamic fee based on the bridge amount
|
|
6177
6201
|
* and fast bridge burn fee, or uses a provided maxFee if specified.
|
|
6178
6202
|
*
|
|
6179
6203
|
* For SLOW bridge operations, it returns 0 as there are no additional fees.
|
|
6180
6204
|
*
|
|
6181
|
-
* @param
|
|
6182
|
-
*
|
|
6183
|
-
*
|
|
6184
|
-
*
|
|
6185
|
-
*
|
|
6205
|
+
* @param params - The bridge parameters object containing:
|
|
6206
|
+
* - `source`: The source wallet context with chain definition and adapter
|
|
6207
|
+
* - `destination`: The destination wallet context with chain definition and adapter
|
|
6208
|
+
* - `amount`: The bridge amount in minor units (e.g., "1000000" for 1 USDC)
|
|
6209
|
+
* - `config`: Optional bridge configuration including transferSpeed and maxFee settings
|
|
6210
|
+
* @returns The maximum fee to be used for the bridge operation in minor units
|
|
6186
6211
|
*
|
|
6187
6212
|
* @example
|
|
6188
6213
|
* ```typescript
|
|
6189
|
-
* const maxFee = await provider.getMaxFee(
|
|
6190
|
-
*
|
|
6191
|
-
*
|
|
6192
|
-
* '1000000', // 1 USDC
|
|
6193
|
-
*
|
|
6194
|
-
*
|
|
6214
|
+
* const maxFee = await provider.getMaxFee({
|
|
6215
|
+
* source: { adapter: sourceAdapter, chain: Chains.Ethereum, address: '0x...' },
|
|
6216
|
+
* destination: { adapter: destAdapter, chain: Chains.Base, address: '0x...' },
|
|
6217
|
+
* amount: '1000000', // 1 USDC
|
|
6218
|
+
* token: 'USDC',
|
|
6219
|
+
* config: { transferSpeed: TransferSpeed.FAST }
|
|
6220
|
+
* })
|
|
6195
6221
|
* console.log('Max fee:', maxFee)
|
|
6196
6222
|
* ```
|
|
6197
6223
|
*/
|
|
@@ -6258,8 +6284,11 @@ class CCTPV2BridgingProvider extends BridgingProvider {
|
|
|
6258
6284
|
// Get the min finality threshold based on the transfer speed
|
|
6259
6285
|
const minFinalityThreshold = CCTPv2MinFinalityThreshold[transferSpeed];
|
|
6260
6286
|
// Calculate the max fee
|
|
6261
|
-
const maxFee = await
|
|
6262
|
-
|
|
6287
|
+
const [maxFee, mintRecipient] = await Promise.all([
|
|
6288
|
+
this.getMaxFee(params),
|
|
6289
|
+
getMintRecipientAccount(destination.chain.type, destination.address ??
|
|
6290
|
+
(await destination.adapter.getAddress(destination.chain)), destination.chain.usdcAddress),
|
|
6291
|
+
]);
|
|
6263
6292
|
const actionParams = {
|
|
6264
6293
|
fromChain: source.chain,
|
|
6265
6294
|
toChain: destination.chain,
|
package/package.json
CHANGED
|
@@ -1,18 +1,32 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@circle-fin/provider-cctp-v2",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"main": "./index.cjs.js",
|
|
5
5
|
"module": "./index.mjs",
|
|
6
6
|
"types": "./index.d.ts",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@
|
|
9
|
-
"
|
|
10
|
-
"
|
|
8
|
+
"@coral-xyz/anchor": "^0.31.1",
|
|
9
|
+
"bs58": "6.0.0",
|
|
10
|
+
"buffer": "^6.0.3",
|
|
11
|
+
"abitype": "^1.1.0",
|
|
12
|
+
"@solana/web3.js": "^1.98.4",
|
|
13
|
+
"@solana/spl-token": "0.4.14",
|
|
11
14
|
"zod": "3.25.67",
|
|
12
15
|
"@ethersproject/address": "^5.8.0",
|
|
13
16
|
"@ethersproject/bytes": "^5.8.0",
|
|
14
|
-
"@ethersproject/units": "^5.8.0"
|
|
15
|
-
|
|
17
|
+
"@ethersproject/units": "^5.8.0"
|
|
18
|
+
},
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"@solana/spl-token": "^0.4.13",
|
|
21
|
+
"@solana/web3.js": "^1.98.2"
|
|
22
|
+
},
|
|
23
|
+
"peerDependenciesMeta": {
|
|
24
|
+
"@solana/spl-token": {
|
|
25
|
+
"optional": true
|
|
26
|
+
},
|
|
27
|
+
"@solana/web3.js": {
|
|
28
|
+
"optional": true
|
|
29
|
+
}
|
|
16
30
|
},
|
|
17
31
|
"exports": {
|
|
18
32
|
"./package.json": "./package.json",
|