@circle-fin/bridge-kit 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/LICENSE +190 -0
- package/QUICKSTART.md +1147 -0
- package/README.md +478 -0
- package/chains.cjs.js +2250 -0
- package/chains.cjs.js.map +1 -0
- package/chains.d.ts +1088 -0
- package/chains.mjs +2225 -0
- package/chains.mjs.map +1 -0
- package/index.cjs.js +4862 -0
- package/index.cjs.js.map +1 -0
- package/index.d.ts +4048 -0
- package/index.mjs +4858 -0
- package/index.mjs.map +1 -0
- package/package.json +46 -0
package/index.d.ts
ADDED
|
@@ -0,0 +1,4048 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025, Circle Internet Group, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this file except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { Abi } from 'abitype';
|
|
20
|
+
import { TransactionInstruction, Signer } from '@solana/web3.js';
|
|
21
|
+
import { CCTPV2BridgingProvider } from '@circle-fin/provider-cctp-v2';
|
|
22
|
+
import { z } from '/home/runner/_work/stablecoin-kits-private/stablecoin-kits-private/node_modules/zod/dist/types/index.d.ts';
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @packageDocumentation
|
|
26
|
+
* @module ChainDefinitions
|
|
27
|
+
*
|
|
28
|
+
* This module provides a complete type system for blockchain chain definitions.
|
|
29
|
+
* It supports both EVM and non‑EVM chains, token configurations, and multiple
|
|
30
|
+
* versions of the Cross-Chain Transfer Protocol (CCTP). Additionally, utility types
|
|
31
|
+
* are provided to extract subsets of chains (e.g. chains supporting USDC, EURC, or specific
|
|
32
|
+
* CCTP versions) from a provided collection.
|
|
33
|
+
*
|
|
34
|
+
* All types are fully documented with TSDoc to maximize developer experience.
|
|
35
|
+
*/
|
|
36
|
+
/**
|
|
37
|
+
* Represents basic information about a currency or token.
|
|
38
|
+
* @interface Currency
|
|
39
|
+
* @category Types
|
|
40
|
+
* @description Provides the essential properties of a cryptocurrency or token.
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* const ethCurrency: Currency = {
|
|
44
|
+
* name: "Ether",
|
|
45
|
+
* symbol: "ETH",
|
|
46
|
+
* decimals: 18
|
|
47
|
+
* };
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
interface Currency {
|
|
51
|
+
/**
|
|
52
|
+
* The full name of the currency.
|
|
53
|
+
* @example "Ether", "USDC"
|
|
54
|
+
*/
|
|
55
|
+
name: string;
|
|
56
|
+
/**
|
|
57
|
+
* The symbol or ticker of the currency.
|
|
58
|
+
* @example "ETH", "USDC"
|
|
59
|
+
*/
|
|
60
|
+
symbol: string;
|
|
61
|
+
/**
|
|
62
|
+
* The number of decimal places for the currency.
|
|
63
|
+
* @description Defines the divisibility of the currency (e.g., 1 ETH = 10^18 wei).
|
|
64
|
+
* @example 18 for ETH, 6 for USDC
|
|
65
|
+
*/
|
|
66
|
+
decimals: number;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Base information that all chain definitions must include.
|
|
70
|
+
* @interface BaseChainDefinition
|
|
71
|
+
* @category Types
|
|
72
|
+
* @description Provides the common properties shared by all blockchain definitions.
|
|
73
|
+
* @example
|
|
74
|
+
* ```typescript
|
|
75
|
+
* const baseChain: BaseChainDefinition = {
|
|
76
|
+
* chain: Blockchain.Ethereum,
|
|
77
|
+
* name: "Ethereum",
|
|
78
|
+
* nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
|
|
79
|
+
* isTestnet: false
|
|
80
|
+
* };
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
interface BaseChainDefinition {
|
|
84
|
+
/**
|
|
85
|
+
* The blockchain identifier from the {@link Blockchain} enum.
|
|
86
|
+
*/
|
|
87
|
+
chain: Blockchain;
|
|
88
|
+
/**
|
|
89
|
+
* The display name of the blockchain.
|
|
90
|
+
* @example "Ethereum", "Solana", "Avalanche"
|
|
91
|
+
*/
|
|
92
|
+
name: string;
|
|
93
|
+
/**
|
|
94
|
+
* Optional title or alternative name for the blockchain.
|
|
95
|
+
* @example "Ethereum Mainnet", "Solana Mainnet"
|
|
96
|
+
*/
|
|
97
|
+
title?: string;
|
|
98
|
+
/**
|
|
99
|
+
* Information about the native currency of the blockchain.
|
|
100
|
+
*/
|
|
101
|
+
nativeCurrency: Currency;
|
|
102
|
+
/**
|
|
103
|
+
* Indicates whether this is a testnet or mainnet.
|
|
104
|
+
* @description Used to differentiate between production and testing environments.
|
|
105
|
+
*/
|
|
106
|
+
isTestnet: boolean;
|
|
107
|
+
/**
|
|
108
|
+
* Template URL for the blockchain explorer to view transactions.
|
|
109
|
+
* @description URL template with a `\{hash\}` placeholder for transaction hash.
|
|
110
|
+
* @example "https://etherscan.io/tx/\{hash\}", "https://sepolia.etherscan.io/tx/\{hash\}"
|
|
111
|
+
*/
|
|
112
|
+
explorerUrl: string;
|
|
113
|
+
/**
|
|
114
|
+
* Default RPC endpoints for connecting to the blockchain network.
|
|
115
|
+
* @description Array of reliable public RPC endpoints that can be used for read and write operations.
|
|
116
|
+
* The first endpoint in the array is considered the primary endpoint.
|
|
117
|
+
* @example ["https://cloudflare-eth.com", "https://ethereum.publicnode.com"]
|
|
118
|
+
*/
|
|
119
|
+
rpcEndpoints: readonly string[];
|
|
120
|
+
/**
|
|
121
|
+
* The contract address for EURC.
|
|
122
|
+
* @description Its presence indicates that EURC is supported.
|
|
123
|
+
*/
|
|
124
|
+
eurcAddress: string | null;
|
|
125
|
+
/**
|
|
126
|
+
* The contract address for USDC.
|
|
127
|
+
* @description Its presence indicates that USDC is supported.
|
|
128
|
+
*/
|
|
129
|
+
usdcAddress: string | null;
|
|
130
|
+
/**
|
|
131
|
+
* Optional CCTP configuration.
|
|
132
|
+
* @description If provided, the chain supports CCTP.
|
|
133
|
+
*/
|
|
134
|
+
cctp: CCTPConfig | null;
|
|
135
|
+
/**
|
|
136
|
+
* Optional kit-specific contract addresses for enhanced chain functionality.
|
|
137
|
+
*
|
|
138
|
+
* @description When provided, the chain supports additional kit-specific logic in addition
|
|
139
|
+
* to standard CCTP. This enables hybrid flows where both standard approve/burn/mint
|
|
140
|
+
* and enhanced custom features are available. When undefined, the chain uses only
|
|
141
|
+
* the standard CCTP flow.
|
|
142
|
+
*
|
|
143
|
+
* The address format varies by blockchain:
|
|
144
|
+
* - EVM chains: 40-character hexadecimal with 0x prefix (e.g., "0x1234...")
|
|
145
|
+
* - Solana: Base58-encoded 32-byte address (e.g., "9WzDX...")
|
|
146
|
+
* - Other chains: Platform-specific address formats
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```typescript
|
|
150
|
+
* // EVM chain with bridge contract
|
|
151
|
+
* const evmChain: ChainDefinition = {
|
|
152
|
+
* // ... other properties
|
|
153
|
+
* kitContracts: {
|
|
154
|
+
* bridge: "0x1234567890abcdef1234567890abcdef12345678"
|
|
155
|
+
* }
|
|
156
|
+
* }
|
|
157
|
+
*
|
|
158
|
+
* // Solana chain with bridge contract
|
|
159
|
+
* const solanaChain: ChainDefinition = {
|
|
160
|
+
* // ... other properties
|
|
161
|
+
* kitContracts: {
|
|
162
|
+
* bridge: "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM"
|
|
163
|
+
* }
|
|
164
|
+
* }
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
kitContracts?: KitContracts;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Represents chain definitions for Ethereum Virtual Machine (EVM) compatible blockchains.
|
|
171
|
+
* @interface EVMChainDefinition
|
|
172
|
+
* @extends BaseChainDefinition
|
|
173
|
+
* @category Types
|
|
174
|
+
* @description Adds properties specific to EVM chains.
|
|
175
|
+
* @example
|
|
176
|
+
* ```typescript
|
|
177
|
+
* const ethereum: EVMChainDefinition = {
|
|
178
|
+
* type: 'evm',
|
|
179
|
+
* chain: Blockchain.Ethereum,
|
|
180
|
+
* chainId: 1,
|
|
181
|
+
* name: 'Ethereum',
|
|
182
|
+
* title: 'Ethereum Mainnet',
|
|
183
|
+
* nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
|
|
184
|
+
* isTestnet: false
|
|
185
|
+
* };
|
|
186
|
+
* ```
|
|
187
|
+
*/
|
|
188
|
+
interface EVMChainDefinition extends BaseChainDefinition {
|
|
189
|
+
/**
|
|
190
|
+
* Discriminator for EVM chains.
|
|
191
|
+
* @description Used for type narrowing when handling different chain types.
|
|
192
|
+
*/
|
|
193
|
+
type: 'evm';
|
|
194
|
+
/**
|
|
195
|
+
* The unique identifier for the blockchain.
|
|
196
|
+
* @description Standard EVM chain ID as defined in EIP-155.
|
|
197
|
+
* @example 1 for Ethereum Mainnet, 137 for Polygon.
|
|
198
|
+
*/
|
|
199
|
+
chainId: number;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Represents chain definitions for non-EVM blockchains.
|
|
203
|
+
* @interface NonEVMChainDefinition
|
|
204
|
+
* @extends BaseChainDefinition
|
|
205
|
+
* @category Types
|
|
206
|
+
* @description Contains properties for blockchains that do not use the EVM.
|
|
207
|
+
* @example
|
|
208
|
+
* ```typescript
|
|
209
|
+
* const solana: NonEVMChainDefinition = {
|
|
210
|
+
* type: 'solana',
|
|
211
|
+
* chain: Blockchain.Solana,
|
|
212
|
+
* name: 'Solana',
|
|
213
|
+
* nativeCurrency: { name: 'Solana', symbol: 'SOL', decimals: 9 },
|
|
214
|
+
* isTestnet: false
|
|
215
|
+
* };
|
|
216
|
+
* ```
|
|
217
|
+
*/
|
|
218
|
+
interface NonEVMChainDefinition extends BaseChainDefinition {
|
|
219
|
+
/**
|
|
220
|
+
* Discriminator for non-EVM chains.
|
|
221
|
+
* @description Identifies the specific blockchain platform.
|
|
222
|
+
*/
|
|
223
|
+
type: 'algorand' | 'avalanche' | 'solana' | 'aptos' | 'near' | 'stellar' | 'sui' | 'hedera' | 'noble' | 'polkadot';
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* The type of chain.
|
|
227
|
+
* @alias ChainType
|
|
228
|
+
* @category Types
|
|
229
|
+
* @description Represents the type of chain.
|
|
230
|
+
* @example
|
|
231
|
+
* ```typescript
|
|
232
|
+
* const chainType: ChainType = 'evm'
|
|
233
|
+
* ```
|
|
234
|
+
*/
|
|
235
|
+
type ChainType = EVMChainDefinition['type'] | NonEVMChainDefinition['type'];
|
|
236
|
+
/**
|
|
237
|
+
* Public chain definition type.
|
|
238
|
+
* @alias ChainDefinition
|
|
239
|
+
* @category Types
|
|
240
|
+
* @description Represents either an EVM-based or non-EVM-based blockchain definition.
|
|
241
|
+
* This type is used by developers to define chain configurations.
|
|
242
|
+
* @example
|
|
243
|
+
* ```typescript
|
|
244
|
+
* // Standard chain with CCTP support only
|
|
245
|
+
* const ethereumChain: ChainDefinition = {
|
|
246
|
+
* type: 'evm',
|
|
247
|
+
* chain: Blockchain.Ethereum,
|
|
248
|
+
* chainId: 1,
|
|
249
|
+
* name: 'Ethereum',
|
|
250
|
+
* nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
|
|
251
|
+
* isTestnet: false,
|
|
252
|
+
* explorerUrl: 'https://etherscan.io/tx/{hash}',
|
|
253
|
+
* rpcEndpoints: ['https://eth.example.com'],
|
|
254
|
+
* eurcAddress: null,
|
|
255
|
+
* usdcAddress: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
|
|
256
|
+
* cctp: {
|
|
257
|
+
* domain: 0,
|
|
258
|
+
* contracts: {
|
|
259
|
+
* v2: {
|
|
260
|
+
* type: 'split',
|
|
261
|
+
* tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
|
|
262
|
+
* messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
|
|
263
|
+
* confirmations: 65,
|
|
264
|
+
* fastConfirmations: 2
|
|
265
|
+
* }
|
|
266
|
+
* }
|
|
267
|
+
* },
|
|
268
|
+
* kitContracts: undefined
|
|
269
|
+
* };
|
|
270
|
+
*
|
|
271
|
+
* // Chain with custom contract support (hybrid flow)
|
|
272
|
+
* const customChain: ChainDefinition = {
|
|
273
|
+
* ...ethereumChain,
|
|
274
|
+
* kitContracts: {
|
|
275
|
+
* bridge: '0x1234567890abcdef1234567890abcdef12345678'
|
|
276
|
+
* }
|
|
277
|
+
* };
|
|
278
|
+
* ```
|
|
279
|
+
*/
|
|
280
|
+
type ChainDefinition = EVMChainDefinition | NonEVMChainDefinition;
|
|
281
|
+
/**
|
|
282
|
+
* Chain definition with CCTPv2 configuration.
|
|
283
|
+
* @alias ChainDefinitionWithCCTPv2
|
|
284
|
+
* @extends ChainDefinition
|
|
285
|
+
* @category Types
|
|
286
|
+
* @description Represents a chain definition that includes CCTPv2 configuration. This is useful for typescript consumers to narrow down the type of chain definition to a chain that supports CCTPv2.
|
|
287
|
+
* @example
|
|
288
|
+
* ```typescript
|
|
289
|
+
* const ethereumWithCCTPv2: ChainDefinitionWithCCTPv2 = {
|
|
290
|
+
* ...ethereum,
|
|
291
|
+
* cctp: {
|
|
292
|
+
* domain: 0,
|
|
293
|
+
* contracts: {
|
|
294
|
+
* v2: {
|
|
295
|
+
* type: 'merged',
|
|
296
|
+
* contract: '0x123...'
|
|
297
|
+
* }
|
|
298
|
+
* }
|
|
299
|
+
* }
|
|
300
|
+
* };
|
|
301
|
+
* ```
|
|
302
|
+
*/
|
|
303
|
+
type ChainDefinitionWithCCTPv2 = ChainDefinition & {
|
|
304
|
+
cctp: CCTPConfig & {
|
|
305
|
+
contracts: {
|
|
306
|
+
v2: VersionConfig;
|
|
307
|
+
};
|
|
308
|
+
};
|
|
309
|
+
usdcAddress: string;
|
|
310
|
+
};
|
|
311
|
+
/**
|
|
312
|
+
* Chain identifier that can be used in transfer parameters and factory functions.
|
|
313
|
+
* This can be either:
|
|
314
|
+
* - A ChainDefinition object
|
|
315
|
+
* - A Blockchain enum value (e.g., Blockchain.Ethereum)
|
|
316
|
+
* - A string literal of the blockchain value (e.g., "Ethereum")
|
|
317
|
+
*/
|
|
318
|
+
type ChainIdentifier = ChainDefinition | Blockchain | `${Blockchain}`;
|
|
319
|
+
interface CCTPSplitConfig {
|
|
320
|
+
type: 'split';
|
|
321
|
+
tokenMessenger: string;
|
|
322
|
+
messageTransmitter: string;
|
|
323
|
+
confirmations: number;
|
|
324
|
+
}
|
|
325
|
+
interface CCTPMergedConfig {
|
|
326
|
+
type: 'merged';
|
|
327
|
+
contract: string;
|
|
328
|
+
confirmations: number;
|
|
329
|
+
}
|
|
330
|
+
type VersionConfig = CCTPSplitConfig | CCTPMergedConfig;
|
|
331
|
+
type CCTPContracts = Partial<{
|
|
332
|
+
v1: VersionConfig;
|
|
333
|
+
v2: VersionConfig & {
|
|
334
|
+
fastConfirmations: number;
|
|
335
|
+
};
|
|
336
|
+
}>;
|
|
337
|
+
/**
|
|
338
|
+
* Configuration for the Cross-Chain Transfer Protocol (CCTP).
|
|
339
|
+
* @interface CCTPConfig
|
|
340
|
+
* @category Types
|
|
341
|
+
* @description Contains the domain and required contract addresses for CCTP support.
|
|
342
|
+
* @example
|
|
343
|
+
* ```
|
|
344
|
+
* const cctpConfig: CCTPConfig = {
|
|
345
|
+
* domain: 0,
|
|
346
|
+
* contracts: {
|
|
347
|
+
* TokenMessenger: '0xabc',
|
|
348
|
+
* MessageReceiver: '0xdef'
|
|
349
|
+
* }
|
|
350
|
+
* };
|
|
351
|
+
* ```
|
|
352
|
+
*/
|
|
353
|
+
interface CCTPConfig {
|
|
354
|
+
/**
|
|
355
|
+
* The CCTP domain identifier.
|
|
356
|
+
*/
|
|
357
|
+
domain: number;
|
|
358
|
+
/**
|
|
359
|
+
* The contracts required for CCTP.
|
|
360
|
+
*/
|
|
361
|
+
contracts: CCTPContracts;
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Available kit contract types for enhanced chain functionality.
|
|
365
|
+
*
|
|
366
|
+
* @description Defines the valid contract types that can be deployed on chains
|
|
367
|
+
* to provide additional features beyond standard CCTP functionality.
|
|
368
|
+
*
|
|
369
|
+
* @example
|
|
370
|
+
* ```typescript
|
|
371
|
+
* import type { KitContractType } from '@core/chains'
|
|
372
|
+
*
|
|
373
|
+
* const contractType: KitContractType = 'bridge' // Valid
|
|
374
|
+
* const invalidType: KitContractType = 'invalid' // TypeScript error
|
|
375
|
+
* ```
|
|
376
|
+
*/
|
|
377
|
+
type KitContractType = 'bridge';
|
|
378
|
+
/**
|
|
379
|
+
* Kit-specific contract addresses for enhanced chain functionality.
|
|
380
|
+
*
|
|
381
|
+
* @description Maps contract types to their addresses on a specific chain.
|
|
382
|
+
* All contract types are optional, allowing chains to selectively support
|
|
383
|
+
* specific kit features.
|
|
384
|
+
*
|
|
385
|
+
* @example
|
|
386
|
+
* ```typescript
|
|
387
|
+
* import type { KitContracts } from '@core/chains'
|
|
388
|
+
*
|
|
389
|
+
* const contracts: KitContracts = {
|
|
390
|
+
* bridge: "0x1234567890abcdef1234567890abcdef12345678"
|
|
391
|
+
* }
|
|
392
|
+
*
|
|
393
|
+
* // Future example with multiple contract types:
|
|
394
|
+
* const futureContracts: KitContracts = {
|
|
395
|
+
* bridge: "0x1234567890abcdef1234567890abcdef12345678",
|
|
396
|
+
* // Note: other contract types would be added to KitContractType union
|
|
397
|
+
* // customType: "0xabcdef1234567890abcdef1234567890abcdef12"
|
|
398
|
+
* }
|
|
399
|
+
* ```
|
|
400
|
+
*/
|
|
401
|
+
type KitContracts = Partial<Record<KitContractType, string>>;
|
|
402
|
+
/**
|
|
403
|
+
* Enumeration of all blockchains supported by this library.
|
|
404
|
+
* @enum
|
|
405
|
+
* @category Enums
|
|
406
|
+
* @description Provides string identifiers for each supported blockchain.
|
|
407
|
+
*/
|
|
408
|
+
declare enum Blockchain {
|
|
409
|
+
Algorand = "Algorand",
|
|
410
|
+
Algorand_Testnet = "Algorand_Testnet",
|
|
411
|
+
Aptos = "Aptos",
|
|
412
|
+
Aptos_Testnet = "Aptos_Testnet",
|
|
413
|
+
Arbitrum = "Arbitrum",
|
|
414
|
+
Arbitrum_Sepolia = "Arbitrum_Sepolia",
|
|
415
|
+
Avalanche = "Avalanche",
|
|
416
|
+
Avalanche_Fuji = "Avalanche_Fuji",
|
|
417
|
+
Base = "Base",
|
|
418
|
+
Base_Sepolia = "Base_Sepolia",
|
|
419
|
+
Celo = "Celo",
|
|
420
|
+
Celo_Alfajores_Testnet = "Celo_Alfajores_Testnet",
|
|
421
|
+
Codex = "Codex",
|
|
422
|
+
Codex_Testnet = "Codex_Testnet",
|
|
423
|
+
Ethereum = "Ethereum",
|
|
424
|
+
Ethereum_Sepolia = "Ethereum_Sepolia",
|
|
425
|
+
Hedera = "Hedera",
|
|
426
|
+
Hedera_Testnet = "Hedera_Testnet",
|
|
427
|
+
HyperEVM = "HyperEVM",
|
|
428
|
+
HyperEVM_Testnet = "HyperEVM_Testnet",
|
|
429
|
+
Ink = "Ink",
|
|
430
|
+
Ink_Testnet = "Ink_Testnet",
|
|
431
|
+
Linea = "Linea",
|
|
432
|
+
Linea_Sepolia = "Linea_Sepolia",
|
|
433
|
+
NEAR = "NEAR",
|
|
434
|
+
NEAR_Testnet = "NEAR_Testnet",
|
|
435
|
+
Noble = "Noble",
|
|
436
|
+
Noble_Testnet = "Noble_Testnet",
|
|
437
|
+
Optimism = "Optimism",
|
|
438
|
+
Optimism_Sepolia = "Optimism_Sepolia",
|
|
439
|
+
Polkadot_Asset_Hub = "Polkadot_Asset_Hub",
|
|
440
|
+
Polkadot_Westmint = "Polkadot_Westmint",
|
|
441
|
+
Plume = "Plume",
|
|
442
|
+
Plume_Testnet = "Plume_Testnet",
|
|
443
|
+
Polygon = "Polygon",
|
|
444
|
+
Polygon_Amoy_Testnet = "Polygon_Amoy_Testnet",
|
|
445
|
+
Sei = "Sei",
|
|
446
|
+
Sei_Testnet = "Sei_Testnet",
|
|
447
|
+
Solana = "Solana",
|
|
448
|
+
Solana_Devnet = "Solana_Devnet",
|
|
449
|
+
Sonic = "Sonic",
|
|
450
|
+
Sonic_Testnet = "Sonic_Testnet",
|
|
451
|
+
Stellar = "Stellar",
|
|
452
|
+
Stellar_Testnet = "Stellar_Testnet",
|
|
453
|
+
Sui = "Sui",
|
|
454
|
+
Sui_Testnet = "Sui_Testnet",
|
|
455
|
+
Unichain = "Unichain",
|
|
456
|
+
Unichain_Sepolia = "Unichain_Sepolia",
|
|
457
|
+
World_Chain = "World_Chain",
|
|
458
|
+
World_Chain_Sepolia = "World_Chain_Sepolia",
|
|
459
|
+
XDC = "XDC",
|
|
460
|
+
XDC_Apothem = "XDC_Apothem",
|
|
461
|
+
ZKSync_Era = "ZKSync_Era",
|
|
462
|
+
ZKSync_Sepolia = "ZKSync_Sepolia"
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* Core type definitions for blockchain transaction execution and gas estimation.
|
|
467
|
+
*
|
|
468
|
+
* This module provides TypeScript interfaces and types for handling blockchain
|
|
469
|
+
* transactions across different networks, with a focus on EVM-compatible chains
|
|
470
|
+
* and gas estimation.
|
|
471
|
+
*
|
|
472
|
+
* @module types
|
|
473
|
+
*/
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Estimated gas information for a blockchain transaction.
|
|
477
|
+
*
|
|
478
|
+
* This interface provides a unified way to represent gas costs across different
|
|
479
|
+
* blockchain networks, supporting both EVM-style gas calculations and other
|
|
480
|
+
* fee models.
|
|
481
|
+
*
|
|
482
|
+
* @interface EstimatedGas
|
|
483
|
+
* @category Types
|
|
484
|
+
* @example
|
|
485
|
+
* ```typescript
|
|
486
|
+
* // EVM chain example
|
|
487
|
+
* const evmGas: EstimatedGas = {
|
|
488
|
+
* gas: 21000n,
|
|
489
|
+
* gasPrice: 1000000000n, // 1 Gwei
|
|
490
|
+
* fee: (21000n * 1000000000n).toString() // Total fee in wei
|
|
491
|
+
* };
|
|
492
|
+
*
|
|
493
|
+
* // Solana example
|
|
494
|
+
* const solanaGas: EstimatedGas = {
|
|
495
|
+
* gas: 5000n, // Lamports for compute units
|
|
496
|
+
* fee: '5000' // Total fee in Lamports
|
|
497
|
+
* };
|
|
498
|
+
* ```
|
|
499
|
+
*/
|
|
500
|
+
interface EstimatedGas {
|
|
501
|
+
/**
|
|
502
|
+
* The amount of gas estimated for the transaction.
|
|
503
|
+
* For EVM chains, this represents the gas units.
|
|
504
|
+
* For other chains, this might represent compute units or similar metrics.
|
|
505
|
+
*
|
|
506
|
+
* @example 21000n, 5000n
|
|
507
|
+
*/
|
|
508
|
+
gas: bigint;
|
|
509
|
+
/**
|
|
510
|
+
* The estimated price per unit of gas.
|
|
511
|
+
* This is primarily used in EVM chains where gas price is a separate metric.
|
|
512
|
+
*
|
|
513
|
+
* @example 1000000000n
|
|
514
|
+
*/
|
|
515
|
+
gasPrice: bigint;
|
|
516
|
+
/**
|
|
517
|
+
* The total estimated fee as a string.
|
|
518
|
+
* This field is useful for chains where gas/gasPrice isn't the whole story
|
|
519
|
+
* or when the total fee needs to be represented in a different format.
|
|
520
|
+
* For EVM chains, this is the total fee in wei (gas * gasPrice).
|
|
521
|
+
*
|
|
522
|
+
* @example "21000000000000", "5000"
|
|
523
|
+
*/
|
|
524
|
+
fee: string;
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* Override parameters for EVM gas estimation.
|
|
528
|
+
*
|
|
529
|
+
* These parameters allow customization of gas estimation behavior
|
|
530
|
+
* for EVM-compatible chains.
|
|
531
|
+
*
|
|
532
|
+
* @interface EvmEstimateOverrides
|
|
533
|
+
*/
|
|
534
|
+
interface EvmEstimateOverrides {
|
|
535
|
+
/**
|
|
536
|
+
* The sender's address for the transaction.
|
|
537
|
+
* @example "0x742d35Cc6634C0532925a3b844Bc454e4438f44e"
|
|
538
|
+
*/
|
|
539
|
+
from?: string;
|
|
540
|
+
/**
|
|
541
|
+
* The value to be sent with the transaction in wei.
|
|
542
|
+
* @example 1000000000000000000n // 1 ETH
|
|
543
|
+
*/
|
|
544
|
+
value?: bigint;
|
|
545
|
+
/**
|
|
546
|
+
* The block tag to use for estimation.
|
|
547
|
+
* @example "latest", "safe", "finalized"
|
|
548
|
+
*/
|
|
549
|
+
blockTag?: 'latest' | 'earliest' | 'pending' | 'safe' | 'finalized';
|
|
550
|
+
/**
|
|
551
|
+
* The maximum gas limit for the transaction.
|
|
552
|
+
* @example 3000000
|
|
553
|
+
*/
|
|
554
|
+
gasLimit?: number;
|
|
555
|
+
/**
|
|
556
|
+
* The maximum fee per gas unit (EIP-1559).
|
|
557
|
+
* @example 20000000000n // 20 Gwei
|
|
558
|
+
*/
|
|
559
|
+
maxFeePerGas?: bigint;
|
|
560
|
+
/**
|
|
561
|
+
* The maximum priority fee per gas unit (EIP-1559).
|
|
562
|
+
* @example 1500000000n // 1.5 Gwei
|
|
563
|
+
*/
|
|
564
|
+
maxPriorityFeePerGas?: bigint;
|
|
565
|
+
}
|
|
566
|
+
/**
|
|
567
|
+
* Extended override parameters for EVM transaction execution.
|
|
568
|
+
*
|
|
569
|
+
* Includes all estimation overrides plus additional parameters
|
|
570
|
+
* specific to transaction execution.
|
|
571
|
+
*
|
|
572
|
+
* @interface EvmExecuteOverrides
|
|
573
|
+
* @extends EvmEstimateOverrides
|
|
574
|
+
*/
|
|
575
|
+
interface EvmExecuteOverrides extends EvmEstimateOverrides {
|
|
576
|
+
/**
|
|
577
|
+
* The nonce to use for the transaction.
|
|
578
|
+
* If not provided, the current nonce of the sender will be used.
|
|
579
|
+
* @example 42
|
|
580
|
+
*/
|
|
581
|
+
nonce?: number;
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* Prepared contract execution for EVM chains.
|
|
585
|
+
*
|
|
586
|
+
* Represents a prepared contract execution that can be estimated
|
|
587
|
+
* and executed on EVM-compatible chains.
|
|
588
|
+
*
|
|
589
|
+
* @interface EvmPreparedChainRequest
|
|
590
|
+
*/
|
|
591
|
+
interface EvmPreparedChainRequest {
|
|
592
|
+
/** The type of the prepared execution. */
|
|
593
|
+
type: 'evm';
|
|
594
|
+
/**
|
|
595
|
+
* Estimate the gas cost for the contract execution.
|
|
596
|
+
*
|
|
597
|
+
* @param overrides - Optional parameters to override the default estimation behavior
|
|
598
|
+
* @returns A promise that resolves to the estimated gas information
|
|
599
|
+
* @throws If the estimation fails
|
|
600
|
+
*/
|
|
601
|
+
estimate(overrides?: EvmEstimateOverrides): Promise<EstimatedGas>;
|
|
602
|
+
/**
|
|
603
|
+
* Execute the prepared contract call.
|
|
604
|
+
*
|
|
605
|
+
* @param overrides - Optional parameters to override the default execution behavior
|
|
606
|
+
* @returns A promise that resolves to the transaction hash
|
|
607
|
+
* @throws If the execution fails
|
|
608
|
+
*/
|
|
609
|
+
execute(overrides?: EvmExecuteOverrides): Promise<string>;
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* Union type for all supported prepared contract executions.
|
|
613
|
+
* Currently only supports EVM chains, but can be extended for other chains.
|
|
614
|
+
*/
|
|
615
|
+
type PreparedChainRequest = EvmPreparedChainRequest | SolanaPreparedChainRequest | NoopPreparedChainRequest;
|
|
616
|
+
/**
|
|
617
|
+
* Parameters for preparing an EVM contract execution.
|
|
618
|
+
*/
|
|
619
|
+
type EvmPreparedChainRequestParams = {
|
|
620
|
+
/** The type of the prepared execution. */
|
|
621
|
+
type: 'evm';
|
|
622
|
+
/** The ABI of the contract. */
|
|
623
|
+
abi: Abi | string[];
|
|
624
|
+
/** The address of the contract. */
|
|
625
|
+
address: `0x${string}`;
|
|
626
|
+
/** The name of the function to call. */
|
|
627
|
+
functionName: string;
|
|
628
|
+
/** The arguments to pass to the function. */
|
|
629
|
+
args: unknown[];
|
|
630
|
+
} & Partial<EvmEstimateOverrides>;
|
|
631
|
+
/**
|
|
632
|
+
* Solana-specific parameters for preparing a transaction.
|
|
633
|
+
* @interface SolanaPreparedChainRequestParams
|
|
634
|
+
*/
|
|
635
|
+
interface SolanaPreparedChainRequestParams {
|
|
636
|
+
/**
|
|
637
|
+
* The array of instructions to include in the transaction.
|
|
638
|
+
*/
|
|
639
|
+
instructions: TransactionInstruction[];
|
|
640
|
+
/**
|
|
641
|
+
* Additional signers besides the Adapter’s wallet (e.g. program-derived authorities).
|
|
642
|
+
*/
|
|
643
|
+
signers?: Signer[];
|
|
644
|
+
/**
|
|
645
|
+
* Optional override for how many compute units this transaction may consume.
|
|
646
|
+
* If omitted, the network’s default compute budget applies.
|
|
647
|
+
*/
|
|
648
|
+
computeUnitLimit?: number;
|
|
649
|
+
}
|
|
650
|
+
/**
|
|
651
|
+
* Solana-specific configuration for transaction estimation.
|
|
652
|
+
* @interface SolanaEstimateOverrides
|
|
653
|
+
*/
|
|
654
|
+
interface SolanaEstimateOverrides {
|
|
655
|
+
/** Optional compute unit limit for the transaction. */
|
|
656
|
+
computeUnitLimit?: number;
|
|
657
|
+
}
|
|
658
|
+
/**
|
|
659
|
+
* Solana-specific configuration for transaction execution.
|
|
660
|
+
* @interface SolanaExecuteOverrides
|
|
661
|
+
* @extends SolanaEstimateOverrides
|
|
662
|
+
*/
|
|
663
|
+
interface SolanaExecuteOverrides extends SolanaEstimateOverrides {
|
|
664
|
+
/** The commitment level for the transaction. */
|
|
665
|
+
preflightCommitment?: 'processed' | 'confirmed' | 'finalized';
|
|
666
|
+
/** The maximum number of retries for the transaction. */
|
|
667
|
+
maxRetries?: number;
|
|
668
|
+
/** Whether to skip the preflight check. */
|
|
669
|
+
skipPreflight?: boolean;
|
|
670
|
+
}
|
|
671
|
+
/**
|
|
672
|
+
* Solana-specific prepared chain request.
|
|
673
|
+
* @interface SolanaPreparedChainRequest
|
|
674
|
+
*/
|
|
675
|
+
interface SolanaPreparedChainRequest {
|
|
676
|
+
/** The type of the chain request. */
|
|
677
|
+
type: 'solana';
|
|
678
|
+
/** Estimate the compute units and fee for the transaction. */
|
|
679
|
+
estimate(overrides?: SolanaEstimateOverrides): Promise<EstimatedGas>;
|
|
680
|
+
/** Execute the prepared transaction. */
|
|
681
|
+
execute(overrides?: SolanaExecuteOverrides): Promise<string>;
|
|
682
|
+
}
|
|
683
|
+
/**
|
|
684
|
+
* No-op prepared chain request for unsupported operations.
|
|
685
|
+
*
|
|
686
|
+
* This interface represents a prepared chain request that performs no operation.
|
|
687
|
+
* It is returned when an action is not supported by the target chain or when
|
|
688
|
+
* no actual blockchain interaction is required.
|
|
689
|
+
*
|
|
690
|
+
* @remarks
|
|
691
|
+
* The estimate and execute methods return placeholder values since no actual
|
|
692
|
+
* transaction is performed. This allows the calling code to handle unsupported
|
|
693
|
+
* operations gracefully without breaking the expected interface contract.
|
|
694
|
+
*
|
|
695
|
+
* @example
|
|
696
|
+
* ```typescript
|
|
697
|
+
* const noopRequest: NoopPreparedChainRequest = {
|
|
698
|
+
* type: 'noop',
|
|
699
|
+
* estimate: async () => ({ gasLimit: 0n, gasPrice: 0n, totalFee: 0n }),
|
|
700
|
+
* execute: async () => '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
701
|
+
* }
|
|
702
|
+
* ```
|
|
703
|
+
*/
|
|
704
|
+
interface NoopPreparedChainRequest {
|
|
705
|
+
/** The type of the prepared request. */
|
|
706
|
+
type: 'noop';
|
|
707
|
+
/**
|
|
708
|
+
* Placeholder for the estimate method.
|
|
709
|
+
* @returns The estimated gas cost.
|
|
710
|
+
*/
|
|
711
|
+
estimate: () => Promise<EstimatedGas>;
|
|
712
|
+
/**
|
|
713
|
+
* Placeholder for the execute method.
|
|
714
|
+
* @returns The transaction hash.
|
|
715
|
+
*/
|
|
716
|
+
execute: () => Promise<string>;
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* Union type for all supported contract execution parameters.
|
|
720
|
+
* Currently only supports EVM chains, but can be extended for other chains.
|
|
721
|
+
*/
|
|
722
|
+
type PreparedChainRequestParams = EvmPreparedChainRequestParams | SolanaPreparedChainRequestParams;
|
|
723
|
+
/**
|
|
724
|
+
* Response from waiting for a transaction to be mined and confirmed on the blockchain.
|
|
725
|
+
*
|
|
726
|
+
* @interface WaitForTransactionResponse
|
|
727
|
+
*/
|
|
728
|
+
interface WaitForTransactionResponse {
|
|
729
|
+
/**
|
|
730
|
+
* The transaction hash identifier.
|
|
731
|
+
* @example "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"
|
|
732
|
+
*/
|
|
733
|
+
txHash: string;
|
|
734
|
+
/**
|
|
735
|
+
* The final status of the transaction execution.
|
|
736
|
+
* Indicates whether the transaction was successfully executed or reverted.
|
|
737
|
+
* @example "success", "reverted"
|
|
738
|
+
*/
|
|
739
|
+
status: 'success' | 'reverted';
|
|
740
|
+
/**
|
|
741
|
+
* The total amount of gas used by all transactions in the block up to and including this transaction.
|
|
742
|
+
* Represents the cumulative gas consumption within the block.
|
|
743
|
+
* @example 2100000n
|
|
744
|
+
*/
|
|
745
|
+
cumulativeGasUsed?: bigint;
|
|
746
|
+
/**
|
|
747
|
+
* The amount of gas actually consumed by this specific transaction.
|
|
748
|
+
* This value is always less than or equal to the gas limit set for the transaction.
|
|
749
|
+
* @example 21000n
|
|
750
|
+
*/
|
|
751
|
+
gasUsed?: bigint;
|
|
752
|
+
/**
|
|
753
|
+
* The block number where the transaction was mined.
|
|
754
|
+
* Represents the sequential position of the block in the blockchain.
|
|
755
|
+
* @example 18500000n
|
|
756
|
+
*/
|
|
757
|
+
blockNumber?: bigint;
|
|
758
|
+
/**
|
|
759
|
+
* The hash of the block containing this transaction.
|
|
760
|
+
* Provides a unique identifier for the block where the transaction was included.
|
|
761
|
+
* @example "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
|
|
762
|
+
*/
|
|
763
|
+
blockHash?: string;
|
|
764
|
+
/**
|
|
765
|
+
* The zero-based index position of the transaction within the block.
|
|
766
|
+
* Indicates the order in which this transaction appears in the block.
|
|
767
|
+
* @example 5
|
|
768
|
+
*/
|
|
769
|
+
transactionIndex?: number;
|
|
770
|
+
/**
|
|
771
|
+
* The actual gas price paid per unit of gas for this transaction.
|
|
772
|
+
* For EIP-1559 transactions, this reflects the base fee plus priority fee.
|
|
773
|
+
* @example 15000000000n // 15 Gwei
|
|
774
|
+
*/
|
|
775
|
+
effectiveGasPrice?: bigint;
|
|
776
|
+
}
|
|
777
|
+
interface WaitForTransactionConfig {
|
|
778
|
+
/**
|
|
779
|
+
* The timeout for the transaction to be mined and confirmed on the blockchain.
|
|
780
|
+
* @example 10000
|
|
781
|
+
*/
|
|
782
|
+
timeout?: number | undefined;
|
|
783
|
+
/**
|
|
784
|
+
* The number of confirmations to wait for the transaction to be mined and confirmed on the blockchain.
|
|
785
|
+
* @example 1
|
|
786
|
+
*/
|
|
787
|
+
confirmations?: number;
|
|
788
|
+
/**
|
|
789
|
+
* The maximum supported transaction version for getTransaction.
|
|
790
|
+
* Defaults to 0 if not provided.
|
|
791
|
+
* @example 0
|
|
792
|
+
*/
|
|
793
|
+
maxSupportedTransactionVersion?: number;
|
|
794
|
+
}
|
|
795
|
+
/**
|
|
796
|
+
* Type utility to extract the address context from adapter capabilities.
|
|
797
|
+
*
|
|
798
|
+
* @typeParam TAdapterCapabilities - The adapter capabilities type
|
|
799
|
+
* @returns The address context type or never if capabilities are undefined
|
|
800
|
+
*/
|
|
801
|
+
type ExtractAddressContext<TAdapterCapabilities extends AdapterCapabilities> = TAdapterCapabilities extends {
|
|
802
|
+
addressContext: infer TContext;
|
|
803
|
+
} ? TContext : never;
|
|
804
|
+
type AddressField<TAddressContext> = TAddressContext extends 'user-controlled' ? {
|
|
805
|
+
/**
|
|
806
|
+
* ℹ️ Address is forbidden for user-controlled adapters.
|
|
807
|
+
*
|
|
808
|
+
* User-controlled adapters (like browser wallets or private key adapters)
|
|
809
|
+
* automatically resolve the address from the connected wallet or signer.
|
|
810
|
+
* Providing an explicit address would conflict with this behavior.
|
|
811
|
+
*
|
|
812
|
+
* @example
|
|
813
|
+
* ```typescript
|
|
814
|
+
* // ℹ️ This will cause a TypeScript error:
|
|
815
|
+
* const context: AdapterContext<{ addressContext: 'user-controlled' }> = {
|
|
816
|
+
* adapter: userAdapter,
|
|
817
|
+
* chain: 'Ethereum',
|
|
818
|
+
* address: '0x123...' // Error: Address is forbidden for user-controlled adapters
|
|
819
|
+
* }
|
|
820
|
+
* ```
|
|
821
|
+
*/
|
|
822
|
+
address?: never;
|
|
823
|
+
} : TAddressContext extends 'developer-controlled' ? {
|
|
824
|
+
/**
|
|
825
|
+
* ℹ️ Address is required for developer-controlled adapters.
|
|
826
|
+
*
|
|
827
|
+
* Developer-controlled adapters (like enterprise providers or server-side adapters)
|
|
828
|
+
* require an explicit address for each operation since they don't have a single
|
|
829
|
+
* connected wallet. The address must be provided for every operation.
|
|
830
|
+
*
|
|
831
|
+
* @example
|
|
832
|
+
* ```typescript
|
|
833
|
+
* // ℹ️ This is required:
|
|
834
|
+
* const context: AdapterContext<{ addressContext: 'developer-controlled' }> = {
|
|
835
|
+
* adapter: devAdapter,
|
|
836
|
+
* chain: 'Ethereum',
|
|
837
|
+
* address: '0x123...' // Required for developer-controlled adapters
|
|
838
|
+
* }
|
|
839
|
+
*
|
|
840
|
+
* // ℹ️ This will cause a TypeScript error:
|
|
841
|
+
* const context: AdapterContext<{ addressContext: 'developer-controlled' }> = {
|
|
842
|
+
* adapter: devAdapter,
|
|
843
|
+
* chain: 'Ethereum'
|
|
844
|
+
* // Error: Address is required for developer-controlled adapters
|
|
845
|
+
* }
|
|
846
|
+
* ```
|
|
847
|
+
*/
|
|
848
|
+
address: string;
|
|
849
|
+
} : {
|
|
850
|
+
/**
|
|
851
|
+
* Address is optional for legacy adapters.
|
|
852
|
+
*
|
|
853
|
+
* Legacy adapters without defined capabilities maintain backward compatibility
|
|
854
|
+
* by allowing optional address specification.
|
|
855
|
+
*/
|
|
856
|
+
address?: string;
|
|
857
|
+
};
|
|
858
|
+
/**
|
|
859
|
+
* Generic operation context for adapter methods with compile-time address validation.
|
|
860
|
+
*
|
|
861
|
+
* This type provides compile-time enforcement of address requirements based on the
|
|
862
|
+
* adapter's capabilities. The address field behavior is determined by the adapter's
|
|
863
|
+
* address control model:
|
|
864
|
+
*
|
|
865
|
+
* - **User-controlled adapters** (default): The `address` field is forbidden (never) because
|
|
866
|
+
* the address is automatically resolved from the connected wallet or signer.
|
|
867
|
+
* - **Developer-controlled adapters**: The `address` field is required (string) because
|
|
868
|
+
* each operation must explicitly specify which address to use.
|
|
869
|
+
* - **Legacy adapters**: The `address` field remains optional for backward compatibility.
|
|
870
|
+
*
|
|
871
|
+
* @typeParam TAdapterCapabilities - The adapter capabilities type to derive address requirements from
|
|
872
|
+
*
|
|
873
|
+
* @example
|
|
874
|
+
* ```typescript
|
|
875
|
+
* import { OperationContext } from '@core/adapter'
|
|
876
|
+
*
|
|
877
|
+
* // User-controlled adapter context (default - address forbidden)
|
|
878
|
+
* type UserContext = OperationContext<{ addressContext: 'user-controlled', supportedChains: [] }>
|
|
879
|
+
* const userCtx: UserContext = {
|
|
880
|
+
* chain: 'Ethereum'
|
|
881
|
+
* // address: '0x123...' // ❌ TypeScript error: address not allowed
|
|
882
|
+
* }
|
|
883
|
+
*
|
|
884
|
+
* // Developer-controlled adapter context (explicit - address required)
|
|
885
|
+
* type DevContext = OperationContext<{ addressContext: 'developer-controlled', supportedChains: [] }>
|
|
886
|
+
* const devCtx: DevContext = {
|
|
887
|
+
* chain: 'Ethereum',
|
|
888
|
+
* address: '0x123...' // ✅ Required for developer-controlled
|
|
889
|
+
* }
|
|
890
|
+
* ```
|
|
891
|
+
*/
|
|
892
|
+
type OperationContext<TAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities> = {
|
|
893
|
+
/**
|
|
894
|
+
* The blockchain network to use for this operation.
|
|
895
|
+
*/
|
|
896
|
+
chain: ChainIdentifier;
|
|
897
|
+
} & AddressField<ExtractAddressContext<TAdapterCapabilities>>;
|
|
898
|
+
/**
|
|
899
|
+
* Fully resolved context for an adapter operation, with concrete chain and address.
|
|
900
|
+
*
|
|
901
|
+
* This interface guarantees that both the blockchain network (`chain`) and the account
|
|
902
|
+
* address (`address`) are present and valid. It is produced by resolving an {@link OperationContext},
|
|
903
|
+
* which may have optional or conditional fields, into a form suitable for internal logic and action handlers.
|
|
904
|
+
*
|
|
905
|
+
* - `chain`: A fully resolved {@link ChainDefinition}, either explicitly provided or inferred from the adapter.
|
|
906
|
+
* - `address`: A string representing the resolved account address, determined by the context or adapter,
|
|
907
|
+
* depending on the address control model (developer- or user-controlled).
|
|
908
|
+
*
|
|
909
|
+
* Use this type when an operation requires both the chain and address to be unambiguous and available.
|
|
910
|
+
*
|
|
911
|
+
* @example
|
|
912
|
+
* ```ts
|
|
913
|
+
* import { ResolvedOperationContext} from "@core/adapter"
|
|
914
|
+
* import { Solana, ChainDefinition } from '@core/chains';
|
|
915
|
+
*
|
|
916
|
+
* const context: ResolvedOperationContext = {
|
|
917
|
+
* chain: Solana,
|
|
918
|
+
* address: '7Gk1v...abc123', // a valid Solana address
|
|
919
|
+
* };
|
|
920
|
+
*
|
|
921
|
+
* // Use context.chain and context.address in adapter operations
|
|
922
|
+
* ```
|
|
923
|
+
*/
|
|
924
|
+
interface ResolvedOperationContext {
|
|
925
|
+
/**
|
|
926
|
+
* The chain identifier for this operation.
|
|
927
|
+
* Guaranteed to be defined - either from context or adapter default.
|
|
928
|
+
*/
|
|
929
|
+
chain: ChainDefinition;
|
|
930
|
+
/**
|
|
931
|
+
* The address for this operation.
|
|
932
|
+
* Guaranteed to be defined - either specified (developer-controlled) or resolved (user-controlled).
|
|
933
|
+
*/
|
|
934
|
+
address: string;
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
/**
|
|
938
|
+
* Base interface for all action parameter objects.
|
|
939
|
+
*
|
|
940
|
+
* Provide a compile-time marker to explicitly identify objects that represent
|
|
941
|
+
* action parameters (leaf nodes) versus namespace containers that should be
|
|
942
|
+
* traversed during type recursion.
|
|
943
|
+
*
|
|
944
|
+
* @remarks
|
|
945
|
+
* This marker property exists only at the type level and is stripped away
|
|
946
|
+
* during compilation. It serves as a deterministic way to identify action
|
|
947
|
+
* parameter objects without relying on property name heuristics.
|
|
948
|
+
*
|
|
949
|
+
* All action parameter objects must extend this interface to be properly
|
|
950
|
+
* recognized by the recursive utility types in the action system.
|
|
951
|
+
*/
|
|
952
|
+
interface ActionParameters {
|
|
953
|
+
/**
|
|
954
|
+
* Compile-time marker identifying this as an action parameter object.
|
|
955
|
+
*
|
|
956
|
+
* This property is used by the type system to distinguish between
|
|
957
|
+
* namespace containers and action parameter definitions. It does not
|
|
958
|
+
* exist at runtime and is purely for TypeScript's type checking.
|
|
959
|
+
*/
|
|
960
|
+
readonly __isActionParams: true;
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
/**
|
|
964
|
+
* EIP-2612 permit signature parameters for gasless token approvals.
|
|
965
|
+
*
|
|
966
|
+
* Contains the signature components and deadline required for permit-based
|
|
967
|
+
* token spending authorization without requiring separate approval transactions.
|
|
968
|
+
*
|
|
969
|
+
* @example
|
|
970
|
+
* ```typescript
|
|
971
|
+
* const permitParams: PermitParams = {
|
|
972
|
+
* deadline: BigInt(Math.floor(Date.now() / 1000) + 3600), // 1 hour from now
|
|
973
|
+
* v: 27,
|
|
974
|
+
* r: '0x1234567890abcdef...',
|
|
975
|
+
* s: '0xfedcba0987654321...'
|
|
976
|
+
* }
|
|
977
|
+
* ```
|
|
978
|
+
*/
|
|
979
|
+
interface PermitParams {
|
|
980
|
+
/**
|
|
981
|
+
* Permit expiration timestamp (Unix timestamp in seconds).
|
|
982
|
+
*
|
|
983
|
+
* The permit signature becomes invalid after this timestamp.
|
|
984
|
+
* Must be greater than the current block timestamp.
|
|
985
|
+
*/
|
|
986
|
+
deadline: bigint;
|
|
987
|
+
/**
|
|
988
|
+
* Recovery parameter of the ECDSA signature (27 or 28).
|
|
989
|
+
*
|
|
990
|
+
* Used to recover the public key from the signature components.
|
|
991
|
+
*/
|
|
992
|
+
v: number;
|
|
993
|
+
/**
|
|
994
|
+
* R component of the ECDSA signature.
|
|
995
|
+
*
|
|
996
|
+
* First 32 bytes of the signature as a hex string.
|
|
997
|
+
*/
|
|
998
|
+
r: string;
|
|
999
|
+
/**
|
|
1000
|
+
* S component of the ECDSA signature.
|
|
1001
|
+
*
|
|
1002
|
+
* Second 32 bytes of the signature as a hex string.
|
|
1003
|
+
*/
|
|
1004
|
+
s: string;
|
|
1005
|
+
}
|
|
1006
|
+
/**
|
|
1007
|
+
* Action map for Circle's Cross-Chain Transfer Protocol (CCTP) version 2 operations.
|
|
1008
|
+
*
|
|
1009
|
+
* Define the parameter schemas for CCTP v2 actions that enable native USDC
|
|
1010
|
+
* transfers between supported blockchain networks. Use Circle's attestation
|
|
1011
|
+
* service to verify and complete cross-chain transactions with cryptographic
|
|
1012
|
+
* proof of burn and mint operations.
|
|
1013
|
+
*
|
|
1014
|
+
* @remarks
|
|
1015
|
+
* CCTP v2 represents Circle's native cross-chain transfer protocol that allows
|
|
1016
|
+
* USDC to move between chains without traditional lock-and-mint bridging.
|
|
1017
|
+
* Instead, USDC is burned on the source chain and minted natively on the
|
|
1018
|
+
* destination chain using cryptographic attestations.
|
|
1019
|
+
*
|
|
1020
|
+
* The protocol supports both "slow" (free) and "fast" (fee-based) transfer
|
|
1021
|
+
* modes, with configurable finality thresholds and destination execution
|
|
1022
|
+
* parameters for advanced use cases.
|
|
1023
|
+
*
|
|
1024
|
+
* @example
|
|
1025
|
+
* ```typescript
|
|
1026
|
+
* import type { CCTPv2ActionMap } from '@core/adapter/actions/cctp/v2'
|
|
1027
|
+
* import { mainnet, polygon } from '@core/chains'
|
|
1028
|
+
*
|
|
1029
|
+
* // Deposit and burn USDC for cross-chain transfer
|
|
1030
|
+
* const burnParams: CCTPv2ActionMap['depositForBurn'] = {
|
|
1031
|
+
* amount: '1000000', // 1 USDC (6 decimals)
|
|
1032
|
+
* mintRecipient: '0x742d35Cc6634C0532925a3b8D8E5e8d8D8e5e8d8D8e5e8',
|
|
1033
|
+
* maxFee: '1000', // 0.001 USDC fast fee
|
|
1034
|
+
* minFinalityThreshold: 65,
|
|
1035
|
+
* fromChain: mainnet,
|
|
1036
|
+
* toChain: polygon
|
|
1037
|
+
* }
|
|
1038
|
+
*
|
|
1039
|
+
* // Receive and mint USDC on destination chain
|
|
1040
|
+
* const receiveParams: CCTPv2ActionMap['receiveMessage'] = {
|
|
1041
|
+
* eventNonce: '0x123abc...',
|
|
1042
|
+
* attestation: '0xdef456...',
|
|
1043
|
+
* message: '0x789012...',
|
|
1044
|
+
* fromChain: mainnet,
|
|
1045
|
+
* toChain: polygon
|
|
1046
|
+
* }
|
|
1047
|
+
* ```
|
|
1048
|
+
*
|
|
1049
|
+
* @see {@link ChainDefinitionWithCCTPv2} for supported chain definitions
|
|
1050
|
+
*/
|
|
1051
|
+
interface CCTPv2ActionMap {
|
|
1052
|
+
/**
|
|
1053
|
+
* Initiate a cross-chain USDC transfer by depositing and burning tokens on the source chain.
|
|
1054
|
+
*
|
|
1055
|
+
* Burn USDC tokens on the source chain and generate a message for attestation
|
|
1056
|
+
* by Circle's infrastructure. The burned tokens will be minted on the destination
|
|
1057
|
+
* chain once the attestation is obtained and the receive message is executed.
|
|
1058
|
+
*
|
|
1059
|
+
* @remarks
|
|
1060
|
+
* This action represents the first step in a CCTP cross-chain transfer. After
|
|
1061
|
+
* execution, you must wait for Circle's attestation service to observe the burn
|
|
1062
|
+
* event and provide a cryptographic attestation that can be used to mint the
|
|
1063
|
+
* equivalent amount on the destination chain.
|
|
1064
|
+
*
|
|
1065
|
+
* The `maxFee` parameter enables fast transfers through Circle's fast liquidity
|
|
1066
|
+
* network, where liquidity providers can fulfill transfers immediately in exchange
|
|
1067
|
+
* for a fee. Set to "0" for slower, free transfers that wait for full finality.
|
|
1068
|
+
*/
|
|
1069
|
+
depositForBurn: ActionParameters & {
|
|
1070
|
+
/**
|
|
1071
|
+
* Amount of USDC to deposit and burn (in token's smallest unit).
|
|
1072
|
+
*
|
|
1073
|
+
* Specify the amount in the token's atomic units (e.g., for USDC with
|
|
1074
|
+
* 6 decimals, "1000000" represents 1 USDC). This amount will be burned
|
|
1075
|
+
* on the source chain and minted on the destination chain.
|
|
1076
|
+
*/
|
|
1077
|
+
amount: bigint;
|
|
1078
|
+
/**
|
|
1079
|
+
* Address of the recipient who will receive minted tokens on the destination chain.
|
|
1080
|
+
*
|
|
1081
|
+
* Provide the destination address as a 32-byte hex string (bytes32 format).
|
|
1082
|
+
*/
|
|
1083
|
+
mintRecipient: string;
|
|
1084
|
+
/**
|
|
1085
|
+
* Address authorized to call receiveMessage on the destination chain.
|
|
1086
|
+
*
|
|
1087
|
+
* Restrict who can execute the final minting step on the destination chain.
|
|
1088
|
+
* If not specified or set to bytes32(0), any address can call receiveMessage.
|
|
1089
|
+
* Use this for advanced integrations requiring specific execution control.
|
|
1090
|
+
*
|
|
1091
|
+
* @defaultValue bytes32(0) - allows any address to complete the transfer
|
|
1092
|
+
*/
|
|
1093
|
+
destinationCaller?: string;
|
|
1094
|
+
/**
|
|
1095
|
+
* Maximum fee to pay for fast transfer fulfillment.
|
|
1096
|
+
*
|
|
1097
|
+
* Specify the maximum amount (in the same units as `amount`) you're willing
|
|
1098
|
+
* to pay for immediate liquidity. Set to "0" for free transfers that wait
|
|
1099
|
+
* for full chain finality. Higher fees increase the likelihood of fast
|
|
1100
|
+
* fulfillment.
|
|
1101
|
+
*/
|
|
1102
|
+
maxFee: bigint;
|
|
1103
|
+
/**
|
|
1104
|
+
* Minimum finality threshold for attestation eligibility.
|
|
1105
|
+
*
|
|
1106
|
+
* Set the number of confirmations required before Circle's attestation
|
|
1107
|
+
* service will observe and attest to the burn event. Higher values
|
|
1108
|
+
* provide stronger finality guarantees but increase transfer time.
|
|
1109
|
+
* Typical values: 1000 for fast transfers, 2000 for maximum security.
|
|
1110
|
+
*/
|
|
1111
|
+
minFinalityThreshold: number;
|
|
1112
|
+
/**
|
|
1113
|
+
* Source chain definition where tokens will be burned.
|
|
1114
|
+
*/
|
|
1115
|
+
fromChain: ChainDefinitionWithCCTPv2;
|
|
1116
|
+
/**
|
|
1117
|
+
* Destination chain definition where tokens will be minted.
|
|
1118
|
+
*/
|
|
1119
|
+
toChain: ChainDefinitionWithCCTPv2;
|
|
1120
|
+
};
|
|
1121
|
+
/**
|
|
1122
|
+
* Complete a cross-chain transfer by receiving and processing an attested message.
|
|
1123
|
+
*
|
|
1124
|
+
* Execute the final step of a CCTP transfer by submitting Circle's attestation
|
|
1125
|
+
* and the original message to mint USDC tokens on the destination chain.
|
|
1126
|
+
* This action consumes the attestation and delivers tokens to the specified
|
|
1127
|
+
* recipient from the original burn operation.
|
|
1128
|
+
*
|
|
1129
|
+
* @remarks
|
|
1130
|
+
* This action must be called after obtaining a valid attestation from Circle's
|
|
1131
|
+
* API for a corresponding `depositForBurn` operation. The attestation proves
|
|
1132
|
+
* that tokens were burned on the source chain and authorizes minting the
|
|
1133
|
+
* equivalent amount on the destination chain.
|
|
1134
|
+
*
|
|
1135
|
+
* The message parameter contains the original burn message data, while the
|
|
1136
|
+
* attestation provides the cryptographic proof. Both must match exactly
|
|
1137
|
+
* with Circle's records for the transaction to succeed.
|
|
1138
|
+
*/
|
|
1139
|
+
receiveMessage: ActionParameters & {
|
|
1140
|
+
/**
|
|
1141
|
+
* Unique nonce identifying the specific burn event.
|
|
1142
|
+
*
|
|
1143
|
+
* Provide the event nonce from the MessageSent event emitted by the
|
|
1144
|
+
* depositForBurn transaction. This must be a 0x-prefixed 64-character
|
|
1145
|
+
* hex string representing the 32-byte nonce value.
|
|
1146
|
+
*/
|
|
1147
|
+
readonly eventNonce: string;
|
|
1148
|
+
/**
|
|
1149
|
+
* Cryptographic attestation from Circle's infrastructure.
|
|
1150
|
+
*
|
|
1151
|
+
* Submit the attestation obtained from Circle's API that proves the
|
|
1152
|
+
* corresponding burn event occurred and was observed. This must be
|
|
1153
|
+
* a valid 0x-prefixed hex string containing Circle's signature data.
|
|
1154
|
+
*/
|
|
1155
|
+
readonly attestation: string;
|
|
1156
|
+
/**
|
|
1157
|
+
* Original message bytes from the source chain burn event.
|
|
1158
|
+
*
|
|
1159
|
+
* Provide the raw message data emitted in the MessageSent event from
|
|
1160
|
+
* the depositForBurn transaction. This 0x-prefixed hex string contains
|
|
1161
|
+
* the encoded transfer details that will be verified against the attestation.
|
|
1162
|
+
*/
|
|
1163
|
+
readonly message: string;
|
|
1164
|
+
/**
|
|
1165
|
+
* Source chain definition where the original burn occurred.
|
|
1166
|
+
*/
|
|
1167
|
+
readonly fromChain: ChainDefinitionWithCCTPv2;
|
|
1168
|
+
/**
|
|
1169
|
+
* Destination chain definition where tokens will be minted.
|
|
1170
|
+
*/
|
|
1171
|
+
readonly toChain: ChainDefinitionWithCCTPv2;
|
|
1172
|
+
/**
|
|
1173
|
+
* Optional destination wallet address on the destination chain to receive minted USDC.
|
|
1174
|
+
*
|
|
1175
|
+
* When provided (e.g., for Solana), the mint instruction will derive the
|
|
1176
|
+
* recipient's Associated Token Account (ATA) from this address instead of
|
|
1177
|
+
* the adapter's default address.
|
|
1178
|
+
*/
|
|
1179
|
+
readonly destinationAddress?: string;
|
|
1180
|
+
};
|
|
1181
|
+
/**
|
|
1182
|
+
* Initiate a cross-chain USDC transfer using a custom bridge contract with preapproval funnel.
|
|
1183
|
+
*
|
|
1184
|
+
* This action combines token approval and burning into a single transaction using
|
|
1185
|
+
* a custom bridge contract that supports preapproval functionality. It provides
|
|
1186
|
+
* enhanced gas efficiency by eliminating separate approval transactions while
|
|
1187
|
+
* maintaining the same developer interface as standard CCTP transfers.
|
|
1188
|
+
*
|
|
1189
|
+
* @remarks
|
|
1190
|
+
* This action is only available on chains that support custom bridge contracts,
|
|
1191
|
+
* as determined by `hasCustomContractSupport(chain, 'bridge')`. The custom bridge
|
|
1192
|
+
* handles token approval internally and supports advanced features like protocol
|
|
1193
|
+
* fees and custom routing logic.
|
|
1194
|
+
*
|
|
1195
|
+
* For basic use cases, this provides the same interface as `depositForBurn`.
|
|
1196
|
+
* For advanced use cases, optional protocol fee parameters enable custom fee
|
|
1197
|
+
* collection and revenue sharing models.
|
|
1198
|
+
*
|
|
1199
|
+
* @example
|
|
1200
|
+
* ```typescript
|
|
1201
|
+
* // Basic usage (same as depositForBurn)
|
|
1202
|
+
* await adapter.action('cctp.v2.customBurn', {
|
|
1203
|
+
* amount: BigInt('1000000'),
|
|
1204
|
+
* mintRecipient: '0x...',
|
|
1205
|
+
* maxFee: BigInt('1000'),
|
|
1206
|
+
* minFinalityThreshold: 65
|
|
1207
|
+
* })
|
|
1208
|
+
*
|
|
1209
|
+
* // Advanced usage with protocol fees
|
|
1210
|
+
* await adapter.action('cctp.v2.customBurn', {
|
|
1211
|
+
* amount: BigInt('1000000'),
|
|
1212
|
+
* mintRecipient: '0x...',
|
|
1213
|
+
* maxFee: BigInt('1000'),
|
|
1214
|
+
* minFinalityThreshold: 65,
|
|
1215
|
+
* protocolFee: BigInt('100'),
|
|
1216
|
+
* feeRecipient: '0xFeeRecipientAddress'
|
|
1217
|
+
* })
|
|
1218
|
+
* ```
|
|
1219
|
+
*/
|
|
1220
|
+
customBurn: ActionParameters & {
|
|
1221
|
+
/**
|
|
1222
|
+
* Amount of USDC to burn (in token's smallest unit).
|
|
1223
|
+
*
|
|
1224
|
+
* Specify the amount in the token's atomic units (e.g., for USDC with
|
|
1225
|
+
* 6 decimals, 1000000n represents 1 USDC). This amount will be burned
|
|
1226
|
+
* on the source chain and minted on the destination chain.
|
|
1227
|
+
*/
|
|
1228
|
+
amount: bigint;
|
|
1229
|
+
/**
|
|
1230
|
+
* Address of the recipient who will receive minted tokens on the destination chain.
|
|
1231
|
+
*
|
|
1232
|
+
* Provide the destination address as a 32-byte hex string (bytes32 format).
|
|
1233
|
+
*/
|
|
1234
|
+
mintRecipient: string;
|
|
1235
|
+
/**
|
|
1236
|
+
* Address authorized to call receiveMessage on the destination chain.
|
|
1237
|
+
*
|
|
1238
|
+
* Restrict who can execute the final minting step on the destination chain.
|
|
1239
|
+
* If not specified or set to bytes32(0), any address can call receiveMessage.
|
|
1240
|
+
* Use this for advanced integrations requiring specific execution control.
|
|
1241
|
+
*
|
|
1242
|
+
* @defaultValue bytes32(0) - allows any address to complete the transfer
|
|
1243
|
+
*/
|
|
1244
|
+
destinationCaller?: string;
|
|
1245
|
+
/**
|
|
1246
|
+
* Maximum fee to pay for fast transfer fulfillment.
|
|
1247
|
+
*
|
|
1248
|
+
* Specify the maximum amount (in the same units as `amount`) you're willing
|
|
1249
|
+
* to pay for immediate liquidity. Set to "0" for free transfers that wait
|
|
1250
|
+
* for full chain finality. Higher fees increase the likelihood of fast
|
|
1251
|
+
* fulfillment.
|
|
1252
|
+
*/
|
|
1253
|
+
maxFee: bigint;
|
|
1254
|
+
/**
|
|
1255
|
+
* Minimum finality threshold for attestation eligibility.
|
|
1256
|
+
*
|
|
1257
|
+
* Set the number of confirmations required before Circle's attestation
|
|
1258
|
+
* service will observe and attest to the burn event. Higher values
|
|
1259
|
+
* provide stronger finality guarantees but increase transfer time.
|
|
1260
|
+
* Typical values: 65 for standard transfers, 2000 for maximum security.
|
|
1261
|
+
*/
|
|
1262
|
+
minFinalityThreshold: number;
|
|
1263
|
+
/**
|
|
1264
|
+
* Protocol fee amount (in token's smallest unit).
|
|
1265
|
+
*
|
|
1266
|
+
* Additional fee charged by the custom bridge for enhanced functionality.
|
|
1267
|
+
* This fee is separate from the Circle fast transfer fee and is paid to
|
|
1268
|
+
* the specified fee recipient. Enables custom fee collection and revenue
|
|
1269
|
+
* sharing models for bridge operators.
|
|
1270
|
+
*
|
|
1271
|
+
* @defaultValue 0n - no protocol fee for basic usage
|
|
1272
|
+
*/
|
|
1273
|
+
protocolFee?: bigint | undefined;
|
|
1274
|
+
/**
|
|
1275
|
+
* Address to receive the protocol fee.
|
|
1276
|
+
*
|
|
1277
|
+
* Wallet address where the protocol fee will be sent. This enables
|
|
1278
|
+
* custom fee collection and revenue sharing models for bridge operators.
|
|
1279
|
+
* Only relevant when protocolFee is greater than 0.
|
|
1280
|
+
*
|
|
1281
|
+
* @defaultValue bridge contract address - safe fallback for zero fees
|
|
1282
|
+
*/
|
|
1283
|
+
feeRecipient?: string | undefined;
|
|
1284
|
+
/**
|
|
1285
|
+
* Source chain definition where tokens will be burned.
|
|
1286
|
+
*/
|
|
1287
|
+
fromChain: ChainDefinitionWithCCTPv2;
|
|
1288
|
+
/**
|
|
1289
|
+
* Destination chain definition where tokens will be minted.
|
|
1290
|
+
*/
|
|
1291
|
+
toChain: ChainDefinitionWithCCTPv2;
|
|
1292
|
+
/**
|
|
1293
|
+
* Permit parameters for the custom bridge contract.
|
|
1294
|
+
*/
|
|
1295
|
+
permitParams?: PermitParams;
|
|
1296
|
+
};
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
/**
|
|
1300
|
+
* Central registry for Cross-Chain Transfer Protocol (CCTP) action namespaces.
|
|
1301
|
+
*
|
|
1302
|
+
* Define versioned action maps for CCTP operations across different protocol
|
|
1303
|
+
* versions. Each version key represents a specific CCTP implementation with
|
|
1304
|
+
* its own parameter schemas and operational requirements.
|
|
1305
|
+
*
|
|
1306
|
+
* @remarks
|
|
1307
|
+
* CCTP actions enable cross-chain USDC transfers through Circle's native
|
|
1308
|
+
* bridging protocol. Each version namespace contains actions specific to
|
|
1309
|
+
* that protocol iteration, allowing for protocol upgrades while maintaining
|
|
1310
|
+
* backward compatibility in the action system.
|
|
1311
|
+
*
|
|
1312
|
+
* This interface follows the same pattern as other action namespaces but
|
|
1313
|
+
* is organized by protocol version rather than token type.
|
|
1314
|
+
*
|
|
1315
|
+
* @see {@link CCTPv2ActionMap} for version 2 action definitions
|
|
1316
|
+
*/
|
|
1317
|
+
interface CCTPActionMap {
|
|
1318
|
+
/** CCTP version 2 operations for cross-chain USDC transfers. */
|
|
1319
|
+
readonly v2: CCTPv2ActionMap;
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1322
|
+
interface TokenActionMap {
|
|
1323
|
+
/**
|
|
1324
|
+
* Set an allowance for a delegate to spend tokens on behalf of the wallet.
|
|
1325
|
+
*
|
|
1326
|
+
* On chains without native allowance support, this may return a noop result
|
|
1327
|
+
* indicating the step can be safely skipped.
|
|
1328
|
+
*/
|
|
1329
|
+
approve: ActionParameters & {
|
|
1330
|
+
/**
|
|
1331
|
+
* The contract address of the token.
|
|
1332
|
+
*/
|
|
1333
|
+
tokenAddress: string;
|
|
1334
|
+
/**
|
|
1335
|
+
* The address that will be approved to spend the tokens.
|
|
1336
|
+
*/
|
|
1337
|
+
delegate: string;
|
|
1338
|
+
/**
|
|
1339
|
+
* The amount of tokens to approve for spending (in token's smallest unit).
|
|
1340
|
+
*/
|
|
1341
|
+
amount: bigint;
|
|
1342
|
+
};
|
|
1343
|
+
/**
|
|
1344
|
+
* Check the current allowance between an owner and spender for any token.
|
|
1345
|
+
*
|
|
1346
|
+
* On chains without allowance support, this typically returns the maximum
|
|
1347
|
+
* possible value to indicate unlimited spending capability.
|
|
1348
|
+
*/
|
|
1349
|
+
allowance: ActionParameters & {
|
|
1350
|
+
/**
|
|
1351
|
+
* The contract address of the token.
|
|
1352
|
+
*/
|
|
1353
|
+
tokenAddress: string;
|
|
1354
|
+
/**
|
|
1355
|
+
* The address of the wallet that owns the tokens. If not provided, it will be
|
|
1356
|
+
* automatically derived from the adapter context.
|
|
1357
|
+
*/
|
|
1358
|
+
walletAddress?: string | undefined;
|
|
1359
|
+
/**
|
|
1360
|
+
* The address to check the allowance for.
|
|
1361
|
+
*/
|
|
1362
|
+
delegate: string;
|
|
1363
|
+
};
|
|
1364
|
+
/**
|
|
1365
|
+
* Transfer tokens directly from the wallet to another address.
|
|
1366
|
+
*/
|
|
1367
|
+
transfer: ActionParameters & {
|
|
1368
|
+
/**
|
|
1369
|
+
* The contract address of the token.
|
|
1370
|
+
*/
|
|
1371
|
+
tokenAddress: string;
|
|
1372
|
+
/**
|
|
1373
|
+
* The address to send the tokens to.
|
|
1374
|
+
*/
|
|
1375
|
+
to: string;
|
|
1376
|
+
/**
|
|
1377
|
+
* The amount of tokens to transfer (in token's smallest unit).
|
|
1378
|
+
*/
|
|
1379
|
+
amount: bigint;
|
|
1380
|
+
};
|
|
1381
|
+
/**
|
|
1382
|
+
* Transfer tokens from one address to another using a pre-approved allowance.
|
|
1383
|
+
*
|
|
1384
|
+
* On chains without allowance support, this may behave differently or throw
|
|
1385
|
+
* an error if the operation is not supported.
|
|
1386
|
+
*/
|
|
1387
|
+
transferFrom: ActionParameters & {
|
|
1388
|
+
/**
|
|
1389
|
+
* The contract address of the token.
|
|
1390
|
+
*/
|
|
1391
|
+
tokenAddress: string;
|
|
1392
|
+
/**
|
|
1393
|
+
* The address to transfer tokens from (must have given allowance to the caller).
|
|
1394
|
+
*/
|
|
1395
|
+
from: string;
|
|
1396
|
+
/**
|
|
1397
|
+
* The address to send the tokens to.
|
|
1398
|
+
*/
|
|
1399
|
+
to: string;
|
|
1400
|
+
/**
|
|
1401
|
+
* The amount of tokens to transfer (in token's smallest unit).
|
|
1402
|
+
*/
|
|
1403
|
+
amount: bigint;
|
|
1404
|
+
};
|
|
1405
|
+
/**
|
|
1406
|
+
* Get the current token balance for a wallet address.
|
|
1407
|
+
*/
|
|
1408
|
+
balanceOf: ActionParameters & {
|
|
1409
|
+
/**
|
|
1410
|
+
* The contract address of the token.
|
|
1411
|
+
*/
|
|
1412
|
+
tokenAddress: string;
|
|
1413
|
+
/**
|
|
1414
|
+
* The address to check the balance for. If not provided, it will be
|
|
1415
|
+
* automatically derived from the adapter context.
|
|
1416
|
+
*/
|
|
1417
|
+
walletAddress?: string | undefined;
|
|
1418
|
+
};
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1421
|
+
/**
|
|
1422
|
+
* USDC-specific operations that automatically resolve the token address.
|
|
1423
|
+
*
|
|
1424
|
+
* These include all standard ERC20 operations plus additional safety functions
|
|
1425
|
+
* that USDC supports. The interface provides the same core operations as
|
|
1426
|
+
* {@link TokenActionMap} but without requiring a `tokenAddress` parameter,
|
|
1427
|
+
* plus additional USDC-specific extensions.
|
|
1428
|
+
*
|
|
1429
|
+
* @example
|
|
1430
|
+
* ```typescript
|
|
1431
|
+
* // USDC operations (address auto-resolved)
|
|
1432
|
+
* await adapter.action('usdc.approve', {
|
|
1433
|
+
* delegate: '0x1234...',
|
|
1434
|
+
* amount: '1000000' // 1 USDC
|
|
1435
|
+
* })
|
|
1436
|
+
*
|
|
1437
|
+
* // USDC-specific safe allowance functions
|
|
1438
|
+
* await adapter.action('usdc.increaseAllowance', {
|
|
1439
|
+
* delegate: '0x1234...',
|
|
1440
|
+
* amount: '500000' // increase by 0.5 USDC
|
|
1441
|
+
* })
|
|
1442
|
+
*
|
|
1443
|
+
* // vs. general token operations (address required)
|
|
1444
|
+
* await adapter.action('token.approve', {
|
|
1445
|
+
* tokenAddress: '0xA0b86a33E6441c8C1c7C16e4c5e3e5b5e4c5e3e5b5e4c5e',
|
|
1446
|
+
* delegate: '0x1234...',
|
|
1447
|
+
* amount: '1000000'
|
|
1448
|
+
* })
|
|
1449
|
+
* ```
|
|
1450
|
+
*/
|
|
1451
|
+
type BaseUSDCActions = {
|
|
1452
|
+
[K in keyof TokenActionMap]: Omit<TokenActionMap[K], 'tokenAddress'>;
|
|
1453
|
+
};
|
|
1454
|
+
/**
|
|
1455
|
+
* USDC action map with both standard ERC20 operations and USDC-specific extensions.
|
|
1456
|
+
*
|
|
1457
|
+
* This provides all standard token operations plus additional safety functions
|
|
1458
|
+
* that USDC implements beyond the base ERC20 standard.
|
|
1459
|
+
*/
|
|
1460
|
+
interface USDCActionMap {
|
|
1461
|
+
/**
|
|
1462
|
+
* Set an allowance for a delegate to spend USDC tokens on behalf of the wallet.
|
|
1463
|
+
*
|
|
1464
|
+
* Automatically uses the USDC contract address for the current chain.
|
|
1465
|
+
* On chains without native allowance support, this may return a noop result.
|
|
1466
|
+
*/
|
|
1467
|
+
approve: BaseUSDCActions['approve'];
|
|
1468
|
+
/**
|
|
1469
|
+
* Check the current allowance between an owner and spender for USDC tokens.
|
|
1470
|
+
*
|
|
1471
|
+
* Automatically uses the USDC contract address for the current chain.
|
|
1472
|
+
* This is a read-only operation.
|
|
1473
|
+
*/
|
|
1474
|
+
allowance: BaseUSDCActions['allowance'];
|
|
1475
|
+
/**
|
|
1476
|
+
* Safely increase the allowance for a delegate to spend USDC tokens.
|
|
1477
|
+
*
|
|
1478
|
+
* This is a USDC-specific function that provides safer allowance management
|
|
1479
|
+
* compared to direct approve() calls. Automatically uses the USDC contract
|
|
1480
|
+
* address for the current chain.
|
|
1481
|
+
*/
|
|
1482
|
+
increaseAllowance: ActionParameters & {
|
|
1483
|
+
/**
|
|
1484
|
+
* The address that will have their allowance increased.
|
|
1485
|
+
*/
|
|
1486
|
+
delegate: string;
|
|
1487
|
+
/**
|
|
1488
|
+
* The amount to increase the allowance by (in USDC's smallest unit).
|
|
1489
|
+
*/
|
|
1490
|
+
amount: bigint;
|
|
1491
|
+
/**
|
|
1492
|
+
* The chain definition for the current chain.
|
|
1493
|
+
*/
|
|
1494
|
+
chain?: ChainDefinition;
|
|
1495
|
+
};
|
|
1496
|
+
/**
|
|
1497
|
+
* Safely decrease the allowance for a delegate to spend USDC tokens.
|
|
1498
|
+
*
|
|
1499
|
+
* This is a USDC-specific function that provides safer allowance management.
|
|
1500
|
+
* Automatically uses the USDC contract address for the current chain.
|
|
1501
|
+
*/
|
|
1502
|
+
decreaseAllowance: ActionParameters & {
|
|
1503
|
+
/**
|
|
1504
|
+
* The address that will have their allowance decreased.
|
|
1505
|
+
*/
|
|
1506
|
+
delegate: string;
|
|
1507
|
+
/**
|
|
1508
|
+
* The amount to decrease the allowance by (in USDC's smallest unit).
|
|
1509
|
+
*/
|
|
1510
|
+
amount: bigint;
|
|
1511
|
+
};
|
|
1512
|
+
/**
|
|
1513
|
+
* Transfer USDC tokens directly from the wallet to another address.
|
|
1514
|
+
*
|
|
1515
|
+
* Automatically uses the USDC contract address for the current chain.
|
|
1516
|
+
*/
|
|
1517
|
+
transfer: BaseUSDCActions['transfer'];
|
|
1518
|
+
/**
|
|
1519
|
+
* Transfer USDC tokens from one address to another using a pre-approved allowance.
|
|
1520
|
+
*
|
|
1521
|
+
* Automatically uses the USDC contract address for the current chain.
|
|
1522
|
+
* The caller must have sufficient allowance from the 'from' address.
|
|
1523
|
+
*/
|
|
1524
|
+
transferFrom: BaseUSDCActions['transferFrom'];
|
|
1525
|
+
/**
|
|
1526
|
+
* Get the current USDC balance for a wallet address.
|
|
1527
|
+
*
|
|
1528
|
+
* Automatically uses the USDC contract address for the current chain.
|
|
1529
|
+
* This is a read-only operation.
|
|
1530
|
+
*/
|
|
1531
|
+
balanceOf: Omit<BaseUSDCActions['balanceOf'], 'tokenAddress'>;
|
|
1532
|
+
}
|
|
1533
|
+
|
|
1534
|
+
/**
|
|
1535
|
+
* Central registry of all available action namespaces and their operations.
|
|
1536
|
+
*
|
|
1537
|
+
* Define the complete action map structure used throughout the bridge kit.
|
|
1538
|
+
* Each top-level key represents a namespace (e.g., 'token', 'usdc') containing
|
|
1539
|
+
* related operations. The structure supports arbitrary nesting depth through
|
|
1540
|
+
* the recursive utility types provided in this module.
|
|
1541
|
+
*
|
|
1542
|
+
* @remarks
|
|
1543
|
+
* This interface serves as the foundation for type-safe action dispatching
|
|
1544
|
+
* and provides compile-time validation of action keys and payload types.
|
|
1545
|
+
* All action-related utility types derive from this central definition.
|
|
1546
|
+
*
|
|
1547
|
+
* @see {@link ActionKeys} for dot-notation action paths
|
|
1548
|
+
* @see {@link ActionPayload} for extracting payload types
|
|
1549
|
+
*/
|
|
1550
|
+
interface ActionMap {
|
|
1551
|
+
/** CCTP-specific operations with automatic address resolution. */
|
|
1552
|
+
readonly cctp: CCTPActionMap;
|
|
1553
|
+
/** General token operations requiring explicit token addresses. */
|
|
1554
|
+
readonly token: TokenActionMap;
|
|
1555
|
+
/** USDC-specific operations with automatic address resolution. */
|
|
1556
|
+
readonly usdc: USDCActionMap;
|
|
1557
|
+
}
|
|
1558
|
+
/**
|
|
1559
|
+
* Determine if a type represents an action parameter object (leaf node).
|
|
1560
|
+
*
|
|
1561
|
+
* Check whether a type extends the ActionParameters interface, which provides
|
|
1562
|
+
* an explicit marker for identifying action parameter objects versus namespace
|
|
1563
|
+
* containers that should be traversed during type recursion.
|
|
1564
|
+
*
|
|
1565
|
+
* @typeParam T - The type to examine for parameter object characteristics
|
|
1566
|
+
*
|
|
1567
|
+
* @remarks
|
|
1568
|
+
* This utility type provides deterministic leaf detection for the recursive
|
|
1569
|
+
* type system. By requiring all action parameter objects to extend the
|
|
1570
|
+
* ActionParameters interface, we eliminate the need for property name
|
|
1571
|
+
* heuristics and make the system more maintainable.
|
|
1572
|
+
*
|
|
1573
|
+
* @see {@link ActionParameters} for the base interface
|
|
1574
|
+
* @see {@link NestedKeys} for usage in path extraction
|
|
1575
|
+
*/
|
|
1576
|
+
type IsActionParameterObject<T> = T extends ActionParameters ? true : false;
|
|
1577
|
+
/**
|
|
1578
|
+
* Recursively extract all nested keys from an object type as dot-notation string literals.
|
|
1579
|
+
*
|
|
1580
|
+
* Traverse object structures of arbitrary depth and generate string literal
|
|
1581
|
+
* types representing all possible paths through the structure using dot
|
|
1582
|
+
* notation. Stop recursion when encountering action parameter objects (leaves).
|
|
1583
|
+
*
|
|
1584
|
+
* @typeParam T - The object type to extract nested keys from
|
|
1585
|
+
*
|
|
1586
|
+
* @remarks
|
|
1587
|
+
* This type is the foundation for generating type-safe action paths in
|
|
1588
|
+
* dot notation. It automatically adapts to changes in the ActionMap
|
|
1589
|
+
* structure and supports unlimited nesting depth for future extensibility.
|
|
1590
|
+
*
|
|
1591
|
+
* The recursion stops when it encounters objects that match the
|
|
1592
|
+
* {@link IsActionParameterObject} criteria, ensuring that only valid
|
|
1593
|
+
* action paths are generated.
|
|
1594
|
+
*
|
|
1595
|
+
* @see {@link ActionKeys} for ActionMap-specific paths
|
|
1596
|
+
* @see {@link NestedValue} for extracting types at specific paths
|
|
1597
|
+
* @see {@link IsActionParameterObject} for leaf detection logic
|
|
1598
|
+
*/
|
|
1599
|
+
type NestedKeys<T> = {
|
|
1600
|
+
[K in Extract<keyof T, string>]: IsActionParameterObject<T[K]> extends true ? K : T[K] extends object ? `${K}.${NestedKeys<T[K]>}` : never;
|
|
1601
|
+
}[Extract<keyof T, string>];
|
|
1602
|
+
/**
|
|
1603
|
+
* Recursively extract the value type at a given dot-notation path.
|
|
1604
|
+
*
|
|
1605
|
+
* Navigate through nested object types using a dot-notation string path
|
|
1606
|
+
* and return the type of the value at that location. Parse the path
|
|
1607
|
+
* recursively by splitting on dots and traversing the object structure.
|
|
1608
|
+
*
|
|
1609
|
+
* @typeParam T - The object type to navigate through
|
|
1610
|
+
* @typeParam K - The dot-notation path as a string literal type
|
|
1611
|
+
*
|
|
1612
|
+
* @remarks
|
|
1613
|
+
* This utility type enables type-safe access to deeply nested object
|
|
1614
|
+
* properties using dot notation paths. It forms the foundation for
|
|
1615
|
+
* extracting payload types from action paths in the ActionMap.
|
|
1616
|
+
*
|
|
1617
|
+
* @see {@link ActionPayload} for ActionMap-specific value extraction
|
|
1618
|
+
* @see {@link NestedKeys} for generating valid path types
|
|
1619
|
+
*/
|
|
1620
|
+
type NestedValue<T, K extends string> = K extends `${infer First}.${infer Rest}` ? First extends keyof T ? NestedValue<T[First], Rest> : never : K extends keyof T ? T[K] : never;
|
|
1621
|
+
/**
|
|
1622
|
+
* Union type of all nested action keys in dot notation.
|
|
1623
|
+
*
|
|
1624
|
+
* Generate string literal types for all possible action paths in the
|
|
1625
|
+
* ActionMap structure. Automatically adapt to changes in the ActionMap
|
|
1626
|
+
* and support arbitrary levels of nesting for future extensibility.
|
|
1627
|
+
*
|
|
1628
|
+
* @remarks
|
|
1629
|
+
* This type serves as the canonical source for all valid action identifiers
|
|
1630
|
+
* in the bridge kit. It ensures compile-time validation of action keys
|
|
1631
|
+
* and enables type-safe action dispatching throughout the application.
|
|
1632
|
+
*
|
|
1633
|
+
* @see {@link ActionPayload} for extracting parameter types
|
|
1634
|
+
* @see {@link NamespaceActions} for namespace-specific actions
|
|
1635
|
+
* @see {@link ActionMap} for the underlying structure
|
|
1636
|
+
*/
|
|
1637
|
+
type ActionKeys = NestedKeys<ActionMap>;
|
|
1638
|
+
/**
|
|
1639
|
+
* Extract the payload type for a specific action based on its dot-notation key.
|
|
1640
|
+
*
|
|
1641
|
+
* Resolve the parameter type for any action by providing its complete path
|
|
1642
|
+
* in dot notation. Leverage the recursive NestedValue type to navigate to
|
|
1643
|
+
* the correct payload type regardless of nesting depth. The internal
|
|
1644
|
+
* ActionParameters marker is automatically removed from the result.
|
|
1645
|
+
*
|
|
1646
|
+
* @typeParam T - The action key in dot notation (must extend ActionKeys)
|
|
1647
|
+
*
|
|
1648
|
+
* @remarks
|
|
1649
|
+
* This utility type enables type-safe parameter passing for action
|
|
1650
|
+
* dispatching. It automatically infers the correct parameter shape
|
|
1651
|
+
* based on the action key, providing compile-time validation and
|
|
1652
|
+
* excellent IntelliSense support.
|
|
1653
|
+
*
|
|
1654
|
+
* The internal `__isActionParams` marker used for type system recursion
|
|
1655
|
+
* is automatically omitted from the resulting type, providing clean
|
|
1656
|
+
* parameter objects for consumers.
|
|
1657
|
+
*
|
|
1658
|
+
* @see {@link ActionKeys} for available action identifiers
|
|
1659
|
+
* @see {@link NestedValue} for the underlying path resolution logic
|
|
1660
|
+
*/
|
|
1661
|
+
type ActionPayload<T extends ActionKeys> = Omit<NestedValue<ActionMap, T>, '__isActionParams'>;
|
|
1662
|
+
|
|
1663
|
+
/**
|
|
1664
|
+
* Type-safe action handler function signature for specific action types.
|
|
1665
|
+
*
|
|
1666
|
+
* Defines the contract for functions that process action payloads and return
|
|
1667
|
+
* prepared chain requests. Each handler is strongly typed to accept only the
|
|
1668
|
+
* payload structure corresponding to its specific action key.
|
|
1669
|
+
*
|
|
1670
|
+
* @typeParam TActionKey - The specific action key this handler processes.
|
|
1671
|
+
* @param params - The action payload matching the specified action key.
|
|
1672
|
+
* @param context - The resolved operation context with concrete chain and address values.
|
|
1673
|
+
* @returns A promise resolving to a prepared chain request.
|
|
1674
|
+
*
|
|
1675
|
+
* @example
|
|
1676
|
+
* ```typescript
|
|
1677
|
+
* import type { ActionHandler } from '@core/adapter'
|
|
1678
|
+
*
|
|
1679
|
+
* const depositHandler: ActionHandler<'cctp.v2.depositForBurn'> = async (params, context) => {
|
|
1680
|
+
* // context is always defined and has concrete chain and address values
|
|
1681
|
+
* console.log(context.chain.name);
|
|
1682
|
+
* console.log(context.address);
|
|
1683
|
+
* // ... handler logic ...
|
|
1684
|
+
* return preparedRequest;
|
|
1685
|
+
* }
|
|
1686
|
+
* ```
|
|
1687
|
+
*/
|
|
1688
|
+
type ActionHandler$1<TActionKey extends ActionKeys> = (params: ActionPayload<TActionKey>, context: ResolvedOperationContext) => Promise<PreparedChainRequest>;
|
|
1689
|
+
/**
|
|
1690
|
+
* Type-safe mapping of all available action keys to their corresponding handlers.
|
|
1691
|
+
*
|
|
1692
|
+
* This type defines a registry object where each key is a valid action key
|
|
1693
|
+
* (as defined by {@link ActionKeys}) and each value is an {@link ActionHandler}
|
|
1694
|
+
* capable of processing the payload for that action. This enables strongly-typed
|
|
1695
|
+
* handler registration and lookup for all supported actions in the Stablecoin Kits.
|
|
1696
|
+
*
|
|
1697
|
+
* @remarks
|
|
1698
|
+
* Each handler is typed as {@link ActionHandler}, which means the handler
|
|
1699
|
+
* must accept the payload type for the specific action key it is registered under.
|
|
1700
|
+
* This provides type safety for handler registration and execution, but does not
|
|
1701
|
+
* enforce per-key handler parameterization at the type level. For stricter per-key
|
|
1702
|
+
* typing, consider using mapped types or generic registry patterns.
|
|
1703
|
+
*
|
|
1704
|
+
* @example
|
|
1705
|
+
* ```typescript
|
|
1706
|
+
* import type { ActionHandlers } from '@core/adapter'
|
|
1707
|
+
* import type { ActionHandler } from '@core/adapter'
|
|
1708
|
+
*
|
|
1709
|
+
* const handlers: ActionHandlers = {
|
|
1710
|
+
* 'cctp.v2.depositForBurn': async (params, resolved) => {
|
|
1711
|
+
* // params is correctly typed for 'cctp.v2.depositForBurn'
|
|
1712
|
+
* // resolved has concrete chain and address values
|
|
1713
|
+
* // ...handler logic...
|
|
1714
|
+
* },
|
|
1715
|
+
* 'usdc.approve': async (params, resolved) => {
|
|
1716
|
+
* // params is correctly typed for 'usdc.approve'
|
|
1717
|
+
* // resolved has concrete chain and address values
|
|
1718
|
+
* // ...handler logic...
|
|
1719
|
+
* }
|
|
1720
|
+
* }
|
|
1721
|
+
* ```
|
|
1722
|
+
*/
|
|
1723
|
+
type ActionHandlers = {
|
|
1724
|
+
[K in ActionKeys]?: ActionHandler$1<K>;
|
|
1725
|
+
};
|
|
1726
|
+
/**
|
|
1727
|
+
* Type-safe registry for managing and executing blockchain action handlers.
|
|
1728
|
+
*
|
|
1729
|
+
* Provides a centralized system for registering action handlers with full
|
|
1730
|
+
* TypeScript type safety, ensuring that handlers can only be registered
|
|
1731
|
+
* with compatible action keys and payload types. Supports both individual
|
|
1732
|
+
* handler registration and batch registration operations.
|
|
1733
|
+
*
|
|
1734
|
+
* @remarks
|
|
1735
|
+
* The registry uses a Map internally for O(1) lookups and maintains type
|
|
1736
|
+
* safety through generic constraints and careful type assertions. All
|
|
1737
|
+
* type assertions are validated at registration time to ensure runtime
|
|
1738
|
+
* type safety matches compile-time guarantees.
|
|
1739
|
+
*/
|
|
1740
|
+
declare class ActionRegistry {
|
|
1741
|
+
readonly actionHandlers: Map<ActionKeys, ActionHandler$1<ActionKeys>>;
|
|
1742
|
+
/**
|
|
1743
|
+
* Register a type-safe action handler for a specific action key.
|
|
1744
|
+
*
|
|
1745
|
+
* Associates an action handler function with its corresponding action key,
|
|
1746
|
+
* ensuring compile-time type safety between the action and its expected
|
|
1747
|
+
* payload structure. The handler will be available for execution via
|
|
1748
|
+
* {@link executeAction}.
|
|
1749
|
+
*
|
|
1750
|
+
* @typeParam TActionKey - The specific action key being registered.
|
|
1751
|
+
* @param action - The action key to register the handler for.
|
|
1752
|
+
* @param handler - The handler function for processing this action type.
|
|
1753
|
+
* @returns Void.
|
|
1754
|
+
*
|
|
1755
|
+
* @throws Error When action parameter is not a valid string.
|
|
1756
|
+
* @throws TypeError When handler parameter is not a function.
|
|
1757
|
+
*
|
|
1758
|
+
* @example
|
|
1759
|
+
* ```typescript
|
|
1760
|
+
* import { ActionRegistry } from '@core/adapter'
|
|
1761
|
+
* import type { ActionHandler } from '@core/adapter'
|
|
1762
|
+
*
|
|
1763
|
+
* const registry = new ActionRegistry()
|
|
1764
|
+
*
|
|
1765
|
+
* // Register a CCTP deposit handler
|
|
1766
|
+
* const depositHandler: ActionHandler<'cctp.v2.depositForBurn'> = async (params, resolved) => {
|
|
1767
|
+
* console.log('Processing deposit:', params.amount)
|
|
1768
|
+
* return {
|
|
1769
|
+
* chainId: params.chainId,
|
|
1770
|
+
* data: '0x...',
|
|
1771
|
+
* to: '0x...',
|
|
1772
|
+
* value: '0'
|
|
1773
|
+
* }
|
|
1774
|
+
* }
|
|
1775
|
+
*
|
|
1776
|
+
* registry.registerHandler('cctp.v2.depositForBurn', depositHandler)
|
|
1777
|
+
* ```
|
|
1778
|
+
*/
|
|
1779
|
+
registerHandler<TActionKey extends ActionKeys>(action: TActionKey, handler: ActionHandler$1<TActionKey>): void;
|
|
1780
|
+
/**
|
|
1781
|
+
* Register multiple action handlers in a single operation.
|
|
1782
|
+
*
|
|
1783
|
+
* Efficiently register multiple handlers from a record object, where keys
|
|
1784
|
+
* are action identifiers and values are their corresponding handler
|
|
1785
|
+
* functions. Provides a convenient way to bulk-register handlers while
|
|
1786
|
+
* maintaining type safety.
|
|
1787
|
+
*
|
|
1788
|
+
* @param handlers - A record mapping action keys to their handler functions.
|
|
1789
|
+
* @returns Void.
|
|
1790
|
+
*
|
|
1791
|
+
* @throws {Error} When handlers parameter is not a valid object.
|
|
1792
|
+
* @throws {Error} When any individual handler registration fails.
|
|
1793
|
+
*
|
|
1794
|
+
* @example
|
|
1795
|
+
* ```typescript
|
|
1796
|
+
* import { ActionRegistry } from '@core/adapter'
|
|
1797
|
+
* import type { ActionHandler, ActionHandlers } from '@core/adapter'
|
|
1798
|
+
*
|
|
1799
|
+
* const registry = new ActionRegistry()
|
|
1800
|
+
*
|
|
1801
|
+
* // Register multiple handlers at once
|
|
1802
|
+
* const tokenHandlers: ActionHandlers = {
|
|
1803
|
+
* 'token.approve': async (params, resolved) => ({
|
|
1804
|
+
* chainId: resolved.chain,
|
|
1805
|
+
* data: '0x095ea7b3...',
|
|
1806
|
+
* to: params.tokenAddress,
|
|
1807
|
+
* value: '0'
|
|
1808
|
+
* }),
|
|
1809
|
+
* 'token.transfer': async (params, resolved) => ({
|
|
1810
|
+
* chainId: resolved.chain,
|
|
1811
|
+
* data: '0xa9059cbb...',
|
|
1812
|
+
* to: params.tokenAddress,
|
|
1813
|
+
* value: '0'
|
|
1814
|
+
* })
|
|
1815
|
+
* }
|
|
1816
|
+
*
|
|
1817
|
+
* registry.registerHandlers(tokenHandlers)
|
|
1818
|
+
* console.log('Registered multiple token handlers')
|
|
1819
|
+
* ```
|
|
1820
|
+
*/
|
|
1821
|
+
registerHandlers(handlers: ActionHandlers): void;
|
|
1822
|
+
/**
|
|
1823
|
+
* Check whether a specific action is supported by this registry.
|
|
1824
|
+
*
|
|
1825
|
+
* Determine if a handler has been registered for the given action key.
|
|
1826
|
+
* Use this method to conditionally execute actions or provide appropriate
|
|
1827
|
+
* error messages when actions are not available.
|
|
1828
|
+
*
|
|
1829
|
+
* @param action - The action key to check for support.
|
|
1830
|
+
* @returns True if the action is supported, false otherwise.
|
|
1831
|
+
*
|
|
1832
|
+
* @throws {Error} When action parameter is not a valid string.
|
|
1833
|
+
*
|
|
1834
|
+
* @example
|
|
1835
|
+
* ```typescript
|
|
1836
|
+
* import { ActionRegistry } from '@core/adapter'
|
|
1837
|
+
*
|
|
1838
|
+
* const registry = new ActionRegistry()
|
|
1839
|
+
*
|
|
1840
|
+
* // Check if actions are supported before attempting to use them
|
|
1841
|
+
* if (registry.supportsAction('token.approve')) {
|
|
1842
|
+
* console.log('Token approval is supported')
|
|
1843
|
+
* } else {
|
|
1844
|
+
* console.log('Token approval not available')
|
|
1845
|
+
* }
|
|
1846
|
+
*
|
|
1847
|
+
* // Conditional logic based on support
|
|
1848
|
+
* const action = 'cctp.v2.depositForBurn'
|
|
1849
|
+
* if (registry.supportsAction(action)) {
|
|
1850
|
+
* // Safe to execute
|
|
1851
|
+
* console.log(`${action} is available`)
|
|
1852
|
+
* } else {
|
|
1853
|
+
* console.warn(`${action} is not registered`)
|
|
1854
|
+
* }
|
|
1855
|
+
* ```
|
|
1856
|
+
*/
|
|
1857
|
+
supportsAction(action: ActionKeys): boolean;
|
|
1858
|
+
/**
|
|
1859
|
+
* Execute a registered action handler with type-safe parameters.
|
|
1860
|
+
*
|
|
1861
|
+
* Look up and execute the handler associated with the given action key,
|
|
1862
|
+
* passing the provided parameters and context, returning the resulting prepared
|
|
1863
|
+
* chain request. TypeScript ensures the parameters match the expected
|
|
1864
|
+
* structure for the specified action.
|
|
1865
|
+
*
|
|
1866
|
+
* @typeParam TActionKey - The specific action key being executed.
|
|
1867
|
+
* @param action - The action key identifying which handler to execute.
|
|
1868
|
+
* @param params - The parameters to pass to the action handler.
|
|
1869
|
+
* @param context - The resolved operation context with concrete chain and address values.
|
|
1870
|
+
* @returns A promise resolving to the prepared chain request.
|
|
1871
|
+
*
|
|
1872
|
+
* @throws {Error} When action parameter is not a valid string.
|
|
1873
|
+
* @throws {Error} When no handler is registered for the specified action.
|
|
1874
|
+
* @throws {Error} When the handler execution fails.
|
|
1875
|
+
*
|
|
1876
|
+
* @example
|
|
1877
|
+
* ```typescript
|
|
1878
|
+
* import { ActionRegistry } from '@core/adapter'
|
|
1879
|
+
* import type { ChainEnum } from '@core/chains'
|
|
1880
|
+
*
|
|
1881
|
+
* const registry = new ActionRegistry()
|
|
1882
|
+
*
|
|
1883
|
+
* // First register a handler
|
|
1884
|
+
* registry.registerHandler('token.approve', async (params, context) => ({
|
|
1885
|
+
* chainId: context.chain, // Always defined
|
|
1886
|
+
* data: '0x095ea7b3...',
|
|
1887
|
+
* to: params.tokenAddress,
|
|
1888
|
+
* value: '0'
|
|
1889
|
+
* }))
|
|
1890
|
+
*
|
|
1891
|
+
* // Execute the action with resolved context (typically called from adapter.prepareAction)
|
|
1892
|
+
* const resolvedContext = { chain: 'Base', address: '0x123...' }
|
|
1893
|
+
* const result = await registry.executeAction('token.approve', {
|
|
1894
|
+
* chainId: ChainEnum.Ethereum,
|
|
1895
|
+
* tokenAddress: '0xA0b86a33E6441c8C1c7C16e4c5e3e5b5e4c5e3e5b5e4c5e',
|
|
1896
|
+
* delegate: '0x1234567890123456789012345678901234567890',
|
|
1897
|
+
* amount: '1000000'
|
|
1898
|
+
* }, resolvedContext)
|
|
1899
|
+
*
|
|
1900
|
+
* console.log('Transaction prepared:', result.data)
|
|
1901
|
+
* ```
|
|
1902
|
+
*/
|
|
1903
|
+
executeAction<TActionKey extends ActionKeys>(action: TActionKey, params: ActionPayload<TActionKey>, context: ResolvedOperationContext): Promise<PreparedChainRequest>;
|
|
1904
|
+
}
|
|
1905
|
+
|
|
1906
|
+
/**
|
|
1907
|
+
* Defines the capabilities of an adapter, including address handling patterns and supported chains.
|
|
1908
|
+
*
|
|
1909
|
+
* @interface TAdapterCapabilities
|
|
1910
|
+
* @category Types
|
|
1911
|
+
* @description
|
|
1912
|
+
* This interface specifies how an adapter manages address control and which blockchain networks it supports.
|
|
1913
|
+
* It is used for capability discovery, validation, and to inform consumers about the adapter's operational model.
|
|
1914
|
+
*
|
|
1915
|
+
* The `addressContext` property determines both address selection behavior and bridge API requirements:
|
|
1916
|
+
* - `'user-controlled'`: User controls addresses through wallet UI, address optional in operations
|
|
1917
|
+
* - `'developer-controlled'`: Service manages addresses programmatically, address required in operations
|
|
1918
|
+
*
|
|
1919
|
+
* @example
|
|
1920
|
+
* ```typescript
|
|
1921
|
+
* // Browser wallet adapter (user-controlled)
|
|
1922
|
+
* const capabilities: AdapterCapabilities = {
|
|
1923
|
+
* addressContext: 'user-controlled', // User selects address in wallet UI
|
|
1924
|
+
* supportedChains: [Ethereum, Base, Polygon]
|
|
1925
|
+
* }
|
|
1926
|
+
*
|
|
1927
|
+
* // Enterprise provider adapter (developer-controlled)
|
|
1928
|
+
* const capabilities: AdapterCapabilities = {
|
|
1929
|
+
* addressContext: 'developer-controlled', // Address must be specified per operation
|
|
1930
|
+
* supportedChains: [Ethereum, Base, Solana]
|
|
1931
|
+
* }
|
|
1932
|
+
* ```
|
|
1933
|
+
*/
|
|
1934
|
+
interface AdapterCapabilities {
|
|
1935
|
+
/**
|
|
1936
|
+
* Defines who controls address selection for wallet operations.
|
|
1937
|
+
*
|
|
1938
|
+
* - `'user-controlled'`: User controls addresses through wallet UI (browser wallets, hardware wallets)
|
|
1939
|
+
* - Address is implicit in bridge operations (uses wallet's current address)
|
|
1940
|
+
* - Adapter may listen for accountsChanged/chainChanged events
|
|
1941
|
+
* - Suitable for MetaMask, Coinbase Wallet, WalletConnect, private keys, etc.
|
|
1942
|
+
*
|
|
1943
|
+
* - `'developer-controlled'`: Service manages addresses programmatically (enterprise providers)
|
|
1944
|
+
* - Address must be explicitly provided in bridge operations
|
|
1945
|
+
* - No event listening (addresses controlled programmatically)
|
|
1946
|
+
* - Suitable for Fireblocks, Circle Wallets, institutional custody, etc.
|
|
1947
|
+
*/
|
|
1948
|
+
addressContext: 'user-controlled' | 'developer-controlled';
|
|
1949
|
+
/**
|
|
1950
|
+
* The set of blockchain networks this adapter supports.
|
|
1951
|
+
* Used for validation, capability discovery, and to restrict operations to supported chains.
|
|
1952
|
+
*/
|
|
1953
|
+
supportedChains: ChainDefinition[];
|
|
1954
|
+
}
|
|
1955
|
+
/**
|
|
1956
|
+
* Abstract class defining the standard interface for an adapter that interacts with a specific blockchain.
|
|
1957
|
+
*
|
|
1958
|
+
* A `Adapter` is responsible for encapsulating chain-specific logic necessary to
|
|
1959
|
+
* perform operations like sending transactions, querying balances, or interacting with smart contracts.
|
|
1960
|
+
* Implementations of this class will provide concrete logic for a particular blockchain protocol.
|
|
1961
|
+
*
|
|
1962
|
+
* This abstraction allows the Stablecoin Kits to work with multiple blockchains in a uniform way.
|
|
1963
|
+
*
|
|
1964
|
+
* @typeParam TAdapterCapabilities - The adapter capabilities type for compile-time address validation.
|
|
1965
|
+
* When provided, enables strict typing of operation context based on the adapter's address control model.
|
|
1966
|
+
*/
|
|
1967
|
+
declare abstract class Adapter<TAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities> {
|
|
1968
|
+
/**
|
|
1969
|
+
* The type of the chain.
|
|
1970
|
+
* @example 'evm', 'solana'
|
|
1971
|
+
*/
|
|
1972
|
+
abstract chainType: ChainType;
|
|
1973
|
+
/**
|
|
1974
|
+
* Capabilities of this adapter, defining address control model and supported chains.
|
|
1975
|
+
*
|
|
1976
|
+
* This property determines how the adapter behaves, especially for address selection
|
|
1977
|
+
* and bridge API requirements. The `addressContext` must match the adapter's type parameter.
|
|
1978
|
+
*
|
|
1979
|
+
* @remarks
|
|
1980
|
+
* The `addressContext` value must align with the adapter's generic type parameter for proper
|
|
1981
|
+
* type safety in bridge operations.
|
|
1982
|
+
*
|
|
1983
|
+
* @example
|
|
1984
|
+
* ```typescript
|
|
1985
|
+
* // User-controlled adapter (private key, browser wallet)
|
|
1986
|
+
* capabilities = {
|
|
1987
|
+
* addressContext: 'user-controlled', // Address implicit in bridge operations
|
|
1988
|
+
* supportedChains: [Ethereum, Base, Polygon]
|
|
1989
|
+
* }
|
|
1990
|
+
*
|
|
1991
|
+
* // Developer-controlled adapter (enterprise provider)
|
|
1992
|
+
* capabilities = {
|
|
1993
|
+
* addressContext: 'developer-controlled', // Address required in bridge operations
|
|
1994
|
+
* supportedChains: [Ethereum, Base, Solana]
|
|
1995
|
+
* }
|
|
1996
|
+
* ```
|
|
1997
|
+
*/
|
|
1998
|
+
capabilities?: TAdapterCapabilities;
|
|
1999
|
+
/**
|
|
2000
|
+
* Registry of available actions for this adapter.
|
|
2001
|
+
*
|
|
2002
|
+
* The {@link ActionRegistry} provides a catalog of supported operations
|
|
2003
|
+
* (such as token transfers, approvals, etc.) that can be performed by this adapter
|
|
2004
|
+
* on the connected blockchain. This enables dynamic discovery and invocation
|
|
2005
|
+
* of chain-specific or cross-chain actions in a type-safe manner.
|
|
2006
|
+
*
|
|
2007
|
+
* @readonly
|
|
2008
|
+
*/
|
|
2009
|
+
readonly actionRegistry: ActionRegistry;
|
|
2010
|
+
/**
|
|
2011
|
+
* Prepares (but does not execute) an action for the connected blockchain.
|
|
2012
|
+
*
|
|
2013
|
+
* This method looks up the appropriate action handler for the given action key
|
|
2014
|
+
* and prepares the transaction request using the provided parameters. The returned
|
|
2015
|
+
* {@link PreparedChainRequest} allows developers to estimate gas costs and execute
|
|
2016
|
+
* the transaction at a later time, enabling pre-flight simulation and deferred execution.
|
|
2017
|
+
*
|
|
2018
|
+
* **Compile-time Address Validation**: When used with typed adapters that have capabilities,
|
|
2019
|
+
* this method enforces address requirements at compile time:
|
|
2020
|
+
* - **User-controlled adapters**: The `address` field is forbidden in the context
|
|
2021
|
+
* - **Developer-controlled adapters**: The `address` field is required in the context
|
|
2022
|
+
* - **Legacy adapters**: The `address` field remains optional for backward compatibility
|
|
2023
|
+
*
|
|
2024
|
+
* @remarks
|
|
2025
|
+
* This method does not send any transaction to the network. Instead, it returns a
|
|
2026
|
+
* prepared request object with `estimate()` and `execute()` methods, allowing
|
|
2027
|
+
* developers to inspect, simulate, or submit the transaction as needed.
|
|
2028
|
+
*
|
|
2029
|
+
* @param action - The action key identifying which handler to use for preparation.
|
|
2030
|
+
* @param params - The parameters to pass to the action handler.
|
|
2031
|
+
* @param ctx - Operation context with compile-time validated address requirements based on adapter capabilities.
|
|
2032
|
+
* @returns A promise that resolves to a {@link PreparedChainRequest} for estimation and execution.
|
|
2033
|
+
* @throws Error If the specified action key does not correspond to a registered handler.
|
|
2034
|
+
* @throws Error If the provided parameters are invalid for the action.
|
|
2035
|
+
* @throws Error If the operation context cannot be resolved.
|
|
2036
|
+
*
|
|
2037
|
+
* @example
|
|
2038
|
+
* ```typescript
|
|
2039
|
+
* // User-controlled adapter (address forbidden)
|
|
2040
|
+
* const userAdapter: Adapter<{ addressContext: 'user-controlled', supportedChains: [] }>
|
|
2041
|
+
* await userAdapter.prepareAction('token.approve', params, {
|
|
2042
|
+
* chain: 'Ethereum'
|
|
2043
|
+
* // address: '0x123...' // ❌ TypeScript error: address not allowed
|
|
2044
|
+
* })
|
|
2045
|
+
*
|
|
2046
|
+
* // Developer-controlled adapter (address required)
|
|
2047
|
+
* const devAdapter: Adapter<{ addressContext: 'developer-controlled', supportedChains: [] }>
|
|
2048
|
+
* await devAdapter.prepareAction('token.approve', params, {
|
|
2049
|
+
* chain: 'Ethereum',
|
|
2050
|
+
* address: '0x123...' // ✅ Required for developer-controlled
|
|
2051
|
+
* })
|
|
2052
|
+
* ```
|
|
2053
|
+
*/
|
|
2054
|
+
prepareAction<TActionKey extends ActionKeys>(action: TActionKey, params: ActionPayload<TActionKey>, ctx?: OperationContext<TAdapterCapabilities>): Promise<PreparedChainRequest>;
|
|
2055
|
+
/**
|
|
2056
|
+
* Prepares a transaction for future gas estimation and execution.
|
|
2057
|
+
*
|
|
2058
|
+
* This method should handle any preliminary steps required before a transaction
|
|
2059
|
+
* can be estimated or sent. This might include things like serializing transaction
|
|
2060
|
+
* data, but it should NOT yet send anything to the network.
|
|
2061
|
+
*
|
|
2062
|
+
* The returned object contains two functions:
|
|
2063
|
+
* - `estimate()`: Asynchronously calculates and returns the {@link EstimatedGas} for the prepared transaction.
|
|
2064
|
+
* - `execute()`: Asynchronously executes the prepared transaction and returns a promise that resolves
|
|
2065
|
+
* with the transaction result (e.g., a transaction hash, receipt, or other chain-specific response).
|
|
2066
|
+
*
|
|
2067
|
+
* **Compile-time Address Validation**: When used with typed adapters that have capabilities,
|
|
2068
|
+
* this method enforces address requirements at compile time:
|
|
2069
|
+
* - **User-controlled adapters**: The `address` field is forbidden in the context
|
|
2070
|
+
* - **Developer-controlled adapters**: The `address` field is required in the context
|
|
2071
|
+
* - **Legacy adapters**: The `address` field remains optional for backward compatibility
|
|
2072
|
+
*
|
|
2073
|
+
* @remarks
|
|
2074
|
+
* The specific parameters for `prepare` might vary greatly between chain implementations.
|
|
2075
|
+
* Consider defining a generic type or a base type for `transactionRequest` if common patterns emerge,
|
|
2076
|
+
* or allow `...args: any[]` if extreme flexibility is needed by implementers.
|
|
2077
|
+
* For this abstract definition, we keep it parameter-less, assuming implementations will add specific
|
|
2078
|
+
* parameters as needed for their `prepare` method (e.g. `prepare(txDetails: MyChainTxDetails)`).
|
|
2079
|
+
*
|
|
2080
|
+
* @param params - The prepared chain request parameters for the specific blockchain.
|
|
2081
|
+
* @param ctx - Operation context with compile-time validated address requirements based on adapter capabilities.
|
|
2082
|
+
* @returns An object containing `estimate` and `execute` methods for the prepared transaction.
|
|
2083
|
+
*
|
|
2084
|
+
* @example
|
|
2085
|
+
* ```typescript
|
|
2086
|
+
* // User-controlled adapter (address forbidden)
|
|
2087
|
+
* const userAdapter: Adapter<{ addressContext: 'user-controlled', supportedChains: [] }>
|
|
2088
|
+
* await userAdapter.prepare(params, {
|
|
2089
|
+
* chain: 'Ethereum'
|
|
2090
|
+
* // address: '0x123...' // ❌ TypeScript error: address not allowed
|
|
2091
|
+
* })
|
|
2092
|
+
*
|
|
2093
|
+
* // Developer-controlled adapter (address required)
|
|
2094
|
+
* const devAdapter: Adapter<{ addressContext: 'developer-controlled', supportedChains: [] }>
|
|
2095
|
+
* await devAdapter.prepare(params, {
|
|
2096
|
+
* chain: 'Ethereum',
|
|
2097
|
+
* address: '0x123...' // ✅ Required for developer-controlled
|
|
2098
|
+
* })
|
|
2099
|
+
* ```
|
|
2100
|
+
*/
|
|
2101
|
+
abstract prepare(params: PreparedChainRequestParams, ctx: OperationContext<TAdapterCapabilities>): Promise<PreparedChainRequest>;
|
|
2102
|
+
/**
|
|
2103
|
+
* Retrieves the public address of the connected wallet.
|
|
2104
|
+
*
|
|
2105
|
+
* This address is used as the default sender for transactions
|
|
2106
|
+
* and interactions initiated by this adapter.
|
|
2107
|
+
*
|
|
2108
|
+
* @param chain - Optional chain definition for chain-specific address resolution (used by EVM adapters)
|
|
2109
|
+
* @returns A promise that resolves to the blockchain address as a string.
|
|
2110
|
+
*/
|
|
2111
|
+
abstract getAddress(chain?: ChainDefinition): Promise<string>;
|
|
2112
|
+
/**
|
|
2113
|
+
* Switches the adapter to operate on the specified chain.
|
|
2114
|
+
*
|
|
2115
|
+
* This abstract method must be implemented by concrete adapters to handle their specific
|
|
2116
|
+
* chain switching logic. The behavior varies by adapter type:
|
|
2117
|
+
* - **Private key adapters**: Recreate clients with new RPC endpoints
|
|
2118
|
+
* - **Browser wallet adapters**: Request chain switch via EIP-1193 or equivalent
|
|
2119
|
+
* - **Multi-entity adapters**: Typically a no-op (operations are contextual)
|
|
2120
|
+
*
|
|
2121
|
+
* @param chain - The target chain to switch to.
|
|
2122
|
+
* @returns A promise that resolves when the chain switch is complete.
|
|
2123
|
+
* @throws When the chain switching fails or is not supported.
|
|
2124
|
+
*
|
|
2125
|
+
* @remarks
|
|
2126
|
+
* This method is called by `ensureChain()` after validation is complete.
|
|
2127
|
+
* Implementations should focus only on the actual switching logic, not validation.
|
|
2128
|
+
*
|
|
2129
|
+
* @example
|
|
2130
|
+
* ```typescript
|
|
2131
|
+
* // EVM adapter implementation
|
|
2132
|
+
* protected async switchToChain(chain: ChainDefinition): Promise<void> {
|
|
2133
|
+
* if (chain.type !== 'evm') {
|
|
2134
|
+
* throw new Error('Only EVM chains supported')
|
|
2135
|
+
* }
|
|
2136
|
+
* await this.recreateWalletClient(chain)
|
|
2137
|
+
* }
|
|
2138
|
+
*
|
|
2139
|
+
* // Multi-entity adapter implementation
|
|
2140
|
+
* protected async switchToChain(chain: ChainDefinition): Promise<void> {
|
|
2141
|
+
* // No-op - operations are contextual
|
|
2142
|
+
* return
|
|
2143
|
+
* }
|
|
2144
|
+
* ```
|
|
2145
|
+
*/
|
|
2146
|
+
abstract switchToChain(chain: ChainDefinition): Promise<void>;
|
|
2147
|
+
/**
|
|
2148
|
+
* Ensures the adapter is operating on the specified chain, switching if necessary.
|
|
2149
|
+
*
|
|
2150
|
+
* This method provides a unified interface for establishing chain preconditions across different adapter types.
|
|
2151
|
+
* The behavior varies based on the adapter's capabilities:
|
|
2152
|
+
* - **Private key adapters**: Recreate clients with new RPC endpoints
|
|
2153
|
+
* - **Browser wallet adapters**: Request chain switch via EIP-1193 or equivalent
|
|
2154
|
+
* - **Multi-entity adapters**: Validate chain support (operations are contextual)
|
|
2155
|
+
*
|
|
2156
|
+
* @param chain - The target chain for operations.
|
|
2157
|
+
* @returns A promise that resolves when the adapter is operating on the specified chain.
|
|
2158
|
+
* @throws When the target chain is not supported or chain switching fails.
|
|
2159
|
+
*
|
|
2160
|
+
* @remarks
|
|
2161
|
+
* This method always calls `switchToChain()` to ensure consistency across all adapter types.
|
|
2162
|
+
* The underlying implementations handle idempotent switching efficiently (e.g., browser wallets
|
|
2163
|
+
* gracefully handle switching to the current chain, private key adapters recreate lightweight clients).
|
|
2164
|
+
*
|
|
2165
|
+
* @example
|
|
2166
|
+
* ```typescript
|
|
2167
|
+
* // Private key adapter - switches chains seamlessly
|
|
2168
|
+
* await privateKeyAdapter.ensureChain(Base)
|
|
2169
|
+
*
|
|
2170
|
+
* // Browser wallet - requests user to switch chains
|
|
2171
|
+
* await metamaskAdapter.ensureChain(Polygon)
|
|
2172
|
+
*
|
|
2173
|
+
* // Multi-entity adapter - validates chain is supported
|
|
2174
|
+
* await circleWalletsAdapter.ensureChain(Ethereum)
|
|
2175
|
+
* ```
|
|
2176
|
+
*/
|
|
2177
|
+
ensureChain(targetChain: ChainDefinition): Promise<void>;
|
|
2178
|
+
/**
|
|
2179
|
+
* Validate that the target chain is supported by this adapter.
|
|
2180
|
+
*
|
|
2181
|
+
* @param targetChain - The chain to validate.
|
|
2182
|
+
* @throws Error if the chain is not supported.
|
|
2183
|
+
*/
|
|
2184
|
+
validateChainSupport(targetChain: ChainDefinition): void;
|
|
2185
|
+
/**
|
|
2186
|
+
* Waits for a transaction to be mined and confirmed on the blockchain.
|
|
2187
|
+
*
|
|
2188
|
+
* This method should block until the transaction is confirmed on the blockchain.
|
|
2189
|
+
* The response includes comprehensive transaction details for the confirmed transaction.
|
|
2190
|
+
*
|
|
2191
|
+
* @param txHash - The hash of the transaction to wait for.
|
|
2192
|
+
* @param config - Optional configuration for waiting behavior including timeout and confirmations.
|
|
2193
|
+
* @param chain - The chain definition where the transaction was submitted.
|
|
2194
|
+
* @returns Promise resolving to comprehensive transaction details.
|
|
2195
|
+
*/
|
|
2196
|
+
abstract waitForTransaction(txHash: string, config: WaitForTransactionConfig | undefined, chain: ChainDefinition): Promise<WaitForTransactionResponse>;
|
|
2197
|
+
/**
|
|
2198
|
+
* Calculate the total transaction fee including compute cost and buffer for the configured chain.
|
|
2199
|
+
*
|
|
2200
|
+
* This method computes the fee by multiplying the base compute units by the current
|
|
2201
|
+
* fee rate, then adds a configurable buffer to account for fee fluctuations and ensure
|
|
2202
|
+
* transaction success. The buffer is specified in basis points (1 basis point = 0.01%).
|
|
2203
|
+
*
|
|
2204
|
+
* @param baseComputeUnits - The base compute units for the transaction (gas for EVM, compute units for Solana, etc.).
|
|
2205
|
+
* @param bufferBasisPoints - The buffer to add as basis points (e.g., 500 = 5%). Defaults to implementation-specific value.
|
|
2206
|
+
* @param chain - The chain definition to calculate fees for.
|
|
2207
|
+
* @returns A promise that resolves to the total transaction fee as a bigint.
|
|
2208
|
+
*/
|
|
2209
|
+
abstract calculateTransactionFee(baseComputeUnits: bigint, bufferBasisPoints: bigint | undefined, chain: ChainDefinition): Promise<EstimatedGas>;
|
|
2210
|
+
}
|
|
2211
|
+
|
|
2212
|
+
/**
|
|
2213
|
+
* A type-safe event emitter for managing action-based event subscriptions.
|
|
2214
|
+
*
|
|
2215
|
+
* Actionable provides a strongly-typed publish/subscribe pattern for events,
|
|
2216
|
+
* where each event (action) has its own specific payload type. Handlers can
|
|
2217
|
+
* subscribe to specific events or use a wildcard to receive all events.
|
|
2218
|
+
*
|
|
2219
|
+
* @typeParam AllActions - A record mapping action names to their payload types.
|
|
2220
|
+
*
|
|
2221
|
+
* @example
|
|
2222
|
+
* ```typescript
|
|
2223
|
+
* import { Actionable } from '@circle-fin/bridge-kit/utils';
|
|
2224
|
+
*
|
|
2225
|
+
* // Define your action types
|
|
2226
|
+
* type TransferActions = {
|
|
2227
|
+
* started: { txHash: string; amount: string };
|
|
2228
|
+
* completed: { txHash: string; destinationTxHash: string };
|
|
2229
|
+
* failed: { error: Error };
|
|
2230
|
+
* };
|
|
2231
|
+
*
|
|
2232
|
+
* // Create an actionable instance
|
|
2233
|
+
* const transferEvents = new Actionable<TransferActions>();
|
|
2234
|
+
*
|
|
2235
|
+
* // Subscribe to a specific event
|
|
2236
|
+
* transferEvents.on('completed', (payload) => {
|
|
2237
|
+
* console.log(`Transfer completed with hash: ${payload.destinationTxHash}`);
|
|
2238
|
+
* });
|
|
2239
|
+
*
|
|
2240
|
+
* // Subscribe to all events
|
|
2241
|
+
* transferEvents.on('*', (payload) => {
|
|
2242
|
+
* console.log('Event received:', payload);
|
|
2243
|
+
* });
|
|
2244
|
+
*
|
|
2245
|
+
* // Dispatch an event
|
|
2246
|
+
* transferEvents.dispatch('completed', {
|
|
2247
|
+
* txHash: '0x123',
|
|
2248
|
+
* destinationTxHash: '0xabc'
|
|
2249
|
+
* });
|
|
2250
|
+
* ```
|
|
2251
|
+
*/
|
|
2252
|
+
declare class Actionable<AllActions> {
|
|
2253
|
+
private readonly handlers;
|
|
2254
|
+
private readonly wildcard;
|
|
2255
|
+
/**
|
|
2256
|
+
* Register a handler for a specific action.
|
|
2257
|
+
*
|
|
2258
|
+
* @param action - The specific action key to listen for.
|
|
2259
|
+
* @param handler - The callback function to execute when the action occurs.
|
|
2260
|
+
*
|
|
2261
|
+
* @example
|
|
2262
|
+
* ```typescript
|
|
2263
|
+
* const events = new Actionable<{ dataReceived: string }>();
|
|
2264
|
+
*
|
|
2265
|
+
* events.on('dataReceived', (data) => {
|
|
2266
|
+
* console.log(`Received: ${data}`);
|
|
2267
|
+
* });
|
|
2268
|
+
* ```
|
|
2269
|
+
*/
|
|
2270
|
+
on<Action extends keyof AllActions>(action: Action, handler: (payload: AllActions[Action]) => void): void;
|
|
2271
|
+
/**
|
|
2272
|
+
* Register a handler for all actions using the wildcard '*'.
|
|
2273
|
+
*
|
|
2274
|
+
* @param action - The wildcard '*' signifying interest in all actions.
|
|
2275
|
+
* @param handler - The callback function to execute for any action.
|
|
2276
|
+
*
|
|
2277
|
+
* @example
|
|
2278
|
+
* ```typescript
|
|
2279
|
+
* const events = new Actionable<{ started: boolean; completed: string }>();
|
|
2280
|
+
*
|
|
2281
|
+
* events.on('*', (payload) => {
|
|
2282
|
+
* console.log('Action occurred:', payload);
|
|
2283
|
+
* });
|
|
2284
|
+
* ```
|
|
2285
|
+
*/
|
|
2286
|
+
on(action: '*', handler: (payload: AllActions[keyof AllActions]) => void): void;
|
|
2287
|
+
/**
|
|
2288
|
+
* Remove a previously registered handler for a specific action.
|
|
2289
|
+
*
|
|
2290
|
+
* @param action - The specific action key to unregister from.
|
|
2291
|
+
* @param handler - The callback function to remove.
|
|
2292
|
+
*
|
|
2293
|
+
* @example
|
|
2294
|
+
* ```typescript
|
|
2295
|
+
* const events = new Actionable<{ dataReceived: string }>();
|
|
2296
|
+
*
|
|
2297
|
+
* const handler = (data: string) => console.log(data);
|
|
2298
|
+
* events.on('dataReceived', handler);
|
|
2299
|
+
*
|
|
2300
|
+
* // Later, to remove the handler:
|
|
2301
|
+
* events.off('dataReceived', handler);
|
|
2302
|
+
* ```
|
|
2303
|
+
*/
|
|
2304
|
+
off<Action extends keyof AllActions>(action: Action, handler: (payload: AllActions[Action]) => void): void;
|
|
2305
|
+
/**
|
|
2306
|
+
* Remove a previously registered wildcard handler.
|
|
2307
|
+
*
|
|
2308
|
+
* @param action - The wildcard '*' signifying removal from all actions.
|
|
2309
|
+
* @param handler - The callback function to remove.
|
|
2310
|
+
*
|
|
2311
|
+
* @example
|
|
2312
|
+
* ```typescript
|
|
2313
|
+
* const events = new Actionable<{ started: boolean; completed: string }>();
|
|
2314
|
+
*
|
|
2315
|
+
* const globalHandler = (payload: any) => console.log(payload);
|
|
2316
|
+
* events.on('*', globalHandler);
|
|
2317
|
+
*
|
|
2318
|
+
* // Later, to remove the handler:
|
|
2319
|
+
* events.off('*', globalHandler);
|
|
2320
|
+
* ```
|
|
2321
|
+
*/
|
|
2322
|
+
off(action: '*', handler: (payload: AllActions[keyof AllActions]) => void): void;
|
|
2323
|
+
/**
|
|
2324
|
+
* Dispatch an action with its payload to all registered handlers.
|
|
2325
|
+
*
|
|
2326
|
+
* This method notifies both:
|
|
2327
|
+
* - Handlers registered specifically for this action
|
|
2328
|
+
* - Wildcard handlers registered for all actions
|
|
2329
|
+
*
|
|
2330
|
+
* @param action - The action key identifying the event type.
|
|
2331
|
+
* @param payload - The data associated with the action.
|
|
2332
|
+
*
|
|
2333
|
+
* @example
|
|
2334
|
+
* ```typescript
|
|
2335
|
+
* type Actions = {
|
|
2336
|
+
* transferStarted: { amount: string; destination: string };
|
|
2337
|
+
* transferComplete: { txHash: string };
|
|
2338
|
+
* };
|
|
2339
|
+
*
|
|
2340
|
+
* const events = new Actionable<Actions>();
|
|
2341
|
+
*
|
|
2342
|
+
* // Dispatch an event
|
|
2343
|
+
* events.dispatch('transferStarted', {
|
|
2344
|
+
* amount: '100',
|
|
2345
|
+
* destination: '0xABC123'
|
|
2346
|
+
* });
|
|
2347
|
+
* ```
|
|
2348
|
+
*/
|
|
2349
|
+
dispatch<K extends keyof AllActions>(action: K, payload: AllActions[K]): void;
|
|
2350
|
+
}
|
|
2351
|
+
|
|
2352
|
+
/**
|
|
2353
|
+
* Transfer speed options for cross-chain operations.
|
|
2354
|
+
*
|
|
2355
|
+
* Defines the available speed modes for CCTPv2 transfers, affecting
|
|
2356
|
+
* both transfer time and potential fee implications.
|
|
2357
|
+
*/
|
|
2358
|
+
declare enum TransferSpeed {
|
|
2359
|
+
/** Fast burn mode - reduces transfer time but may have different fee implications */
|
|
2360
|
+
FAST = "FAST",
|
|
2361
|
+
/** Standard burn mode - normal transfer time with standard fees */
|
|
2362
|
+
SLOW = "SLOW"
|
|
2363
|
+
}
|
|
2364
|
+
/**
|
|
2365
|
+
* Context object representing a wallet and signing authority on a specific blockchain network.
|
|
2366
|
+
*
|
|
2367
|
+
* Combines a wallet or contract address, the blockchain it resides on, and the adapter (signer)
|
|
2368
|
+
* responsible for authorizing transactions. Used to specify the source or destination in cross-chain
|
|
2369
|
+
* transfer operations.
|
|
2370
|
+
*
|
|
2371
|
+
* @remarks
|
|
2372
|
+
* The `adapter` (signer) and `address` do not always have to belong to the same entity. For example,
|
|
2373
|
+
* in minting or withdrawal scenarios, the signing adapter may authorize a transaction that credits
|
|
2374
|
+
* funds to a different recipient address. This context is essential for cross-chain operations,
|
|
2375
|
+
* ensuring that both the address and the associated adapter are correctly paired with the intended
|
|
2376
|
+
* blockchain, but not necessarily with each other.
|
|
2377
|
+
*
|
|
2378
|
+
* @example
|
|
2379
|
+
* ```typescript
|
|
2380
|
+
* import type { WalletContext } from '@core/provider'
|
|
2381
|
+
* import { adapter, blockchain } from './setup'
|
|
2382
|
+
*
|
|
2383
|
+
* const wallet: WalletContext = {
|
|
2384
|
+
* adapter,
|
|
2385
|
+
* address: '0x1234...abcd',
|
|
2386
|
+
* chain: blockchain,
|
|
2387
|
+
* }
|
|
2388
|
+
* ```
|
|
2389
|
+
*/
|
|
2390
|
+
interface WalletContext<TAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities,
|
|
2391
|
+
/**
|
|
2392
|
+
* The chain definition type to use for the wallet context.
|
|
2393
|
+
*
|
|
2394
|
+
* @defaultValue ChainDefinition
|
|
2395
|
+
*/
|
|
2396
|
+
TChainDefinition extends ChainDefinition = ChainDefinition> {
|
|
2397
|
+
/**
|
|
2398
|
+
* The adapter (signer) for the wallet on the specified chain.
|
|
2399
|
+
*
|
|
2400
|
+
* Responsible for authorizing transactions and signing messages on behalf of the wallet or
|
|
2401
|
+
* for a different recipient, depending on the use case.
|
|
2402
|
+
*/
|
|
2403
|
+
adapter: Adapter<TAdapterCapabilities>;
|
|
2404
|
+
/**
|
|
2405
|
+
* The wallet or contract address.
|
|
2406
|
+
*
|
|
2407
|
+
* Must be a valid address format for the specified blockchain. May differ from the adapter's
|
|
2408
|
+
* own address in scenarios such as relayed transactions or third-party minting.
|
|
2409
|
+
*/
|
|
2410
|
+
address: string;
|
|
2411
|
+
/**
|
|
2412
|
+
* The blockchain network where the wallet or contract address resides.
|
|
2413
|
+
*
|
|
2414
|
+
* Determines the context and format for the address and adapter.
|
|
2415
|
+
*/
|
|
2416
|
+
chain: TChainDefinition;
|
|
2417
|
+
}
|
|
2418
|
+
/**
|
|
2419
|
+
* Parameters for executing a cross-chain bridge operation.
|
|
2420
|
+
*/
|
|
2421
|
+
interface BridgeParams$1<TFromCapabilities extends AdapterCapabilities = AdapterCapabilities, TToCapabilities extends AdapterCapabilities = AdapterCapabilities,
|
|
2422
|
+
/**
|
|
2423
|
+
* The chain definition type to use for the wallet context.
|
|
2424
|
+
*
|
|
2425
|
+
* @defaultValue ChainDefinition
|
|
2426
|
+
*/
|
|
2427
|
+
TChainDefinition extends ChainDefinition = ChainDefinition> {
|
|
2428
|
+
/** The source adapter containing wallet and chain information */
|
|
2429
|
+
source: WalletContext<TFromCapabilities, TChainDefinition>;
|
|
2430
|
+
/** The destination adapter containing wallet and chain information */
|
|
2431
|
+
destination: WalletContext<TToCapabilities, TChainDefinition>;
|
|
2432
|
+
/** The amount to transfer (as a string to avoid precision issues) */
|
|
2433
|
+
amount: string;
|
|
2434
|
+
/** The token to transfer (currently only USDC is supported) */
|
|
2435
|
+
token: 'USDC';
|
|
2436
|
+
/** Bridge configuration (e.g., fast burn settings) */
|
|
2437
|
+
config: BridgeConfig;
|
|
2438
|
+
}
|
|
2439
|
+
/**
|
|
2440
|
+
* A step in the bridge process.
|
|
2441
|
+
*
|
|
2442
|
+
* @remarks
|
|
2443
|
+
* This interface represents a single step in the bridge process,
|
|
2444
|
+
* such as approval, burn, or mint.
|
|
2445
|
+
*
|
|
2446
|
+
* @example
|
|
2447
|
+
* ```typescript
|
|
2448
|
+
* const step: BridgeStep = {
|
|
2449
|
+
* name: 'Approve',
|
|
2450
|
+
* state: 'success',
|
|
2451
|
+
* txHash: '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef',
|
|
2452
|
+
* explorerUrl: 'https://etherscan.io/tx/0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef',
|
|
2453
|
+
* }
|
|
2454
|
+
* ```
|
|
2455
|
+
*/
|
|
2456
|
+
interface BridgeStep {
|
|
2457
|
+
/** Human-readable name of the step (e.g., "Approve", "Burn", "Mint") */
|
|
2458
|
+
name: string;
|
|
2459
|
+
/** The state of the step */
|
|
2460
|
+
state: 'pending' | 'success' | 'error' | 'noop';
|
|
2461
|
+
/** Optional transaction hash for this step (if applicable) */
|
|
2462
|
+
txHash?: string;
|
|
2463
|
+
/** Optional explorer URL for viewing this transaction on a block explorer */
|
|
2464
|
+
explorerUrl?: string;
|
|
2465
|
+
/** Optional data for the step */
|
|
2466
|
+
data?: unknown;
|
|
2467
|
+
/** Optional human-readable error message */
|
|
2468
|
+
errorMessage?: string;
|
|
2469
|
+
/** Optional raw error object (can be Viem/Ethers/Chain error) */
|
|
2470
|
+
error?: unknown;
|
|
2471
|
+
}
|
|
2472
|
+
/**
|
|
2473
|
+
* Result object returned after a successful cross-chain bridge operation.
|
|
2474
|
+
*
|
|
2475
|
+
* This interface contains all the details about a completed bridge, including
|
|
2476
|
+
* the bridge parameters, source and destination information,
|
|
2477
|
+
* and the sequence of steps that were executed.
|
|
2478
|
+
*
|
|
2479
|
+
* @example
|
|
2480
|
+
* ```typescript
|
|
2481
|
+
* const result: BridgeResult = await provider.bridge(source, dest, '100')
|
|
2482
|
+
* console.log(`Transferred ${result.amount} ${result.token}`)
|
|
2483
|
+
* console.log(`Steps executed: ${result.steps.length}`)
|
|
2484
|
+
* ```
|
|
2485
|
+
*/
|
|
2486
|
+
interface BridgeResult {
|
|
2487
|
+
/** The amount that was transferred (as a string to avoid precision issues) */
|
|
2488
|
+
amount: string;
|
|
2489
|
+
/** The token that was transferred (currently only USDC is supported) */
|
|
2490
|
+
token: 'USDC';
|
|
2491
|
+
/** The state of the transfer */
|
|
2492
|
+
state: 'pending' | 'success' | 'error';
|
|
2493
|
+
/** The bridge configuration that was used for this operation */
|
|
2494
|
+
config?: BridgeConfig;
|
|
2495
|
+
/** The provider that was used for this operation */
|
|
2496
|
+
provider: string;
|
|
2497
|
+
/** Information about the source chain and address */
|
|
2498
|
+
source: {
|
|
2499
|
+
/** The source wallet/contract address */
|
|
2500
|
+
address: string;
|
|
2501
|
+
/** The source blockchain network */
|
|
2502
|
+
chain: ChainDefinition;
|
|
2503
|
+
};
|
|
2504
|
+
/** Information about the destination chain and address */
|
|
2505
|
+
destination: {
|
|
2506
|
+
/** The destination wallet/contract address */
|
|
2507
|
+
address: string;
|
|
2508
|
+
/** The destination blockchain network */
|
|
2509
|
+
chain: ChainDefinition;
|
|
2510
|
+
};
|
|
2511
|
+
/** Array of steps that were executed during the bridge process */
|
|
2512
|
+
steps: BridgeStep[];
|
|
2513
|
+
}
|
|
2514
|
+
/**
|
|
2515
|
+
* Cost estimation result for a cross-chain transfer operation.
|
|
2516
|
+
*
|
|
2517
|
+
* This interface provides detailed information about the expected costs
|
|
2518
|
+
* for a transfer, including gas fees on different chains and protocol fees.
|
|
2519
|
+
*
|
|
2520
|
+
* @example
|
|
2521
|
+
* ```typescript
|
|
2522
|
+
* const estimate: EstimateResult = await provider.estimate(source, dest, '100')
|
|
2523
|
+
* console.log('Total gas fees:', estimate.gasFees.length)
|
|
2524
|
+
* console.log('Protocol fees:', estimate.fees.length)
|
|
2525
|
+
* ```
|
|
2526
|
+
*/
|
|
2527
|
+
interface EstimateResult {
|
|
2528
|
+
/** Array of gas fees required for the transfer on different blockchains */
|
|
2529
|
+
gasFees: {
|
|
2530
|
+
/** The name of the step */
|
|
2531
|
+
name: string;
|
|
2532
|
+
/** The token used to pay gas fees (e.g., "ETH", "MATIC") */
|
|
2533
|
+
token: string;
|
|
2534
|
+
/** The blockchain where this gas fee applies */
|
|
2535
|
+
blockchain: Blockchain;
|
|
2536
|
+
/** The estimated gas fee amount (as a string to avoid precision issues) */
|
|
2537
|
+
fees: EstimatedGas | null;
|
|
2538
|
+
/** Optional error object if the estimate failed */
|
|
2539
|
+
error?: unknown;
|
|
2540
|
+
}[];
|
|
2541
|
+
/** Array of protocol and service fees for the transfer */
|
|
2542
|
+
fees: {
|
|
2543
|
+
/** The type of fee - either from the bridge kit or the underlying provider */
|
|
2544
|
+
type: 'kit' | 'provider';
|
|
2545
|
+
/** The token in which the fee is charged (currently only USDC) */
|
|
2546
|
+
token: 'USDC';
|
|
2547
|
+
/** The fee amount (as a string to avoid precision issues) */
|
|
2548
|
+
amount: string | null;
|
|
2549
|
+
/** Optional error object if the estimate failed */
|
|
2550
|
+
error?: unknown;
|
|
2551
|
+
}[];
|
|
2552
|
+
}
|
|
2553
|
+
/**
|
|
2554
|
+
* Configuration options for customizing bridge behavior.
|
|
2555
|
+
*
|
|
2556
|
+
* @remarks
|
|
2557
|
+
* This interface is currently incomplete and will be expanded in future versions
|
|
2558
|
+
* to include additional configuration options such as slippage tolerance,
|
|
2559
|
+
* deadline settings, and other bridge parameters.
|
|
2560
|
+
*
|
|
2561
|
+
*/
|
|
2562
|
+
interface BridgeConfig {
|
|
2563
|
+
/**
|
|
2564
|
+
* The transfer speed mode for CCTPv2 transfers.
|
|
2565
|
+
*
|
|
2566
|
+
* Controls whether to use fast burn mode (FAST) or standard mode (SLOW).
|
|
2567
|
+
* Fast burn may reduce transfer time but could have different fee implications.
|
|
2568
|
+
*
|
|
2569
|
+
* @defaultValue TransferSpeed.FAST
|
|
2570
|
+
*/
|
|
2571
|
+
transferSpeed?: TransferSpeed | `${TransferSpeed}` | undefined;
|
|
2572
|
+
/**
|
|
2573
|
+
* The maximum fee to pay for the burn operation.
|
|
2574
|
+
*
|
|
2575
|
+
* @defaultValue 0
|
|
2576
|
+
*/
|
|
2577
|
+
maxFee?: string;
|
|
2578
|
+
/**
|
|
2579
|
+
* The custom fee to charge for the transfer.
|
|
2580
|
+
*/
|
|
2581
|
+
customFee?: CustomFee | undefined;
|
|
2582
|
+
}
|
|
2583
|
+
/**
|
|
2584
|
+
* Custom fee configuration charged by the integrator.
|
|
2585
|
+
*
|
|
2586
|
+
* Use to charge an absolute fee on the source chain, in the token's
|
|
2587
|
+
* smallest unit.
|
|
2588
|
+
*
|
|
2589
|
+
* @remarks
|
|
2590
|
+
* This is an absolute amount, not a percentage. The `recipientAddress` must be
|
|
2591
|
+
* a valid address for the source chain of the transfer.
|
|
2592
|
+
*
|
|
2593
|
+
* @example
|
|
2594
|
+
* ```typescript
|
|
2595
|
+
* import type { CustomFee } from '@core/provider'
|
|
2596
|
+
*
|
|
2597
|
+
* const config: CustomFee = {
|
|
2598
|
+
* value: '1000000', // 1 USDC in base units (6 decimals)
|
|
2599
|
+
* recipientAddress: '0x1234567890123456789012345678901234567890',
|
|
2600
|
+
* }
|
|
2601
|
+
* ```
|
|
2602
|
+
*/
|
|
2603
|
+
interface CustomFee {
|
|
2604
|
+
/**
|
|
2605
|
+
* The absolute fee to charge for the transfer.
|
|
2606
|
+
* Provide the amount as a base-10 numeric string representing the integer amount of the token (not in smallest units).
|
|
2607
|
+
* For example: to charge 1 USDC or 1 USDC, pass `'1'`.
|
|
2608
|
+
* This is not a percentage.
|
|
2609
|
+
*
|
|
2610
|
+
* Note: passing `'0'` results in no fee being charged.
|
|
2611
|
+
*/
|
|
2612
|
+
value?: string | undefined;
|
|
2613
|
+
/**
|
|
2614
|
+
* The fee recipient for the bridge transfer.
|
|
2615
|
+
* This is the address that will receive the fee on the source chain of the bridge transfer.
|
|
2616
|
+
* The fee recipient address **must be a valid address for the source chain** of the bridge transfer.
|
|
2617
|
+
*
|
|
2618
|
+
* For example: if bridging from Ethereum to Solana, pass an EVM address like
|
|
2619
|
+
* `'0x1234567890123456789012345678901234567890'` because the source chain is Ethereum.
|
|
2620
|
+
*/
|
|
2621
|
+
recipientAddress?: string | undefined;
|
|
2622
|
+
}
|
|
2623
|
+
/**
|
|
2624
|
+
* Represents the context of an adapter used for cross-chain operations.
|
|
2625
|
+
*
|
|
2626
|
+
* An AdapterContext must always specify both the adapter and the chain explicitly.
|
|
2627
|
+
* The address field behavior is determined by the adapter's address control model:
|
|
2628
|
+
*
|
|
2629
|
+
* - **Developer-controlled adapters**: The `address` field is required because
|
|
2630
|
+
* each operation must explicitly specify which address to use.
|
|
2631
|
+
* - **User-controlled adapters**: The `address` field is forbidden because
|
|
2632
|
+
* the address is automatically resolved from the connected wallet or signer.
|
|
2633
|
+
* - **Legacy adapters**: The `address` field remains optional for backward compatibility.
|
|
2634
|
+
*
|
|
2635
|
+
* This ensures clear, debuggable code where the intended chain is always visible at the call site,
|
|
2636
|
+
* and address requirements are enforced at compile time based on adapter capabilities.
|
|
2637
|
+
*
|
|
2638
|
+
* @typeParam TAdapterCapabilities - The adapter capabilities type to derive address requirements from
|
|
2639
|
+
*
|
|
2640
|
+
* @example
|
|
2641
|
+
* ```typescript
|
|
2642
|
+
* // Developer-controlled adapter (address required)
|
|
2643
|
+
* const devContext: AdapterContext<{ addressContext: 'developer-controlled', supportedChains: [] }> = {
|
|
2644
|
+
* adapter: myDevAdapter,
|
|
2645
|
+
* chain: 'Ethereum',
|
|
2646
|
+
* address: '0x123...' // Required
|
|
2647
|
+
* }
|
|
2648
|
+
*
|
|
2649
|
+
* // User-controlled adapter (address forbidden)
|
|
2650
|
+
* const userContext: AdapterContext<{ addressContext: 'user-controlled', supportedChains: [] }> = {
|
|
2651
|
+
* adapter: myUserAdapter,
|
|
2652
|
+
* chain: 'Ethereum'
|
|
2653
|
+
* // address: '0x123...' // TypeScript error: not allowed
|
|
2654
|
+
* }
|
|
2655
|
+
* ```
|
|
2656
|
+
*/
|
|
2657
|
+
type AdapterContext<TAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities> = {
|
|
2658
|
+
/** The adapter instance for blockchain operations */
|
|
2659
|
+
adapter: Adapter<TAdapterCapabilities>;
|
|
2660
|
+
/** The chain reference, which can be a ChainDefinition, Blockchain enum, or string literal */
|
|
2661
|
+
chain: ChainIdentifier;
|
|
2662
|
+
} & AddressField<ExtractAddressContext<TAdapterCapabilities>>;
|
|
2663
|
+
/**
|
|
2664
|
+
* Represents a bridge destination with an explicit custom recipient address.
|
|
2665
|
+
*
|
|
2666
|
+
* Extends {@link AdapterContext} with an additional `recipientAddress` field to specify
|
|
2667
|
+
* a custom recipient that differs from the adapter's address. Use this when bridging to
|
|
2668
|
+
* third-party wallets or smart contracts rather than the default address associated with
|
|
2669
|
+
* the destination adapter.
|
|
2670
|
+
*
|
|
2671
|
+
* @typeParam TCapabilities - The adapter capabilities type for the destination adapter
|
|
2672
|
+
*
|
|
2673
|
+
* @remarks
|
|
2674
|
+
* The `recipientAddress` must be a valid address format for the destination chain
|
|
2675
|
+
* specified in the adapter context. The bridge provider validates address compatibility
|
|
2676
|
+
* during the transfer preparation phase and will throw an error if the address format
|
|
2677
|
+
* is invalid for the target chain.
|
|
2678
|
+
*
|
|
2679
|
+
* @example
|
|
2680
|
+
* ```typescript
|
|
2681
|
+
* import { BridgeDestinationWithAddress } from '@core/provider'
|
|
2682
|
+
* import { ethereumAdapter } from './adapters'
|
|
2683
|
+
*
|
|
2684
|
+
* // Bridge to a custom recipient address on Ethereum
|
|
2685
|
+
* const destination: BridgeDestinationWithAddress = {
|
|
2686
|
+
* adapter: ethereumAdapter,
|
|
2687
|
+
* chain: 'Ethereum',
|
|
2688
|
+
* recipientAddress: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0'
|
|
2689
|
+
* }
|
|
2690
|
+
* ```
|
|
2691
|
+
*/
|
|
2692
|
+
type BridgeDestinationWithAddress<TCapabilities extends AdapterCapabilities = AdapterCapabilities> = AdapterContext<TCapabilities> & {
|
|
2693
|
+
/**
|
|
2694
|
+
* The custom recipient address on the destination chain.
|
|
2695
|
+
*
|
|
2696
|
+
* Must be a valid address format for the chain specified in this adapter context.
|
|
2697
|
+
* This address will receive the bridged funds instead of the adapter's default address.
|
|
2698
|
+
*/
|
|
2699
|
+
recipientAddress: string;
|
|
2700
|
+
};
|
|
2701
|
+
/**
|
|
2702
|
+
* Union type representing a bridge destination.
|
|
2703
|
+
* Can be either an AdapterContext (for default recipient) or BridgeDestinationWithAddress (for explicit recipient).
|
|
2704
|
+
*/
|
|
2705
|
+
type BridgeDestination<TAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities> = AdapterContext<TAdapterCapabilities> | BridgeDestinationWithAddress<TAdapterCapabilities>;
|
|
2706
|
+
/**
|
|
2707
|
+
* Context for retry operations containing source and destination adapter contexts.
|
|
2708
|
+
*
|
|
2709
|
+
* This interface provides the necessary context for retry operations, including
|
|
2710
|
+
* both the source adapter context (where the retry originates) and the destination
|
|
2711
|
+
* adapter context (where the retry is targeted). This ensures that retry operations
|
|
2712
|
+
* have access to both the source and destination chain information needed for
|
|
2713
|
+
* validation and execution.
|
|
2714
|
+
*
|
|
2715
|
+
* @example
|
|
2716
|
+
* ```typescript
|
|
2717
|
+
* const retryContext: RetryContext = {
|
|
2718
|
+
* from: { adapter: sourceAdapter, chain: 'Ethereum' },
|
|
2719
|
+
* to: { adapter: destAdapter, chain: 'Base' }
|
|
2720
|
+
* }
|
|
2721
|
+
* ```
|
|
2722
|
+
*/
|
|
2723
|
+
interface RetryContext<TFromAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities, TToAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities> {
|
|
2724
|
+
/** The source adapter context for the retry operation */
|
|
2725
|
+
from: Adapter<TFromAdapterCapabilities>;
|
|
2726
|
+
/** The destination adapter context for the retry operation */
|
|
2727
|
+
to: Adapter<TToAdapterCapabilities>;
|
|
2728
|
+
}
|
|
2729
|
+
/**
|
|
2730
|
+
* Result of analyzing bridge steps to determine retry feasibility and continuation point.
|
|
2731
|
+
*
|
|
2732
|
+
* This interface provides comprehensive information about the state of bridge steps,
|
|
2733
|
+
* including which steps have completed, which have failed, and whether the operation
|
|
2734
|
+
* can be retried from a specific point. It also includes the reason for failure
|
|
2735
|
+
* and identifies the next step to continue from.
|
|
2736
|
+
*
|
|
2737
|
+
* @example
|
|
2738
|
+
* ```typescript
|
|
2739
|
+
* const analysis: StepAnalysisResult = {
|
|
2740
|
+
* continuationStep: 'Burn',
|
|
2741
|
+
* isRetryable: true,
|
|
2742
|
+
* completedSteps: ['Approve'],
|
|
2743
|
+
* failedSteps: ['Burn'],
|
|
2744
|
+
* reason: 'Transaction timeout'
|
|
2745
|
+
* }
|
|
2746
|
+
* ```
|
|
2747
|
+
*/
|
|
2748
|
+
interface StepAnalysisResult {
|
|
2749
|
+
/** The next step to continue from, or null if no continuation is possible */
|
|
2750
|
+
continuationStep: string | null;
|
|
2751
|
+
/** Whether the flow requires user action (false for pending states that need waiting) */
|
|
2752
|
+
isActionable: boolean;
|
|
2753
|
+
/** Array of step names that have completed successfully */
|
|
2754
|
+
completedSteps: string[];
|
|
2755
|
+
/** Array of step names that have failed */
|
|
2756
|
+
failedSteps: string[];
|
|
2757
|
+
/** Optional reason for failure or retry decision */
|
|
2758
|
+
reason?: string;
|
|
2759
|
+
}
|
|
2760
|
+
|
|
2761
|
+
/**
|
|
2762
|
+
* Abstract base class for bridging providers that implement cross-chain bridging protocols.
|
|
2763
|
+
*
|
|
2764
|
+
* This class defines the standard interface that all bridging providers must implement
|
|
2765
|
+
* to support cross-chain bridging. It provides a standardized way to check route
|
|
2766
|
+
* support, estimate costs, and execute bridge operations across different protocols.
|
|
2767
|
+
*
|
|
2768
|
+
* Bridging providers are responsible for:
|
|
2769
|
+
* - Validating bridge parameters and route support
|
|
2770
|
+
* - Estimating gas costs and protocol fees
|
|
2771
|
+
* - Executing the actual bridge operations
|
|
2772
|
+
* - Handling protocol-specific logic and error conditions
|
|
2773
|
+
*
|
|
2774
|
+
* @example
|
|
2775
|
+
* ```typescript
|
|
2776
|
+
* class CustomBridgingProvider extends BridgingProvider {
|
|
2777
|
+
* async supportsRoute(source: Chain, destination: Chain, token: TokenType): Promise<boolean> {
|
|
2778
|
+
* // Implementation specific logic
|
|
2779
|
+
* return true
|
|
2780
|
+
* }
|
|
2781
|
+
*
|
|
2782
|
+
* async estimate(params: BridgeParams): Promise<BridgeEstimate> {
|
|
2783
|
+
* // Cost estimation logic
|
|
2784
|
+
* return { ... }
|
|
2785
|
+
* }
|
|
2786
|
+
*
|
|
2787
|
+
* async bridge(params: BridgeParams): Promise<BridgeResult> {
|
|
2788
|
+
* // Bridge execution logic
|
|
2789
|
+
* return { ... }
|
|
2790
|
+
* }
|
|
2791
|
+
* }
|
|
2792
|
+
* ```
|
|
2793
|
+
*/
|
|
2794
|
+
declare abstract class BridgingProvider<TProviderActions = Record<string, unknown>> {
|
|
2795
|
+
/** The name of the provider */
|
|
2796
|
+
abstract name: string;
|
|
2797
|
+
/**
|
|
2798
|
+
* The chains that this provider supports.
|
|
2799
|
+
*/
|
|
2800
|
+
abstract supportedChains: ChainDefinition[];
|
|
2801
|
+
/**
|
|
2802
|
+
* The action dispatcher for this provider.
|
|
2803
|
+
*
|
|
2804
|
+
* This property holds a reference to an action dispatcher that can be used to
|
|
2805
|
+
* dispatch events or actions during the transfer process. It is optional and
|
|
2806
|
+
* can be null if no dispatcher is registered.
|
|
2807
|
+
*/
|
|
2808
|
+
actionDispatcher?: Actionable<TProviderActions> | null;
|
|
2809
|
+
/**
|
|
2810
|
+
* Type-level map of action names to their payload types.
|
|
2811
|
+
* This property exists only at the type level and is used for TypeScript inference.
|
|
2812
|
+
*/
|
|
2813
|
+
readonly actions: TProviderActions;
|
|
2814
|
+
/**
|
|
2815
|
+
* Determines if this provider supports transfers between the specified source and destination chains.
|
|
2816
|
+
*
|
|
2817
|
+
* This method should check if the provider can handle transfers between the given chains,
|
|
2818
|
+
* typically by verifying that both chains have the necessary contract deployments and
|
|
2819
|
+
* configurations for the provider's protocol.
|
|
2820
|
+
*
|
|
2821
|
+
* @param source - The source chain definition
|
|
2822
|
+
* @param destination - The destination chain definition
|
|
2823
|
+
* @param token - The token to transfer (currently only USDC is supported)
|
|
2824
|
+
* @returns `true` if the provider supports this route, `false` otherwise
|
|
2825
|
+
*
|
|
2826
|
+
* @example
|
|
2827
|
+
* ```typescript
|
|
2828
|
+
* const provider = new CCTPV2Provider()
|
|
2829
|
+
* const canTransfer = provider.supportsRoute(Ethereum, Base)
|
|
2830
|
+
* if (canTransfer) {
|
|
2831
|
+
* console.log('CCTP v2 transfer is supported between Ethereum and Base')
|
|
2832
|
+
* }
|
|
2833
|
+
* ```
|
|
2834
|
+
*/
|
|
2835
|
+
abstract supportsRoute(source: ChainDefinition, destination: ChainDefinition, token: 'USDC'): boolean;
|
|
2836
|
+
/**
|
|
2837
|
+
* Executes a cross-chain bridge operation between the specified source and destination chains.
|
|
2838
|
+
*
|
|
2839
|
+
* This method performs the actual bridge operation by coordinating with the underlying
|
|
2840
|
+
* protocol contracts and handling the multi-step process required for cross-chain
|
|
2841
|
+
* bridging. The implementation details vary by protocol but typically involve
|
|
2842
|
+
* burning/locking tokens on the source chain and minting/unlocking on the destination.
|
|
2843
|
+
*
|
|
2844
|
+
* @param params - The bridge parameters containing source, destination, amount, and configuration
|
|
2845
|
+
* @param token - The token to bridge (currently only USDC is supported)
|
|
2846
|
+
* @param config - Optional bridge configuration including speed and fee settings
|
|
2847
|
+
* @returns Promise resolving to the bridge result with transaction details and steps
|
|
2848
|
+
* @throws {ValidationError} If the parameters are invalid
|
|
2849
|
+
* @throws {UnsupportedRouteError} If the route is not supported
|
|
2850
|
+
* @throws {BridgeError} If the bridge operation fails
|
|
2851
|
+
*
|
|
2852
|
+
* @example
|
|
2853
|
+
* ```typescript
|
|
2854
|
+
* const result = await provider.bridge({
|
|
2855
|
+
* source: { adapter: sourceAdapter, chain: 'Ethereum' },
|
|
2856
|
+
* destination: { adapter: destAdapter, chain: 'Base' },
|
|
2857
|
+
* amount: '10.50',
|
|
2858
|
+
* token: 'USDC'
|
|
2859
|
+
* })
|
|
2860
|
+
* ```
|
|
2861
|
+
*/
|
|
2862
|
+
abstract bridge<TFromAdapterCapabilities extends AdapterCapabilities, TToAdapterCapabilities extends AdapterCapabilities>(params: BridgeParams$1<TFromAdapterCapabilities, TToAdapterCapabilities>): Promise<BridgeResult>;
|
|
2863
|
+
/**
|
|
2864
|
+
* Estimates the cost and fees for a cross-chain bridge operation without executing it.
|
|
2865
|
+
*
|
|
2866
|
+
* This method calculates the expected gas costs and protocol fees for a bridge
|
|
2867
|
+
* operation, allowing users to understand the total cost before committing to
|
|
2868
|
+
* the transaction. The estimation should be as accurate as possible but may
|
|
2869
|
+
* vary slightly from actual execution due to network conditions.
|
|
2870
|
+
*
|
|
2871
|
+
* @param params - The bridge parameters for cost estimation
|
|
2872
|
+
* @returns Promise resolving to the cost estimate including gas and protocol fees
|
|
2873
|
+
* @throws {ValidationError} If the parameters are invalid
|
|
2874
|
+
* @throws {UnsupportedRouteError} If the route is not supported
|
|
2875
|
+
*
|
|
2876
|
+
* @example
|
|
2877
|
+
* ```typescript
|
|
2878
|
+
* const estimate = await provider.estimate({
|
|
2879
|
+
* source: { adapter: sourceAdapter, chain: 'Ethereum' },
|
|
2880
|
+
* destination: { adapter: destAdapter, chain: 'Base' },
|
|
2881
|
+
* amount: '10.50',
|
|
2882
|
+
* token: 'USDC'
|
|
2883
|
+
* })
|
|
2884
|
+
* console.log('Estimated cost:', estimate.totalCost)
|
|
2885
|
+
* ```
|
|
2886
|
+
*/
|
|
2887
|
+
abstract estimate<TFromAdapterCapabilities extends AdapterCapabilities, TToAdapterCapabilities extends AdapterCapabilities>(params: BridgeParams$1<TFromAdapterCapabilities, TToAdapterCapabilities>): Promise<EstimateResult>;
|
|
2888
|
+
/**
|
|
2889
|
+
* Get all destination chains that are supported for transfers from the given source chain.
|
|
2890
|
+
*
|
|
2891
|
+
* This method filters the provider's supported chains to return only those that are
|
|
2892
|
+
* compatible with the source chain. Compatibility is determined by matching testnet
|
|
2893
|
+
* status (mainnet chains can only transfer to mainnet chains, testnets to testnets)
|
|
2894
|
+
* and excluding the source chain itself.
|
|
2895
|
+
*
|
|
2896
|
+
* @param source - The source chain definition to find compatible destinations for
|
|
2897
|
+
* @returns Array of chain definitions that can serve as destinations for the given source
|
|
2898
|
+
*
|
|
2899
|
+
* @example
|
|
2900
|
+
* ```typescript
|
|
2901
|
+
* const provider = new BridgingProvider()
|
|
2902
|
+
* const destinations = provider.getSupportedDestinationsFor(Ethereum)
|
|
2903
|
+
* console.log('Available destinations from Ethereum:', destinations.map(d => d.name))
|
|
2904
|
+
* ```
|
|
2905
|
+
*/
|
|
2906
|
+
getSupportedDestinationsFor(source: ChainDefinition): ChainDefinition[];
|
|
2907
|
+
/**
|
|
2908
|
+
* Register an event dispatcher for handling provider-specific actions and events.
|
|
2909
|
+
*
|
|
2910
|
+
*
|
|
2911
|
+
* @param dispatcher - The event dispatcher implementing the Actionable interface
|
|
2912
|
+
*
|
|
2913
|
+
* @example
|
|
2914
|
+
* ```typescript
|
|
2915
|
+
* const provider = new BridgingProvider()
|
|
2916
|
+
*
|
|
2917
|
+
* const actionDispatcher = new Actionable()
|
|
2918
|
+
*
|
|
2919
|
+
* provider.registerDispatcher(actionDispatcher)
|
|
2920
|
+
*
|
|
2921
|
+
* // Now provider actions will be dispatched to the action dispatcher
|
|
2922
|
+
* await provider.bridge(transferParams)
|
|
2923
|
+
* ```
|
|
2924
|
+
*/
|
|
2925
|
+
registerDispatcher(dispatcher: Actionable<TProviderActions>): void;
|
|
2926
|
+
/**
|
|
2927
|
+
* Determines if this provider supports retry operations for the given bridge result.
|
|
2928
|
+
*
|
|
2929
|
+
* This method checks whether the provider can retry a failed bridge operation.
|
|
2930
|
+
* By default, all providers return false unless explicitly implemented.
|
|
2931
|
+
* Providers that support retry should override this method to return true
|
|
2932
|
+
* when retry is feasible for the given result.
|
|
2933
|
+
*
|
|
2934
|
+
* @param result - The bridge result to check for retry support
|
|
2935
|
+
* @returns `true` if retry is supported for this result, `false` otherwise
|
|
2936
|
+
*
|
|
2937
|
+
* @example
|
|
2938
|
+
* ```typescript
|
|
2939
|
+
* const result = await provider.bridge(params)
|
|
2940
|
+
* if (provider.supportsRetry(result)) {
|
|
2941
|
+
* const retryResult = await provider.retry(result, retryContext)
|
|
2942
|
+
* }
|
|
2943
|
+
* ```
|
|
2944
|
+
*/
|
|
2945
|
+
supportsRetry(result: BridgeResult): boolean;
|
|
2946
|
+
/**
|
|
2947
|
+
* Retries a failed bridge operation from the point of failure.
|
|
2948
|
+
*
|
|
2949
|
+
* This method attempts to retry a bridge operation that has previously failed,
|
|
2950
|
+
* continuing from the appropriate step based on the analysis of completed and
|
|
2951
|
+
* failed steps. By default, this method throws an error indicating that retry
|
|
2952
|
+
* is not supported. Providers that support retry should override this method.
|
|
2953
|
+
*
|
|
2954
|
+
* @param result - The failed bridge result to retry
|
|
2955
|
+
* @param context - The retry context containing source and destination adapter contexts
|
|
2956
|
+
* @returns Promise resolving to the retry bridge result
|
|
2957
|
+
* @throws {Error} If retry is not supported by this provider
|
|
2958
|
+
*
|
|
2959
|
+
* @example
|
|
2960
|
+
* ```typescript
|
|
2961
|
+
* const result = await provider.bridge(params)
|
|
2962
|
+
* if (result.state === 'error' && provider.supportsRetry(result)) {
|
|
2963
|
+
* const retryContext: RetryContext = {
|
|
2964
|
+
* from: { adapter: sourceAdapter, chain: 'Ethereum' },
|
|
2965
|
+
* to: { adapter: destAdapter, chain: 'Base' }
|
|
2966
|
+
* }
|
|
2967
|
+
* const retryResult = await provider.retry(result, retryContext)
|
|
2968
|
+
* }
|
|
2969
|
+
* ```
|
|
2970
|
+
*/
|
|
2971
|
+
retry<TFromAdapterCapabilities extends AdapterCapabilities, TToAdapterCapabilities extends AdapterCapabilities>(result: BridgeResult, context: RetryContext<TFromAdapterCapabilities, TToAdapterCapabilities>): Promise<BridgeResult>;
|
|
2972
|
+
/**
|
|
2973
|
+
* Analyzes bridge steps to determine retry feasibility and continuation point.
|
|
2974
|
+
*
|
|
2975
|
+
* This method examines the steps of a bridge operation to determine which steps
|
|
2976
|
+
* have completed, which have failed, and whether the operation can be retried
|
|
2977
|
+
* from a specific point. By default, this method throws an error indicating that
|
|
2978
|
+
* step analysis is not supported. Providers that support retry should override
|
|
2979
|
+
* this method to provide step analysis capabilities.
|
|
2980
|
+
*
|
|
2981
|
+
* @param steps - Array of bridge steps to analyze
|
|
2982
|
+
* @returns StepAnalysisResult containing retry analysis information
|
|
2983
|
+
* @throws Error If step analysis is not supported by this provider
|
|
2984
|
+
*
|
|
2985
|
+
* @example
|
|
2986
|
+
* ```typescript
|
|
2987
|
+
* const result = await provider.bridge(params)
|
|
2988
|
+
* if (result.state === 'error') {
|
|
2989
|
+
* const analysis = provider.analyzeStepsForRetry(result.steps)
|
|
2990
|
+
* if (analysis.isRetryable) {
|
|
2991
|
+
* console.log(`Can retry from step: ${analysis.continuationStep}`)
|
|
2992
|
+
* }
|
|
2993
|
+
* }
|
|
2994
|
+
* ```
|
|
2995
|
+
*/
|
|
2996
|
+
analyzeStepsForRetry(steps: BridgeStep[]): StepAnalysisResult;
|
|
2997
|
+
}
|
|
2998
|
+
|
|
2999
|
+
/**
|
|
3000
|
+
* Custom fee policy for BridgeKit.
|
|
3001
|
+
*
|
|
3002
|
+
* Provides hooks to calculate an absolute fee (in smallest unit string)
|
|
3003
|
+
* and to resolve the fee recipient address on the source chain.
|
|
3004
|
+
*
|
|
3005
|
+
* @example
|
|
3006
|
+
* ```typescript
|
|
3007
|
+
* import type { CustomFeePolicy, BridgeParams } from '@circle-fin/bridge-kit'
|
|
3008
|
+
*
|
|
3009
|
+
* const policy: CustomFeePolicy = {
|
|
3010
|
+
* // Charge 1 USDC on Solana, 0 on Ethereum, else 2 USDC
|
|
3011
|
+
* calculateFee: (params: BridgeParams): string => {
|
|
3012
|
+
* if (params.from.chain.type === 'solana') return '1000000'
|
|
3013
|
+
* if (params.from.chain.name === 'Ethereum') return '0'
|
|
3014
|
+
* return '2000000'
|
|
3015
|
+
* },
|
|
3016
|
+
* // Return a valid fee recipient for the source chain
|
|
3017
|
+
* resolveFeeRecipientAddress: (feePayoutChain): string => {
|
|
3018
|
+
* if (feePayoutChain.type === 'solana') {
|
|
3019
|
+
* return 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'
|
|
3020
|
+
* }
|
|
3021
|
+
* return '0x1234567890123456789012345678901234567890'
|
|
3022
|
+
* },
|
|
3023
|
+
* }
|
|
3024
|
+
* ```
|
|
3025
|
+
*/
|
|
3026
|
+
interface CustomFeePolicy {
|
|
3027
|
+
/**
|
|
3028
|
+
* A function that returns the fee to charge for the bridge transfer.
|
|
3029
|
+
* The value returned from the function represents an absolute fee in the smallest unit of the token.
|
|
3030
|
+
* It **does not** represent a percentage fee, only an absolute value.
|
|
3031
|
+
*
|
|
3032
|
+
* For example: if you want to charge 1 USDC, you would return `'1000000'`.
|
|
3033
|
+
*
|
|
3034
|
+
* Note: returning `'0'` will result in no fee being charged.
|
|
3035
|
+
*/
|
|
3036
|
+
calculateFee: <TFromAdapterCapabilities extends AdapterCapabilities, TToAdapterCapabilities extends AdapterCapabilities>(params: BridgeParams$1<TFromAdapterCapabilities, TToAdapterCapabilities>) => Promise<string> | string;
|
|
3037
|
+
/**
|
|
3038
|
+
* A function that returns the fee recipient for a bridge transfer.
|
|
3039
|
+
* The value returned from the function represents the address that will receive the fee on the source chain of the bridge transfer.
|
|
3040
|
+
* The fee recipient address **must be a valid address for the source chain** of the bridge transfer.
|
|
3041
|
+
*
|
|
3042
|
+
* For example: if you are bridging from Ethereum to Solana you would return `'0x1234567890123456789012345678901234567890'`,
|
|
3043
|
+
* because the source chain of the bridge transfer is Ethereum.
|
|
3044
|
+
*/
|
|
3045
|
+
resolveFeeRecipientAddress: <TFromAdapterCapabilities extends AdapterCapabilities, TToAdapterCapabilities extends AdapterCapabilities>(
|
|
3046
|
+
/**
|
|
3047
|
+
* The chain definition for the chain on which the fee is paid (the source chain).
|
|
3048
|
+
* For example, when bridging from Ethereum to Base, the fee payout chain is Ethereum,
|
|
3049
|
+
* since the bridging originates on Ethereum and the fee is taken on the source chain.
|
|
3050
|
+
*/
|
|
3051
|
+
feePayoutChain: ChainDefinition,
|
|
3052
|
+
/**
|
|
3053
|
+
* The bridge parameters.
|
|
3054
|
+
*/
|
|
3055
|
+
params: BridgeParams$1<TFromAdapterCapabilities, TToAdapterCapabilities>) => Promise<string> | string;
|
|
3056
|
+
}
|
|
3057
|
+
/**
|
|
3058
|
+
* Parameters for initiating a cross-chain USDC bridge transfer.
|
|
3059
|
+
*
|
|
3060
|
+
* This type is used as the primary input to {@link BridgeKit.bridge}, allowing users to specify
|
|
3061
|
+
* the source and destination adapters, transfer amount, and optional configuration.
|
|
3062
|
+
*
|
|
3063
|
+
* - The `from` field specifies the source adapter context (wallet and chain).
|
|
3064
|
+
* - The `to` field specifies the destination, supporting both explicit and derived recipient addresses.
|
|
3065
|
+
* - The `config` field allows customization of bridge behavior (e.g., transfer speed).
|
|
3066
|
+
* - The `token` field is optional and defaults to 'USDC'; other tokens are not currently supported.
|
|
3067
|
+
*
|
|
3068
|
+
* @typeParam TChainDefinition - The chain definition type for advanced usage (defaults to {@link ChainDefinition}).
|
|
3069
|
+
*
|
|
3070
|
+
* @example
|
|
3071
|
+
* ```typescript
|
|
3072
|
+
* const params: BridgeParams = {
|
|
3073
|
+
* from: { adapter: sourceAdapter, chain: 'Ethereum' },
|
|
3074
|
+
* to: { adapter: destAdapter, chain: 'Base' },
|
|
3075
|
+
* amount: '10.5',
|
|
3076
|
+
* // Optional:
|
|
3077
|
+
* config: { transferSpeed: 'FAST' },
|
|
3078
|
+
* token: 'USDC'
|
|
3079
|
+
* }
|
|
3080
|
+
*
|
|
3081
|
+
* // Or with explicit recipient address:
|
|
3082
|
+
* const paramsWithAddress: BridgeParams = {
|
|
3083
|
+
* from: { adapter: sourceAdapter, chain: 'Ethereum' },
|
|
3084
|
+
* to: {
|
|
3085
|
+
* recipientAddress: '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
|
|
3086
|
+
* adapter: destAdapter, chain: 'Base'
|
|
3087
|
+
* },
|
|
3088
|
+
* amount: '10.5'
|
|
3089
|
+
* }
|
|
3090
|
+
* ```
|
|
3091
|
+
*/
|
|
3092
|
+
interface BridgeParams<TFromAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities, TToAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities> {
|
|
3093
|
+
/**
|
|
3094
|
+
* The source adapter context (wallet and chain) for the transfer.
|
|
3095
|
+
*/
|
|
3096
|
+
from: AdapterContext<TFromAdapterCapabilities>;
|
|
3097
|
+
/**
|
|
3098
|
+
* The destination for the transfer, supporting explicit or derived recipient addresses.
|
|
3099
|
+
*/
|
|
3100
|
+
to: BridgeDestination<TToAdapterCapabilities>;
|
|
3101
|
+
/**
|
|
3102
|
+
* The amount to transfer.
|
|
3103
|
+
*/
|
|
3104
|
+
amount: string;
|
|
3105
|
+
/**
|
|
3106
|
+
* Optional bridge configuration (e.g., transfer speed).
|
|
3107
|
+
* If omitted, defaults will be used.
|
|
3108
|
+
*/
|
|
3109
|
+
config?: BridgeConfig;
|
|
3110
|
+
/**
|
|
3111
|
+
* The token to transfer. Defaults to 'USDC'.
|
|
3112
|
+
* If omitted, the provider will use 'USDC' by default.
|
|
3113
|
+
*/
|
|
3114
|
+
token?: 'USDC';
|
|
3115
|
+
}
|
|
3116
|
+
|
|
3117
|
+
/**
|
|
3118
|
+
* The default providers that will be used in addition to the providers provided
|
|
3119
|
+
* to the BridgeKit constructor.
|
|
3120
|
+
*/
|
|
3121
|
+
declare const getDefaultProviders: () => readonly [CCTPV2BridgingProvider];
|
|
3122
|
+
|
|
3123
|
+
/**
|
|
3124
|
+
* Configuration options for initializing a BridgeKit instance.
|
|
3125
|
+
*
|
|
3126
|
+
* The configuration allows you to specify which bridging providers should be
|
|
3127
|
+
* available for cross-chain token transfers. Each provider implements a specific
|
|
3128
|
+
* bridging protocol (e.g., CCTPv2) and supports a set of chains.
|
|
3129
|
+
*
|
|
3130
|
+
* When multiple providers are specified, the kit will automatically select the
|
|
3131
|
+
* appropriate provider based on the source/destination chains and token type
|
|
3132
|
+
* for each transfer request.
|
|
3133
|
+
*
|
|
3134
|
+
* @example
|
|
3135
|
+
* ```typescript
|
|
3136
|
+
* import { BridgeKit } from '@circle-fin/bridge-kit'
|
|
3137
|
+
* import type { BridgeParams, CustomFeePolicy } from '@circle-fin/bridge-kit'
|
|
3138
|
+
* import type { ChainDefinition } from '@core/chains'
|
|
3139
|
+
*
|
|
3140
|
+
* // Create kit with default CCTPV2BridgingProvider
|
|
3141
|
+
* const kit = new BridgeKit()
|
|
3142
|
+
*
|
|
3143
|
+
* // Set custom fee policy using the setter method
|
|
3144
|
+
* kit.setCustomFeePolicy({
|
|
3145
|
+
* calculateFee: (params: BridgeParams): string => {
|
|
3146
|
+
* return '1000000' // 1 USDC
|
|
3147
|
+
* },
|
|
3148
|
+
* resolveFeeRecipientAddress: (chain: ChainDefinition): string => {
|
|
3149
|
+
* return '0x1234567890123456789012345678901234567890'
|
|
3150
|
+
* }
|
|
3151
|
+
* })
|
|
3152
|
+
*
|
|
3153
|
+
* // Add additional custom providers if needed
|
|
3154
|
+
* // const kit = new BridgeKit({
|
|
3155
|
+
* // providers: [new MyCustomBridgingProvider()]
|
|
3156
|
+
* // })
|
|
3157
|
+
* ```
|
|
3158
|
+
*/
|
|
3159
|
+
interface BridgeKitConfig<TExtraProviders extends FlexibleBridgingProvider[] = []> {
|
|
3160
|
+
/**
|
|
3161
|
+
* Array of bridging providers that will be available for routing transfers.
|
|
3162
|
+
*
|
|
3163
|
+
* Each provider must implement the BridgingProvider interface and declare
|
|
3164
|
+
* which chains and tokens it supports. The kit will automatically select
|
|
3165
|
+
* the appropriate provider based on order and the transfer parameters.
|
|
3166
|
+
*/
|
|
3167
|
+
providers?: TExtraProviders;
|
|
3168
|
+
}
|
|
3169
|
+
/**
|
|
3170
|
+
* Merges action types from multiple bridging providers into a unified action map.
|
|
3171
|
+
*
|
|
3172
|
+
* This utility type takes an array of bridging providers and creates a merged
|
|
3173
|
+
* action type that combines all action names and their corresponding payload types
|
|
3174
|
+
* from each provider. It ensures type safety when dispatching events across
|
|
3175
|
+
* multiple providers while maintaining the specific payload types for each action.
|
|
3176
|
+
*
|
|
3177
|
+
* The type works by:
|
|
3178
|
+
* 1. Extracting all action names from the union of provider action maps
|
|
3179
|
+
* 2. For each action name, creating a union of all payload types that use that name
|
|
3180
|
+
* 3. Preserving the specific payload type for each action across providers
|
|
3181
|
+
*
|
|
3182
|
+
* @typeParam Ps - A readonly array of flexible bridging providers
|
|
3183
|
+
* @returns A merged action map where each key is an action name and the value is
|
|
3184
|
+
* the union of all payload types for that action across providers
|
|
3185
|
+
*
|
|
3186
|
+
* @example
|
|
3187
|
+
* ```typescript
|
|
3188
|
+
* // Given providers with actions:
|
|
3189
|
+
* // Provider1: { 'transfer.started': { txHash: string } }
|
|
3190
|
+
* // Provider2: { 'transfer.started': { blockNumber: number } }
|
|
3191
|
+
*
|
|
3192
|
+
* // MergeActions will create:
|
|
3193
|
+
* // { 'transfer.started': { txHash: string } | { blockNumber: number } }
|
|
3194
|
+
* ```
|
|
3195
|
+
*/
|
|
3196
|
+
type MergeActions<Ps extends readonly FlexibleBridgingProvider[]> = {
|
|
3197
|
+
[K in keyof Ps[number]['actions']]: Extract<Ps[number]['actions'], Record<K, unknown>>[K];
|
|
3198
|
+
};
|
|
3199
|
+
/**
|
|
3200
|
+
* Type representing the default providers included in the BridgeKit.
|
|
3201
|
+
*
|
|
3202
|
+
* This type extracts the return type from the `getDefaultProviders()` function,
|
|
3203
|
+
* ensuring that the default providers are properly typed and included in the
|
|
3204
|
+
* overall provider configuration.
|
|
3205
|
+
*/
|
|
3206
|
+
type DefaultProviders = ReturnType<typeof getDefaultProviders>;
|
|
3207
|
+
/**
|
|
3208
|
+
* Complete action map combining default providers with extra providers.
|
|
3209
|
+
*
|
|
3210
|
+
* This type merges the actions from both the default providers (CCTPv2) and any
|
|
3211
|
+
* additional providers passed to the BridgeKit constructor. It ensures that
|
|
3212
|
+
* all available actions from all providers are accessible through the event system.
|
|
3213
|
+
*
|
|
3214
|
+
* @typeParam EP - Array of extra bridging providers beyond the defaults
|
|
3215
|
+
* @returns A merged action map containing all actions from default and extra providers
|
|
3216
|
+
*
|
|
3217
|
+
* @example
|
|
3218
|
+
* ```typescript
|
|
3219
|
+
* import { BridgeKit } from '@circle-fin/bridge-kit'
|
|
3220
|
+
* import { CustomProvider } from './custom-provider'
|
|
3221
|
+
*
|
|
3222
|
+
* const kit = new BridgeKit({
|
|
3223
|
+
* providers: [new CustomProvider()]
|
|
3224
|
+
* })
|
|
3225
|
+
*
|
|
3226
|
+
* // AllActions will include actions from both CCTPv2 and CustomProvider
|
|
3227
|
+
* type AvailableActions = AllActions<[CustomProvider]>
|
|
3228
|
+
* ```
|
|
3229
|
+
*/
|
|
3230
|
+
type AllActions<EP extends FlexibleBridgingProvider[]> = MergeActions<[
|
|
3231
|
+
...DefaultProviders,
|
|
3232
|
+
...EP
|
|
3233
|
+
]>;
|
|
3234
|
+
/**
|
|
3235
|
+
* Union of all available action names across all providers.
|
|
3236
|
+
*
|
|
3237
|
+
* This type extracts the keys from the merged action map, providing a union
|
|
3238
|
+
* of all possible action names that can be used with the event system.
|
|
3239
|
+
* It enables type-safe event handling by ensuring only valid action names
|
|
3240
|
+
* can be used when registering event handlers.
|
|
3241
|
+
*
|
|
3242
|
+
* @typeParam EP - Array of extra bridging providers beyond the defaults
|
|
3243
|
+
* @returns A union of all action names available across all providers
|
|
3244
|
+
*
|
|
3245
|
+
* @example
|
|
3246
|
+
* ```typescript
|
|
3247
|
+
* // ActionName will be something like:
|
|
3248
|
+
* // 'transfer.started' | 'transfer.completed' | 'custom.action'
|
|
3249
|
+
*
|
|
3250
|
+
* kit.on('transfer.started', (payload) => {
|
|
3251
|
+
* // TypeScript knows this is a valid action name
|
|
3252
|
+
* })
|
|
3253
|
+
* ```
|
|
3254
|
+
*/
|
|
3255
|
+
type ActionName<EP extends FlexibleBridgingProvider[]> = keyof AllActions<EP>;
|
|
3256
|
+
/**
|
|
3257
|
+
* Type for event handler functions that can be registered with the BridgeKit.
|
|
3258
|
+
*
|
|
3259
|
+
* This type extracts the handler function type from the `on` method parameters,
|
|
3260
|
+
* ensuring that event handlers have the correct signature and payload types.
|
|
3261
|
+
* It enables type-safe event handling by preserving the specific payload types
|
|
3262
|
+
* for each action.
|
|
3263
|
+
*
|
|
3264
|
+
* @typeParam T - The specific BridgeKit instance type
|
|
3265
|
+
* @returns The function type for event handlers with proper payload typing
|
|
3266
|
+
*
|
|
3267
|
+
* @example
|
|
3268
|
+
* ```typescript
|
|
3269
|
+
* const kit = new BridgeKit()
|
|
3270
|
+
*
|
|
3271
|
+
* // ActionHandler will be the correct function type for handlers
|
|
3272
|
+
* const handler: ActionHandler<typeof kit> = (payload) => {
|
|
3273
|
+
* // payload is properly typed based on the action
|
|
3274
|
+
* }
|
|
3275
|
+
* ```
|
|
3276
|
+
*/
|
|
3277
|
+
type ActionHandler<T extends BridgeKit> = Parameters<T['on']>[1];
|
|
3278
|
+
/**
|
|
3279
|
+
* A type alias that enables flexible provider type handling in the event system.
|
|
3280
|
+
*
|
|
3281
|
+
* This uses `any` as an intentional "escape hatch" to allow the complex generic
|
|
3282
|
+
* type machinery to work when merging action types from different providers.
|
|
3283
|
+
* Type safety is still preserved at usage sites through overloaded method signatures
|
|
3284
|
+
* and the Actionable dispatcher's typing system.
|
|
3285
|
+
*
|
|
3286
|
+
* Without this flexibility, TypeScript cannot properly infer the merged action types
|
|
3287
|
+
* across different provider implementations while maintaining a clean developer
|
|
3288
|
+
* experience for event handlers.
|
|
3289
|
+
*/
|
|
3290
|
+
type FlexibleBridgingProvider = BridgingProvider<any>;
|
|
3291
|
+
/**
|
|
3292
|
+
* Route cross-chain USDC bridging through Circle's Cross-Chain Transfer Protocol v2 (CCTPv2).
|
|
3293
|
+
*
|
|
3294
|
+
* This method orchestrates the entire cross-chain bridging process including:
|
|
3295
|
+
* 1. Parameter validation and route resolution
|
|
3296
|
+
* 2. Provider selection and configuration
|
|
3297
|
+
* 3. Transaction execution on both source and destination chains
|
|
3298
|
+
* 4. Event emission for monitoring and debugging
|
|
3299
|
+
*
|
|
3300
|
+
* The process is atomic - if any step fails, the method will throw an error
|
|
3301
|
+
* with detailed information about the failure point and any completed steps.
|
|
3302
|
+
*
|
|
3303
|
+
* @param params - The bridge parameters containing source, destination, amount, and token
|
|
3304
|
+
* @returns Promise resolving to the bridge result with transaction details and steps
|
|
3305
|
+
* @throws {ValidationError} If the parameters are invalid
|
|
3306
|
+
* @throws {BridgeError} If the bridging process fails
|
|
3307
|
+
* @throws {UnsupportedRouteError} If the route is not supported
|
|
3308
|
+
*
|
|
3309
|
+
* @example
|
|
3310
|
+
* ```typescript
|
|
3311
|
+
* import { BridgeKit } from '@circle-fin/bridge-kit'
|
|
3312
|
+
* import { createAdapterFromPrivateKey } from '@circle-fin/adapter-viem-v2'
|
|
3313
|
+
*
|
|
3314
|
+
* // Create kit with default CCTPv2 provider
|
|
3315
|
+
* const kit = new BridgeKit()
|
|
3316
|
+
* const adapter = createAdapterFromPrivateKey({ privateKey: '0x...' })
|
|
3317
|
+
*
|
|
3318
|
+
* // Execute cross-chain transfer
|
|
3319
|
+
* const result = await kit.bridge({
|
|
3320
|
+
* from: { adapter, chain: 'Ethereum' },
|
|
3321
|
+
* to: { adapter, chain: 'Base' },
|
|
3322
|
+
* amount: '10.50'
|
|
3323
|
+
* })
|
|
3324
|
+
*
|
|
3325
|
+
* // Monitor bridge events
|
|
3326
|
+
* kit.on('approve', (payload) => {
|
|
3327
|
+
* console.log('Approval complete:', payload.values.txHash)
|
|
3328
|
+
* })
|
|
3329
|
+
* ```
|
|
3330
|
+
*/
|
|
3331
|
+
declare class BridgeKit<TExtraProviders extends FlexibleBridgingProvider[] = []> {
|
|
3332
|
+
/**
|
|
3333
|
+
* The providers used for executing transfers.
|
|
3334
|
+
*/
|
|
3335
|
+
providers: [...DefaultProviders, ...TExtraProviders];
|
|
3336
|
+
/**
|
|
3337
|
+
* The action dispatcher for the kit.
|
|
3338
|
+
*/
|
|
3339
|
+
actionDispatcher: Actionable<AllActions<TExtraProviders>>;
|
|
3340
|
+
/**
|
|
3341
|
+
* A custom fee policy for the kit.
|
|
3342
|
+
*/
|
|
3343
|
+
customFeePolicy: CustomFeePolicy | undefined;
|
|
3344
|
+
/**
|
|
3345
|
+
* Create a new BridgeKit instance.
|
|
3346
|
+
*
|
|
3347
|
+
* @param config - The configuration containing the CCTPv2 provider
|
|
3348
|
+
*
|
|
3349
|
+
* @example
|
|
3350
|
+
* ```typescript
|
|
3351
|
+
* import { BridgeKit } from '@circle-fin/bridge-kit'
|
|
3352
|
+
*
|
|
3353
|
+
* const kit = new BridgeKit()
|
|
3354
|
+
* ```
|
|
3355
|
+
*/
|
|
3356
|
+
constructor(config?: BridgeKitConfig<TExtraProviders>);
|
|
3357
|
+
/**
|
|
3358
|
+
* Register an event handler for a specific bridge action.
|
|
3359
|
+
*
|
|
3360
|
+
* Subscribe to events emitted during bridge operations such as approval, burn,
|
|
3361
|
+
* attestation fetch, and mint actions. Handlers receive strongly-typed payloads
|
|
3362
|
+
* based on the action name.
|
|
3363
|
+
*
|
|
3364
|
+
* Multiple handlers can be registered for the same action, and all will be invoked
|
|
3365
|
+
* when the action occurs. Use the wildcard '*' to listen to all actions.
|
|
3366
|
+
*
|
|
3367
|
+
* @typeParam K - The action name to listen for
|
|
3368
|
+
* @param action - The action name or '*' for all actions
|
|
3369
|
+
* @param handler - Callback function to invoke when the action occurs
|
|
3370
|
+
*
|
|
3371
|
+
* @example
|
|
3372
|
+
* ```typescript
|
|
3373
|
+
* import { BridgeKit } from '@circle-fin/bridge-kit'
|
|
3374
|
+
*
|
|
3375
|
+
* const kit = new BridgeKit()
|
|
3376
|
+
*
|
|
3377
|
+
* // Listen to specific action
|
|
3378
|
+
* kit.on('approve', (payload) => {
|
|
3379
|
+
* console.log('Approval transaction:', payload.values.txHash)
|
|
3380
|
+
* })
|
|
3381
|
+
*
|
|
3382
|
+
* // Listen to all actions
|
|
3383
|
+
* kit.on('*', (payload) => {
|
|
3384
|
+
* console.log('Action:', payload.method)
|
|
3385
|
+
* })
|
|
3386
|
+
* ```
|
|
3387
|
+
*/
|
|
3388
|
+
on<K extends ActionName<TExtraProviders>>(action: K, handlers: (payload: AllActions<TExtraProviders>[K]) => void): void;
|
|
3389
|
+
on(action: '*', handler: (payload: AllActions<TExtraProviders>[keyof AllActions<TExtraProviders>]) => void): void;
|
|
3390
|
+
/**
|
|
3391
|
+
* Unregister an event handler for a specific bridge action.
|
|
3392
|
+
*
|
|
3393
|
+
* This method removes a previously registered event handler. You must pass
|
|
3394
|
+
* the exact same handler function reference that was used during registration.
|
|
3395
|
+
* Use the wildcard '*' to remove handlers listening to all actions.
|
|
3396
|
+
*
|
|
3397
|
+
* @typeParam K - The action name to stop listening for
|
|
3398
|
+
* @param action - The action name or '*' for all actions
|
|
3399
|
+
* @param handler - The handler function to remove (must be the same reference)
|
|
3400
|
+
*
|
|
3401
|
+
* @example
|
|
3402
|
+
* ```typescript
|
|
3403
|
+
* import { BridgeKit } from '@circle-fin/bridge-kit'
|
|
3404
|
+
*
|
|
3405
|
+
* const kit = new BridgeKit()
|
|
3406
|
+
*
|
|
3407
|
+
* // Define handler
|
|
3408
|
+
* const handler = (payload) => {
|
|
3409
|
+
* console.log('Approval:', payload)
|
|
3410
|
+
* }
|
|
3411
|
+
*
|
|
3412
|
+
* // Register
|
|
3413
|
+
* kit.on('approve', handler)
|
|
3414
|
+
*
|
|
3415
|
+
* // Later, unregister
|
|
3416
|
+
* kit.off('approve', handler)
|
|
3417
|
+
* ```
|
|
3418
|
+
*/
|
|
3419
|
+
off<K extends ActionName<TExtraProviders>>(action: K, handlers: (payload: AllActions<TExtraProviders>[K]) => void): void;
|
|
3420
|
+
off(action: '*', handler: (payload: AllActions<TExtraProviders>[keyof AllActions<TExtraProviders>]) => void): void;
|
|
3421
|
+
/**
|
|
3422
|
+
* Execute a cross-chain USDC transfer using CCTPv2.
|
|
3423
|
+
*
|
|
3424
|
+
* Handle the complete CCTPv2 transfer flow, including parameter validation,
|
|
3425
|
+
* chain resolution, and transfer execution. Provide comprehensive validation of
|
|
3426
|
+
* all parameters before initiating the transfer.
|
|
3427
|
+
*
|
|
3428
|
+
* Perform validation of:
|
|
3429
|
+
* - Source and destination wallet contexts
|
|
3430
|
+
* - Chain identifiers (string, enum, or chain definition)
|
|
3431
|
+
* - Amount format and token type
|
|
3432
|
+
* - CCTPv2 support for the chain pair
|
|
3433
|
+
* - Transfer configuration options
|
|
3434
|
+
*
|
|
3435
|
+
* @param params - The transfer parameters containing source, destination, amount, and token
|
|
3436
|
+
* @returns Promise resolving to the transfer result with transaction details and steps
|
|
3437
|
+
* @throws {ValidationError} When any parameter validation fails.
|
|
3438
|
+
* @throws {Error} When CCTPv2 does not support the specified route.
|
|
3439
|
+
*
|
|
3440
|
+
* @example
|
|
3441
|
+
* ```typescript
|
|
3442
|
+
* import { BridgeKit } from '@circle-fin/bridge-kit'
|
|
3443
|
+
* import { createAdapterFromPrivateKey } from '@circle-fin/adapter-viem-v2'
|
|
3444
|
+
*
|
|
3445
|
+
* const kit = new BridgeKit()
|
|
3446
|
+
*
|
|
3447
|
+
* // Create a single adapter that can work across chains
|
|
3448
|
+
* const adapter = createAdapterFromPrivateKey({
|
|
3449
|
+
* privateKey: process.env.PRIVATE_KEY,
|
|
3450
|
+
* })
|
|
3451
|
+
*
|
|
3452
|
+
* const result = await kit.bridge({
|
|
3453
|
+
* from: {
|
|
3454
|
+
* adapter,
|
|
3455
|
+
* chain: 'Ethereum'
|
|
3456
|
+
* },
|
|
3457
|
+
* to: {
|
|
3458
|
+
* adapter,
|
|
3459
|
+
* chain: 'Base'
|
|
3460
|
+
* },
|
|
3461
|
+
* amount: '100.50'
|
|
3462
|
+
* })
|
|
3463
|
+
*
|
|
3464
|
+
* // Handle result
|
|
3465
|
+
* if (result.state === 'success') {
|
|
3466
|
+
* console.log('Bridge completed!')
|
|
3467
|
+
* result.steps.forEach(step => {
|
|
3468
|
+
* console.log(`${step.name}: ${step.explorerUrl}`)
|
|
3469
|
+
* })
|
|
3470
|
+
* } else {
|
|
3471
|
+
* console.error('Bridge failed:', result.steps)
|
|
3472
|
+
* }
|
|
3473
|
+
* ```
|
|
3474
|
+
*/
|
|
3475
|
+
bridge<TFromAdapterCapabilities extends AdapterCapabilities, TToAdapterCapabilities extends AdapterCapabilities>(params: BridgeParams<TFromAdapterCapabilities, TToAdapterCapabilities>): Promise<BridgeResult>;
|
|
3476
|
+
/**
|
|
3477
|
+
* Retry a failed or incomplete cross-chain USDC bridge operation.
|
|
3478
|
+
*
|
|
3479
|
+
* Provide a high-level interface for resuming bridge operations that have failed
|
|
3480
|
+
* or become stuck during execution. Automatically identify the provider that was
|
|
3481
|
+
* used for the original transfer and delegate the retry logic to that provider's
|
|
3482
|
+
* implementation.
|
|
3483
|
+
*
|
|
3484
|
+
* Use this functionality to handle:
|
|
3485
|
+
* - Network timeouts or temporary connectivity issues
|
|
3486
|
+
* - Gas estimation failures that can be resolved with updated parameters
|
|
3487
|
+
* - Pending transactions that need to be resubmitted
|
|
3488
|
+
* - Failed steps in multi-step bridge flows
|
|
3489
|
+
*
|
|
3490
|
+
* @param result - The bridge result from a previous failed or incomplete operation.
|
|
3491
|
+
* Must contain the provider name and step execution history.
|
|
3492
|
+
* @param context - The retry context containing fresh adapter instances for both
|
|
3493
|
+
* source and destination chains. These adapters should be properly
|
|
3494
|
+
* configured with current network connections and signing capabilities.
|
|
3495
|
+
* @returns A promise that resolves to the updated bridge result after retry execution.
|
|
3496
|
+
* The result will contain the complete step history including both original
|
|
3497
|
+
* and retry attempts.
|
|
3498
|
+
*
|
|
3499
|
+
* @throws {Error} When the original provider specified in the result is not found
|
|
3500
|
+
* in the current kit configuration.
|
|
3501
|
+
* @throws {Error} When the underlying provider's retry operation fails due to
|
|
3502
|
+
* non-recoverable errors or invalid state.
|
|
3503
|
+
*
|
|
3504
|
+
* @example
|
|
3505
|
+
* ```typescript
|
|
3506
|
+
* import { BridgeKit } from '@circle-fin/bridge-kit'
|
|
3507
|
+
* import { createAdapterFromPrivateKey } from '@circle-fin/adapter-viem-v2'
|
|
3508
|
+
*
|
|
3509
|
+
* const kit = new BridgeKit()
|
|
3510
|
+
*
|
|
3511
|
+
* // Assume we have a failed bridge result from a previous operation
|
|
3512
|
+
* const failedResult: BridgeResult = {
|
|
3513
|
+
* state: 'error',
|
|
3514
|
+
* provider: 'CCTPV2BridgingProvider',
|
|
3515
|
+
* steps: [
|
|
3516
|
+
* { name: 'approve', state: 'success', txHash: '0x123...' },
|
|
3517
|
+
* { name: 'burn', state: 'error', errorMessage: 'Gas limit exceeded' }
|
|
3518
|
+
* ],
|
|
3519
|
+
* // ... other properties
|
|
3520
|
+
* }
|
|
3521
|
+
*
|
|
3522
|
+
*
|
|
3523
|
+
* try {
|
|
3524
|
+
* const retryResult = await kit.retry(failedResult, {
|
|
3525
|
+
* from: sourceAdapter,
|
|
3526
|
+
* to: destAdapter
|
|
3527
|
+
* })
|
|
3528
|
+
*
|
|
3529
|
+
* console.log('Retry completed successfully:', retryResult.state)
|
|
3530
|
+
* console.log('Total steps executed:', retryResult.steps.length)
|
|
3531
|
+
* } catch (error) {
|
|
3532
|
+
* console.error('Retry failed:', error.message)
|
|
3533
|
+
* // Handle retry failure (may require manual intervention)
|
|
3534
|
+
* }
|
|
3535
|
+
* ```
|
|
3536
|
+
*/
|
|
3537
|
+
retry<TFromAdapterCapabilities extends AdapterCapabilities, TToAdapterCapabilities extends AdapterCapabilities>(result: BridgeResult, context: RetryContext<TFromAdapterCapabilities, TToAdapterCapabilities>): Promise<BridgeResult>;
|
|
3538
|
+
/**
|
|
3539
|
+
* Estimate the cost and fees for a cross-chain USDC bridge operation.
|
|
3540
|
+
*
|
|
3541
|
+
* This method calculates the expected gas fees and protocol costs for bridging
|
|
3542
|
+
* without actually executing the transaction. It performs the same validation
|
|
3543
|
+
* as the bridge method but stops before execution.
|
|
3544
|
+
* @param params - The bridge parameters for cost estimation
|
|
3545
|
+
* @returns Promise resolving to detailed cost breakdown including gas estimates
|
|
3546
|
+
* @throws {ValidationError} When the parameters are invalid.
|
|
3547
|
+
* @throws {UnsupportedRouteError} When the route is not supported.
|
|
3548
|
+
*
|
|
3549
|
+
* @example
|
|
3550
|
+
* ```typescript
|
|
3551
|
+
* const estimate = await kit.estimate({
|
|
3552
|
+
* from: { adapter: adapter, chain: 'Ethereum' },
|
|
3553
|
+
* to: { adapter: adapter, chain: 'Base' },
|
|
3554
|
+
* amount: '10.50',
|
|
3555
|
+
* token: 'USDC'
|
|
3556
|
+
* })
|
|
3557
|
+
* console.log('Estimated cost:', estimate.totalCost)
|
|
3558
|
+
* ```
|
|
3559
|
+
*/
|
|
3560
|
+
estimate<TFromAdapterCapabilities extends AdapterCapabilities, TToAdapterCapabilities extends AdapterCapabilities>(params: BridgeParams<TFromAdapterCapabilities, TToAdapterCapabilities>): Promise<EstimateResult>;
|
|
3561
|
+
/**
|
|
3562
|
+
* Get all chains supported by any provider in the kit.
|
|
3563
|
+
*
|
|
3564
|
+
* Aggregate and deduplicate the supported chains from all registered providers.
|
|
3565
|
+
* This provides a comprehensive list of chains that can be used as either source
|
|
3566
|
+
* or destination for transfers through this kit instance.
|
|
3567
|
+
*
|
|
3568
|
+
* The method automatically deduplicates chains based on their chain identifier,
|
|
3569
|
+
* ensuring each chain appears only once in the result regardless of how many
|
|
3570
|
+
* providers support it.
|
|
3571
|
+
*
|
|
3572
|
+
* @returns Array of unique chain definitions supported by the registered providers
|
|
3573
|
+
*
|
|
3574
|
+
* @example
|
|
3575
|
+
* ```typescript
|
|
3576
|
+
* import { BridgeKit } from '@circle-fin/bridge-kit'
|
|
3577
|
+
*
|
|
3578
|
+
* const kit = new BridgeKit()
|
|
3579
|
+
* const chains = kit.getSupportedChains()
|
|
3580
|
+
*
|
|
3581
|
+
* console.log('Supported chains:')
|
|
3582
|
+
* chains.forEach(chain => {
|
|
3583
|
+
* console.log(`- ${chain.name} (${chain.type})`)
|
|
3584
|
+
* })
|
|
3585
|
+
* ```
|
|
3586
|
+
*/
|
|
3587
|
+
getSupportedChains(): ChainDefinition[];
|
|
3588
|
+
/**
|
|
3589
|
+
* Validate that source and destination chains are on the same network type.
|
|
3590
|
+
*
|
|
3591
|
+
* This method ensures that both chains are either testnet or mainnet, preventing
|
|
3592
|
+
* cross-network transfers which are not supported by the bridging protocols.
|
|
3593
|
+
*
|
|
3594
|
+
* @param resolvedParams - The resolved bridge parameters containing source and destination chains
|
|
3595
|
+
* @throws {NetworkMismatchError} If source and destination chains are on different network types
|
|
3596
|
+
*/
|
|
3597
|
+
private validateNetworkCompatibility;
|
|
3598
|
+
/**
|
|
3599
|
+
* Find a provider that supports the given transfer route.
|
|
3600
|
+
*
|
|
3601
|
+
* This method centralizes the provider selection logic to ensure consistency
|
|
3602
|
+
* between transfer and estimate operations. It resolves the source and destination
|
|
3603
|
+
* chains from the provided adapters and finds the first provider that supports
|
|
3604
|
+
* the route for the specified token.
|
|
3605
|
+
*
|
|
3606
|
+
* @param params - The transfer parameters containing source, destination, and token
|
|
3607
|
+
* @returns Promise resolving to the provider that supports this route
|
|
3608
|
+
* @throws Will throw an error if no provider supports the route
|
|
3609
|
+
*/
|
|
3610
|
+
private findProviderForRoute;
|
|
3611
|
+
/**
|
|
3612
|
+
* Merge custom fee configuration into provider parameters.
|
|
3613
|
+
*
|
|
3614
|
+
* Prioritizes any custom fee configuration already present on the
|
|
3615
|
+
* provider-resolved params and uses the kit-level custom fee configuration
|
|
3616
|
+
* as a fallback only when a value is missing. If neither the provider params
|
|
3617
|
+
* nor the kit configuration can supply a value, no custom fee configuration
|
|
3618
|
+
* is added to the provider params.
|
|
3619
|
+
*
|
|
3620
|
+
* @param originalParams - The original bridge parameters received by the kit.
|
|
3621
|
+
* @param providerParams - The provider-resolved bridge parameters that may be enriched.
|
|
3622
|
+
* @returns The same `providerParams` reference with custom fee configuration merged when applicable.
|
|
3623
|
+
*
|
|
3624
|
+
* @remarks
|
|
3625
|
+
* - Existing values on `providerParams.config.customFee` are preserved.
|
|
3626
|
+
* - Kit-level functions are invoked lazily and only for missing values.
|
|
3627
|
+
* - If both sources provide no values, `customFee` is omitted entirely.
|
|
3628
|
+
*/
|
|
3629
|
+
private mergeCustomFeeConfig;
|
|
3630
|
+
/**
|
|
3631
|
+
* Sets the custom fee policy for the kit.
|
|
3632
|
+
*
|
|
3633
|
+
* Ensures the fee is represented in the smallest unit of the token.
|
|
3634
|
+
* - If the token is USDC, the fee is converted to base units (6 decimals).
|
|
3635
|
+
* - If the token is not USDC, the fee is returned as is.
|
|
3636
|
+
*
|
|
3637
|
+
* This allows developers to specify the kit-level fee in base units (e.g., USDC: 1, ETH: 0.000001),
|
|
3638
|
+
* and the kit will handle conversion to the smallest unit as needed.
|
|
3639
|
+
*
|
|
3640
|
+
* @param customFeePolicy - The custom fee policy to set.
|
|
3641
|
+
* @throws {ValidationError} If the custom fee policy is invalid or missing required functions
|
|
3642
|
+
*
|
|
3643
|
+
* @example
|
|
3644
|
+
* ```typescript
|
|
3645
|
+
* import { BridgeKit } from '@circle-fin/bridge-kit'
|
|
3646
|
+
* import { Blockchain } from '@core/chains'
|
|
3647
|
+
*
|
|
3648
|
+
* const kit = new BridgeKit()
|
|
3649
|
+
*
|
|
3650
|
+
* kit.setCustomFeePolicy({
|
|
3651
|
+
* calculateFee: (params) => {
|
|
3652
|
+
* // Return decimal string - kit converts to smallest units automatically
|
|
3653
|
+
* // '0.1' becomes '100000' (0.1 USDC with 6 decimals)
|
|
3654
|
+
* return params.source.chain.chain === Blockchain.Ethereum_Sepolia
|
|
3655
|
+
* ? '0.1' // 0.1 USDC
|
|
3656
|
+
* : '0.2'; // 0.2 USDC
|
|
3657
|
+
* },
|
|
3658
|
+
* resolveFeeRecipientAddress: (feePayoutChain, params) => {
|
|
3659
|
+
* // Return valid address for the source chain
|
|
3660
|
+
* return params.source.chain.chain === Blockchain.Ethereum_Sepolia
|
|
3661
|
+
* ? '0x23f9a5BEA7B92a0638520607407BC7f0310aEeD4'
|
|
3662
|
+
* : '0x1E1A18B7bD95bcFcFb4d6E245D289C1e95547b35';
|
|
3663
|
+
* },
|
|
3664
|
+
* });
|
|
3665
|
+
* ```
|
|
3666
|
+
*/
|
|
3667
|
+
setCustomFeePolicy(customFeePolicy: CustomFeePolicy): void;
|
|
3668
|
+
/**
|
|
3669
|
+
* Remove the custom fee policy for the kit.
|
|
3670
|
+
*
|
|
3671
|
+
* @example
|
|
3672
|
+
* ```typescript
|
|
3673
|
+
* kit.removeCustomFeePolicy()
|
|
3674
|
+
* ```
|
|
3675
|
+
*/
|
|
3676
|
+
removeCustomFeePolicy(): void;
|
|
3677
|
+
}
|
|
3678
|
+
|
|
3679
|
+
/**
|
|
3680
|
+
* Schema for validating bridge parameters with chain identifiers.
|
|
3681
|
+
* This extends the core provider's schema but adapts it for the bridge kit's
|
|
3682
|
+
* more flexible interface that accepts chain identifiers.
|
|
3683
|
+
*
|
|
3684
|
+
* The schema validates:
|
|
3685
|
+
* - From adapter context (must always include both adapter and chain)
|
|
3686
|
+
* - To bridge destination (AdapterContext or BridgeDestinationWithAddress)
|
|
3687
|
+
* - Amount is a non-empty numeric string \> 0
|
|
3688
|
+
* - Token is optional and defaults to 'USDC'
|
|
3689
|
+
* - Optional config parameters (transfer speed, max fee)
|
|
3690
|
+
*
|
|
3691
|
+
* @example
|
|
3692
|
+
* ```typescript
|
|
3693
|
+
* import { bridgeParamsWithChainIdentifierSchema } from '@circle-fin/bridge-kit'
|
|
3694
|
+
*
|
|
3695
|
+
* const params = {
|
|
3696
|
+
* from: {
|
|
3697
|
+
* adapter: sourceAdapter,
|
|
3698
|
+
* chain: 'Ethereum'
|
|
3699
|
+
* },
|
|
3700
|
+
* to: {
|
|
3701
|
+
* adapter: destAdapter,
|
|
3702
|
+
* chain: 'Base'
|
|
3703
|
+
* },
|
|
3704
|
+
* amount: '100.50',
|
|
3705
|
+
* token: 'USDC',
|
|
3706
|
+
* config: {
|
|
3707
|
+
* transferSpeed: 'FAST'
|
|
3708
|
+
* }
|
|
3709
|
+
* }
|
|
3710
|
+
*
|
|
3711
|
+
* const result = bridgeParamsWithChainIdentifierSchema.safeParse(params)
|
|
3712
|
+
* if (result.success) {
|
|
3713
|
+
* console.log('Parameters are valid')
|
|
3714
|
+
* } else {
|
|
3715
|
+
* console.error('Validation failed:', result.error)
|
|
3716
|
+
* }
|
|
3717
|
+
* ```
|
|
3718
|
+
*/
|
|
3719
|
+
declare const bridgeParamsWithChainIdentifierSchema: z.ZodObject<{
|
|
3720
|
+
from: z.ZodObject<{
|
|
3721
|
+
adapter: z.ZodObject<{
|
|
3722
|
+
prepare: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>;
|
|
3723
|
+
waitForTransaction: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>;
|
|
3724
|
+
getAddress: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>;
|
|
3725
|
+
}, "strip", z.ZodTypeAny, {
|
|
3726
|
+
prepare: (...args: unknown[]) => unknown;
|
|
3727
|
+
waitForTransaction: (...args: unknown[]) => unknown;
|
|
3728
|
+
getAddress: (...args: unknown[]) => unknown;
|
|
3729
|
+
}, {
|
|
3730
|
+
prepare: (...args: unknown[]) => unknown;
|
|
3731
|
+
waitForTransaction: (...args: unknown[]) => unknown;
|
|
3732
|
+
getAddress: (...args: unknown[]) => unknown;
|
|
3733
|
+
}>;
|
|
3734
|
+
chain: never;
|
|
3735
|
+
}, "strip", z.ZodTypeAny, {
|
|
3736
|
+
adapter: {
|
|
3737
|
+
prepare: (...args: unknown[]) => unknown;
|
|
3738
|
+
waitForTransaction: (...args: unknown[]) => unknown;
|
|
3739
|
+
getAddress: (...args: unknown[]) => unknown;
|
|
3740
|
+
};
|
|
3741
|
+
chain: never;
|
|
3742
|
+
}, {
|
|
3743
|
+
adapter: {
|
|
3744
|
+
prepare: (...args: unknown[]) => unknown;
|
|
3745
|
+
waitForTransaction: (...args: unknown[]) => unknown;
|
|
3746
|
+
getAddress: (...args: unknown[]) => unknown;
|
|
3747
|
+
};
|
|
3748
|
+
chain: never;
|
|
3749
|
+
}>;
|
|
3750
|
+
to: z.ZodUnion<[z.ZodEffects<z.ZodObject<{
|
|
3751
|
+
adapter: z.ZodObject<{
|
|
3752
|
+
prepare: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>;
|
|
3753
|
+
waitForTransaction: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>;
|
|
3754
|
+
getAddress: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>;
|
|
3755
|
+
}, "strip", z.ZodTypeAny, {
|
|
3756
|
+
prepare: (...args: unknown[]) => unknown;
|
|
3757
|
+
waitForTransaction: (...args: unknown[]) => unknown;
|
|
3758
|
+
getAddress: (...args: unknown[]) => unknown;
|
|
3759
|
+
}, {
|
|
3760
|
+
prepare: (...args: unknown[]) => unknown;
|
|
3761
|
+
waitForTransaction: (...args: unknown[]) => unknown;
|
|
3762
|
+
getAddress: (...args: unknown[]) => unknown;
|
|
3763
|
+
}>;
|
|
3764
|
+
chain: never;
|
|
3765
|
+
} & {
|
|
3766
|
+
recipientAddress: z.ZodString;
|
|
3767
|
+
}, "strip", z.ZodTypeAny, {
|
|
3768
|
+
adapter: {
|
|
3769
|
+
prepare: (...args: unknown[]) => unknown;
|
|
3770
|
+
waitForTransaction: (...args: unknown[]) => unknown;
|
|
3771
|
+
getAddress: (...args: unknown[]) => unknown;
|
|
3772
|
+
};
|
|
3773
|
+
chain: never;
|
|
3774
|
+
recipientAddress: string;
|
|
3775
|
+
}, {
|
|
3776
|
+
adapter: {
|
|
3777
|
+
prepare: (...args: unknown[]) => unknown;
|
|
3778
|
+
waitForTransaction: (...args: unknown[]) => unknown;
|
|
3779
|
+
getAddress: (...args: unknown[]) => unknown;
|
|
3780
|
+
};
|
|
3781
|
+
chain: never;
|
|
3782
|
+
recipientAddress: string;
|
|
3783
|
+
}>, {
|
|
3784
|
+
adapter: {
|
|
3785
|
+
prepare: (...args: unknown[]) => unknown;
|
|
3786
|
+
waitForTransaction: (...args: unknown[]) => unknown;
|
|
3787
|
+
getAddress: (...args: unknown[]) => unknown;
|
|
3788
|
+
};
|
|
3789
|
+
chain: never;
|
|
3790
|
+
recipientAddress: string;
|
|
3791
|
+
}, {
|
|
3792
|
+
adapter: {
|
|
3793
|
+
prepare: (...args: unknown[]) => unknown;
|
|
3794
|
+
waitForTransaction: (...args: unknown[]) => unknown;
|
|
3795
|
+
getAddress: (...args: unknown[]) => unknown;
|
|
3796
|
+
};
|
|
3797
|
+
chain: never;
|
|
3798
|
+
recipientAddress: string;
|
|
3799
|
+
}>, z.ZodObject<{
|
|
3800
|
+
adapter: z.ZodObject<{
|
|
3801
|
+
prepare: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>;
|
|
3802
|
+
waitForTransaction: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>;
|
|
3803
|
+
getAddress: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>;
|
|
3804
|
+
}, "strip", z.ZodTypeAny, {
|
|
3805
|
+
prepare: (...args: unknown[]) => unknown;
|
|
3806
|
+
waitForTransaction: (...args: unknown[]) => unknown;
|
|
3807
|
+
getAddress: (...args: unknown[]) => unknown;
|
|
3808
|
+
}, {
|
|
3809
|
+
prepare: (...args: unknown[]) => unknown;
|
|
3810
|
+
waitForTransaction: (...args: unknown[]) => unknown;
|
|
3811
|
+
getAddress: (...args: unknown[]) => unknown;
|
|
3812
|
+
}>;
|
|
3813
|
+
chain: never;
|
|
3814
|
+
}, "strict", z.ZodTypeAny, {
|
|
3815
|
+
adapter: {
|
|
3816
|
+
prepare: (...args: unknown[]) => unknown;
|
|
3817
|
+
waitForTransaction: (...args: unknown[]) => unknown;
|
|
3818
|
+
getAddress: (...args: unknown[]) => unknown;
|
|
3819
|
+
};
|
|
3820
|
+
chain: never;
|
|
3821
|
+
}, {
|
|
3822
|
+
adapter: {
|
|
3823
|
+
prepare: (...args: unknown[]) => unknown;
|
|
3824
|
+
waitForTransaction: (...args: unknown[]) => unknown;
|
|
3825
|
+
getAddress: (...args: unknown[]) => unknown;
|
|
3826
|
+
};
|
|
3827
|
+
chain: never;
|
|
3828
|
+
}>]>;
|
|
3829
|
+
amount: z.ZodPipeline<z.ZodString, z.ZodType<string, z.ZodTypeDef, string>>;
|
|
3830
|
+
token: z.ZodOptional<z.ZodLiteral<"USDC">>;
|
|
3831
|
+
config: z.ZodOptional<z.ZodObject<{
|
|
3832
|
+
transferSpeed: z.ZodOptional<z.ZodNativeEnum<typeof TransferSpeed>>;
|
|
3833
|
+
maxFee: z.ZodOptional<z.ZodString>;
|
|
3834
|
+
customFee: z.ZodOptional<z.ZodObject<{
|
|
3835
|
+
value: z.ZodOptional<z.ZodType<string, z.ZodTypeDef, string>>;
|
|
3836
|
+
recipientAddress: z.ZodOptional<z.ZodString>;
|
|
3837
|
+
}, "strict", z.ZodTypeAny, {
|
|
3838
|
+
value?: string | undefined;
|
|
3839
|
+
recipientAddress?: string | undefined;
|
|
3840
|
+
}, {
|
|
3841
|
+
value?: string | undefined;
|
|
3842
|
+
recipientAddress?: string | undefined;
|
|
3843
|
+
}>>;
|
|
3844
|
+
}, "strip", z.ZodTypeAny, {
|
|
3845
|
+
transferSpeed?: TransferSpeed | undefined;
|
|
3846
|
+
maxFee?: string | undefined;
|
|
3847
|
+
customFee?: {
|
|
3848
|
+
value?: string | undefined;
|
|
3849
|
+
recipientAddress?: string | undefined;
|
|
3850
|
+
} | undefined;
|
|
3851
|
+
}, {
|
|
3852
|
+
transferSpeed?: TransferSpeed | undefined;
|
|
3853
|
+
maxFee?: string | undefined;
|
|
3854
|
+
customFee?: {
|
|
3855
|
+
value?: string | undefined;
|
|
3856
|
+
recipientAddress?: string | undefined;
|
|
3857
|
+
} | undefined;
|
|
3858
|
+
}>>;
|
|
3859
|
+
}, "strip", z.ZodTypeAny, {
|
|
3860
|
+
from: {
|
|
3861
|
+
adapter: {
|
|
3862
|
+
prepare: (...args: unknown[]) => unknown;
|
|
3863
|
+
waitForTransaction: (...args: unknown[]) => unknown;
|
|
3864
|
+
getAddress: (...args: unknown[]) => unknown;
|
|
3865
|
+
};
|
|
3866
|
+
chain: never;
|
|
3867
|
+
};
|
|
3868
|
+
to: {
|
|
3869
|
+
adapter: {
|
|
3870
|
+
prepare: (...args: unknown[]) => unknown;
|
|
3871
|
+
waitForTransaction: (...args: unknown[]) => unknown;
|
|
3872
|
+
getAddress: (...args: unknown[]) => unknown;
|
|
3873
|
+
};
|
|
3874
|
+
chain: never;
|
|
3875
|
+
} | {
|
|
3876
|
+
adapter: {
|
|
3877
|
+
prepare: (...args: unknown[]) => unknown;
|
|
3878
|
+
waitForTransaction: (...args: unknown[]) => unknown;
|
|
3879
|
+
getAddress: (...args: unknown[]) => unknown;
|
|
3880
|
+
};
|
|
3881
|
+
chain: never;
|
|
3882
|
+
recipientAddress: string;
|
|
3883
|
+
};
|
|
3884
|
+
amount: string;
|
|
3885
|
+
token?: "USDC" | undefined;
|
|
3886
|
+
config?: {
|
|
3887
|
+
transferSpeed?: TransferSpeed | undefined;
|
|
3888
|
+
maxFee?: string | undefined;
|
|
3889
|
+
customFee?: {
|
|
3890
|
+
value?: string | undefined;
|
|
3891
|
+
recipientAddress?: string | undefined;
|
|
3892
|
+
} | undefined;
|
|
3893
|
+
} | undefined;
|
|
3894
|
+
}, {
|
|
3895
|
+
from: {
|
|
3896
|
+
adapter: {
|
|
3897
|
+
prepare: (...args: unknown[]) => unknown;
|
|
3898
|
+
waitForTransaction: (...args: unknown[]) => unknown;
|
|
3899
|
+
getAddress: (...args: unknown[]) => unknown;
|
|
3900
|
+
};
|
|
3901
|
+
chain: never;
|
|
3902
|
+
};
|
|
3903
|
+
to: {
|
|
3904
|
+
adapter: {
|
|
3905
|
+
prepare: (...args: unknown[]) => unknown;
|
|
3906
|
+
waitForTransaction: (...args: unknown[]) => unknown;
|
|
3907
|
+
getAddress: (...args: unknown[]) => unknown;
|
|
3908
|
+
};
|
|
3909
|
+
chain: never;
|
|
3910
|
+
} | {
|
|
3911
|
+
adapter: {
|
|
3912
|
+
prepare: (...args: unknown[]) => unknown;
|
|
3913
|
+
waitForTransaction: (...args: unknown[]) => unknown;
|
|
3914
|
+
getAddress: (...args: unknown[]) => unknown;
|
|
3915
|
+
};
|
|
3916
|
+
chain: never;
|
|
3917
|
+
recipientAddress: string;
|
|
3918
|
+
};
|
|
3919
|
+
amount: string;
|
|
3920
|
+
token?: "USDC" | undefined;
|
|
3921
|
+
config?: {
|
|
3922
|
+
transferSpeed?: TransferSpeed | undefined;
|
|
3923
|
+
maxFee?: string | undefined;
|
|
3924
|
+
customFee?: {
|
|
3925
|
+
value?: string | undefined;
|
|
3926
|
+
recipientAddress?: string | undefined;
|
|
3927
|
+
} | undefined;
|
|
3928
|
+
} | undefined;
|
|
3929
|
+
}>;
|
|
3930
|
+
|
|
3931
|
+
/**
|
|
3932
|
+
* Valid recoverability values for error handling strategies.
|
|
3933
|
+
*
|
|
3934
|
+
* - FATAL errors are thrown immediately (invalid inputs, insufficient funds)
|
|
3935
|
+
* - RETRYABLE errors are returned when a flow fails to start but could work later
|
|
3936
|
+
* - RESUMABLE errors are returned when a flow fails mid-execution but can be continued
|
|
3937
|
+
*/
|
|
3938
|
+
declare const RECOVERABILITY_VALUES: readonly ["RETRYABLE", "RESUMABLE", "FATAL"];
|
|
3939
|
+
/**
|
|
3940
|
+
* Error handling strategy for different types of failures.
|
|
3941
|
+
*
|
|
3942
|
+
* - FATAL errors are thrown immediately (invalid inputs, insufficient funds)
|
|
3943
|
+
* - RETRYABLE errors are returned when a flow fails to start but could work later
|
|
3944
|
+
* - RESUMABLE errors are returned when a flow fails mid-execution but can be continued
|
|
3945
|
+
*/
|
|
3946
|
+
type Recoverability = (typeof RECOVERABILITY_VALUES)[number];
|
|
3947
|
+
/**
|
|
3948
|
+
* Structured error details with consistent properties for programmatic handling.
|
|
3949
|
+
*
|
|
3950
|
+
* This interface provides a standardized format for all errors in the
|
|
3951
|
+
* Stablecoin Kits system, enabling developers to handle different error
|
|
3952
|
+
* types consistently and provide appropriate user feedback.
|
|
3953
|
+
*
|
|
3954
|
+
* @example
|
|
3955
|
+
* ```typescript
|
|
3956
|
+
* const error: ErrorDetails = {
|
|
3957
|
+
* code: 1001,
|
|
3958
|
+
* name: "NETWORK_MISMATCH",
|
|
3959
|
+
* recoverability: "FATAL",
|
|
3960
|
+
* message: "Source and destination networks must be different",
|
|
3961
|
+
* cause: {
|
|
3962
|
+
* trace: { sourceChain: "ethereum", destChain: "ethereum" }
|
|
3963
|
+
* }
|
|
3964
|
+
* }
|
|
3965
|
+
* ```
|
|
3966
|
+
*/
|
|
3967
|
+
interface ErrorDetails {
|
|
3968
|
+
/** Numeric identifier following standardized ranges (1000+ for INPUT errors) */
|
|
3969
|
+
code: number;
|
|
3970
|
+
/** Human-readable ID (e.g., "NETWORK_MISMATCH") */
|
|
3971
|
+
name: string;
|
|
3972
|
+
/** Error handling strategy */
|
|
3973
|
+
recoverability: Recoverability;
|
|
3974
|
+
/** User-friendly explanation with network context */
|
|
3975
|
+
message: string;
|
|
3976
|
+
/** Raw error details, context, or the original error that caused this one. */
|
|
3977
|
+
cause?: {
|
|
3978
|
+
/** Free-form error payload from underlying system */
|
|
3979
|
+
trace?: unknown;
|
|
3980
|
+
};
|
|
3981
|
+
}
|
|
3982
|
+
|
|
3983
|
+
/**
|
|
3984
|
+
* Structured error class for Stablecoin Kit operations.
|
|
3985
|
+
*
|
|
3986
|
+
* This class extends the native Error class while implementing the ErrorDetails
|
|
3987
|
+
* interface, providing a consistent error format for programmatic handling
|
|
3988
|
+
* across the Stablecoin Kits ecosystem. All properties are immutable to ensure
|
|
3989
|
+
* error objects cannot be modified after creation.
|
|
3990
|
+
*
|
|
3991
|
+
* @example
|
|
3992
|
+
* ```typescript
|
|
3993
|
+
* import { KitError } from '@core/errors'
|
|
3994
|
+
*
|
|
3995
|
+
* const error = new KitError({
|
|
3996
|
+
* code: 1001,
|
|
3997
|
+
* name: 'INPUT_NETWORK_MISMATCH',
|
|
3998
|
+
* recoverability: 'FATAL',
|
|
3999
|
+
* message: 'Cannot bridge between mainnet and testnet'
|
|
4000
|
+
* })
|
|
4001
|
+
*
|
|
4002
|
+
* if (error instanceof KitError) {
|
|
4003
|
+
* console.log(`Error ${error.code}: ${error.name}`)
|
|
4004
|
+
* // → "Error 1001: INPUT_NETWORK_MISMATCH"
|
|
4005
|
+
* }
|
|
4006
|
+
* ```
|
|
4007
|
+
*
|
|
4008
|
+
* @example
|
|
4009
|
+
* ```typescript
|
|
4010
|
+
* import { KitError } from '@core/errors'
|
|
4011
|
+
*
|
|
4012
|
+
* // Error with cause information
|
|
4013
|
+
* const error = new KitError({
|
|
4014
|
+
* code: 1002,
|
|
4015
|
+
* name: 'INVALID_AMOUNT',
|
|
4016
|
+
* recoverability: 'FATAL',
|
|
4017
|
+
* message: 'Amount must be greater than zero',
|
|
4018
|
+
* cause: {
|
|
4019
|
+
* trace: { providedAmount: -100, minimumAmount: 0 }
|
|
4020
|
+
* }
|
|
4021
|
+
* })
|
|
4022
|
+
*
|
|
4023
|
+
* throw error
|
|
4024
|
+
* ```
|
|
4025
|
+
*/
|
|
4026
|
+
declare class KitError extends Error implements ErrorDetails {
|
|
4027
|
+
/** Numeric identifier following standardized ranges (1000+ for INPUT errors) */
|
|
4028
|
+
readonly code: number;
|
|
4029
|
+
/** Human-readable ID (e.g., "NETWORK_MISMATCH") */
|
|
4030
|
+
readonly name: string;
|
|
4031
|
+
/** Error handling strategy */
|
|
4032
|
+
readonly recoverability: Recoverability;
|
|
4033
|
+
/** Raw error details, context, or the original error that caused this one. */
|
|
4034
|
+
readonly cause?: {
|
|
4035
|
+
/** Free-form error payload from underlying system */
|
|
4036
|
+
trace?: unknown;
|
|
4037
|
+
};
|
|
4038
|
+
/**
|
|
4039
|
+
* Create a new KitError instance.
|
|
4040
|
+
*
|
|
4041
|
+
* @param details - The error details object containing all required properties.
|
|
4042
|
+
* @throws \{TypeError\} When details parameter is missing or invalid.
|
|
4043
|
+
*/
|
|
4044
|
+
constructor(details: ErrorDetails);
|
|
4045
|
+
}
|
|
4046
|
+
|
|
4047
|
+
export { Blockchain, BridgeKit, KitError, bridgeParamsWithChainIdentifierSchema };
|
|
4048
|
+
export type { ActionHandler, BridgeKitConfig, BridgeParams, BridgeResult, ChainDefinition, ChainIdentifier, ErrorDetails, Recoverability };
|