@circle-fin/provider-cctp-v2 1.3.1 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -0
- package/README.md +98 -14
- package/index.cjs +5439 -2119
- package/index.d.ts +2139 -148
- package/index.mjs +5438 -2120
- package/package.json +1 -6
package/index.d.ts
CHANGED
|
@@ -33,7 +33,6 @@ import { TransactionInstruction, Signer, AddressLookupTableAccount } from '@sola
|
|
|
33
33
|
*/
|
|
34
34
|
/**
|
|
35
35
|
* Represents basic information about a currency or token.
|
|
36
|
-
* @interface Currency
|
|
37
36
|
* @category Types
|
|
38
37
|
* @description Provides the essential properties of a cryptocurrency or token.
|
|
39
38
|
* @example
|
|
@@ -65,7 +64,6 @@ interface Currency {
|
|
|
65
64
|
}
|
|
66
65
|
/**
|
|
67
66
|
* Base information that all chain definitions must include.
|
|
68
|
-
* @interface BaseChainDefinition
|
|
69
67
|
* @category Types
|
|
70
68
|
* @description Provides the common properties shared by all blockchain definitions.
|
|
71
69
|
* @example
|
|
@@ -125,6 +123,11 @@ interface BaseChainDefinition {
|
|
|
125
123
|
* @description Its presence indicates that USDC is supported.
|
|
126
124
|
*/
|
|
127
125
|
usdcAddress: string | null;
|
|
126
|
+
/**
|
|
127
|
+
* The contract address for USDT.
|
|
128
|
+
* @description Its presence indicates that USDT is supported.
|
|
129
|
+
*/
|
|
130
|
+
usdtAddress: string | null;
|
|
128
131
|
/**
|
|
129
132
|
* Optional CCTP configuration.
|
|
130
133
|
* @description If provided, the chain supports CCTP.
|
|
@@ -166,7 +169,6 @@ interface BaseChainDefinition {
|
|
|
166
169
|
}
|
|
167
170
|
/**
|
|
168
171
|
* Represents chain definitions for Ethereum Virtual Machine (EVM) compatible blockchains.
|
|
169
|
-
* @interface EVMChainDefinition
|
|
170
172
|
* @extends BaseChainDefinition
|
|
171
173
|
* @category Types
|
|
172
174
|
* @description Adds properties specific to EVM chains.
|
|
@@ -198,7 +200,6 @@ interface EVMChainDefinition extends BaseChainDefinition {
|
|
|
198
200
|
}
|
|
199
201
|
/**
|
|
200
202
|
* Represents chain definitions for non-EVM blockchains.
|
|
201
|
-
* @interface NonEVMChainDefinition
|
|
202
203
|
* @extends BaseChainDefinition
|
|
203
204
|
* @category Types
|
|
204
205
|
* @description Contains properties for blockchains that do not use the EVM.
|
|
@@ -251,6 +252,7 @@ type ChainType = EVMChainDefinition['type'] | NonEVMChainDefinition['type'];
|
|
|
251
252
|
* rpcEndpoints: ['https://eth.example.com'],
|
|
252
253
|
* eurcAddress: null,
|
|
253
254
|
* usdcAddress: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
|
|
255
|
+
* usdtAddress: '0xdac17f958d2ee523a2206206994597c13d831ec7',
|
|
254
256
|
* cctp: {
|
|
255
257
|
* domain: 0,
|
|
256
258
|
* contracts: {
|
|
@@ -313,18 +315,75 @@ type ChainDefinitionWithCCTPv2 = ChainDefinition & {
|
|
|
313
315
|
* - A Blockchain enum value (e.g., Blockchain.Ethereum)
|
|
314
316
|
* - A string literal of the blockchain value (e.g., "Ethereum")
|
|
315
317
|
*/
|
|
316
|
-
type ChainIdentifier = ChainDefinition | Blockchain | `${Blockchain}`;
|
|
318
|
+
type ChainIdentifier$1 = ChainDefinition | Blockchain | `${Blockchain}`;
|
|
319
|
+
/**
|
|
320
|
+
* Split CCTP contract configuration.
|
|
321
|
+
*
|
|
322
|
+
* Used by chains that deploy separate TokenMessenger and MessageTransmitter contracts.
|
|
323
|
+
* This is the traditional CCTP architecture used by most EVM chains.
|
|
324
|
+
*
|
|
325
|
+
* @example
|
|
326
|
+
* ```typescript
|
|
327
|
+
* const splitConfig: CCTPSplitConfig = {
|
|
328
|
+
* type: 'split',
|
|
329
|
+
* tokenMessenger: '0x1234567890abcdef1234567890abcdef12345678',
|
|
330
|
+
* messageTransmitter: '0xabcdef1234567890abcdef1234567890abcdef12',
|
|
331
|
+
* confirmations: 12
|
|
332
|
+
* }
|
|
333
|
+
* ```
|
|
334
|
+
*/
|
|
317
335
|
interface CCTPSplitConfig {
|
|
318
336
|
type: 'split';
|
|
319
337
|
tokenMessenger: string;
|
|
320
338
|
messageTransmitter: string;
|
|
321
339
|
confirmations: number;
|
|
322
340
|
}
|
|
341
|
+
/**
|
|
342
|
+
* Merged CCTP contract configuration.
|
|
343
|
+
*
|
|
344
|
+
* Used by chains that deploy a single unified CCTP contract.
|
|
345
|
+
* This simplified architecture is used by newer chain integrations.
|
|
346
|
+
*
|
|
347
|
+
* @example
|
|
348
|
+
* ```typescript
|
|
349
|
+
* const mergedConfig: CCTPMergedConfig = {
|
|
350
|
+
* type: 'merged',
|
|
351
|
+
* contract: '0x9876543210fedcba9876543210fedcba98765432',
|
|
352
|
+
* confirmations: 1
|
|
353
|
+
* }
|
|
354
|
+
* ```
|
|
355
|
+
*/
|
|
323
356
|
interface CCTPMergedConfig {
|
|
324
357
|
type: 'merged';
|
|
325
358
|
contract: string;
|
|
326
359
|
confirmations: number;
|
|
327
360
|
}
|
|
361
|
+
/**
|
|
362
|
+
* Version configuration for CCTP contracts.
|
|
363
|
+
*
|
|
364
|
+
* Defines whether the chain uses split or merged CCTP contract architecture.
|
|
365
|
+
* Split configuration uses separate TokenMessenger and MessageTransmitter contracts,
|
|
366
|
+
* while merged configuration uses a single unified contract.
|
|
367
|
+
*
|
|
368
|
+
* @example Split configuration (most EVM chains)
|
|
369
|
+
* ```typescript
|
|
370
|
+
* const splitConfig: VersionConfig = {
|
|
371
|
+
* type: 'split',
|
|
372
|
+
* tokenMessenger: '0x1234567890abcdef1234567890abcdef12345678',
|
|
373
|
+
* messageTransmitter: '0xabcdef1234567890abcdef1234567890abcdef12',
|
|
374
|
+
* confirmations: 12
|
|
375
|
+
* }
|
|
376
|
+
* ```
|
|
377
|
+
*
|
|
378
|
+
* @example Merged configuration (newer chains)
|
|
379
|
+
* ```typescript
|
|
380
|
+
* const mergedConfig: VersionConfig = {
|
|
381
|
+
* type: 'merged',
|
|
382
|
+
* contract: '0x9876543210fedcba9876543210fedcba98765432',
|
|
383
|
+
* confirmations: 1
|
|
384
|
+
* }
|
|
385
|
+
* ```
|
|
386
|
+
*/
|
|
328
387
|
type VersionConfig = CCTPSplitConfig | CCTPMergedConfig;
|
|
329
388
|
type CCTPContracts = Partial<{
|
|
330
389
|
v1: VersionConfig;
|
|
@@ -334,7 +393,6 @@ type CCTPContracts = Partial<{
|
|
|
334
393
|
}>;
|
|
335
394
|
/**
|
|
336
395
|
* Configuration for the Cross-Chain Transfer Protocol (CCTP).
|
|
337
|
-
* @interface CCTPConfig
|
|
338
396
|
* @category Types
|
|
339
397
|
* @description Contains the domain and required contract addresses for CCTP support.
|
|
340
398
|
* @example
|
|
@@ -357,6 +415,22 @@ interface CCTPConfig {
|
|
|
357
415
|
* The contracts required for CCTP.
|
|
358
416
|
*/
|
|
359
417
|
contracts: CCTPContracts;
|
|
418
|
+
/**
|
|
419
|
+
* Indicates whether the chain supports forwarder for source and destination.
|
|
420
|
+
* @example
|
|
421
|
+
* ```typescript
|
|
422
|
+
* const chainWithForwarderSupported: ChainDefinition = {
|
|
423
|
+
* forwarderSupported: {
|
|
424
|
+
* source: true,
|
|
425
|
+
* destination: true,
|
|
426
|
+
* },
|
|
427
|
+
* }
|
|
428
|
+
* ```
|
|
429
|
+
*/
|
|
430
|
+
forwarderSupported: {
|
|
431
|
+
source: boolean;
|
|
432
|
+
destination: boolean;
|
|
433
|
+
};
|
|
360
434
|
}
|
|
361
435
|
/**
|
|
362
436
|
* Available kit contract types for enhanced chain functionality.
|
|
@@ -372,7 +446,7 @@ interface CCTPConfig {
|
|
|
372
446
|
* const invalidType: KitContractType = 'invalid' // TypeScript error
|
|
373
447
|
* ```
|
|
374
448
|
*/
|
|
375
|
-
type KitContractType = 'bridge';
|
|
449
|
+
type KitContractType = 'bridge' | 'adapter';
|
|
376
450
|
/**
|
|
377
451
|
* Kit-specific contract addresses for enhanced chain functionality.
|
|
378
452
|
*
|
|
@@ -643,8 +717,20 @@ type EvmPreparedChainRequestParams = {
|
|
|
643
717
|
interface SolanaPreparedChainRequestParams {
|
|
644
718
|
/**
|
|
645
719
|
* The array of instructions to include in the transaction.
|
|
720
|
+
*
|
|
721
|
+
* @remarks
|
|
722
|
+
* Used for instruction-based transaction building. Mutually exclusive with
|
|
723
|
+
* `serializedTransaction`.
|
|
724
|
+
*/
|
|
725
|
+
instructions?: TransactionInstruction[];
|
|
726
|
+
/**
|
|
727
|
+
* A pre-serialized transaction as a Uint8Array (e.g., from a service like Jupiter).
|
|
728
|
+
*
|
|
729
|
+
* @remarks
|
|
730
|
+
* Used for executing pre-built transactions from external services.
|
|
731
|
+
* The transaction may be partially signed. Mutually exclusive with `instructions`.
|
|
646
732
|
*/
|
|
647
|
-
|
|
733
|
+
serializedTransaction?: Uint8Array;
|
|
648
734
|
/**
|
|
649
735
|
* Additional signers besides the Adapter's wallet (e.g. program-derived authorities).
|
|
650
736
|
*/
|
|
@@ -913,7 +999,7 @@ type OperationContext<TAdapterCapabilities extends AdapterCapabilities = Adapter
|
|
|
913
999
|
/**
|
|
914
1000
|
* The blockchain network to use for this operation.
|
|
915
1001
|
*/
|
|
916
|
-
chain: ChainIdentifier;
|
|
1002
|
+
chain: ChainIdentifier$1;
|
|
917
1003
|
} & AddressField<ExtractAddressContext<TAdapterCapabilities>>;
|
|
918
1004
|
/**
|
|
919
1005
|
* Fully resolved context for an adapter operation, with concrete chain and address.
|
|
@@ -1322,6 +1408,99 @@ interface CCTPv2ActionMap {
|
|
|
1322
1408
|
*/
|
|
1323
1409
|
permitParams?: PermitParams;
|
|
1324
1410
|
};
|
|
1411
|
+
/**
|
|
1412
|
+
* Initiate a cross-chain USDC transfer using a custom bridge contract with hook data for CCTP forwarding.
|
|
1413
|
+
*
|
|
1414
|
+
* This action combines the custom bridge functionality with CCTP forwarding hookData.
|
|
1415
|
+
* It uses either `bridgeWithPreapprovalAndHook` or `bridgeWithPermitAndHook` contract
|
|
1416
|
+
* functions depending on whether permit parameters are provided.
|
|
1417
|
+
*
|
|
1418
|
+
* @remarks
|
|
1419
|
+
* When CCTP forwarding is enabled with custom burn, Circle's relay infrastructure will:
|
|
1420
|
+
* 1. Watch for the burn transaction with forwarding hookData
|
|
1421
|
+
* 2. Fetch the attestation automatically
|
|
1422
|
+
* 3. Submit the destination mint transaction on behalf of the user
|
|
1423
|
+
* 4. Deduct the relay fee from the minted USDC
|
|
1424
|
+
*
|
|
1425
|
+
* The hookData must be formatted with the CCTP forwarding magic bytes prefix
|
|
1426
|
+
* followed by version and length fields. Use the `buildForwardingHookData`
|
|
1427
|
+
* utility to construct properly formatted hookData.
|
|
1428
|
+
*
|
|
1429
|
+
* @example
|
|
1430
|
+
* ```typescript
|
|
1431
|
+
* import { buildForwardingHookData } from '@core/utils'
|
|
1432
|
+
* import { hasCustomContractSupport } from '@core/chains'
|
|
1433
|
+
*
|
|
1434
|
+
* if (hasCustomContractSupport(sourceChain, 'bridge')) {
|
|
1435
|
+
* await adapter.action('cctp.v2.customBurnWithHook', {
|
|
1436
|
+
* amount: BigInt('1000000'),
|
|
1437
|
+
* mintRecipient: '0x...',
|
|
1438
|
+
* maxFee: BigInt('50000'),
|
|
1439
|
+
* minFinalityThreshold: 1000,
|
|
1440
|
+
* fromChain: ethereum,
|
|
1441
|
+
* toChain: base,
|
|
1442
|
+
* hookData: buildForwardingHookData()
|
|
1443
|
+
* })
|
|
1444
|
+
* }
|
|
1445
|
+
* ```
|
|
1446
|
+
*/
|
|
1447
|
+
customBurnWithHook: CCTPv2ActionMap['customBurn'] & {
|
|
1448
|
+
/**
|
|
1449
|
+
* Hex-encoded hook data for CCTP forwarding.
|
|
1450
|
+
*
|
|
1451
|
+
* The hookData signals to Circle's Orbit relayer that forwarding is requested.
|
|
1452
|
+
* Must be formatted with the CCTP forwarding magic bytes prefix ("cctp-forward"
|
|
1453
|
+
* right-padded to 24 bytes) followed by uint32 version and uint32 length fields.
|
|
1454
|
+
*
|
|
1455
|
+
* Use the `buildForwardingHookData` utility to construct properly formatted hookData.
|
|
1456
|
+
*/
|
|
1457
|
+
hookData: string;
|
|
1458
|
+
};
|
|
1459
|
+
/**
|
|
1460
|
+
* Initiate a cross-chain USDC transfer with hook data for CCTP forwarding.
|
|
1461
|
+
*
|
|
1462
|
+
* This action extends the standard `depositForBurn` with an additional `hookData`
|
|
1463
|
+
* parameter that signals to Circle's Orbit relayer that the user wants automated
|
|
1464
|
+
* attestation fetching and destination mint execution.
|
|
1465
|
+
*
|
|
1466
|
+
* @remarks
|
|
1467
|
+
* When CCTP forwarding is enabled, Circle's relay infrastructure will:
|
|
1468
|
+
* 1. Watch for the burn transaction with forwarding hookData
|
|
1469
|
+
* 2. Fetch the attestation automatically
|
|
1470
|
+
* 3. Submit the destination mint transaction on behalf of the user
|
|
1471
|
+
* 4. Deduct the relay fee from the minted USDC
|
|
1472
|
+
*
|
|
1473
|
+
* The hookData must be formatted with the CCTP forwarding magic bytes prefix
|
|
1474
|
+
* followed by version and length fields. Use the `buildForwardingHookData`
|
|
1475
|
+
* utility to construct properly formatted hookData.
|
|
1476
|
+
*
|
|
1477
|
+
* @example
|
|
1478
|
+
* ```typescript
|
|
1479
|
+
* import { buildForwardingHookData } from '@core/utils'
|
|
1480
|
+
*
|
|
1481
|
+
* await adapter.action('cctp.v2.depositForBurnWithHook', {
|
|
1482
|
+
* amount: BigInt('1000000'),
|
|
1483
|
+
* mintRecipient: '0x...',
|
|
1484
|
+
* maxFee: BigInt('50000'), // Must cover burn fee + forwarding fee
|
|
1485
|
+
* minFinalityThreshold: 1000,
|
|
1486
|
+
* fromChain: ethereum,
|
|
1487
|
+
* toChain: base,
|
|
1488
|
+
* hookData: buildForwardingHookData()
|
|
1489
|
+
* })
|
|
1490
|
+
* ```
|
|
1491
|
+
*/
|
|
1492
|
+
depositForBurnWithHook: CCTPv2ActionMap['depositForBurn'] & {
|
|
1493
|
+
/**
|
|
1494
|
+
* Hex-encoded hook data for CCTP forwarding.
|
|
1495
|
+
*
|
|
1496
|
+
* The hookData signals to Circle's Orbit relayer that forwarding is requested.
|
|
1497
|
+
* Must be formatted with the CCTP forwarding magic bytes prefix ("cctp-forward"
|
|
1498
|
+
* right-padded to 24 bytes) followed by uint32 version and uint32 length fields.
|
|
1499
|
+
*
|
|
1500
|
+
* Use the `buildForwardingHookData` utility to construct properly formatted hookData.
|
|
1501
|
+
*/
|
|
1502
|
+
hookData: string;
|
|
1503
|
+
};
|
|
1325
1504
|
}
|
|
1326
1505
|
|
|
1327
1506
|
/**
|
|
@@ -1348,31 +1527,443 @@ interface CCTPActionMap {
|
|
|
1348
1527
|
}
|
|
1349
1528
|
|
|
1350
1529
|
/**
|
|
1351
|
-
*
|
|
1530
|
+
* Permit signature standards for gasless token approvals.
|
|
1352
1531
|
*
|
|
1353
|
-
*
|
|
1354
|
-
*
|
|
1355
|
-
* These actions operate on the native token without requiring
|
|
1356
|
-
* a separate token contract address.
|
|
1532
|
+
* Defines the permit types that can be used to approve token spending
|
|
1533
|
+
* without requiring a separate approval transaction.
|
|
1357
1534
|
*
|
|
1358
1535
|
* @remarks
|
|
1359
|
-
*
|
|
1360
|
-
*
|
|
1361
|
-
|
|
1536
|
+
* - NONE: No permit, tokens must be pre-approved via separate transaction
|
|
1537
|
+
* - EIP2612: Standard ERC-20 permit (USDC, DAI v2, and most modern tokens)
|
|
1538
|
+
*/
|
|
1539
|
+
declare enum PermitType {
|
|
1540
|
+
/** No permit required - tokens must be pre-approved */
|
|
1541
|
+
NONE = 0,
|
|
1542
|
+
/** EIP-2612 standard permit */
|
|
1543
|
+
EIP2612 = 1
|
|
1544
|
+
}
|
|
1545
|
+
/**
|
|
1546
|
+
* Token input with permit signature for gasless approval.
|
|
1362
1547
|
*
|
|
1363
|
-
*
|
|
1548
|
+
* The Adapter Contract uses this to pull tokens from the user's wallet
|
|
1549
|
+
* using permit signatures instead of requiring separate approval transactions.
|
|
1550
|
+
*
|
|
1551
|
+
* @example
|
|
1552
|
+
* ```typescript
|
|
1553
|
+
* const tokenInput: TokenInput = {
|
|
1554
|
+
* permitType: PermitType.EIP2612,
|
|
1555
|
+
* token: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC
|
|
1556
|
+
* from: '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
|
|
1557
|
+
* amount: 1000000n, // 1 USDC
|
|
1558
|
+
* permitCalldata: '0x...' // Encoded permit(value, deadline, v, r, s)
|
|
1559
|
+
* }
|
|
1560
|
+
* ```
|
|
1364
1561
|
*/
|
|
1365
|
-
interface
|
|
1562
|
+
interface TokenInput {
|
|
1366
1563
|
/**
|
|
1367
|
-
*
|
|
1564
|
+
* Type of permit to execute.
|
|
1368
1565
|
*/
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1566
|
+
permitType: PermitType;
|
|
1567
|
+
/**
|
|
1568
|
+
* Token contract address to pull from user.
|
|
1569
|
+
*/
|
|
1570
|
+
token: `0x${string}`;
|
|
1571
|
+
/**
|
|
1572
|
+
* Amount of tokens to pull via permit.
|
|
1573
|
+
*/
|
|
1574
|
+
amount: bigint;
|
|
1575
|
+
/**
|
|
1576
|
+
* ABI-encoded permit calldata.
|
|
1577
|
+
*
|
|
1578
|
+
* For EIP-2612: encode(value, deadline, v, r, s)
|
|
1579
|
+
* For Permit2: encode(permit, signature)
|
|
1580
|
+
*
|
|
1581
|
+
* @example '0x0000000000000000000000000000000000000000000000000000000000989680...'
|
|
1582
|
+
*/
|
|
1583
|
+
permitCalldata: `0x${string}`;
|
|
1584
|
+
}
|
|
1585
|
+
/**
|
|
1586
|
+
* Single instruction to execute within the Adapter Contract.
|
|
1587
|
+
*
|
|
1588
|
+
* Each instruction represents a contract call (swap, fee collection, etc.)
|
|
1589
|
+
* with pre-execution approval and post-execution validation.
|
|
1590
|
+
*
|
|
1591
|
+
* @example
|
|
1592
|
+
* ```typescript
|
|
1593
|
+
* const swapInstruction: Instruction = {
|
|
1594
|
+
* target: '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE', // LiFi Diamond
|
|
1595
|
+
* data: '0x...', // LiFi swap calldata
|
|
1596
|
+
* value: 0n,
|
|
1597
|
+
* tokenIn: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC
|
|
1598
|
+
* amountToApprove: 1000000000n, // 1000 USDC to approve
|
|
1599
|
+
* tokenOut: '0xdAC17F958D2ee523a2206206994597C13D831ec7', // USDT
|
|
1600
|
+
* minTokenOut: 995000000n // 995 USDT minimum (0.5% slippage)
|
|
1601
|
+
* }
|
|
1602
|
+
* ```
|
|
1603
|
+
*/
|
|
1604
|
+
interface Instruction {
|
|
1605
|
+
/**
|
|
1606
|
+
* Target contract address to call.
|
|
1607
|
+
*
|
|
1608
|
+
* Can be a DEX router, fee taker contract, or token contract.
|
|
1609
|
+
*/
|
|
1610
|
+
target: `0x${string}`;
|
|
1611
|
+
/**
|
|
1612
|
+
* ABI-encoded calldata for the target contract.
|
|
1613
|
+
*/
|
|
1614
|
+
data: `0x${string}`;
|
|
1615
|
+
/**
|
|
1616
|
+
* ETH value to send with the call (for native token operations).
|
|
1617
|
+
*
|
|
1618
|
+
* @defaultValue 0n
|
|
1619
|
+
*/
|
|
1620
|
+
value: bigint;
|
|
1621
|
+
/**
|
|
1622
|
+
* Token to approve to target before executing instruction.
|
|
1623
|
+
*
|
|
1624
|
+
* Set to zero address (0x00...00) to disable pre-approval.
|
|
1625
|
+
*/
|
|
1626
|
+
tokenIn: `0x${string}`;
|
|
1627
|
+
/**
|
|
1628
|
+
* Amount of tokenIn to approve to target before executing instruction.
|
|
1629
|
+
*
|
|
1630
|
+
* @remarks
|
|
1631
|
+
* Field name matches the adapter contract's `amountToApprove` parameter exactly.
|
|
1632
|
+
*
|
|
1633
|
+
* @defaultValue 0n if tokenIn is zero address
|
|
1634
|
+
*/
|
|
1635
|
+
amountToApprove: bigint;
|
|
1636
|
+
/**
|
|
1637
|
+
* Token to validate minimum balance after instruction.
|
|
1638
|
+
*
|
|
1639
|
+
* Set to zero address (0x00...00) to disable post-validation.
|
|
1640
|
+
*/
|
|
1641
|
+
tokenOut: `0x${string}`;
|
|
1642
|
+
/**
|
|
1643
|
+
* Minimum required balance of tokenOut after instruction.
|
|
1644
|
+
*
|
|
1645
|
+
* @defaultValue 0n if tokenOut is zero address
|
|
1646
|
+
*/
|
|
1647
|
+
minTokenOut: bigint;
|
|
1648
|
+
}
|
|
1649
|
+
/**
|
|
1650
|
+
* Token recipient for residual sweep.
|
|
1651
|
+
*
|
|
1652
|
+
* After all instructions complete, the Adapter Contract sweeps
|
|
1653
|
+
* any remaining balances to the specified beneficiaries.
|
|
1654
|
+
*/
|
|
1655
|
+
interface TokenRecipient {
|
|
1656
|
+
/**
|
|
1657
|
+
* Token contract address to sweep.
|
|
1658
|
+
*/
|
|
1659
|
+
token: `0x${string}`;
|
|
1660
|
+
/**
|
|
1661
|
+
* Address to receive swept tokens.
|
|
1662
|
+
*/
|
|
1663
|
+
beneficiary: `0x${string}`;
|
|
1664
|
+
}
|
|
1665
|
+
/**
|
|
1666
|
+
* Execution parameters for the Adapter Contract.
|
|
1667
|
+
*
|
|
1668
|
+
* This struct is signed via EIP-712 by the Circle proxy and verified
|
|
1669
|
+
* on-chain to ensure the execution is authorized.
|
|
1670
|
+
*
|
|
1671
|
+
* @remarks
|
|
1672
|
+
* The executeParams are provided by the stablecoin-service and must be
|
|
1673
|
+
* passed to the Adapter Contract exactly as received (no modification).
|
|
1674
|
+
*
|
|
1675
|
+
* @example
|
|
1676
|
+
* ```typescript
|
|
1677
|
+
* const executeParams: ExecuteParams = {
|
|
1678
|
+
* instructions: [
|
|
1679
|
+
* { target: dexRouter, data: swapCalldata, ... }
|
|
1680
|
+
* ],
|
|
1681
|
+
* tokens: [
|
|
1682
|
+
* { token: USDC, beneficiary: userAddress },
|
|
1683
|
+
* { token: USDT, beneficiary: userAddress }
|
|
1684
|
+
* ],
|
|
1685
|
+
* execId: 123456789n,
|
|
1686
|
+
* deadline: BigInt(Math.floor(Date.now() / 1000) + 1800),
|
|
1687
|
+
* metadata: '0x'
|
|
1688
|
+
* }
|
|
1689
|
+
* ```
|
|
1690
|
+
*/
|
|
1691
|
+
interface ExecuteParams {
|
|
1692
|
+
/**
|
|
1693
|
+
* Array of instructions to execute sequentially.
|
|
1694
|
+
*
|
|
1695
|
+
* Each instruction can be a swap, fee collection, or other contract call.
|
|
1696
|
+
*/
|
|
1697
|
+
instructions: Instruction[];
|
|
1698
|
+
/**
|
|
1699
|
+
* Token recipients for residual sweep.
|
|
1700
|
+
*
|
|
1701
|
+
* Typically a 2-tuple: [tokenIn recipient, tokenOut recipient]
|
|
1702
|
+
*/
|
|
1703
|
+
tokens: TokenRecipient[];
|
|
1704
|
+
/**
|
|
1705
|
+
* Unique execution identifier for replay protection.
|
|
1706
|
+
*
|
|
1707
|
+
* Must be globally unique and is marked as used after execution.
|
|
1708
|
+
*/
|
|
1709
|
+
execId: bigint;
|
|
1710
|
+
/**
|
|
1711
|
+
* Execution deadline timestamp (Unix seconds).
|
|
1712
|
+
*
|
|
1713
|
+
* Transaction reverts if block.timestamp is greater than deadline.
|
|
1714
|
+
*/
|
|
1715
|
+
deadline: bigint;
|
|
1716
|
+
/**
|
|
1717
|
+
* Optional metadata for tracking and analytics.
|
|
1718
|
+
*/
|
|
1719
|
+
metadata: `0x${string}`;
|
|
1720
|
+
}
|
|
1721
|
+
/**
|
|
1722
|
+
* Parameters for executing a swap transaction via the Adapter smart contract.
|
|
1723
|
+
*
|
|
1724
|
+
* This action executes swap transactions through the Adapter Contract, which
|
|
1725
|
+
* handles token approvals via permits (EIP-2612, Permit2, etc.) and executes
|
|
1726
|
+
* multi-step swap instructions atomically on-chain.
|
|
1727
|
+
*
|
|
1728
|
+
* @remarks
|
|
1729
|
+
* The swap flow uses the Adapter Contract pattern:
|
|
1730
|
+
* 1. Service provides `executeParams` and `signature` (proxy-signed EIP-712)
|
|
1731
|
+
* 2. SDK builds `tokenInputs` with permit signatures for gasless approvals
|
|
1732
|
+
* 3. SDK calls AdapterContract.execute(executeParams, tokenInputs, signature)
|
|
1733
|
+
* 4. Adapter Contract pulls tokens via permits, executes swaps, validates outputs
|
|
1734
|
+
*
|
|
1735
|
+
* This enables:
|
|
1736
|
+
* - Single atomic transaction (permit + swap in one tx)
|
|
1737
|
+
* - Gasless approvals via EIP-2612/Permit2
|
|
1738
|
+
* - Slippage protection enforced on-chain
|
|
1739
|
+
* - Multi-step instructions (swap + fees) atomically
|
|
1740
|
+
*
|
|
1741
|
+
* **Permit Support**: The SDK constructs `TokenInput` with `permitCalldata`
|
|
1742
|
+
* containing the encoded permit signature. The Adapter Contract executes
|
|
1743
|
+
* the permit on-chain before pulling tokens.
|
|
1744
|
+
*
|
|
1745
|
+
* @example
|
|
1746
|
+
* ```typescript
|
|
1747
|
+
* import type { ExecuteSwapParams } from '@core/adapter'
|
|
1748
|
+
* import { createSwap } from '@core/service-client'
|
|
1749
|
+
* import { PermitType } from '@core/adapter'
|
|
1750
|
+
*
|
|
1751
|
+
* // Get swap transaction from service
|
|
1752
|
+
* const swapResponse = await createSwap({
|
|
1753
|
+
* tokenInAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
|
|
1754
|
+
* tokenOutAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
|
|
1755
|
+
* tokenInChain: 'Ethereum',
|
|
1756
|
+
* fromAddress: '0x...',
|
|
1757
|
+
* toAddress: '0x...',
|
|
1758
|
+
* amount: '1000000',
|
|
1759
|
+
* apiKey: 'KIT_KEY:...',
|
|
1760
|
+
* })
|
|
1761
|
+
*
|
|
1762
|
+
* // Build token inputs with permit
|
|
1763
|
+
* const tokenInputs: TokenInput[] = [{
|
|
1764
|
+
* permitType: PermitType.EIP2612,
|
|
1765
|
+
* token: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
|
|
1766
|
+
* from: userAddress,
|
|
1767
|
+
* amount: 1000000n,
|
|
1768
|
+
* permitCalldata: '0x...' // Encoded permit signature
|
|
1769
|
+
* }]
|
|
1770
|
+
*
|
|
1771
|
+
* // Prepare action parameters
|
|
1772
|
+
* const params: ExecuteSwapParams = {
|
|
1773
|
+
* executeParams: swapResponse.transaction.executeParams,
|
|
1774
|
+
* tokenInputs,
|
|
1775
|
+
* signature: swapResponse.transaction.signature,
|
|
1776
|
+
* inputAmount: BigInt(swapResponse.amount),
|
|
1777
|
+
* tokenInAddress: swapResponse.tokenInAddress as `0x${string}`
|
|
1778
|
+
* }
|
|
1779
|
+
* ```
|
|
1780
|
+
*/
|
|
1781
|
+
interface ExecuteSwapEVMParams extends ActionParameters {
|
|
1782
|
+
/**
|
|
1783
|
+
* Execution parameters from the stablecoin-service.
|
|
1784
|
+
*
|
|
1785
|
+
* Contains instructions, token recipients, execution ID, deadline, and metadata.
|
|
1786
|
+
* This is an EIP-712 signed struct that the Adapter Contract validates.
|
|
1787
|
+
*
|
|
1788
|
+
* Provided by the service - do not modify.
|
|
1789
|
+
*/
|
|
1790
|
+
executeParams: ExecuteParams;
|
|
1791
|
+
/**
|
|
1792
|
+
* Token inputs with permit signatures for gasless approvals.
|
|
1793
|
+
*
|
|
1794
|
+
* The SDK constructs this array with permit data for each token that needs
|
|
1795
|
+
* to be pulled from the user's wallet. The Adapter Contract executes these
|
|
1796
|
+
* permits on-chain before executing swap instructions.
|
|
1797
|
+
*
|
|
1798
|
+
* @remarks
|
|
1799
|
+
* For EIP-2612 permits, the SDK must:
|
|
1800
|
+
* 1. Build typed data with token, spender (Adapter), amount, nonce, deadline
|
|
1801
|
+
* 2. Get user signature via `adapter.signTypedData()`
|
|
1802
|
+
* 3. Encode as permitCalldata: encode(value, deadline, v, r, s)
|
|
1803
|
+
*
|
|
1804
|
+
* @example
|
|
1805
|
+
* ```typescript
|
|
1806
|
+
* [{
|
|
1807
|
+
* permitType: PermitType.EIP2612,
|
|
1808
|
+
* token: '0xUSDC',
|
|
1809
|
+
* from: userAddress,
|
|
1810
|
+
* amount: 1000000n,
|
|
1811
|
+
* permitCalldata: '0x...'
|
|
1812
|
+
* }]
|
|
1813
|
+
* ```
|
|
1814
|
+
*/
|
|
1815
|
+
tokenInputs: TokenInput[];
|
|
1816
|
+
/**
|
|
1817
|
+
* EIP-712 signature from the Circle proxy service.
|
|
1818
|
+
*
|
|
1819
|
+
* The service signs the executeParams to authorize the execution.
|
|
1820
|
+
* The Adapter Contract verifies this signature on-chain.
|
|
1821
|
+
*
|
|
1822
|
+
* Provided by the service - do not modify.
|
|
1823
|
+
*/
|
|
1824
|
+
signature: `0x${string}`;
|
|
1825
|
+
/**
|
|
1826
|
+
* Swap input amount in base units.
|
|
1827
|
+
*
|
|
1828
|
+
* @remarks
|
|
1829
|
+
* The amount of tokens being swapped, provided in the token's base units (e.g., wei for ETH,
|
|
1830
|
+
* smallest denomination for ERC20 tokens). This value should be extracted from the service
|
|
1831
|
+
* response, as it represents the authoritative swap amount for the operation.
|
|
1832
|
+
*
|
|
1833
|
+
* For native currency swaps (ETH → USDC), this amount is sent as the transaction `value`.
|
|
1834
|
+
* For ERC20 swaps (USDC → USDT), this amount determines the permit or approval quantity.
|
|
1835
|
+
*
|
|
1836
|
+
* @see CreateSwapResponse.amount - Service response field containing this value
|
|
1837
|
+
*
|
|
1838
|
+
* @example
|
|
1839
|
+
* ```typescript
|
|
1840
|
+
* import { createSwap } from '@core/service-client'
|
|
1841
|
+
*
|
|
1842
|
+
* // Get swap transaction from service
|
|
1843
|
+
* const response = await createSwap({
|
|
1844
|
+
* tokenInAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
|
|
1845
|
+
* amount: '1000000', // 1 USDC (6 decimals)
|
|
1846
|
+
* ...
|
|
1847
|
+
* })
|
|
1848
|
+
*
|
|
1849
|
+
* // Prepare swap execution using service response amount
|
|
1850
|
+
* await adapter.prepareAction('swap.execute', {
|
|
1851
|
+
* executeParams: response.transaction.executeParams,
|
|
1852
|
+
* tokenInputs,
|
|
1853
|
+
* signature: response.transaction.signature,
|
|
1854
|
+
* inputAmount: BigInt(response.amount),
|
|
1855
|
+
* tokenInAddress: response.tokenInAddress,
|
|
1856
|
+
* }, context)
|
|
1857
|
+
* ```
|
|
1858
|
+
*/
|
|
1859
|
+
inputAmount: bigint;
|
|
1860
|
+
/**
|
|
1861
|
+
* Token address being swapped from.
|
|
1862
|
+
*
|
|
1863
|
+
* @remarks
|
|
1864
|
+
* Used to determine if the swap involves native currency (ETH, MATIC, etc.) or ERC20 tokens.
|
|
1865
|
+
* When tokenInAddress is NATIVE_TOKEN_ADDRESS (0xEeee...), the inputAmount is sent as tx.value.
|
|
1866
|
+
*
|
|
1867
|
+
* @see CreateSwapResponse.tokenInAddress - Service response field containing this value
|
|
1868
|
+
*
|
|
1869
|
+
* @example '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE' for ETH
|
|
1870
|
+
* @example '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48' for USDC
|
|
1871
|
+
*/
|
|
1872
|
+
tokenInAddress: `0x${string}`;
|
|
1873
|
+
}
|
|
1874
|
+
/**
|
|
1875
|
+
* Parameters for executing a swap transaction on Solana.
|
|
1876
|
+
*
|
|
1877
|
+
* This action executes swap transactions on Solana chains by deserializing
|
|
1878
|
+
* and executing a pre-built transaction provided by the stablecoin-service.
|
|
1879
|
+
*
|
|
1880
|
+
* @remarks
|
|
1881
|
+
* Unlike EVM chains that use the Adapter Contract pattern, Solana swaps
|
|
1882
|
+
* execute a fully serialized transaction provided by the service. The
|
|
1883
|
+
* transaction is base64-encoded and contains all necessary instructions
|
|
1884
|
+
* for the swap operation.
|
|
1885
|
+
*
|
|
1886
|
+
* The service handles:
|
|
1887
|
+
* - DEX aggregator routing (Jupiter, etc.)
|
|
1888
|
+
* - Fee collection
|
|
1889
|
+
* - Slippage protection
|
|
1890
|
+
* - Token account management
|
|
1891
|
+
*
|
|
1892
|
+
* @example
|
|
1893
|
+
* ```typescript
|
|
1894
|
+
* import type { ExecuteSwapSolanaParams } from '@core/adapter'
|
|
1895
|
+
* import { createSwap } from '@core/service-client'
|
|
1896
|
+
*
|
|
1897
|
+
* // Get swap transaction from service
|
|
1898
|
+
* const swapResponse = await createSwap({
|
|
1899
|
+
* tokenInAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
|
1900
|
+
* tokenOutAddress: 'HzwqbKZw8HxMN6bF2yFZNrht3c2iXXzpKcFu7uBEDKtr',
|
|
1901
|
+
* tokenInChain: 'Solana',
|
|
1902
|
+
* fromAddress: 'YubQzu18FDqJRyNfG8JqHmsdbxhnoQqcKUHBdUkN6tP',
|
|
1903
|
+
* toAddress: 'YubQzu18FDqJRyNfG8JqHmsdbxhnoQqcKUHBdUkN6tP',
|
|
1904
|
+
* amount: '1000000',
|
|
1905
|
+
* apiKey: 'KIT_KEY:...',
|
|
1906
|
+
* })
|
|
1907
|
+
*
|
|
1908
|
+
* // Prepare action parameters
|
|
1909
|
+
* const params: ExecuteSwapSolanaParams = {
|
|
1910
|
+
* serializedTransaction: swapResponse.transaction.data
|
|
1911
|
+
* }
|
|
1912
|
+
* ```
|
|
1913
|
+
*/
|
|
1914
|
+
interface ExecuteSwapSolanaParams extends ActionParameters {
|
|
1915
|
+
/**
|
|
1916
|
+
* Base64-encoded serialized Solana transaction.
|
|
1917
|
+
*
|
|
1918
|
+
* This transaction is fully constructed by the stablecoin-service and
|
|
1919
|
+
* contains all swap instructions, fee payments, and token account setup.
|
|
1920
|
+
* The transaction must be deserialized, signed, and submitted to the network.
|
|
1921
|
+
*
|
|
1922
|
+
* Provided by the service - do not modify.
|
|
1923
|
+
*
|
|
1924
|
+
* @example 'AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAJFQg...'
|
|
1925
|
+
*/
|
|
1926
|
+
serializedTransaction: string;
|
|
1927
|
+
}
|
|
1928
|
+
/**
|
|
1929
|
+
* Parameters accepted by the swap.execute action, supporting both EVM and Solana chains.
|
|
1930
|
+
*
|
|
1931
|
+
* @remarks
|
|
1932
|
+
* This union type covers all chain-specific swap execution parameter interfaces
|
|
1933
|
+
* currently supported by the App Kit. Extend this union to support
|
|
1934
|
+
* additional blockchains as needed. Each member provides all fields required
|
|
1935
|
+
* to prepare and execute a pre-built swap transaction on its respective chain.
|
|
1936
|
+
*
|
|
1937
|
+
* **Type Narrowing**: The correct parameter type is inferred from the chain type
|
|
1938
|
+
* in the `OperationContext` passed to `adapter.prepareAction()`. Action handlers
|
|
1939
|
+
* use property-based type guards (checking for `executeParams`/`tokenInputs` for EVM
|
|
1940
|
+
* or `serializedTransaction` for Solana) to narrow the union type at runtime.
|
|
1941
|
+
*
|
|
1942
|
+
* - {@link ExecuteSwapEVMParams} - For EVM chains (has `executeParams` and `tokenInputs`)
|
|
1943
|
+
* - {@link ExecuteSwapSolanaParams} - For Solana chains (has `serializedTransaction`)
|
|
1944
|
+
*/
|
|
1945
|
+
type ExecuteSwapParams = ExecuteSwapEVMParams | ExecuteSwapSolanaParams;
|
|
1946
|
+
/**
|
|
1947
|
+
* Action map for swap operations on EVM chains.
|
|
1948
|
+
*
|
|
1949
|
+
* This namespace contains actions related to token swapping operations.
|
|
1950
|
+
* These actions handle the execution of pre-built swap transactions from
|
|
1951
|
+
* DEX aggregators and routing services.
|
|
1952
|
+
*
|
|
1953
|
+
* @remarks
|
|
1954
|
+
* The swap namespace is designed to be extensible for future swap-related
|
|
1955
|
+
* operations such as multi-hop swaps, batched swaps, or swap-and-bridge
|
|
1956
|
+
* compositions.
|
|
1957
|
+
*/
|
|
1958
|
+
interface SwapActionMap {
|
|
1959
|
+
/**
|
|
1960
|
+
* Execute a pre-built swap transaction.
|
|
1961
|
+
*
|
|
1962
|
+
* This action prepares and executes swap transactions constructed by the
|
|
1963
|
+
* stablecoin-service API. It accepts transaction parameters (to, data, value)
|
|
1964
|
+
* and returns a prepared chain request suitable for gas estimation or execution.
|
|
1965
|
+
*/
|
|
1966
|
+
readonly execute: ExecuteSwapParams;
|
|
1376
1967
|
}
|
|
1377
1968
|
|
|
1378
1969
|
interface TokenActionMap {
|
|
@@ -1588,14 +2179,89 @@ interface USDCActionMap {
|
|
|
1588
2179
|
}
|
|
1589
2180
|
|
|
1590
2181
|
/**
|
|
1591
|
-
*
|
|
2182
|
+
* USDT-specific operations that automatically resolve the token address.
|
|
1592
2183
|
*
|
|
1593
|
-
*
|
|
1594
|
-
*
|
|
1595
|
-
*
|
|
1596
|
-
* the recursive utility types provided in this module.
|
|
2184
|
+
* These include standard ERC20 operations. The interface provides the same core
|
|
2185
|
+
* operations as {@link TokenActionMap} but without requiring a `tokenAddress`
|
|
2186
|
+
* parameter.
|
|
1597
2187
|
*
|
|
1598
|
-
* @
|
|
2188
|
+
* @example
|
|
2189
|
+
* ```typescript
|
|
2190
|
+
* // USDT operations (address auto-resolved)
|
|
2191
|
+
* await adapter.action('usdt.transfer', {
|
|
2192
|
+
* to: '0x1234...',
|
|
2193
|
+
* amount: '1000000' // 1 USDT
|
|
2194
|
+
* })
|
|
2195
|
+
*
|
|
2196
|
+
* // vs. general token operations (address required)
|
|
2197
|
+
* await adapter.action('token.transfer', {
|
|
2198
|
+
* tokenAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
|
|
2199
|
+
* to: '0x1234...',
|
|
2200
|
+
* amount: '1000000'
|
|
2201
|
+
* })
|
|
2202
|
+
* ```
|
|
2203
|
+
*/
|
|
2204
|
+
type BaseUSDTActions = {
|
|
2205
|
+
[K in keyof TokenActionMap]: Omit<TokenActionMap[K], 'tokenAddress'>;
|
|
2206
|
+
};
|
|
2207
|
+
/**
|
|
2208
|
+
* USDT action map with standard ERC20 operations.
|
|
2209
|
+
*
|
|
2210
|
+
* This provides standard token operations for USDT transfers.
|
|
2211
|
+
*/
|
|
2212
|
+
interface USDTActionMap {
|
|
2213
|
+
/**
|
|
2214
|
+
* Transfer USDT tokens directly from the wallet to another address.
|
|
2215
|
+
*
|
|
2216
|
+
* Automatically uses the USDT contract address for the current chain.
|
|
2217
|
+
*/
|
|
2218
|
+
transfer: BaseUSDTActions['transfer'];
|
|
2219
|
+
}
|
|
2220
|
+
|
|
2221
|
+
/**
|
|
2222
|
+
* Native token-related action maps for the bridge kit.
|
|
2223
|
+
*
|
|
2224
|
+
* This module provides action definitions for native token operations.
|
|
2225
|
+
*/
|
|
2226
|
+
interface NativeActionMap {
|
|
2227
|
+
/**
|
|
2228
|
+
* Transfer native tokens directly from the wallet to another address.
|
|
2229
|
+
*/
|
|
2230
|
+
transfer: ActionParameters & {
|
|
2231
|
+
/**
|
|
2232
|
+
* The chain to transfer the native tokens on.
|
|
2233
|
+
*/
|
|
2234
|
+
chain?: ChainIdentifier$1;
|
|
2235
|
+
/**
|
|
2236
|
+
* The address to send the native tokens to.
|
|
2237
|
+
*/
|
|
2238
|
+
to: string;
|
|
2239
|
+
/**
|
|
2240
|
+
* The amount of native tokens to transfer.
|
|
2241
|
+
*/
|
|
2242
|
+
amount: bigint;
|
|
2243
|
+
};
|
|
2244
|
+
/**
|
|
2245
|
+
* Get the native token balance (SOL, ETH, etc.) for a wallet address.
|
|
2246
|
+
*/
|
|
2247
|
+
balanceOf: ActionParameters & {
|
|
2248
|
+
/**
|
|
2249
|
+
* The address to check the native balance for. If not provided, it will be
|
|
2250
|
+
* automatically derived from the adapter context.
|
|
2251
|
+
*/
|
|
2252
|
+
walletAddress?: string | undefined;
|
|
2253
|
+
};
|
|
2254
|
+
}
|
|
2255
|
+
|
|
2256
|
+
/**
|
|
2257
|
+
* Central registry of all available action namespaces and their operations.
|
|
2258
|
+
*
|
|
2259
|
+
* Define the complete action map structure used throughout the bridge kit.
|
|
2260
|
+
* Each top-level key represents a namespace (e.g., 'token', 'usdc') containing
|
|
2261
|
+
* related operations. The structure supports arbitrary nesting depth through
|
|
2262
|
+
* the recursive utility types provided in this module.
|
|
2263
|
+
*
|
|
2264
|
+
* @remarks
|
|
1599
2265
|
* This interface serves as the foundation for type-safe action dispatching
|
|
1600
2266
|
* and provides compile-time validation of action keys and payload types.
|
|
1601
2267
|
* All action-related utility types derive from this central definition.
|
|
@@ -1606,12 +2272,16 @@ interface USDCActionMap {
|
|
|
1606
2272
|
interface ActionMap {
|
|
1607
2273
|
/** CCTP-specific operations with automatic address resolution. */
|
|
1608
2274
|
readonly cctp: CCTPActionMap;
|
|
1609
|
-
/** Native token operations (ETH, SOL, MATIC, etc.). */
|
|
1610
|
-
readonly native: NativeActionMap;
|
|
1611
2275
|
/** General token operations requiring explicit token addresses. */
|
|
1612
2276
|
readonly token: TokenActionMap;
|
|
1613
2277
|
/** USDC-specific operations with automatic address resolution. */
|
|
1614
2278
|
readonly usdc: USDCActionMap;
|
|
2279
|
+
/** USDT-specific operations with automatic address resolution. */
|
|
2280
|
+
readonly usdt: USDTActionMap;
|
|
2281
|
+
/** Native token operations. */
|
|
2282
|
+
readonly native: NativeActionMap;
|
|
2283
|
+
/** Swap operations for DEX aggregator integrations. */
|
|
2284
|
+
readonly swap: SwapActionMap;
|
|
1615
2285
|
}
|
|
1616
2286
|
/**
|
|
1617
2287
|
* Determine if a type represents an action parameter object (leaf node).
|
|
@@ -1750,7 +2420,7 @@ type ActionHandler<TActionKey extends ActionKeys> = (params: ActionPayload<TActi
|
|
|
1750
2420
|
* This type defines a registry object where each key is a valid action key
|
|
1751
2421
|
* (as defined by {@link ActionKeys}) and each value is an {@link ActionHandler}
|
|
1752
2422
|
* capable of processing the payload for that action. This enables strongly-typed
|
|
1753
|
-
* handler registration and lookup for all supported actions in the
|
|
2423
|
+
* handler registration and lookup for all supported actions in the App Kits.
|
|
1754
2424
|
*
|
|
1755
2425
|
* @remarks
|
|
1756
2426
|
* Each handler is typed as {@link ActionHandler}, which means the handler
|
|
@@ -2012,11 +2682,11 @@ interface AdapterCapabilities {
|
|
|
2012
2682
|
/**
|
|
2013
2683
|
* Abstract class defining the standard interface for an adapter that interacts with a specific blockchain.
|
|
2014
2684
|
*
|
|
2015
|
-
*
|
|
2685
|
+
* An `Adapter` is responsible for encapsulating chain-specific logic necessary to
|
|
2016
2686
|
* perform operations like sending transactions, querying balances, or interacting with smart contracts.
|
|
2017
2687
|
* Implementations of this class will provide concrete logic for a particular blockchain protocol.
|
|
2018
2688
|
*
|
|
2019
|
-
* This abstraction allows the
|
|
2689
|
+
* This abstraction allows the App Kit to work with multiple blockchains in a uniform way.
|
|
2020
2690
|
*
|
|
2021
2691
|
* @typeParam TAdapterCapabilities - The adapter capabilities type for compile-time address validation.
|
|
2022
2692
|
* When provided, enables strict typing of operation context based on the adapter's address control model.
|
|
@@ -2277,6 +2947,35 @@ declare abstract class Adapter<TAdapterCapabilities extends AdapterCapabilities
|
|
|
2277
2947
|
* @returns A promise that resolves to the total transaction fee as a bigint.
|
|
2278
2948
|
*/
|
|
2279
2949
|
abstract calculateTransactionFee(baseComputeUnits: bigint, bufferBasisPoints: bigint | undefined, chain: ChainDefinition): Promise<EstimatedGas>;
|
|
2950
|
+
/**
|
|
2951
|
+
* Get the decimal places for a token address on a given chain.
|
|
2952
|
+
*
|
|
2953
|
+
* This method fetches the number of decimal places from a token contract.
|
|
2954
|
+
* Different chain types implement this differently:
|
|
2955
|
+
* - EVM: Calls the `decimals()` function on ERC-20 contracts
|
|
2956
|
+
* - Solana: Reads the `decimals` field from the SPL token mint account
|
|
2957
|
+
*
|
|
2958
|
+
* @param tokenAddress - The token contract address (EVM) or mint address (Solana)
|
|
2959
|
+
* @param chain - The chain definition where the token is deployed
|
|
2960
|
+
* @returns Promise resolving to the number of decimal places for the token
|
|
2961
|
+
* @throws Error when the token contract doesn't exist or decimals cannot be fetched
|
|
2962
|
+
*
|
|
2963
|
+
* @example
|
|
2964
|
+
* ```typescript
|
|
2965
|
+
* import { EthersAdapter } from '@circle-fin/adapter-ethers-v6'
|
|
2966
|
+
* import { Ethereum } from '@core/chains'
|
|
2967
|
+
*
|
|
2968
|
+
* const adapter = new EthersAdapter({ signer })
|
|
2969
|
+
*
|
|
2970
|
+
* // Fetch decimals for DAI token
|
|
2971
|
+
* const decimals = await adapter.getTokenDecimals(
|
|
2972
|
+
* '0x6B175474E89094C44Da98b954EedeAC495271d0F',
|
|
2973
|
+
* Ethereum
|
|
2974
|
+
* )
|
|
2975
|
+
* console.log(decimals) // 18
|
|
2976
|
+
* ```
|
|
2977
|
+
*/
|
|
2978
|
+
abstract getTokenDecimals(tokenAddress: string, chain: ChainDefinition): Promise<number>;
|
|
2280
2979
|
}
|
|
2281
2980
|
|
|
2282
2981
|
/**
|
|
@@ -2333,111 +3032,1210 @@ interface ApiPollingConfig {
|
|
|
2333
3032
|
* console.log('Event received:', payload);
|
|
2334
3033
|
* });
|
|
2335
3034
|
*
|
|
2336
|
-
* // Dispatch an event
|
|
2337
|
-
* transferEvents.dispatch('completed', {
|
|
2338
|
-
* txHash: '0x123',
|
|
2339
|
-
* destinationTxHash: '0xabc'
|
|
2340
|
-
* });
|
|
3035
|
+
* // Dispatch an event
|
|
3036
|
+
* transferEvents.dispatch('completed', {
|
|
3037
|
+
* txHash: '0x123',
|
|
3038
|
+
* destinationTxHash: '0xabc'
|
|
3039
|
+
* });
|
|
3040
|
+
* ```
|
|
3041
|
+
*/
|
|
3042
|
+
declare class Actionable<AllActions> {
|
|
3043
|
+
private readonly handlers;
|
|
3044
|
+
private readonly wildcard;
|
|
3045
|
+
/**
|
|
3046
|
+
* Register a handler for a specific action.
|
|
3047
|
+
*
|
|
3048
|
+
* @param action - The specific action key to listen for.
|
|
3049
|
+
* @param handler - The callback function to execute when the action occurs.
|
|
3050
|
+
*
|
|
3051
|
+
* @example
|
|
3052
|
+
* ```typescript
|
|
3053
|
+
* const events = new Actionable<{ dataReceived: string }>();
|
|
3054
|
+
*
|
|
3055
|
+
* events.on('dataReceived', (data) => {
|
|
3056
|
+
* console.log(`Received: ${data}`);
|
|
3057
|
+
* });
|
|
3058
|
+
* ```
|
|
3059
|
+
*/
|
|
3060
|
+
on<Action extends keyof AllActions>(action: Action, handler: (payload: AllActions[Action]) => void): void;
|
|
3061
|
+
/**
|
|
3062
|
+
* Register a handler for all actions using the wildcard '*'.
|
|
3063
|
+
*
|
|
3064
|
+
* @param action - The wildcard '*' signifying interest in all actions.
|
|
3065
|
+
* @param handler - The callback function to execute for any action.
|
|
3066
|
+
*
|
|
3067
|
+
* @example
|
|
3068
|
+
* ```typescript
|
|
3069
|
+
* const events = new Actionable<{ started: boolean; completed: string }>();
|
|
3070
|
+
*
|
|
3071
|
+
* events.on('*', (payload) => {
|
|
3072
|
+
* console.log('Action occurred:', payload);
|
|
3073
|
+
* });
|
|
3074
|
+
* ```
|
|
3075
|
+
*/
|
|
3076
|
+
on(action: '*', handler: (payload: AllActions[keyof AllActions]) => void): void;
|
|
3077
|
+
/**
|
|
3078
|
+
* Remove a previously registered handler for a specific action.
|
|
3079
|
+
*
|
|
3080
|
+
* @param action - The specific action key to unregister from.
|
|
3081
|
+
* @param handler - The callback function to remove.
|
|
3082
|
+
*
|
|
3083
|
+
* @example
|
|
3084
|
+
* ```typescript
|
|
3085
|
+
* const events = new Actionable<{ dataReceived: string }>();
|
|
3086
|
+
*
|
|
3087
|
+
* const handler = (data: string) => console.log(data);
|
|
3088
|
+
* events.on('dataReceived', handler);
|
|
3089
|
+
*
|
|
3090
|
+
* // Later, to remove the handler:
|
|
3091
|
+
* events.off('dataReceived', handler);
|
|
3092
|
+
* ```
|
|
3093
|
+
*/
|
|
3094
|
+
off<Action extends keyof AllActions>(action: Action, handler: (payload: AllActions[Action]) => void): void;
|
|
3095
|
+
/**
|
|
3096
|
+
* Remove a previously registered wildcard handler.
|
|
3097
|
+
*
|
|
3098
|
+
* @param action - The wildcard '*' signifying removal from all actions.
|
|
3099
|
+
* @param handler - The callback function to remove.
|
|
3100
|
+
*
|
|
3101
|
+
* @example
|
|
3102
|
+
* ```typescript
|
|
3103
|
+
* const events = new Actionable<{ started: boolean; completed: string }>();
|
|
3104
|
+
*
|
|
3105
|
+
* const globalHandler = (payload: any) => console.log(payload);
|
|
3106
|
+
* events.on('*', globalHandler);
|
|
3107
|
+
*
|
|
3108
|
+
* // Later, to remove the handler:
|
|
3109
|
+
* events.off('*', globalHandler);
|
|
3110
|
+
* ```
|
|
3111
|
+
*/
|
|
3112
|
+
off(action: '*', handler: (payload: AllActions[keyof AllActions]) => void): void;
|
|
3113
|
+
/**
|
|
3114
|
+
* Dispatch an action with its payload to all registered handlers.
|
|
3115
|
+
*
|
|
3116
|
+
* This method notifies both:
|
|
3117
|
+
* - Handlers registered specifically for this action
|
|
3118
|
+
* - Wildcard handlers registered for all actions
|
|
3119
|
+
*
|
|
3120
|
+
* @param action - The action key identifying the event type.
|
|
3121
|
+
* @param payload - The data associated with the action.
|
|
3122
|
+
*
|
|
3123
|
+
* @example
|
|
3124
|
+
* ```typescript
|
|
3125
|
+
* type Actions = {
|
|
3126
|
+
* transferStarted: { amount: string; destination: string };
|
|
3127
|
+
* transferComplete: { txHash: string };
|
|
3128
|
+
* };
|
|
3129
|
+
*
|
|
3130
|
+
* const events = new Actionable<Actions>();
|
|
3131
|
+
*
|
|
3132
|
+
* // Dispatch an event
|
|
3133
|
+
* events.dispatch('transferStarted', {
|
|
3134
|
+
* amount: '100',
|
|
3135
|
+
* destination: '0xABC123'
|
|
3136
|
+
* });
|
|
3137
|
+
* ```
|
|
3138
|
+
*/
|
|
3139
|
+
dispatch<K extends keyof AllActions>(action: K, payload: AllActions[K]): void;
|
|
3140
|
+
}
|
|
3141
|
+
|
|
3142
|
+
/**
|
|
3143
|
+
* Module augmentation to register known token symbols.
|
|
3144
|
+
*
|
|
3145
|
+
* @remarks
|
|
3146
|
+
* This file augments the `TokenSymbolRegistry` interface to provide
|
|
3147
|
+
* type-safe autocomplete for built-in tokens.
|
|
3148
|
+
*
|
|
3149
|
+
* When imported, TypeScript will recognize 'USDC' as a valid
|
|
3150
|
+
* `TokenSymbol` value with autocomplete support.
|
|
3151
|
+
*
|
|
3152
|
+
* Other packages or applications can create their own augmentations
|
|
3153
|
+
* to add additional tokens.
|
|
3154
|
+
*
|
|
3155
|
+
* @example
|
|
3156
|
+
* ```typescript
|
|
3157
|
+
* import '@core/tokens' // Automatically includes this augmentation
|
|
3158
|
+
*
|
|
3159
|
+
* const symbol: TokenSymbol = 'USDC' // ✓ Autocomplete shows USDC
|
|
3160
|
+
* ```
|
|
3161
|
+
*/
|
|
3162
|
+
declare module './types' {
|
|
3163
|
+
/**
|
|
3164
|
+
* Module augmentation: Adds known token symbols as valid keys
|
|
3165
|
+
* to the TokenSymbolRegistry interface.
|
|
3166
|
+
*
|
|
3167
|
+
* Keys are explicitly listed to ensure IDE autocomplete works properly.
|
|
3168
|
+
*/
|
|
3169
|
+
interface TokenSymbolRegistry {
|
|
3170
|
+
USDC: true;
|
|
3171
|
+
USDT: true;
|
|
3172
|
+
EURC: true;
|
|
3173
|
+
DAI: true;
|
|
3174
|
+
USDE: true;
|
|
3175
|
+
PYUSD: true;
|
|
3176
|
+
WETH: true;
|
|
3177
|
+
WBTC: true;
|
|
3178
|
+
WSOL: true;
|
|
3179
|
+
WAVAX: true;
|
|
3180
|
+
WPOL: true;
|
|
3181
|
+
ETH: true;
|
|
3182
|
+
POL: true;
|
|
3183
|
+
PLUME: true;
|
|
3184
|
+
MON: true;
|
|
3185
|
+
}
|
|
3186
|
+
}
|
|
3187
|
+
|
|
3188
|
+
/**
|
|
3189
|
+
* Module augmentation to register Blockchain enum values as ChainIdentifiers.
|
|
3190
|
+
*
|
|
3191
|
+
* @remarks
|
|
3192
|
+
* This file augments the `ChainRegistry` interface to provide type-safe
|
|
3193
|
+
* autocomplete for all `Blockchain` enum values from `@core/chains`.
|
|
3194
|
+
*
|
|
3195
|
+
* When this augmentation is imported (via `@core/tokens`), TypeScript will
|
|
3196
|
+
* recognize all blockchain identifiers as valid `ChainIdentifier` values
|
|
3197
|
+
* with IDE autocomplete support.
|
|
3198
|
+
*
|
|
3199
|
+
* The `Blockchain` enum values are converted to their string representations,
|
|
3200
|
+
* enabling both enum values and string literals to be accepted as chain identifiers.
|
|
3201
|
+
*
|
|
3202
|
+
* @example
|
|
3203
|
+
* ```typescript
|
|
3204
|
+
* import { Blockchain } from '@core/chains'
|
|
3205
|
+
* import type { ChainIdentifier } from '@core/tokens'
|
|
3206
|
+
*
|
|
3207
|
+
* // Using enum value
|
|
3208
|
+
* const chain1: ChainIdentifier = Blockchain.Ethereum
|
|
3209
|
+
*
|
|
3210
|
+
* // Using string literal (with autocomplete!)
|
|
3211
|
+
* const chain2: ChainIdentifier = 'Base'
|
|
3212
|
+
*
|
|
3213
|
+
* // Arbitrary strings also work (escape hatch for custom chains)
|
|
3214
|
+
* const chain3: ChainIdentifier = 'my-custom-chain'
|
|
3215
|
+
* ```
|
|
3216
|
+
*/
|
|
3217
|
+
|
|
3218
|
+
declare module './types' {
|
|
3219
|
+
/**
|
|
3220
|
+
* Module augmentation: Adds all Blockchain enum values as valid keys
|
|
3221
|
+
* to the ChainRegistry interface for type-safe chain identifier support.
|
|
3222
|
+
*
|
|
3223
|
+
* This ensures both enum property access (e.g., Blockchain.Ethereum) and plain
|
|
3224
|
+
* string literals (e.g., 'Ethereum') are accepted by TypeScript as chain keys,
|
|
3225
|
+
* providing robust autocomplete and error checking.
|
|
3226
|
+
*
|
|
3227
|
+
* NOTE:
|
|
3228
|
+
* - This interface intentionally has no body. It merges a mapped Record type
|
|
3229
|
+
* into ChainRegistry solely for type augmentation.
|
|
3230
|
+
* - This empty-body construct is a necessary TypeScript idiom for module
|
|
3231
|
+
* augmentation with Record types—directly listing mapped keys is not
|
|
3232
|
+
* feasible in interface extensions.
|
|
3233
|
+
*
|
|
3234
|
+
* eslint-disable-next-line directives below suppress linter complaints about
|
|
3235
|
+
* the empty interface/mapping, which are benign and required for this pattern.
|
|
3236
|
+
*/
|
|
3237
|
+
interface ChainRegistry extends Record<`${Blockchain}`, true> {
|
|
3238
|
+
}
|
|
3239
|
+
}
|
|
3240
|
+
|
|
3241
|
+
/**
|
|
3242
|
+
* Creates a union type that preserves IDE autocomplete for known literals
|
|
3243
|
+
* while still accepting any string at runtime.
|
|
3244
|
+
*
|
|
3245
|
+
* @remarks
|
|
3246
|
+
* This pattern uses `Record<never, never>` (an empty record type) to prevent
|
|
3247
|
+
* TypeScript from widening string literals to just `string`. This gives us
|
|
3248
|
+
* the best of both worlds: autocomplete for known values and flexibility
|
|
3249
|
+
* for arbitrary strings.
|
|
3250
|
+
*
|
|
3251
|
+
* @typeParam T - The known string literal union to preserve.
|
|
3252
|
+
*/
|
|
3253
|
+
type LiteralUnion<T extends string> = T | (string & Record<never, never>);
|
|
3254
|
+
/**
|
|
3255
|
+
* Registry for known chain identifiers (augmentation target).
|
|
3256
|
+
*
|
|
3257
|
+
* @remarks
|
|
3258
|
+
* This empty interface exists solely for module augmentation. Extend it to
|
|
3259
|
+
* register chain identifiers for type-safe token definitions.
|
|
3260
|
+
*
|
|
3261
|
+
* **Why an interface?** TypeScript only allows module augmentation on
|
|
3262
|
+
* interfaces, not type aliases.
|
|
3263
|
+
*
|
|
3264
|
+
* **Note:** This is NOT the EVM "chain ID" (numeric like 1 for Ethereum).
|
|
3265
|
+
* It's a human-readable identifier like "Ethereum", "Solana", "Base".
|
|
3266
|
+
*
|
|
3267
|
+
* **Usage**
|
|
3268
|
+
*
|
|
3269
|
+
* Without augmentation, `ChainIdentifier` defaults to `string`.
|
|
3270
|
+
* With `@core/chains` imported, you get autocomplete for all `Blockchain` values.
|
|
3271
|
+
*
|
|
3272
|
+
* **Custom Chains**
|
|
3273
|
+
*
|
|
3274
|
+
* ```typescript
|
|
3275
|
+
* declare module '@core/tokens' {
|
|
3276
|
+
* interface ChainRegistry {
|
|
3277
|
+
* MyChain: true
|
|
3278
|
+
* MyTestnet: true
|
|
3279
|
+
* }
|
|
3280
|
+
* }
|
|
3281
|
+
* // Now ChainIdentifier includes 'MyChain' | 'MyTestnet' | ...
|
|
3282
|
+
* ```
|
|
3283
|
+
*
|
|
3284
|
+
* The value (`true`) is a placeholder—only the keys matter.
|
|
3285
|
+
*
|
|
3286
|
+
* NOTE: The eslint-disable below suppresses warnings about empty interfaces.
|
|
3287
|
+
* This is intentional—the interface exists solely as an augmentation target.
|
|
3288
|
+
*/
|
|
3289
|
+
interface ChainRegistry {
|
|
3290
|
+
}
|
|
3291
|
+
/**
|
|
3292
|
+
* Union of all registered chain identifiers.
|
|
3293
|
+
*
|
|
3294
|
+
* @remarks
|
|
3295
|
+
* Derived from `ChainRegistry` keys:
|
|
3296
|
+
* - Without augmentation: `string`
|
|
3297
|
+
* - With `@core/chains`: `'Ethereum' | 'Solana' | ...` plus any string
|
|
3298
|
+
*
|
|
3299
|
+
* Uses `LiteralUnion` to preserve IDE autocomplete while allowing
|
|
3300
|
+
* arbitrary strings at runtime.
|
|
3301
|
+
*
|
|
3302
|
+
* @example
|
|
3303
|
+
* ```typescript
|
|
3304
|
+
* const chain: ChainIdentifier = 'Ethereum' // Autocomplete works
|
|
3305
|
+
* const custom: ChainIdentifier = 'my-chain' // Also valid
|
|
3306
|
+
* ```
|
|
3307
|
+
*/
|
|
3308
|
+
type ChainIdentifier = keyof ChainRegistry extends never ? string : LiteralUnion<Extract<keyof ChainRegistry, string>>;
|
|
3309
|
+
/**
|
|
3310
|
+
* Maps chain identifiers to their token locators.
|
|
3311
|
+
*
|
|
3312
|
+
* @remarks
|
|
3313
|
+
* The key is a chain identifier (type-safe when `KnownChainIdentifiers` is
|
|
3314
|
+
* augmented). This enables a single token definition to work across chains.
|
|
3315
|
+
*
|
|
3316
|
+
* When `@core/chains` is imported, you get autocomplete for known chains
|
|
3317
|
+
* like `Ethereum`, `Base`, `Solana`, etc.
|
|
3318
|
+
*
|
|
3319
|
+
* @example
|
|
3320
|
+
* ```typescript
|
|
3321
|
+
* import { Blockchain } from '@core/chains'
|
|
3322
|
+
*
|
|
3323
|
+
* const usdcLocators: ChainLocatorMap = {
|
|
3324
|
+
* [Blockchain.Ethereum]: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
|
|
3325
|
+
* [Blockchain.Solana]: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
|
3326
|
+
* [Blockchain.Base]: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
|
|
3327
|
+
* }
|
|
3328
|
+
*
|
|
3329
|
+
* // Or with string keys (always works)
|
|
3330
|
+
* const locators: ChainLocatorMap = {
|
|
3331
|
+
* 'ethereum': '0xa0b86991...',
|
|
3332
|
+
* 'my-custom-chain': '0x1234...',
|
|
3333
|
+
* }
|
|
3334
|
+
* ```
|
|
3335
|
+
*/
|
|
3336
|
+
type ChainLocatorMap = Record<ChainIdentifier, string>;
|
|
3337
|
+
/**
|
|
3338
|
+
* Complete definition of a token including metadata and chain locators.
|
|
3339
|
+
*
|
|
3340
|
+
* @remarks
|
|
3341
|
+
* This is the canonical representation of a token in the registry.
|
|
3342
|
+
* It includes the symbol, decimals, and chain-specific locators.
|
|
3343
|
+
*
|
|
3344
|
+
* @example
|
|
3345
|
+
* ```typescript
|
|
3346
|
+
* const usdc: TokenDefinition = {
|
|
3347
|
+
* symbol: 'USDC',
|
|
3348
|
+
* decimals: 6,
|
|
3349
|
+
* locators: {
|
|
3350
|
+
* [Blockchain.Ethereum]: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
|
|
3351
|
+
* [Blockchain.Solana]: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
|
3352
|
+
* },
|
|
3353
|
+
* }
|
|
3354
|
+
* ```
|
|
3355
|
+
*/
|
|
3356
|
+
interface TokenDefinition {
|
|
3357
|
+
/**
|
|
3358
|
+
* The token symbol (e.g., "USDC", "EURC").
|
|
3359
|
+
*/
|
|
3360
|
+
readonly symbol: string;
|
|
3361
|
+
/**
|
|
3362
|
+
* The default number of decimal places for the token.
|
|
3363
|
+
* Used when no chain-specific override exists in {@link chainDecimals}.
|
|
3364
|
+
* @example 6 for USDC, 18 for most ERC20 tokens
|
|
3365
|
+
*/
|
|
3366
|
+
readonly decimals: number;
|
|
3367
|
+
/**
|
|
3368
|
+
* Chain-specific locators for the token.
|
|
3369
|
+
* Keys are chain identifiers, values are the token address/locator on that chain.
|
|
3370
|
+
* Not all chains need to be present - tokens may only exist on a subset of chains.
|
|
3371
|
+
*/
|
|
3372
|
+
readonly locators: Partial<ChainLocatorMap>;
|
|
3373
|
+
/**
|
|
3374
|
+
* Optional per-chain decimal overrides.
|
|
3375
|
+
*
|
|
3376
|
+
* Some tokens have different decimal places on different chains
|
|
3377
|
+
* (e.g., USDe is 18 decimals on EVM but 9 decimals on Solana).
|
|
3378
|
+
* When present, the value for a specific chain takes precedence
|
|
3379
|
+
* over the default {@link decimals}.
|
|
3380
|
+
*/
|
|
3381
|
+
readonly chainDecimals?: Partial<Record<ChainIdentifier, number>>;
|
|
3382
|
+
}
|
|
3383
|
+
/**
|
|
3384
|
+
* A raw token locator selector with explicit decimals.
|
|
3385
|
+
*
|
|
3386
|
+
* @remarks
|
|
3387
|
+
* Use this form when working with arbitrary tokens not in the registry.
|
|
3388
|
+
* The `locator` is the chain-specific address, and `decimals` is required
|
|
3389
|
+
* unless using lenient mode.
|
|
3390
|
+
*
|
|
3391
|
+
* @example
|
|
3392
|
+
* ```typescript
|
|
3393
|
+
* // Selecting a custom token by address
|
|
3394
|
+
* const selector: RawTokenSelector = {
|
|
3395
|
+
* locator: '0x1234567890abcdef1234567890abcdef12345678',
|
|
3396
|
+
* decimals: 18,
|
|
3397
|
+
* }
|
|
3398
|
+
* ```
|
|
3399
|
+
*/
|
|
3400
|
+
interface RawTokenSelector {
|
|
3401
|
+
/**
|
|
3402
|
+
* The chain-specific token locator (address, program ID, etc.).
|
|
3403
|
+
*/
|
|
3404
|
+
readonly locator: string;
|
|
3405
|
+
/**
|
|
3406
|
+
* The number of decimal places.
|
|
3407
|
+
* Required in strict mode, optional in lenient mode.
|
|
3408
|
+
*/
|
|
3409
|
+
readonly decimals?: number;
|
|
3410
|
+
}
|
|
3411
|
+
/**
|
|
3412
|
+
* Registry for known token symbols (augmentation target).
|
|
3413
|
+
*
|
|
3414
|
+
* @remarks
|
|
3415
|
+
* This empty interface exists solely for module augmentation. Extend it to
|
|
3416
|
+
* register token symbols for type-safe selection.
|
|
3417
|
+
*
|
|
3418
|
+
* **Why an interface?** TypeScript only allows module augmentation on
|
|
3419
|
+
* interfaces, not type aliases.
|
|
3420
|
+
*
|
|
3421
|
+
* **Usage**
|
|
3422
|
+
*
|
|
3423
|
+
* Without augmentation, `TokenSymbol` defaults to `string`.
|
|
3424
|
+
*
|
|
3425
|
+
* ```typescript
|
|
3426
|
+
* declare module '@core/tokens' {
|
|
3427
|
+
* interface TokenSymbolRegistry {
|
|
3428
|
+
* USDC: true
|
|
3429
|
+
* EURC: true
|
|
3430
|
+
* }
|
|
3431
|
+
* }
|
|
3432
|
+
* // Now TokenSymbol includes 'USDC' | 'EURC' | ...
|
|
3433
|
+
* ```
|
|
3434
|
+
*
|
|
3435
|
+
* NOTE: The eslint-disable below suppresses warnings about empty interfaces.
|
|
3436
|
+
* This is intentional—the interface exists solely as an augmentation target.
|
|
3437
|
+
*/
|
|
3438
|
+
interface TokenSymbolRegistry {
|
|
3439
|
+
}
|
|
3440
|
+
/**
|
|
3441
|
+
* Union type of all registered token symbols.
|
|
3442
|
+
*
|
|
3443
|
+
* @remarks
|
|
3444
|
+
* This type is derived from the keys of `TokenSymbolRegistry`:
|
|
3445
|
+
* - **Without augmentation** — Simply `string` (any value)
|
|
3446
|
+
* - **With augmentation** — `'USDC' | 'USDT' | ...` plus any string
|
|
3447
|
+
*
|
|
3448
|
+
* Uses `LiteralUnion` to preserve autocomplete for known values while
|
|
3449
|
+
* still accepting any string at runtime.
|
|
3450
|
+
*
|
|
3451
|
+
* @example
|
|
3452
|
+
* ```typescript
|
|
3453
|
+
* // With symbols.augment imported - autocomplete works
|
|
3454
|
+
* const symbol: TokenSymbol = 'USDC'
|
|
3455
|
+
*
|
|
3456
|
+
* // Custom strings still accepted
|
|
3457
|
+
* const symbol: TokenSymbol = 'MY_TOKEN'
|
|
3458
|
+
* ```
|
|
3459
|
+
*/
|
|
3460
|
+
type TokenSymbol = keyof TokenSymbolRegistry extends never ? string : LiteralUnion<Extract<keyof TokenSymbolRegistry, string>>;
|
|
3461
|
+
/**
|
|
3462
|
+
* Selector for identifying a token.
|
|
3463
|
+
*
|
|
3464
|
+
* @remarks
|
|
3465
|
+
* Can be one of:
|
|
3466
|
+
* - A symbol string (e.g., "USDC") - resolves from registry
|
|
3467
|
+
* - A raw locator object with explicit decimals - for arbitrary tokens
|
|
3468
|
+
*
|
|
3469
|
+
* Using a symbol is preferred when the token is in the registry, as it
|
|
3470
|
+
* automatically resolves decimals and the correct chain address.
|
|
3471
|
+
*
|
|
3472
|
+
* @example
|
|
3473
|
+
* ```typescript
|
|
3474
|
+
* // By symbol (preferred for known tokens)
|
|
3475
|
+
* const selector1: TokenSelector = 'USDC'
|
|
3476
|
+
*
|
|
3477
|
+
* // By raw locator (for arbitrary tokens)
|
|
3478
|
+
* const selector2: TokenSelector = {
|
|
3479
|
+
* locator: '0x1234...',
|
|
3480
|
+
* decimals: 18,
|
|
3481
|
+
* }
|
|
3482
|
+
* ```
|
|
3483
|
+
*/
|
|
3484
|
+
type TokenSelector = TokenSymbol | RawTokenSelector;
|
|
3485
|
+
/**
|
|
3486
|
+
* The resolved token information after registry lookup.
|
|
3487
|
+
*
|
|
3488
|
+
* @remarks
|
|
3489
|
+
* This is the result of resolving a `TokenSelector` against a chain.
|
|
3490
|
+
* It always contains the locator and decimals, and optionally the symbol
|
|
3491
|
+
* if the token was resolved from the registry.
|
|
3492
|
+
*/
|
|
3493
|
+
interface ResolvedToken {
|
|
3494
|
+
/**
|
|
3495
|
+
* The token symbol, if known.
|
|
3496
|
+
* Present when resolved from registry, absent for raw locators.
|
|
3497
|
+
*/
|
|
3498
|
+
readonly symbol?: string;
|
|
3499
|
+
/**
|
|
3500
|
+
* The number of decimal places for the token.
|
|
3501
|
+
*/
|
|
3502
|
+
readonly decimals: number;
|
|
3503
|
+
/**
|
|
3504
|
+
* The chain-specific token locator (address, program ID, etc.).
|
|
3505
|
+
*/
|
|
3506
|
+
readonly locator: string;
|
|
3507
|
+
}
|
|
3508
|
+
/**
|
|
3509
|
+
* Interface for the token registry.
|
|
3510
|
+
*
|
|
3511
|
+
* @remarks
|
|
3512
|
+
* The registry is the sole source of truth for token information.
|
|
3513
|
+
* It supports both symbol-based and raw locator-based token selection.
|
|
3514
|
+
*
|
|
3515
|
+
* @example
|
|
3516
|
+
* ```typescript
|
|
3517
|
+
* import { createTokenRegistry } from '@core/tokens'
|
|
3518
|
+
*
|
|
3519
|
+
* // Create registry (includes built-in tokens like USDC)
|
|
3520
|
+
* const registry = createTokenRegistry()
|
|
3521
|
+
*
|
|
3522
|
+
* // Resolve by symbol
|
|
3523
|
+
* const usdc = registry.resolve('USDC', 'Ethereum')
|
|
3524
|
+
* console.log(usdc.locator) // '0xa0b86991...'
|
|
3525
|
+
*
|
|
3526
|
+
* // Resolve raw locator
|
|
3527
|
+
* const custom = registry.resolve({ locator: '0x...', decimals: 18 }, 'Ethereum')
|
|
3528
|
+
* ```
|
|
3529
|
+
*/
|
|
3530
|
+
interface TokenRegistry {
|
|
3531
|
+
/**
|
|
3532
|
+
* Resolve a token selector to concrete token information for a chain.
|
|
3533
|
+
*
|
|
3534
|
+
* @param selector - The token to resolve (symbol or raw locator).
|
|
3535
|
+
* @param chainId - The chain identifier to resolve for.
|
|
3536
|
+
* @returns The resolved token information.
|
|
3537
|
+
* @throws When the token cannot be resolved (unknown symbol, missing decimals, etc.).
|
|
3538
|
+
*/
|
|
3539
|
+
resolve(selector: TokenSelector, chainId: ChainIdentifier): ResolvedToken;
|
|
3540
|
+
/**
|
|
3541
|
+
* Resolve a token by chain-specific locator (address/program ID).
|
|
3542
|
+
*
|
|
3543
|
+
* @param address - The token locator to resolve.
|
|
3544
|
+
* @param chainId - The chain identifier to resolve for.
|
|
3545
|
+
* @returns The resolved token information.
|
|
3546
|
+
* @throws When no registry token matches the locator on the chain.
|
|
3547
|
+
*/
|
|
3548
|
+
resolveByAddress(address: string, chainId: ChainIdentifier): ResolvedToken;
|
|
3549
|
+
/**
|
|
3550
|
+
* Get a token definition by symbol.
|
|
3551
|
+
*
|
|
3552
|
+
* @param symbol - The token symbol (e.g., "USDC").
|
|
3553
|
+
* @returns The token definition, or undefined if not found.
|
|
3554
|
+
*/
|
|
3555
|
+
get(symbol: string): TokenDefinition | undefined;
|
|
3556
|
+
/**
|
|
3557
|
+
* Check if a symbol is registered.
|
|
3558
|
+
*
|
|
3559
|
+
* @param symbol - The token symbol to check.
|
|
3560
|
+
* @returns True if the symbol is in the registry.
|
|
3561
|
+
*/
|
|
3562
|
+
has(symbol: string): boolean;
|
|
3563
|
+
/**
|
|
3564
|
+
* Get all registered token symbols.
|
|
3565
|
+
*
|
|
3566
|
+
* @returns An array of registered symbol strings.
|
|
3567
|
+
*/
|
|
3568
|
+
symbols(): string[];
|
|
3569
|
+
/**
|
|
3570
|
+
* Get all registered token definitions.
|
|
3571
|
+
*
|
|
3572
|
+
* @returns An array of all TokenDefinition objects in the registry.
|
|
3573
|
+
*/
|
|
3574
|
+
entries(): TokenDefinition[];
|
|
3575
|
+
}
|
|
3576
|
+
|
|
3577
|
+
/**
|
|
3578
|
+
* Structured fields that can be attached to log entries.
|
|
3579
|
+
*/
|
|
3580
|
+
type LogFields = Record<string, unknown>;
|
|
3581
|
+
/**
|
|
3582
|
+
* Logger interface providing structured logging with child scoping.
|
|
3583
|
+
*
|
|
3584
|
+
* @remarks
|
|
3585
|
+
* This interface defines a minimal, framework-agnostic logging contract.
|
|
3586
|
+
* The underlying implementation uses pino for transport handling (console,
|
|
3587
|
+
* file, remote, JSON, pretty, etc.) but consumers only interact with this
|
|
3588
|
+
* stable interface.
|
|
3589
|
+
*
|
|
3590
|
+
* @example
|
|
3591
|
+
* ```typescript
|
|
3592
|
+
* import { createLogger } from '@core/runtime'
|
|
3593
|
+
*
|
|
3594
|
+
* const logger = createLogger({ level: 'debug' })
|
|
3595
|
+
*
|
|
3596
|
+
* // Simple message
|
|
3597
|
+
* logger.info('Server started')
|
|
3598
|
+
*
|
|
3599
|
+
* // Message with structured fields
|
|
3600
|
+
* logger.info('Request received', { method: 'POST', path: '/api/transfer' })
|
|
3601
|
+
*
|
|
3602
|
+
* // Create child logger with context
|
|
3603
|
+
* const requestLogger = logger.child({ requestId: 'abc-123' })
|
|
3604
|
+
* requestLogger.debug('Processing transfer')
|
|
3605
|
+
* // Output includes: requestId in all subsequent logs
|
|
3606
|
+
* ```
|
|
3607
|
+
*/
|
|
3608
|
+
interface Logger {
|
|
3609
|
+
/**
|
|
3610
|
+
* Log a debug-level message.
|
|
3611
|
+
* @param message - The log message.
|
|
3612
|
+
* @param fields - Optional structured fields.
|
|
3613
|
+
* @returns void
|
|
3614
|
+
*/
|
|
3615
|
+
debug(message: string, fields?: LogFields): void;
|
|
3616
|
+
/**
|
|
3617
|
+
* Log an info-level message.
|
|
3618
|
+
* @param message - The log message.
|
|
3619
|
+
* @param fields - Optional structured fields.
|
|
3620
|
+
* @returns void
|
|
3621
|
+
*/
|
|
3622
|
+
info(message: string, fields?: LogFields): void;
|
|
3623
|
+
/**
|
|
3624
|
+
* Log a warning-level message.
|
|
3625
|
+
* @param message - The log message.
|
|
3626
|
+
* @param fields - Optional structured fields.
|
|
3627
|
+
* @returns void
|
|
3628
|
+
*/
|
|
3629
|
+
warn(message: string, fields?: LogFields): void;
|
|
3630
|
+
/**
|
|
3631
|
+
* Log an error-level message.
|
|
3632
|
+
* @param message - The log message.
|
|
3633
|
+
* @param fields - Optional structured fields.
|
|
3634
|
+
* @returns void
|
|
3635
|
+
*/
|
|
3636
|
+
error(message: string, fields?: LogFields): void;
|
|
3637
|
+
/**
|
|
3638
|
+
* Create a child logger with additional contextual bindings.
|
|
3639
|
+
*
|
|
3640
|
+
* @param tags - Key-value pairs to add to the child logger's context.
|
|
3641
|
+
* Undefined values are filtered out automatically.
|
|
3642
|
+
* @returns A new Logger instance with merged bindings.
|
|
3643
|
+
*
|
|
3644
|
+
* @example
|
|
3645
|
+
* ```typescript
|
|
3646
|
+
* const requestLogger = logger.child({ requestId: 'req-123' })
|
|
3647
|
+
* const userLogger = requestLogger.child({ userId: 'user-456' })
|
|
3648
|
+
* // All logs from userLogger include both requestId and userId
|
|
3649
|
+
* ```
|
|
3650
|
+
*/
|
|
3651
|
+
child(tags: LogFields): Logger;
|
|
3652
|
+
}
|
|
3653
|
+
|
|
3654
|
+
/**
|
|
3655
|
+
* Handler function for event subscriptions.
|
|
3656
|
+
*/
|
|
3657
|
+
type EventHandler = (event: Event) => void | Promise<void>;
|
|
3658
|
+
/**
|
|
3659
|
+
* Event bus for publishing and subscribing to events.
|
|
3660
|
+
*
|
|
3661
|
+
* @remarks
|
|
3662
|
+
* Supports wildcard topic subscriptions:
|
|
3663
|
+
* - `*` matches exactly one segment
|
|
3664
|
+
* - `**` matches zero or more segments
|
|
3665
|
+
*
|
|
3666
|
+
* @example
|
|
3667
|
+
* ```typescript
|
|
3668
|
+
* const bus = createEventBus()
|
|
3669
|
+
*
|
|
3670
|
+
* // Subscribe to all events
|
|
3671
|
+
* bus.on((event) => console.log(event))
|
|
3672
|
+
*
|
|
3673
|
+
* // Subscribe to specific topic
|
|
3674
|
+
* bus.on('tx.wait.started', (event) => console.log(event))
|
|
3675
|
+
*
|
|
3676
|
+
* // Subscribe with wildcard
|
|
3677
|
+
* bus.on('tx.wait.*', (event) => console.log(event))
|
|
3678
|
+
* bus.on('tx.**', (event) => console.log(event))
|
|
3679
|
+
*
|
|
3680
|
+
* // Emit events
|
|
3681
|
+
* bus.emit({ name: 'tx.wait.started', data: { txId: '0x123' } })
|
|
3682
|
+
* ```
|
|
3683
|
+
*/
|
|
3684
|
+
interface EventBus {
|
|
3685
|
+
/**
|
|
3686
|
+
* Emit an event to all matching subscribers.
|
|
3687
|
+
*
|
|
3688
|
+
* @param event - The event to emit.
|
|
3689
|
+
* @remarks
|
|
3690
|
+
* Synchronous and never throws. Handler errors are isolated.
|
|
3691
|
+
*/
|
|
3692
|
+
emit(event: Event): void;
|
|
3693
|
+
/**
|
|
3694
|
+
* Create a child event bus with scoped tags.
|
|
3695
|
+
*
|
|
3696
|
+
* @param tags - Tags to merge into all emitted events.
|
|
3697
|
+
* @returns A new EventBus with merged tags.
|
|
3698
|
+
*/
|
|
3699
|
+
child(tags: Tags): EventBus;
|
|
3700
|
+
/**
|
|
3701
|
+
* Subscribe to all events.
|
|
3702
|
+
*
|
|
3703
|
+
* @param handler - Function called for every event.
|
|
3704
|
+
* @returns Unsubscribe function.
|
|
3705
|
+
*/
|
|
3706
|
+
on(handler: EventHandler): () => void;
|
|
3707
|
+
/**
|
|
3708
|
+
* Subscribe to events matching a pattern.
|
|
3709
|
+
*
|
|
3710
|
+
* @param pattern - Topic pattern (supports `*` and `**` wildcards).
|
|
3711
|
+
* @param handler - Function called for matching events.
|
|
3712
|
+
* @returns Unsubscribe function.
|
|
3713
|
+
*
|
|
3714
|
+
* @remarks
|
|
3715
|
+
* Wildcard semantics:
|
|
3716
|
+
* - `*` matches exactly one segment (no dots)
|
|
3717
|
+
* - `**` matches zero or more segments (only valid at end)
|
|
3718
|
+
*
|
|
3719
|
+
* @example
|
|
3720
|
+
* ```typescript
|
|
3721
|
+
* bus.on('*', handler) // matches 'tx', 'user' (single segment only)
|
|
3722
|
+
* bus.on('tx.wait.*', handler) // matches tx.wait.started, tx.wait.failed
|
|
3723
|
+
* bus.on('tx.wait.**', handler) // matches tx.wait, tx.wait.started, tx.wait.foo.bar
|
|
3724
|
+
* bus.on('**', handler) // matches all events
|
|
3725
|
+
* ```
|
|
3726
|
+
*/
|
|
3727
|
+
on(pattern: string, handler: EventHandler): () => void;
|
|
3728
|
+
}
|
|
3729
|
+
|
|
3730
|
+
/**
|
|
3731
|
+
* Metrics type definitions for the Runtime module.
|
|
3732
|
+
*
|
|
3733
|
+
* @remarks
|
|
3734
|
+
* Define a minimal, pluggable metrics interface that can be backed by any
|
|
3735
|
+
* metrics library (hot-shots, dd-trace, prom-client, etc.).
|
|
3736
|
+
*
|
|
3737
|
+
* The interface supports:
|
|
3738
|
+
* - Counters for monotonically increasing values
|
|
3739
|
+
* - Histograms for distributions (latencies, sizes)
|
|
3740
|
+
* - Timers as a convenience wrapper for timing operations
|
|
3741
|
+
* - Label scoping via `child()` for dimensional metrics
|
|
3742
|
+
*
|
|
3743
|
+
* @example
|
|
3744
|
+
* ```typescript
|
|
3745
|
+
* // Basic usage
|
|
3746
|
+
* metrics.counter('requests.total').inc({ method: 'POST' })
|
|
3747
|
+
* metrics.histogram('request.duration').observe({ status: 200 }, 42.5)
|
|
3748
|
+
*
|
|
3749
|
+
* // Timer convenience
|
|
3750
|
+
* const stop = metrics.timer('db.query').start({ table: 'users' })
|
|
3751
|
+
* await query()
|
|
3752
|
+
* stop() // Records duration automatically
|
|
3753
|
+
*
|
|
3754
|
+
* // Scoping adds base labels to all metrics
|
|
3755
|
+
* const scoped = metrics.child({ service: 'bridge', env: 'prod' })
|
|
3756
|
+
* scoped.counter('transfers').inc() // Includes service + env labels
|
|
3757
|
+
* ```
|
|
3758
|
+
*/
|
|
3759
|
+
/**
|
|
3760
|
+
* Labels for dimensional metrics.
|
|
3761
|
+
*
|
|
3762
|
+
* @remarks
|
|
3763
|
+
* Labels (also called tags in some systems) are key-value pairs that
|
|
3764
|
+
* provide dimensions for metric aggregation and filtering.
|
|
3765
|
+
* Values must be primitives for serialization compatibility.
|
|
3766
|
+
*
|
|
3767
|
+
* @example
|
|
3768
|
+
* ```typescript
|
|
3769
|
+
* const labels: MetricLabels = {
|
|
3770
|
+
* chain: 'Ethereum',
|
|
3771
|
+
* status: 'success',
|
|
3772
|
+
* retries: 3,
|
|
3773
|
+
* cached: true,
|
|
3774
|
+
* }
|
|
3775
|
+
* ```
|
|
3776
|
+
*/
|
|
3777
|
+
type MetricLabels = Record<string, string | number | boolean>;
|
|
3778
|
+
/**
|
|
3779
|
+
* A counter metric for monotonically increasing values.
|
|
3780
|
+
*
|
|
3781
|
+
* @remarks
|
|
3782
|
+
* Use counters for values that only go up: request counts, error counts,
|
|
3783
|
+
* bytes processed, etc. The value resets only on process restart.
|
|
3784
|
+
*
|
|
3785
|
+
* @see {@link Metrics.counter} to obtain a Counter instance.
|
|
3786
|
+
*
|
|
3787
|
+
* @example
|
|
3788
|
+
* ```typescript
|
|
3789
|
+
* const counter = metrics.counter('http.requests')
|
|
3790
|
+
*
|
|
3791
|
+
* // Increment by 1
|
|
3792
|
+
* counter.inc()
|
|
3793
|
+
* counter.inc({ method: 'GET' })
|
|
3794
|
+
*
|
|
3795
|
+
* // Increment by specific value
|
|
3796
|
+
* counter.inc(5)
|
|
3797
|
+
* counter.inc({ method: 'POST' }, 3)
|
|
3798
|
+
* ```
|
|
3799
|
+
*/
|
|
3800
|
+
interface Counter {
|
|
3801
|
+
/**
|
|
3802
|
+
* Increment the counter value.
|
|
3803
|
+
*
|
|
3804
|
+
* @param labelsOrValue - The labels object or increment value.
|
|
3805
|
+
* When a number, increments by that amount with no labels.
|
|
3806
|
+
* When an object, uses as labels with optional value in second param.
|
|
3807
|
+
* @param value - The increment value when first arg is labels. Default: 1.
|
|
3808
|
+
* @returns void
|
|
3809
|
+
*
|
|
3810
|
+
* @example
|
|
3811
|
+
* ```typescript
|
|
3812
|
+
* counter.inc() // +1, no labels
|
|
3813
|
+
* counter.inc(5) // +5, no labels
|
|
3814
|
+
* counter.inc({ method: 'GET' }) // +1, with labels
|
|
3815
|
+
* counter.inc({ method: 'POST' }, 3) // +3, with labels
|
|
3816
|
+
* ```
|
|
3817
|
+
*/
|
|
3818
|
+
inc(labelsOrValue?: MetricLabels | number, value?: number): void;
|
|
3819
|
+
}
|
|
3820
|
+
/**
|
|
3821
|
+
* A histogram metric for recording value distributions.
|
|
3822
|
+
*
|
|
3823
|
+
* @remarks
|
|
3824
|
+
* Use histograms for values that vary and need percentile analysis:
|
|
3825
|
+
* request durations, response sizes, queue depths, etc.
|
|
3826
|
+
*
|
|
3827
|
+
* @see {@link Metrics.histogram} to obtain a Histogram instance.
|
|
3828
|
+
*
|
|
3829
|
+
* @example
|
|
3830
|
+
* ```typescript
|
|
3831
|
+
* const histogram = metrics.histogram('http.duration')
|
|
3832
|
+
*
|
|
3833
|
+
* // Record a value
|
|
3834
|
+
* histogram.observe(42.5)
|
|
3835
|
+
* histogram.observe({ status: 200 }, 42.5)
|
|
3836
|
+
* ```
|
|
3837
|
+
*/
|
|
3838
|
+
interface Histogram {
|
|
3839
|
+
/**
|
|
3840
|
+
* Record an observation value.
|
|
3841
|
+
*
|
|
3842
|
+
* @param labelsOrValue - The labels object or observed value.
|
|
3843
|
+
* When a number, records that value with no labels.
|
|
3844
|
+
* When an object, uses as labels with value in second param.
|
|
3845
|
+
* @param value - The observed value when first arg is labels. Default: 0.
|
|
3846
|
+
* @returns void
|
|
3847
|
+
*
|
|
3848
|
+
* @example
|
|
3849
|
+
* ```typescript
|
|
3850
|
+
* histogram.observe(42.5) // Value only
|
|
3851
|
+
* histogram.observe({ status: 200 }, 42.5) // With labels
|
|
3852
|
+
* ```
|
|
3853
|
+
*/
|
|
3854
|
+
observe(labelsOrValue?: MetricLabels | number, value?: number): void;
|
|
3855
|
+
}
|
|
3856
|
+
/**
|
|
3857
|
+
* A timer metric for measuring operation durations.
|
|
3858
|
+
*
|
|
3859
|
+
* @remarks
|
|
3860
|
+
* Timers provide a convenience wrapper that automatically records durations
|
|
3861
|
+
* to an underlying histogram. Call `start()` to begin timing and the
|
|
3862
|
+
* returned function to stop and record the elapsed time in milliseconds.
|
|
3863
|
+
*
|
|
3864
|
+
* @see {@link Metrics.timer} to obtain a Timer instance.
|
|
3865
|
+
*
|
|
3866
|
+
* @example
|
|
3867
|
+
* ```typescript
|
|
3868
|
+
* const timer = metrics.timer('db.query')
|
|
3869
|
+
*
|
|
3870
|
+
* // Start timing
|
|
3871
|
+
* const stop = timer.start({ table: 'users' })
|
|
3872
|
+
* await performQuery()
|
|
3873
|
+
* stop() // Records duration in milliseconds
|
|
3874
|
+
* ```
|
|
3875
|
+
*/
|
|
3876
|
+
interface Timer {
|
|
3877
|
+
/**
|
|
3878
|
+
* Start timing an operation.
|
|
3879
|
+
*
|
|
3880
|
+
* @param labels - The optional labels for the timing observation.
|
|
3881
|
+
* @returns A stop function that records the duration when called.
|
|
3882
|
+
*
|
|
3883
|
+
* @example
|
|
3884
|
+
* ```typescript
|
|
3885
|
+
* const stop = timer.start({ operation: 'fetch' })
|
|
3886
|
+
* await fetchData()
|
|
3887
|
+
* stop() // Records elapsed time
|
|
3888
|
+
* ```
|
|
3889
|
+
*/
|
|
3890
|
+
start(labels?: MetricLabels): () => void;
|
|
3891
|
+
}
|
|
3892
|
+
/**
|
|
3893
|
+
* Main metrics interface for instrumentation.
|
|
3894
|
+
*
|
|
3895
|
+
* @remarks
|
|
3896
|
+
* This interface is designed to be thin and pluggable. Implementations
|
|
3897
|
+
* can delegate to any metrics library:
|
|
3898
|
+
*
|
|
3899
|
+
* - **hot-shots**: StatsD/DogStatsD client
|
|
3900
|
+
* - **dd-trace**: Datadog APM
|
|
3901
|
+
* - **prom-client**: Prometheus
|
|
3902
|
+
* - **opentelemetry-js**: OpenTelemetry
|
|
3903
|
+
*
|
|
3904
|
+
* The `child()` method creates a scoped metrics instance that automatically
|
|
3905
|
+
* includes base labels on all metric operations.
|
|
3906
|
+
*
|
|
3907
|
+
* @see {@link createMockMetrics} for testing.
|
|
3908
|
+
* @see {@link noopMetrics} for a no-op implementation.
|
|
3909
|
+
*
|
|
3910
|
+
* @example
|
|
3911
|
+
* ```typescript
|
|
3912
|
+
* // Create a scoped metrics instance
|
|
3913
|
+
* const appMetrics = metrics.child({
|
|
3914
|
+
* service: 'app-kit',
|
|
3915
|
+
* version: '1.0.0',
|
|
3916
|
+
* })
|
|
3917
|
+
*
|
|
3918
|
+
* // All metrics include service + version labels
|
|
3919
|
+
* appMetrics.counter('transfers.initiated').inc({ chain: 'ethereum' })
|
|
2341
3920
|
* ```
|
|
2342
3921
|
*/
|
|
2343
|
-
|
|
2344
|
-
private readonly handlers;
|
|
2345
|
-
private readonly wildcard;
|
|
3922
|
+
interface Metrics {
|
|
2346
3923
|
/**
|
|
2347
|
-
*
|
|
3924
|
+
* Get or create a counter metric by name.
|
|
2348
3925
|
*
|
|
2349
|
-
* @param
|
|
2350
|
-
* @
|
|
3926
|
+
* @param name - The metric name (e.g., 'http.requests.total').
|
|
3927
|
+
* @returns A Counter instance for the given name.
|
|
2351
3928
|
*
|
|
2352
3929
|
* @example
|
|
2353
3930
|
* ```typescript
|
|
2354
|
-
* const
|
|
2355
|
-
*
|
|
2356
|
-
* events.on('dataReceived', (data) => {
|
|
2357
|
-
* console.log(`Received: ${data}`);
|
|
2358
|
-
* });
|
|
3931
|
+
* const counter = metrics.counter('requests.total')
|
|
3932
|
+
* counter.inc({ method: 'GET' })
|
|
2359
3933
|
* ```
|
|
2360
3934
|
*/
|
|
2361
|
-
|
|
3935
|
+
counter(name: string): Counter;
|
|
2362
3936
|
/**
|
|
2363
|
-
*
|
|
3937
|
+
* Get or create a histogram metric by name.
|
|
2364
3938
|
*
|
|
2365
|
-
* @param
|
|
2366
|
-
* @
|
|
3939
|
+
* @param name - The metric name (e.g., 'http.request.duration').
|
|
3940
|
+
* @returns A Histogram instance for the given name.
|
|
2367
3941
|
*
|
|
2368
3942
|
* @example
|
|
2369
3943
|
* ```typescript
|
|
2370
|
-
* const
|
|
2371
|
-
*
|
|
2372
|
-
* events.on('*', (payload) => {
|
|
2373
|
-
* console.log('Action occurred:', payload);
|
|
2374
|
-
* });
|
|
3944
|
+
* const histogram = metrics.histogram('request.duration')
|
|
3945
|
+
* histogram.observe({ status: 200 }, 42.5)
|
|
2375
3946
|
* ```
|
|
2376
3947
|
*/
|
|
2377
|
-
|
|
3948
|
+
histogram(name: string): Histogram;
|
|
2378
3949
|
/**
|
|
2379
|
-
*
|
|
3950
|
+
* Get or create a timer metric by name.
|
|
2380
3951
|
*
|
|
2381
|
-
* @param
|
|
2382
|
-
* @
|
|
3952
|
+
* @param name - The metric name (e.g., 'db.query.duration').
|
|
3953
|
+
* @returns A Timer instance for the given name.
|
|
2383
3954
|
*
|
|
2384
3955
|
* @example
|
|
2385
3956
|
* ```typescript
|
|
2386
|
-
* const
|
|
2387
|
-
*
|
|
2388
|
-
*
|
|
2389
|
-
* events.on('dataReceived', handler);
|
|
2390
|
-
*
|
|
2391
|
-
* // Later, to remove the handler:
|
|
2392
|
-
* events.off('dataReceived', handler);
|
|
3957
|
+
* const stop = metrics.timer('db.query').start()
|
|
3958
|
+
* await query()
|
|
3959
|
+
* stop()
|
|
2393
3960
|
* ```
|
|
2394
3961
|
*/
|
|
2395
|
-
|
|
3962
|
+
timer(name: string): Timer;
|
|
2396
3963
|
/**
|
|
2397
|
-
*
|
|
3964
|
+
* Create a child metrics instance with scoped labels.
|
|
2398
3965
|
*
|
|
2399
|
-
* @param
|
|
2400
|
-
* @
|
|
3966
|
+
* @param labels - The base labels to include on all metric operations.
|
|
3967
|
+
* @returns A new Metrics instance with merged labels.
|
|
3968
|
+
*
|
|
3969
|
+
* @remarks
|
|
3970
|
+
* Labels from the child are merged with any labels passed to individual
|
|
3971
|
+
* metric operations. Call-site labels take precedence for the same key.
|
|
2401
3972
|
*
|
|
2402
3973
|
* @example
|
|
2403
3974
|
* ```typescript
|
|
2404
|
-
* const
|
|
3975
|
+
* const scoped = metrics.child({ chain: 'Ethereum' })
|
|
3976
|
+
* scoped.counter('transfers').inc({ status: 'success' })
|
|
3977
|
+
* // Labels: { chain: 'Ethereum', status: 'success' }
|
|
3978
|
+
* ```
|
|
3979
|
+
*/
|
|
3980
|
+
child(labels: MetricLabels): Metrics;
|
|
3981
|
+
}
|
|
3982
|
+
|
|
3983
|
+
/**
|
|
3984
|
+
* Core type definitions for the runtime package.
|
|
3985
|
+
*
|
|
3986
|
+
* @remarks
|
|
3987
|
+
* This module defines the foundational types used throughout the SDK:
|
|
3988
|
+
*
|
|
3989
|
+
* - {@link Runtime} - Complete runtime with all services (clock, logger, metrics, events)
|
|
3990
|
+
* - {@link ExecutionContext} - Context for middleware with observability surface
|
|
3991
|
+
* - {@link Clock}, {@link Tags}, {@link Event} - Supporting types
|
|
3992
|
+
*
|
|
3993
|
+
* **Naming Convention**
|
|
3994
|
+
*
|
|
3995
|
+
* | Input Type | Resolved Type | Description |
|
|
3996
|
+
* |------------|---------------|-------------|
|
|
3997
|
+
* | `Partial<Runtime>` | `Runtime` | Runtime services |
|
|
3998
|
+
* | `OperationMeta` | `OperationContext` | WHAT - operation target |
|
|
3999
|
+
* | `InvocationMeta` | `InvocationContext` | WHO/HOW - call chain |
|
|
4000
|
+
*
|
|
4001
|
+
* @packageDocumentation
|
|
4002
|
+
*/
|
|
4003
|
+
|
|
4004
|
+
/**
|
|
4005
|
+
* Clock interface for time operations.
|
|
4006
|
+
*
|
|
4007
|
+
* @remarks
|
|
4008
|
+
* Abstracting time allows tests to control timing without real delays.
|
|
4009
|
+
* Production code uses {@link defaultClock}, tests use mock implementations.
|
|
4010
|
+
*
|
|
4011
|
+
* @example
|
|
4012
|
+
* ```typescript
|
|
4013
|
+
* import { defaultClock, type Clock } from '@core/runtime'
|
|
4014
|
+
*
|
|
4015
|
+
* const start = defaultClock.now()
|
|
4016
|
+
* // ... do work ...
|
|
4017
|
+
* const elapsed = defaultClock.since(start)
|
|
4018
|
+
* ```
|
|
4019
|
+
*/
|
|
4020
|
+
interface Clock {
|
|
4021
|
+
/**
|
|
4022
|
+
* Return the current timestamp in milliseconds since Unix epoch.
|
|
2405
4023
|
*
|
|
2406
|
-
*
|
|
2407
|
-
|
|
4024
|
+
* @returns Current time in milliseconds.
|
|
4025
|
+
*/
|
|
4026
|
+
now(): number;
|
|
4027
|
+
/**
|
|
4028
|
+
* Calculate elapsed time since a given timestamp.
|
|
2408
4029
|
*
|
|
2409
|
-
*
|
|
2410
|
-
*
|
|
2411
|
-
* ```
|
|
4030
|
+
* @param start - The start timestamp in milliseconds.
|
|
4031
|
+
* @returns Elapsed time in milliseconds (`now() - start`).
|
|
2412
4032
|
*/
|
|
2413
|
-
|
|
4033
|
+
since: (start: number) => number;
|
|
4034
|
+
}
|
|
4035
|
+
/**
|
|
4036
|
+
* Contextual metadata tags for logging and metrics.
|
|
4037
|
+
*
|
|
4038
|
+
* @remarks
|
|
4039
|
+
* Tags are key-value pairs attached to log entries and metrics.
|
|
4040
|
+
* Values can be primitives or undefined (undefined values are filtered out).
|
|
4041
|
+
*
|
|
4042
|
+
* Common tags include:
|
|
4043
|
+
* - `opId` - Operation identifier for correlation
|
|
4044
|
+
* - `chain` - Blockchain network name
|
|
4045
|
+
* - `phase` - Current pipeline phase
|
|
4046
|
+
*
|
|
4047
|
+
* @example
|
|
4048
|
+
* ```typescript
|
|
4049
|
+
* import type { Tags } from '@core/runtime'
|
|
4050
|
+
*
|
|
4051
|
+
* const tags: Tags = {
|
|
4052
|
+
* opId: 'op-abc123',
|
|
4053
|
+
* chain: 'Ethereum',
|
|
4054
|
+
* phase: 'validate',
|
|
4055
|
+
* optional: undefined, // Will be filtered out
|
|
4056
|
+
* }
|
|
4057
|
+
* ```
|
|
4058
|
+
*/
|
|
4059
|
+
type Tags = Record<string, string | number | boolean | undefined>;
|
|
4060
|
+
/**
|
|
4061
|
+
* A structured event emitted by the runtime.
|
|
4062
|
+
*
|
|
4063
|
+
* @remarks
|
|
4064
|
+
* Events provide a standardized way to capture lifecycle moments,
|
|
4065
|
+
* actions, and state changes throughout the SDK.
|
|
4066
|
+
*/
|
|
4067
|
+
interface Event {
|
|
4068
|
+
/** The event name/identifier. */
|
|
4069
|
+
name: string;
|
|
4070
|
+
/** Log level for the event. */
|
|
4071
|
+
level?: 'debug' | 'info' | 'warn' | 'error';
|
|
4072
|
+
/** Timestamp (epoch ms) when the event occurred. */
|
|
4073
|
+
at?: number;
|
|
4074
|
+
/** Contextual tags for filtering/categorization. */
|
|
4075
|
+
tags?: Tags;
|
|
4076
|
+
/** Arbitrary payload data associated with the event. */
|
|
4077
|
+
data?: unknown;
|
|
4078
|
+
}
|
|
4079
|
+
/**
|
|
4080
|
+
* Complete runtime with all services guaranteed present.
|
|
4081
|
+
*
|
|
4082
|
+
* @remarks
|
|
4083
|
+
* The runtime is the container for all cross-cutting concerns: logging,
|
|
4084
|
+
* timing, events, and metrics. All services are guaranteed to be available.
|
|
4085
|
+
*
|
|
4086
|
+
* **Creating a Runtime**
|
|
4087
|
+
*
|
|
4088
|
+
* Use {@link createRuntime} to create a fully-configured runtime:
|
|
4089
|
+
* ```typescript
|
|
4090
|
+
* import { createRuntime } from '@core/runtime'
|
|
4091
|
+
*
|
|
4092
|
+
* const runtime = createRuntime()
|
|
4093
|
+
* runtime.logger.info('Hello')
|
|
4094
|
+
* runtime.metrics.counter('requests').inc()
|
|
4095
|
+
* ```
|
|
4096
|
+
*
|
|
4097
|
+
* **Partial Runtime Input**
|
|
4098
|
+
*
|
|
4099
|
+
* When accepting runtime configuration as input, use `Partial<Runtime>`:
|
|
4100
|
+
* ```typescript
|
|
4101
|
+
* function myFunction(options: { runtime?: Partial<Runtime> }) {
|
|
4102
|
+
* const runtime = createRuntime(options.runtime)
|
|
4103
|
+
* // ...
|
|
4104
|
+
* }
|
|
4105
|
+
* ```
|
|
4106
|
+
*
|
|
4107
|
+
* @example
|
|
4108
|
+
* ```typescript
|
|
4109
|
+
* import { createRuntime, type Runtime } from '@core/runtime'
|
|
4110
|
+
*
|
|
4111
|
+
* const runtime: Runtime = createRuntime()
|
|
4112
|
+
*
|
|
4113
|
+
* // All services are guaranteed present
|
|
4114
|
+
* runtime.logger.info('Processing request')
|
|
4115
|
+
* runtime.metrics.counter('requests').inc()
|
|
4116
|
+
* runtime.events.emit({ name: 'request.received' })
|
|
4117
|
+
* const now = runtime.clock.now()
|
|
4118
|
+
* ```
|
|
4119
|
+
*/
|
|
4120
|
+
interface Runtime {
|
|
2414
4121
|
/**
|
|
2415
|
-
*
|
|
4122
|
+
* Clock for time operations.
|
|
2416
4123
|
*
|
|
2417
|
-
*
|
|
2418
|
-
*
|
|
2419
|
-
*
|
|
4124
|
+
* @remarks
|
|
4125
|
+
* Provides the current timestamp. Use {@link defaultClock} for production
|
|
4126
|
+
* or custom clocks for deterministic testing.
|
|
4127
|
+
*/
|
|
4128
|
+
clock: Clock;
|
|
4129
|
+
/**
|
|
4130
|
+
* Logger for structured logging.
|
|
2420
4131
|
*
|
|
2421
|
-
* @
|
|
2422
|
-
*
|
|
4132
|
+
* @remarks
|
|
4133
|
+
* Provides debug, info, warn, error methods with structured data support.
|
|
4134
|
+
*/
|
|
4135
|
+
logger: Logger;
|
|
4136
|
+
/**
|
|
4137
|
+
* Metrics collector for observability.
|
|
2423
4138
|
*
|
|
2424
|
-
* @
|
|
2425
|
-
*
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
*
|
|
4139
|
+
* @remarks
|
|
4140
|
+
* Provides counters, histograms, and timers for application metrics.
|
|
4141
|
+
*/
|
|
4142
|
+
metrics: Metrics;
|
|
4143
|
+
/**
|
|
4144
|
+
* Event bus for pub/sub events.
|
|
2430
4145
|
*
|
|
2431
|
-
*
|
|
4146
|
+
* @remarks
|
|
4147
|
+
* Enables decoupled event emission and subscription across the SDK.
|
|
4148
|
+
*/
|
|
4149
|
+
events: EventBus;
|
|
4150
|
+
}
|
|
4151
|
+
/**
|
|
4152
|
+
* A component in the call chain.
|
|
4153
|
+
*
|
|
4154
|
+
* @remarks
|
|
4155
|
+
* Each caller identifies itself with a type (app, kit, provider, adapter)
|
|
4156
|
+
* and a name/version. This enables proper attribution in logs, metrics, and traces.
|
|
4157
|
+
*
|
|
4158
|
+
* @example
|
|
4159
|
+
* ```typescript
|
|
4160
|
+
* import type { Caller } from '@core/runtime'
|
|
4161
|
+
*
|
|
4162
|
+
* const appCaller: Caller = { type: 'app', name: 'MyDApp', version: '1.0.0' }
|
|
4163
|
+
* const kitCaller: Caller = { type: 'kit', name: 'BridgeKit', version: '2.0.0' }
|
|
4164
|
+
* ```
|
|
4165
|
+
*/
|
|
4166
|
+
interface Caller {
|
|
4167
|
+
/**
|
|
4168
|
+
* Type of component in the call hierarchy.
|
|
2432
4169
|
*
|
|
2433
|
-
*
|
|
2434
|
-
*
|
|
2435
|
-
* amount: '100',
|
|
2436
|
-
* destination: '0xABC123'
|
|
2437
|
-
* });
|
|
2438
|
-
* ```
|
|
4170
|
+
* @remarks
|
|
4171
|
+
* Common types: `app`, `kit`, `provider`, `adapter`
|
|
2439
4172
|
*/
|
|
2440
|
-
|
|
4173
|
+
readonly type: string;
|
|
4174
|
+
/** Name of the component (e.g., 'BridgeKit', 'cctp-v2'). */
|
|
4175
|
+
readonly name: string;
|
|
4176
|
+
/** Version of the component (e.g., '1.0.0'). */
|
|
4177
|
+
readonly version?: string | undefined;
|
|
4178
|
+
}
|
|
4179
|
+
/**
|
|
4180
|
+
* User input for invocation metadata.
|
|
4181
|
+
*
|
|
4182
|
+
* @remarks
|
|
4183
|
+
* Defines **WHO** called and **HOW** to observe: trace correlation, runtime override,
|
|
4184
|
+
* and caller chain. This is the user-facing input type, resolved to `InvocationContext`.
|
|
4185
|
+
*
|
|
4186
|
+
* Passed as the optional invocation argument to actions and primitives.
|
|
4187
|
+
*
|
|
4188
|
+
* @example
|
|
4189
|
+
* ```typescript
|
|
4190
|
+
* import type { InvocationMeta } from '@core/runtime'
|
|
4191
|
+
*
|
|
4192
|
+
* // Minimal - just traceId
|
|
4193
|
+
* const meta: InvocationMeta = { traceId: 'abc-123' }
|
|
4194
|
+
*
|
|
4195
|
+
* // Full - with runtime override and caller chain
|
|
4196
|
+
* const meta: InvocationMeta = {
|
|
4197
|
+
* traceId: 'abc-123',
|
|
4198
|
+
* runtime: myRuntime,
|
|
4199
|
+
* callers: [
|
|
4200
|
+
* { type: 'app', name: 'MyDApp', version: '1.0.0' },
|
|
4201
|
+
* ],
|
|
4202
|
+
* }
|
|
4203
|
+
* ```
|
|
4204
|
+
*/
|
|
4205
|
+
interface InvocationMeta {
|
|
4206
|
+
/**
|
|
4207
|
+
* Trace ID for distributed tracing correlation.
|
|
4208
|
+
*
|
|
4209
|
+
* @remarks
|
|
4210
|
+
* If not provided, generated automatically.
|
|
4211
|
+
*/
|
|
4212
|
+
readonly traceId?: string | undefined;
|
|
4213
|
+
/**
|
|
4214
|
+
* Runtime override (complete replacement).
|
|
4215
|
+
*
|
|
4216
|
+
* @remarks
|
|
4217
|
+
* When provided, this runtime completely replaces the default runtime.
|
|
4218
|
+
* Must be a complete Runtime instance (e.g., from `createRuntime()`).
|
|
4219
|
+
* If not provided, the default runtime is used.
|
|
4220
|
+
*/
|
|
4221
|
+
readonly runtime?: Runtime | undefined;
|
|
4222
|
+
/**
|
|
4223
|
+
* Token registry override (complete replacement).
|
|
4224
|
+
*
|
|
4225
|
+
* @remarks
|
|
4226
|
+
* When provided, this registry completely replaces the default token registry.
|
|
4227
|
+
* Enables kits to pass their token registry to adapters.
|
|
4228
|
+
* If not provided, the default token registry is used.
|
|
4229
|
+
*/
|
|
4230
|
+
readonly tokens?: TokenRegistry | undefined;
|
|
4231
|
+
/**
|
|
4232
|
+
* Call chain - each caller appends itself.
|
|
4233
|
+
*
|
|
4234
|
+
* @remarks
|
|
4235
|
+
* Ordered from outermost (first) to innermost (last).
|
|
4236
|
+
* Example: [app, kit, provider]
|
|
4237
|
+
*/
|
|
4238
|
+
readonly callers?: readonly Caller[] | undefined;
|
|
2441
4239
|
}
|
|
2442
4240
|
|
|
2443
4241
|
/**
|
|
@@ -2569,6 +4367,14 @@ TChainDefinition extends ChainDefinition = ChainDefinition> {
|
|
|
2569
4367
|
token: 'USDC';
|
|
2570
4368
|
/** Bridge configuration (e.g., fast burn settings) */
|
|
2571
4369
|
config: BridgeConfig;
|
|
4370
|
+
/**
|
|
4371
|
+
* Optional invocation metadata for tracing and correlation.
|
|
4372
|
+
*
|
|
4373
|
+
* When provided, the `traceId` is used to correlate all events emitted during
|
|
4374
|
+
* the bridge operation. If not provided, an OpenTelemetry-compatible traceId
|
|
4375
|
+
* will be auto-generated.
|
|
4376
|
+
*/
|
|
4377
|
+
invocationMeta?: InvocationMeta;
|
|
2572
4378
|
}
|
|
2573
4379
|
/**
|
|
2574
4380
|
* A step in the bridge process.
|
|
@@ -2598,6 +4404,15 @@ interface BridgeStep {
|
|
|
2598
4404
|
explorerUrl?: string;
|
|
2599
4405
|
/** Optional data for the step */
|
|
2600
4406
|
data?: unknown;
|
|
4407
|
+
/**
|
|
4408
|
+
* Whether this step was executed via Circle's Forwarder (relay service).
|
|
4409
|
+
* Only applicable for mint steps.
|
|
4410
|
+
*
|
|
4411
|
+
* - `true`: The mint was handled by Circle's Orbit relayer
|
|
4412
|
+
* - `false`: The user submitted the mint transaction directly
|
|
4413
|
+
* - `undefined`: Not applicable (non-mint steps)
|
|
4414
|
+
*/
|
|
4415
|
+
forwarded?: boolean;
|
|
2601
4416
|
/** Optional human-readable error message */
|
|
2602
4417
|
errorMessage?: string;
|
|
2603
4418
|
/** Optional raw error object (can be Viem/Ethers/Chain error) */
|
|
@@ -2649,6 +4464,13 @@ interface BridgeResult {
|
|
|
2649
4464
|
* result for retry operations to maintain consistency with the original burn.
|
|
2650
4465
|
*/
|
|
2651
4466
|
recipientAddress?: string;
|
|
4467
|
+
/**
|
|
4468
|
+
* Whether Circle's Forwarder was used for this bridge operation.
|
|
4469
|
+
*
|
|
4470
|
+
* When true, the mint transaction was handled by Circle's Orbit relayer
|
|
4471
|
+
* instead of requiring the user to submit it manually.
|
|
4472
|
+
*/
|
|
4473
|
+
useForwarder?: boolean;
|
|
2652
4474
|
};
|
|
2653
4475
|
/** Array of steps that were executed during the bridge process */
|
|
2654
4476
|
steps: BridgeStep[];
|
|
@@ -2706,8 +4528,8 @@ interface EstimateResult {
|
|
|
2706
4528
|
}[];
|
|
2707
4529
|
/** Array of protocol and service fees for the transfer */
|
|
2708
4530
|
fees: {
|
|
2709
|
-
/** The type of fee -
|
|
2710
|
-
type: 'kit' | 'provider';
|
|
4531
|
+
/** The type of fee - from the bridge kit, provider (CCTP), or forwarder (Circle Orbit relayer) */
|
|
4532
|
+
type: 'kit' | 'provider' | 'forwarder';
|
|
2711
4533
|
/** The token in which the fee is charged (currently only USDC) */
|
|
2712
4534
|
token: 'USDC';
|
|
2713
4535
|
/** The fee amount (as a string to avoid precision issues) */
|
|
@@ -2857,19 +4679,38 @@ interface CustomFee {
|
|
|
2857
4679
|
* have access to both the source and destination chain information needed for
|
|
2858
4680
|
* validation and execution.
|
|
2859
4681
|
*
|
|
4682
|
+
* The destination adapter (`to`) is optional to support forwarder-only destinations
|
|
4683
|
+
* where Circle's Orbit relayer handles the mint transaction without requiring a
|
|
4684
|
+
* destination adapter. When `to` is undefined, the retry operation relies on
|
|
4685
|
+
* IRIS API confirmation instead of on-chain transaction confirmation.
|
|
4686
|
+
*
|
|
2860
4687
|
* @example
|
|
2861
4688
|
* ```typescript
|
|
4689
|
+
* // Standard retry with both adapters
|
|
2862
4690
|
* const retryContext: RetryContext = {
|
|
2863
|
-
* from:
|
|
2864
|
-
* to:
|
|
4691
|
+
* from: sourceAdapter,
|
|
4692
|
+
* to: destAdapter
|
|
4693
|
+
* }
|
|
4694
|
+
*
|
|
4695
|
+
* // Forwarder-only retry (no destination adapter)
|
|
4696
|
+
* const forwarderRetryContext: RetryContext = {
|
|
4697
|
+
* from: sourceAdapter,
|
|
4698
|
+
* to: undefined // Forwarder handles mint
|
|
2865
4699
|
* }
|
|
2866
4700
|
* ```
|
|
2867
4701
|
*/
|
|
2868
4702
|
interface RetryContext<TFromAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities, TToAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities> {
|
|
2869
4703
|
/** The source adapter context for the retry operation */
|
|
2870
4704
|
from: Adapter<TFromAdapterCapabilities>;
|
|
2871
|
-
/**
|
|
2872
|
-
|
|
4705
|
+
/**
|
|
4706
|
+
* The destination adapter context for the retry operation.
|
|
4707
|
+
*
|
|
4708
|
+
* Optional for forwarder-only destinations where Circle's Orbit relayer
|
|
4709
|
+
* handles the mint transaction. When undefined, the retry operation relies
|
|
4710
|
+
* on IRIS API confirmation (`forwardState === 'CONFIRMED'`) instead of
|
|
4711
|
+
* on-chain transaction confirmation via the adapter.
|
|
4712
|
+
*/
|
|
4713
|
+
to?: Adapter<TToAdapterCapabilities>;
|
|
2873
4714
|
}
|
|
2874
4715
|
/**
|
|
2875
4716
|
* Result of analyzing bridge steps to determine retry feasibility and continuation point.
|
|
@@ -2966,6 +4807,7 @@ declare abstract class BridgingProvider<TProviderActions = Record<string, unknow
|
|
|
2966
4807
|
* @param source - The source chain definition
|
|
2967
4808
|
* @param destination - The destination chain definition
|
|
2968
4809
|
* @param token - The token to transfer (currently only USDC is supported)
|
|
4810
|
+
* @param useForwarder - When `true`, also checks that the route supports forwarding
|
|
2969
4811
|
* @returns `true` if the provider supports this route, `false` otherwise
|
|
2970
4812
|
*
|
|
2971
4813
|
* @example
|
|
@@ -2977,7 +4819,7 @@ declare abstract class BridgingProvider<TProviderActions = Record<string, unknow
|
|
|
2977
4819
|
* }
|
|
2978
4820
|
* ```
|
|
2979
4821
|
*/
|
|
2980
|
-
abstract supportsRoute(source: ChainDefinition, destination: ChainDefinition, token: 'USDC'): boolean;
|
|
4822
|
+
abstract supportsRoute(source: ChainDefinition, destination: ChainDefinition, token: 'USDC', useForwarder?: boolean): boolean;
|
|
2981
4823
|
/**
|
|
2982
4824
|
* Executes a cross-chain bridge operation between the specified source and destination chains.
|
|
2983
4825
|
*
|
|
@@ -3098,6 +4940,8 @@ declare abstract class BridgingProvider<TProviderActions = Record<string, unknow
|
|
|
3098
4940
|
*
|
|
3099
4941
|
* @param result - The failed bridge result to retry
|
|
3100
4942
|
* @param context - The retry context containing source and destination adapter contexts
|
|
4943
|
+
* @param invocationMeta - Optional invocation metadata for tracing and correlation.
|
|
4944
|
+
* When provided, enables custom traceId, runtime overrides, and caller chain tracking.
|
|
3101
4945
|
* @returns Promise resolving to the retry bridge result
|
|
3102
4946
|
* @throws {Error} If retry is not supported by this provider
|
|
3103
4947
|
*
|
|
@@ -3113,7 +4957,7 @@ declare abstract class BridgingProvider<TProviderActions = Record<string, unknow
|
|
|
3113
4957
|
* }
|
|
3114
4958
|
* ```
|
|
3115
4959
|
*/
|
|
3116
|
-
retry<TFromAdapterCapabilities extends AdapterCapabilities, TToAdapterCapabilities extends AdapterCapabilities>(result: BridgeResult, context: RetryContext<TFromAdapterCapabilities, TToAdapterCapabilities
|
|
4960
|
+
retry<TFromAdapterCapabilities extends AdapterCapabilities, TToAdapterCapabilities extends AdapterCapabilities>(result: BridgeResult, context: RetryContext<TFromAdapterCapabilities, TToAdapterCapabilities>, invocationMeta?: InvocationMeta): Promise<BridgeResult>;
|
|
3117
4961
|
/**
|
|
3118
4962
|
* Analyzes bridge steps to determine retry feasibility and continuation point.
|
|
3119
4963
|
*
|
|
@@ -3286,6 +5130,21 @@ interface AttestationMessage {
|
|
|
3286
5130
|
* The delay reason if the attestation is delayed.
|
|
3287
5131
|
*/
|
|
3288
5132
|
delayReason?: string | null;
|
|
5133
|
+
/**
|
|
5134
|
+
* Forwarding state from Circle's relayer.
|
|
5135
|
+
* Only present when useForwarder was enabled during burn.
|
|
5136
|
+
* @description
|
|
5137
|
+
* - 'PENDING': Relayer is processing the mint
|
|
5138
|
+
* - 'CONFIRMED': Relayer has submitted the mint tx (waiting for finality)
|
|
5139
|
+
* - 'COMPLETE': Relayer has successfully completed the mint tx with finality
|
|
5140
|
+
* - 'FAILED': Relayer failed to process the mint (user may need manual mint)
|
|
5141
|
+
*/
|
|
5142
|
+
forwardState?: 'PENDING' | 'CONFIRMED' | 'COMPLETE' | 'FAILED' | null;
|
|
5143
|
+
/**
|
|
5144
|
+
* Transaction hash of the mint tx submitted by Circle's relayer.
|
|
5145
|
+
* Only present when forwardState is 'CONFIRMED' or 'COMPLETE'.
|
|
5146
|
+
*/
|
|
5147
|
+
forwardTxHash?: string | null;
|
|
3289
5148
|
}
|
|
3290
5149
|
|
|
3291
5150
|
/**
|
|
@@ -3319,6 +5178,66 @@ type BridgeFetchAttestationStep = BridgeStep &
|
|
|
3319
5178
|
data?: undefined;
|
|
3320
5179
|
});
|
|
3321
5180
|
|
|
5181
|
+
/**
|
|
5182
|
+
* Forwarder-only destination for CCTP v2 transfers without an adapter.
|
|
5183
|
+
*
|
|
5184
|
+
* Used when Circle's Forwarder handles the mint transaction and no destination
|
|
5185
|
+
* adapter is available. Requires both `useForwarder: true` and a `recipientAddress`.
|
|
5186
|
+
*
|
|
5187
|
+
* When using this destination type:
|
|
5188
|
+
* - The mint step completes when the IRIS API confirms `forwardState === 'CONFIRMED'`
|
|
5189
|
+
* - No on-chain transaction confirmation is performed (no adapter available)
|
|
5190
|
+
* - The mint step's `data` field will be undefined (no transaction receipt)
|
|
5191
|
+
*/
|
|
5192
|
+
interface CCTPV2ForwarderOnlyDestination<TChainDefinition extends ChainDefinitionWithCCTPv2 = ChainDefinitionWithCCTPv2> {
|
|
5193
|
+
/** The destination chain where USDC will be minted */
|
|
5194
|
+
chain: TChainDefinition;
|
|
5195
|
+
/** The recipient address that will receive the minted USDC */
|
|
5196
|
+
recipientAddress: string;
|
|
5197
|
+
/** Must be true for forwarder-only destinations */
|
|
5198
|
+
useForwarder: true;
|
|
5199
|
+
/** The resolved address (same as recipientAddress for forwarder-only) */
|
|
5200
|
+
address?: string;
|
|
5201
|
+
}
|
|
5202
|
+
/**
|
|
5203
|
+
* Destination context for CCTP v2 transfers with optional forwarder support.
|
|
5204
|
+
*
|
|
5205
|
+
* Supports two modes:
|
|
5206
|
+
* 1. **With adapter**: Standard destination where user or forwarder submits mint transaction.
|
|
5207
|
+
* The adapter is used for chain validation and transaction confirmation.
|
|
5208
|
+
* 2. **Forwarder-only**: No adapter provided. Circle's Orbit relayer handles the mint
|
|
5209
|
+
* and confirmation is based on IRIS API response only.
|
|
5210
|
+
*
|
|
5211
|
+
* @example
|
|
5212
|
+
* ```typescript
|
|
5213
|
+
* // With adapter (standard or forwarder-assisted)
|
|
5214
|
+
* const dest1: CCTPV2DestinationContext = {
|
|
5215
|
+
* adapter,
|
|
5216
|
+
* chain: BaseSepolia,
|
|
5217
|
+
* address: '0x...',
|
|
5218
|
+
* useForwarder: true // optional
|
|
5219
|
+
* }
|
|
5220
|
+
*
|
|
5221
|
+
* // Forwarder-only (no adapter)
|
|
5222
|
+
* const dest2: CCTPV2DestinationContext = {
|
|
5223
|
+
* chain: BaseSepolia,
|
|
5224
|
+
* recipientAddress: '0x...',
|
|
5225
|
+
* useForwarder: true
|
|
5226
|
+
* }
|
|
5227
|
+
* ```
|
|
5228
|
+
*/
|
|
5229
|
+
type CCTPV2DestinationContext<TAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities, TChainDefinition extends ChainDefinitionWithCCTPv2 = ChainDefinitionWithCCTPv2> = (DestinationWalletContext<TAdapterCapabilities, TChainDefinition> & {
|
|
5230
|
+
/**
|
|
5231
|
+
* Enable Circle's Forwarder to handle the mint transaction.
|
|
5232
|
+
*
|
|
5233
|
+
* When true, Circle's Orbit relayer will fetch the attestation and submit
|
|
5234
|
+
* the mint transaction on the user's behalf. The relay fee is deducted from
|
|
5235
|
+
* the minted USDC at mint time.
|
|
5236
|
+
*
|
|
5237
|
+
* @defaultValue false
|
|
5238
|
+
*/
|
|
5239
|
+
useForwarder?: boolean;
|
|
5240
|
+
}) | CCTPV2ForwarderOnlyDestination<TChainDefinition>;
|
|
3322
5241
|
/**
|
|
3323
5242
|
* CCTPv2 bridge parameters.
|
|
3324
5243
|
*
|
|
@@ -3332,31 +5251,56 @@ type CCTPV2BridgeParams<TFromAdapterCapabilities extends AdapterCapabilities = A
|
|
|
3332
5251
|
*/
|
|
3333
5252
|
source: WalletContext<TFromAdapterCapabilities, ChainDefinitionWithCCTPv2>;
|
|
3334
5253
|
/**
|
|
3335
|
-
* The destination wallet context containing the chain definition
|
|
5254
|
+
* The destination wallet context containing the chain definition, wallet address,
|
|
5255
|
+
* and optional forwarder configuration.
|
|
3336
5256
|
*/
|
|
3337
|
-
destination:
|
|
5257
|
+
destination: CCTPV2DestinationContext<TToAdapterCapabilities>;
|
|
3338
5258
|
/**
|
|
3339
5259
|
* The bridge configuration for the CCTPv2 transfer.
|
|
3340
5260
|
*/
|
|
3341
5261
|
config: BridgeConfig;
|
|
3342
5262
|
};
|
|
5263
|
+
/**
|
|
5264
|
+
* Base payload structure for CCTP v2 action events.
|
|
5265
|
+
*
|
|
5266
|
+
* @remarks
|
|
5267
|
+
* All CCTP v2 actions share these common fields for protocol identification
|
|
5268
|
+
* and tracing support.
|
|
5269
|
+
*/
|
|
5270
|
+
interface CCTPV2ActionBase {
|
|
5271
|
+
/** The protocol identifier */
|
|
5272
|
+
protocol: 'cctp';
|
|
5273
|
+
/** The protocol version */
|
|
5274
|
+
version: 'v2';
|
|
5275
|
+
/**
|
|
5276
|
+
* Optional trace ID for end-to-end correlation.
|
|
5277
|
+
*
|
|
5278
|
+
* When provided, this ID links all events in a single bridge operation, enabling
|
|
5279
|
+
* integration with distributed tracing systems (OpenTelemetry, Datadog, etc.).
|
|
5280
|
+
*
|
|
5281
|
+
* Format: 32-character hex string or custom string (user-provided via invocation context).
|
|
5282
|
+
*/
|
|
5283
|
+
traceId?: string;
|
|
5284
|
+
}
|
|
3343
5285
|
/**
|
|
3344
5286
|
* Action types supported by the CCTP v2 provider.
|
|
3345
5287
|
*
|
|
3346
5288
|
* @remarks
|
|
3347
5289
|
* This interface defines the structure of actions that can be dispatched during
|
|
3348
|
-
* CCTP v2 transfer operations. Each action includes protocol metadata
|
|
3349
|
-
* `values` field containing the full bridge step
|
|
5290
|
+
* CCTP v2 transfer operations. Each action includes protocol metadata, an optional
|
|
5291
|
+
* `traceId` for correlation, and a `values` field containing the full bridge step
|
|
5292
|
+
* with transaction details.
|
|
3350
5293
|
*
|
|
3351
5294
|
* All transaction-based steps (approve, burn, mint) include `txHash` and
|
|
3352
5295
|
* `explorerUrl` fields for direct links to block explorers.
|
|
3353
5296
|
*
|
|
3354
5297
|
* @example
|
|
3355
5298
|
* ```typescript
|
|
3356
|
-
* // Action structure received by event listeners
|
|
5299
|
+
* // Action structure received by event listeners (with traceId)
|
|
3357
5300
|
* const burnAction: CCTPV2Actions['burn'] = {
|
|
3358
5301
|
* protocol: 'cctp',
|
|
3359
5302
|
* version: 'v2',
|
|
5303
|
+
* traceId: '550e8400-e29b-41d4-a716-446655440000', // optional
|
|
3360
5304
|
* method: 'burn',
|
|
3361
5305
|
* values: {
|
|
3362
5306
|
* name: 'burn',
|
|
@@ -3373,9 +5317,7 @@ interface CCTPV2Actions {
|
|
|
3373
5317
|
* Approval action for CCTP v2 transfers.
|
|
3374
5318
|
* Used to approve token spending before initiating a burn operation.
|
|
3375
5319
|
*/
|
|
3376
|
-
approve: {
|
|
3377
|
-
protocol: 'cctp';
|
|
3378
|
-
version: 'v2';
|
|
5320
|
+
approve: CCTPV2ActionBase & {
|
|
3379
5321
|
method: 'approve';
|
|
3380
5322
|
values: BridgeStep;
|
|
3381
5323
|
};
|
|
@@ -3383,9 +5325,7 @@ interface CCTPV2Actions {
|
|
|
3383
5325
|
* Burn action for CCTP v2 transfers.
|
|
3384
5326
|
* Used to burn tokens on the source chain to initiate a cross-chain transfer.
|
|
3385
5327
|
*/
|
|
3386
|
-
burn: {
|
|
3387
|
-
protocol: 'cctp';
|
|
3388
|
-
version: 'v2';
|
|
5328
|
+
burn: CCTPV2ActionBase & {
|
|
3389
5329
|
method: 'burn';
|
|
3390
5330
|
values: BridgeStep;
|
|
3391
5331
|
};
|
|
@@ -3393,9 +5333,7 @@ interface CCTPV2Actions {
|
|
|
3393
5333
|
* Attestation action for CCTP v2 transfers.
|
|
3394
5334
|
* Used to fetch the attestation message for the source wallet.
|
|
3395
5335
|
*/
|
|
3396
|
-
fetchAttestation: {
|
|
3397
|
-
protocol: 'cctp';
|
|
3398
|
-
version: 'v2';
|
|
5336
|
+
fetchAttestation: CCTPV2ActionBase & {
|
|
3399
5337
|
method: 'fetchAttestation';
|
|
3400
5338
|
values: BridgeFetchAttestationStep;
|
|
3401
5339
|
};
|
|
@@ -3403,9 +5341,7 @@ interface CCTPV2Actions {
|
|
|
3403
5341
|
* Mint action for CCTP v2 transfers.
|
|
3404
5342
|
* Used to mint tokens on the destination chain after a successful burn.
|
|
3405
5343
|
*/
|
|
3406
|
-
mint: {
|
|
3407
|
-
protocol: 'cctp';
|
|
3408
|
-
version: 'v2';
|
|
5344
|
+
mint: CCTPV2ActionBase & {
|
|
3409
5345
|
method: 'mint';
|
|
3410
5346
|
values: BridgeStep;
|
|
3411
5347
|
};
|
|
@@ -3413,9 +5349,7 @@ interface CCTPV2Actions {
|
|
|
3413
5349
|
* Re-attestation action for CCTP v2 transfers.
|
|
3414
5350
|
* Used to request a fresh attestation when the original has expired.
|
|
3415
5351
|
*/
|
|
3416
|
-
reAttest: {
|
|
3417
|
-
protocol: 'cctp';
|
|
3418
|
-
version: 'v2';
|
|
5352
|
+
reAttest: CCTPV2ActionBase & {
|
|
3419
5353
|
method: 'reAttest';
|
|
3420
5354
|
values: BridgeFetchAttestationStep;
|
|
3421
5355
|
};
|
|
@@ -3607,7 +5541,7 @@ declare class CCTPV2BridgingProvider extends BridgingProvider<CCTPV2Actions> imp
|
|
|
3607
5541
|
* const retryResult = await provider.retry(failedResult, retryContext)
|
|
3608
5542
|
* ```
|
|
3609
5543
|
*/
|
|
3610
|
-
retry<TFromAdapterCapabilities extends AdapterCapabilities, TToAdapterCapabilities extends AdapterCapabilities>(result: BridgeResult, context: RetryContext<TFromAdapterCapabilities, TToAdapterCapabilities
|
|
5544
|
+
retry<TFromAdapterCapabilities extends AdapterCapabilities, TToAdapterCapabilities extends AdapterCapabilities>(result: BridgeResult, context: RetryContext<TFromAdapterCapabilities, TToAdapterCapabilities>, invocationMeta?: InvocationMeta): Promise<BridgeResult>;
|
|
3611
5545
|
/**
|
|
3612
5546
|
* Estimate the cost and fees for a CCTP v2 cross-chain bridge operation.
|
|
3613
5547
|
*
|
|
@@ -3616,7 +5550,9 @@ declare class CCTPV2BridgingProvider extends BridgingProvider<CCTPV2Actions> imp
|
|
|
3616
5550
|
* chains, as well as any applicable protocol fees.
|
|
3617
5551
|
*
|
|
3618
5552
|
* @param params - The bridge parameters containing source, destination, amount, and optional config.
|
|
5553
|
+
* Supports optional `invocation` for tracing and correlation.
|
|
3619
5554
|
* @returns Promise resolving to detailed cost breakdown including:
|
|
5555
|
+
* - `traceId`: Correlation ID from invocation context (if provided)
|
|
3620
5556
|
* - `gasFees`: Array of gas estimates for each step (Approve, Burn, Mint)
|
|
3621
5557
|
* - Gas amounts in native token smallest units (wei for ETH, lamports for SOL, etc.)
|
|
3622
5558
|
* - `fees`: Array of protocol and kit fees
|
|
@@ -3627,16 +5563,29 @@ declare class CCTPV2BridgingProvider extends BridgingProvider<CCTPV2Actions> imp
|
|
|
3627
5563
|
*
|
|
3628
5564
|
* @example
|
|
3629
5565
|
* ```typescript
|
|
5566
|
+
* import {
|
|
5567
|
+
* resolveInvocationContext,
|
|
5568
|
+
* createRuntime,
|
|
5569
|
+
* } from '\@core/runtime'
|
|
5570
|
+
* import { createTokenRegistry } from '\@core/tokens'
|
|
5571
|
+
*
|
|
5572
|
+
* const defaults = {
|
|
5573
|
+
* runtime: createRuntime(),
|
|
5574
|
+
* tokens: createTokenRegistry(),
|
|
5575
|
+
* }
|
|
5576
|
+
*
|
|
3630
5577
|
* const estimate = await provider.estimate({
|
|
3631
5578
|
* source: { adapter: sourceAdapter, chain: 'Ethereum' },
|
|
3632
5579
|
* destination: { adapter: destAdapter, chain: 'Base' },
|
|
3633
5580
|
* amount: '10.50',
|
|
3634
|
-
* token: 'USDC'
|
|
5581
|
+
* token: 'USDC',
|
|
5582
|
+
* invocationMeta: {
|
|
5583
|
+
* callers: [{ type: 'app', name: 'MyDApp', version: '1.0.0' }],
|
|
5584
|
+
* },
|
|
3635
5585
|
* })
|
|
3636
5586
|
*
|
|
3637
|
-
* console.log('Total
|
|
3638
|
-
* console.log('
|
|
3639
|
-
* console.log('Destination gas:', estimate.destinationGas)
|
|
5587
|
+
* console.log('Total gas fees:', estimate.gasFees.length)
|
|
5588
|
+
* console.log('Protocol fees:', estimate.fees.length)
|
|
3640
5589
|
* ```
|
|
3641
5590
|
*/
|
|
3642
5591
|
estimate<TFromAdapterCapabilities extends AdapterCapabilities, TToAdapterCapabilities extends AdapterCapabilities>(params: CCTPV2BridgeParams<TFromAdapterCapabilities, TToAdapterCapabilities>): Promise<EstimateResult>;
|
|
@@ -3655,7 +5604,8 @@ declare class CCTPV2BridgingProvider extends BridgingProvider<CCTPV2Actions> imp
|
|
|
3655
5604
|
*/
|
|
3656
5605
|
private addGasFeeEstimate;
|
|
3657
5606
|
/**
|
|
3658
|
-
* Helper method to add provider fee estimates to the result.
|
|
5607
|
+
* Helper method to add provider and forwarder fee estimates to the result.
|
|
5608
|
+
* Only adds fee entries when the fee is greater than 0.
|
|
3659
5609
|
*/
|
|
3660
5610
|
private addProviderFeeEstimate;
|
|
3661
5611
|
/**
|
|
@@ -3832,10 +5782,14 @@ declare class CCTPV2BridgingProvider extends BridgingProvider<CCTPV2Actions> imp
|
|
|
3832
5782
|
*
|
|
3833
5783
|
* This method validates that both chains have CCTP v2 contracts deployed and configured.
|
|
3834
5784
|
* It uses the `isCCTPV2Supported` guard function to check each chain individually.
|
|
5785
|
+
* When `useForwarder` is `true`, additionally checks that the source chain supports
|
|
5786
|
+
* forwarding as source and the destination chain supports forwarding as destination.
|
|
3835
5787
|
*
|
|
3836
5788
|
* @param source - The source chain definition to check for CCTP v2 support
|
|
3837
5789
|
* @param destination - The destination chain definition to check for CCTP v2 support
|
|
3838
|
-
* @
|
|
5790
|
+
* @param token - The token to transfer (currently only USDC is supported)
|
|
5791
|
+
* @param useForwarder - When `true`, also checks that the route supports forwarding
|
|
5792
|
+
* @returns `true` if both chains support CCTP v2 (and forwarding if requested), `false` otherwise
|
|
3839
5793
|
*
|
|
3840
5794
|
* @example
|
|
3841
5795
|
* ```typescript
|
|
@@ -3844,19 +5798,30 @@ declare class CCTPV2BridgingProvider extends BridgingProvider<CCTPV2Actions> imp
|
|
|
3844
5798
|
*
|
|
3845
5799
|
* if (canTransfer) {
|
|
3846
5800
|
* console.log('CCTP v2 transfer is supported between these chains')
|
|
3847
|
-
* }
|
|
3848
|
-
*
|
|
5801
|
+
* }
|
|
5802
|
+
*
|
|
5803
|
+
* const canForward = provider.supportsRoute(Ethereum, Base, 'USDC', true)
|
|
5804
|
+
*
|
|
5805
|
+
* if (canForward) {
|
|
5806
|
+
* console.log('CCTP v2 transfer with forwarding is supported')
|
|
3849
5807
|
* }
|
|
3850
5808
|
* ```
|
|
3851
5809
|
*/
|
|
3852
|
-
supportsRoute(source: ChainDefinition, destination: ChainDefinition, token: 'USDC'): boolean;
|
|
5810
|
+
supportsRoute(source: ChainDefinition, destination: ChainDefinition, token: 'USDC', useForwarder?: boolean): boolean;
|
|
3853
5811
|
/**
|
|
3854
5812
|
* Determines the appropriate maximum fee for a cross-chain bridge operation.
|
|
3855
5813
|
*
|
|
3856
|
-
*
|
|
3857
|
-
* and fast bridge burn fee, or uses a provided maxFee if specified.
|
|
5814
|
+
* The fee calculation depends on transfer speed and forwarding settings:
|
|
3858
5815
|
*
|
|
3859
|
-
*
|
|
5816
|
+
* | Transfer Speed | useForwarder | maxFee provided | Behavior |
|
|
5817
|
+
* |----------------|--------------|-----------------|----------|
|
|
5818
|
+
* | SLOW | false | N/A | maxFee = 0 |
|
|
5819
|
+
* | SLOW | true | No | maxFee = forwardingFee |
|
|
5820
|
+
* | SLOW | true | Yes | maxFee = config.maxFee |
|
|
5821
|
+
* | FAST | false | No | maxFee = calculatedBurnFee |
|
|
5822
|
+
* | FAST | false | Yes | maxFee = config.maxFee |
|
|
5823
|
+
* | FAST | true | No | maxFee = calculatedBurnFee + forwardingFee |
|
|
5824
|
+
* | FAST | true | Yes | maxFee = config.maxFee |
|
|
3860
5825
|
*
|
|
3861
5826
|
* @param params - The bridge parameters object containing:
|
|
3862
5827
|
* - `source`: The source wallet context with chain definition and adapter
|
|
@@ -3882,7 +5847,10 @@ declare class CCTPV2BridgingProvider extends BridgingProvider<CCTPV2Actions> imp
|
|
|
3882
5847
|
* console.log('Max fee:', maxFee)
|
|
3883
5848
|
* ```
|
|
3884
5849
|
*/
|
|
3885
|
-
getMaxFee<TFromAdapterCapabilities extends AdapterCapabilities, TToAdapterCapabilities extends AdapterCapabilities>(params: BridgeParams<TFromAdapterCapabilities, TToAdapterCapabilities>): Promise<
|
|
5850
|
+
getMaxFee<TFromAdapterCapabilities extends AdapterCapabilities, TToAdapterCapabilities extends AdapterCapabilities>(params: BridgeParams<TFromAdapterCapabilities, TToAdapterCapabilities>): Promise<{
|
|
5851
|
+
providerFee: bigint;
|
|
5852
|
+
forwarderFee: bigint;
|
|
5853
|
+
}>;
|
|
3886
5854
|
/**
|
|
3887
5855
|
* Prepares a CCTP v2 burn operation to initiate a cross-chain bridge operation.
|
|
3888
5856
|
*
|
|
@@ -3971,6 +5939,29 @@ rawAddress: string,
|
|
|
3971
5939
|
/** The USDC mint address (ignored for EVM chains, required base58 address for Solana) */
|
|
3972
5940
|
mintAddress: string) => Promise<string>;
|
|
3973
5941
|
|
|
5942
|
+
/**
|
|
5943
|
+
* Validates and converts a fee value to bigint.
|
|
5944
|
+
*
|
|
5945
|
+
* This utility performs:
|
|
5946
|
+
* 1. Conversion from string or number to bigint
|
|
5947
|
+
* 2. Validation that the value is non-negative
|
|
5948
|
+
*
|
|
5949
|
+
* @param value - The fee value to validate and convert (string or number)
|
|
5950
|
+
* @param fieldName - The name of the field for error messages
|
|
5951
|
+
* @returns The validated fee as a bigint
|
|
5952
|
+
* @throws {KitError} If the value cannot be converted to bigint or is negative
|
|
5953
|
+
*
|
|
5954
|
+
* @example
|
|
5955
|
+
* ```typescript
|
|
5956
|
+
* const fee = validateAndConvertFee('1000000', 'minimumFee')
|
|
5957
|
+
* console.log(fee) // 1000000n
|
|
5958
|
+
*
|
|
5959
|
+
* const fee2 = validateAndConvertFee(500, 'forwardingFee')
|
|
5960
|
+
* console.log(fee2) // 500n
|
|
5961
|
+
* ```
|
|
5962
|
+
*/
|
|
5963
|
+
declare function validateAndConvertFee(value: number | string, fieldName: string): bigint;
|
|
5964
|
+
|
|
3974
5965
|
/** A block number value that can be provided as bigint, number, or string. */
|
|
3975
5966
|
type BlockNumberInput = bigint | number | string | undefined;
|
|
3976
5967
|
/**
|
|
@@ -4068,5 +6059,5 @@ declare const getBlocksUntilExpiry: (attestation: AttestationMessage, currentBlo
|
|
|
4068
6059
|
*/
|
|
4069
6060
|
declare const isMintFailureRelatedToAttestation: (error: unknown) => boolean;
|
|
4070
6061
|
|
|
4071
|
-
export { CCTPV2BridgingProvider, getBlocksUntilExpiry, getMintRecipientAccount, isAttestationExpired, isMintFailureRelatedToAttestation };
|
|
6062
|
+
export { CCTPV2BridgingProvider, getBlocksUntilExpiry, getMintRecipientAccount, isAttestationExpired, isMintFailureRelatedToAttestation, validateAndConvertFee };
|
|
4072
6063
|
export type { CCTPV2Config };
|