@circle-fin/provider-cctp-v2 1.0.5 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/index.cjs +688 -80
- package/index.d.ts +232 -5
- package/index.mjs +686 -81
- package/package.json +13 -1
package/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright (c)
|
|
2
|
+
* Copyright (c) 2026, Circle Internet Group, Inc. All rights reserved.
|
|
3
3
|
*
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
import { Abi } from 'abitype';
|
|
20
|
-
import { TransactionInstruction, Signer } from '@solana/web3.js';
|
|
20
|
+
import { TransactionInstruction, Signer, AddressLookupTableAccount } from '@solana/web3.js';
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* @packageDocumentation
|
|
@@ -644,14 +644,26 @@ interface SolanaPreparedChainRequestParams {
|
|
|
644
644
|
*/
|
|
645
645
|
instructions: TransactionInstruction[];
|
|
646
646
|
/**
|
|
647
|
-
* Additional signers besides the Adapter
|
|
647
|
+
* Additional signers besides the Adapter's wallet (e.g. program-derived authorities).
|
|
648
648
|
*/
|
|
649
649
|
signers?: Signer[];
|
|
650
650
|
/**
|
|
651
651
|
* Optional override for how many compute units this transaction may consume.
|
|
652
|
-
* If omitted, the network
|
|
652
|
+
* If omitted, the network's default compute budget applies.
|
|
653
653
|
*/
|
|
654
654
|
computeUnitLimit?: number;
|
|
655
|
+
/**
|
|
656
|
+
* Optional Address Lookup Table accounts for transaction compression.
|
|
657
|
+
* Used to reduce transaction size by compressing frequently-used addresses.
|
|
658
|
+
* This is used by @solana/web3.js adapters that have already fetched the ALT data.
|
|
659
|
+
*/
|
|
660
|
+
addressLookupTableAccounts?: AddressLookupTableAccount[];
|
|
661
|
+
/**
|
|
662
|
+
* Optional Address Lookup Table addresses for transaction compression.
|
|
663
|
+
* Used by adapters that need to fetch ALT data themselves (e.g., @solana/kit adapters).
|
|
664
|
+
* These are base58-encoded addresses of ALT accounts to use for compression.
|
|
665
|
+
*/
|
|
666
|
+
addressLookupTableAddresses?: string[];
|
|
655
667
|
}
|
|
656
668
|
/**
|
|
657
669
|
* Solana-specific configuration for transaction estimation.
|
|
@@ -1333,6 +1345,34 @@ interface CCTPActionMap {
|
|
|
1333
1345
|
readonly v2: CCTPv2ActionMap;
|
|
1334
1346
|
}
|
|
1335
1347
|
|
|
1348
|
+
/**
|
|
1349
|
+
* Action map for native token operations (ETH, SOL, MATIC, etc.).
|
|
1350
|
+
*
|
|
1351
|
+
* Native tokens are the primary currency of each blockchain network,
|
|
1352
|
+
* used for paying transaction fees and as a store of value.
|
|
1353
|
+
* These actions operate on the native token without requiring
|
|
1354
|
+
* a separate token contract address.
|
|
1355
|
+
*
|
|
1356
|
+
* @remarks
|
|
1357
|
+
* Native token operations differ from ERC-20/SPL token operations
|
|
1358
|
+
* in that they don't require contract interactions for basic transfers
|
|
1359
|
+
* and balance checks.
|
|
1360
|
+
*
|
|
1361
|
+
* @see {@link ActionMap} for the complete action structure
|
|
1362
|
+
*/
|
|
1363
|
+
interface NativeActionMap {
|
|
1364
|
+
/**
|
|
1365
|
+
* Get the native token balance (SOL, ETH, etc.) for a wallet address.
|
|
1366
|
+
*/
|
|
1367
|
+
balanceOf: ActionParameters & {
|
|
1368
|
+
/**
|
|
1369
|
+
* The address to check the native balance for. If not provided, it will be
|
|
1370
|
+
* automatically derived from the adapter context.
|
|
1371
|
+
*/
|
|
1372
|
+
walletAddress?: string | undefined;
|
|
1373
|
+
};
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1336
1376
|
interface TokenActionMap {
|
|
1337
1377
|
/**
|
|
1338
1378
|
* Set an allowance for a delegate to spend tokens on behalf of the wallet.
|
|
@@ -1564,6 +1604,8 @@ interface USDCActionMap {
|
|
|
1564
1604
|
interface ActionMap {
|
|
1565
1605
|
/** CCTP-specific operations with automatic address resolution. */
|
|
1566
1606
|
readonly cctp: CCTPActionMap;
|
|
1607
|
+
/** Native token operations (ETH, SOL, MATIC, etc.). */
|
|
1608
|
+
readonly native: NativeActionMap;
|
|
1567
1609
|
/** General token operations requiring explicit token addresses. */
|
|
1568
1610
|
readonly token: TokenActionMap;
|
|
1569
1611
|
/** USDC-specific operations with automatic address resolution. */
|
|
@@ -2614,15 +2656,39 @@ interface BridgeResult {
|
|
|
2614
2656
|
*
|
|
2615
2657
|
* This interface provides detailed information about the expected costs
|
|
2616
2658
|
* for a transfer, including gas fees on different chains and protocol fees.
|
|
2659
|
+
* It also includes the input context (token, amount, source, destination) to
|
|
2660
|
+
* provide a complete view of the transfer being estimated.
|
|
2617
2661
|
*
|
|
2618
2662
|
* @example
|
|
2619
2663
|
* ```typescript
|
|
2620
2664
|
* const estimate: EstimateResult = await provider.estimate(source, dest, '100')
|
|
2665
|
+
* console.log('Estimating transfer of', estimate.amount, estimate.token)
|
|
2666
|
+
* console.log('From', estimate.source.chain.name, 'to', estimate.destination.chain.name)
|
|
2621
2667
|
* console.log('Total gas fees:', estimate.gasFees.length)
|
|
2622
2668
|
* console.log('Protocol fees:', estimate.fees.length)
|
|
2623
2669
|
* ```
|
|
2624
2670
|
*/
|
|
2625
2671
|
interface EstimateResult {
|
|
2672
|
+
/** The token being transferred */
|
|
2673
|
+
token: 'USDC';
|
|
2674
|
+
/** The amount being transferred */
|
|
2675
|
+
amount: string;
|
|
2676
|
+
/** Information about the source chain and address */
|
|
2677
|
+
source: {
|
|
2678
|
+
/** The source wallet/contract address */
|
|
2679
|
+
address: string;
|
|
2680
|
+
/** The source blockchain network */
|
|
2681
|
+
chain: Blockchain;
|
|
2682
|
+
};
|
|
2683
|
+
/** Information about the destination chain and address */
|
|
2684
|
+
destination: {
|
|
2685
|
+
/** The destination wallet/contract address */
|
|
2686
|
+
address: string;
|
|
2687
|
+
/** The destination blockchain network */
|
|
2688
|
+
chain: Blockchain;
|
|
2689
|
+
/** Optional custom recipient address for minted funds. */
|
|
2690
|
+
recipientAddress?: string;
|
|
2691
|
+
};
|
|
2626
2692
|
/** Array of gas fees required for the transfer on different blockchains */
|
|
2627
2693
|
gasFees: {
|
|
2628
2694
|
/** The name of the step */
|
|
@@ -3373,6 +3439,20 @@ interface ICCTPV2BridgingProvider extends BridgingProvider<CCTPV2Actions> {
|
|
|
3373
3439
|
* @returns A promise that resolves to the attestation message.
|
|
3374
3440
|
*/
|
|
3375
3441
|
fetchAttestation<TFromAdapterCapabilities extends AdapterCapabilities, TToAdapterCapabilities extends AdapterCapabilities>(source: BridgeParams<TFromAdapterCapabilities, TToAdapterCapabilities>['source'], txHash: string, config?: Partial<ApiPollingConfig>): Promise<AttestationMessage>;
|
|
3442
|
+
/**
|
|
3443
|
+
* Requests a fresh attestation for an expired attestation.
|
|
3444
|
+
*
|
|
3445
|
+
* This method is used when the original attestation has expired before the mint
|
|
3446
|
+
* transaction could be completed. It fetches the existing attestation data to
|
|
3447
|
+
* extract the nonce, requests re-attestation from Circle's API, and then polls
|
|
3448
|
+
* for the fresh attestation.
|
|
3449
|
+
*
|
|
3450
|
+
* @param source - The source wallet context containing the chain definition and wallet address.
|
|
3451
|
+
* @param txHash - The transaction hash of the original burn transaction.
|
|
3452
|
+
* @param config - Optional polling configuration overrides.
|
|
3453
|
+
* @returns A promise that resolves to the fresh attestation message.
|
|
3454
|
+
*/
|
|
3455
|
+
reAttest<TFromAdapterCapabilities extends AdapterCapabilities, TToAdapterCapabilities extends AdapterCapabilities>(source: BridgeParams<TFromAdapterCapabilities, TToAdapterCapabilities>['source'], txHash: string, config?: Partial<ApiPollingConfig>): Promise<AttestationMessage>;
|
|
3376
3456
|
/**
|
|
3377
3457
|
* Mints the amount of tokens for the destination wallet.
|
|
3378
3458
|
*
|
|
@@ -3685,6 +3765,56 @@ declare class CCTPV2BridgingProvider extends BridgingProvider<CCTPV2Actions> imp
|
|
|
3685
3765
|
* ```
|
|
3686
3766
|
*/
|
|
3687
3767
|
fetchAttestation<TFromAdapterCapabilities extends AdapterCapabilities>(source: WalletContext<TFromAdapterCapabilities, ChainDefinitionWithCCTPv2>, transactionHash: string, config?: Partial<ApiPollingConfig>): Promise<AttestationMessage>;
|
|
3768
|
+
/**
|
|
3769
|
+
* Requests a fresh attestation for an expired attestation.
|
|
3770
|
+
*
|
|
3771
|
+
* This method is used when the original attestation has expired before the mint
|
|
3772
|
+
* transaction could be completed. It performs three steps:
|
|
3773
|
+
* 1. Fetches the existing attestation data to extract the nonce
|
|
3774
|
+
* 2. Requests re-attestation from Circle's API using the nonce
|
|
3775
|
+
* 3. Polls for the fresh attestation and returns it
|
|
3776
|
+
*
|
|
3777
|
+
* @typeParam TFromAdapterCapabilities - The type representing the capabilities of the source adapter
|
|
3778
|
+
* @param source - The source wallet context containing the chain definition and wallet address
|
|
3779
|
+
* @param transactionHash - The transaction hash of the original burn transaction
|
|
3780
|
+
* @param config - Optional polling configuration overrides for timeout, retries, and delay
|
|
3781
|
+
* @returns A promise that resolves to the fresh attestation message
|
|
3782
|
+
* @throws {Error} With "Failed to re-attest: No nonce found for transaction" if the original
|
|
3783
|
+
* attestation cannot be found or has no nonce
|
|
3784
|
+
* @throws {Error} With "Failed to re-attest: No attestation found after re-attestation request"
|
|
3785
|
+
* if the fresh attestation cannot be retrieved
|
|
3786
|
+
* @throws {Error} With "Failed to re-attest: {details}" for other errors
|
|
3787
|
+
*
|
|
3788
|
+
* @example
|
|
3789
|
+
* ```typescript
|
|
3790
|
+
* import { CCTPV2BridgingProvider } from '@circle-fin/provider-cctp-v2'
|
|
3791
|
+
* import { Chains } from '@core/chains'
|
|
3792
|
+
*
|
|
3793
|
+
* const provider = new CCTPV2BridgingProvider()
|
|
3794
|
+
*
|
|
3795
|
+
* // After a mint fails due to expired attestation, request a fresh one
|
|
3796
|
+
* const source = {
|
|
3797
|
+
* adapter: viemAdapter,
|
|
3798
|
+
* chain: Chains.EthereumSepolia,
|
|
3799
|
+
* address: '0x1234...'
|
|
3800
|
+
* }
|
|
3801
|
+
*
|
|
3802
|
+
* try {
|
|
3803
|
+
* const freshAttestation = await provider.reAttest(
|
|
3804
|
+
* source,
|
|
3805
|
+
* '0xabc123...', // Original burn transaction hash
|
|
3806
|
+
* { timeout: 10000, maxRetries: 5 }
|
|
3807
|
+
* )
|
|
3808
|
+
*
|
|
3809
|
+
* // Use the fresh attestation to retry the mint
|
|
3810
|
+
* const mintRequest = await provider.mint(source, destination, freshAttestation)
|
|
3811
|
+
* const result = await mintRequest.execute()
|
|
3812
|
+
* } catch (error) {
|
|
3813
|
+
* console.error('Re-attestation failed:', error.message)
|
|
3814
|
+
* }
|
|
3815
|
+
* ```
|
|
3816
|
+
*/
|
|
3817
|
+
reAttest<TFromAdapterCapabilities extends AdapterCapabilities>(source: WalletContext<TFromAdapterCapabilities, ChainDefinitionWithCCTPv2>, transactionHash: string, config?: Partial<ApiPollingConfig>): Promise<AttestationMessage>;
|
|
3688
3818
|
/**
|
|
3689
3819
|
* Checks if both source and destination chains support CCTP v2 transfers.
|
|
3690
3820
|
*
|
|
@@ -3829,5 +3959,102 @@ rawAddress: string,
|
|
|
3829
3959
|
/** The USDC mint address (ignored for EVM chains, required base58 address for Solana) */
|
|
3830
3960
|
mintAddress: string) => Promise<string>;
|
|
3831
3961
|
|
|
3832
|
-
|
|
3962
|
+
/** A block number value that can be provided as bigint, number, or string. */
|
|
3963
|
+
type BlockNumberInput = bigint | number | string | undefined;
|
|
3964
|
+
/**
|
|
3965
|
+
* Determines whether an attestation has expired based on the current block number.
|
|
3966
|
+
*
|
|
3967
|
+
* An attestation expires when the destination chain's current block number is greater
|
|
3968
|
+
* than or equal to the expiration block specified in the attestation message.
|
|
3969
|
+
* Slow transfers and re-attested messages have `expirationBlock: '0'` and never expire.
|
|
3970
|
+
*
|
|
3971
|
+
* @param attestation - The attestation message containing expiration block information
|
|
3972
|
+
* @param currentBlockNumber - The current block number on the destination chain (bigint, number, or string)
|
|
3973
|
+
* @returns `true` if the attestation has expired, `false` if still valid or never expires
|
|
3974
|
+
* @throws KitError If currentBlockNumber or expirationBlock is invalid
|
|
3975
|
+
*
|
|
3976
|
+
* @example
|
|
3977
|
+
* ```typescript
|
|
3978
|
+
* import { isAttestationExpired } from '@circle-fin/cctp-v2-provider'
|
|
3979
|
+
*
|
|
3980
|
+
* // Check if attestation is expired on EVM chain
|
|
3981
|
+
* const publicClient = await adapter.getPublicClient(destinationChain)
|
|
3982
|
+
* const currentBlock = await publicClient.getBlockNumber()
|
|
3983
|
+
* const expired = isAttestationExpired(attestation, currentBlock)
|
|
3984
|
+
*
|
|
3985
|
+
* if (expired) {
|
|
3986
|
+
* const freshAttestation = await provider.reAttest(source, burnTxHash)
|
|
3987
|
+
* }
|
|
3988
|
+
* ```
|
|
3989
|
+
*
|
|
3990
|
+
* @example
|
|
3991
|
+
* ```typescript
|
|
3992
|
+
* // Check on Solana
|
|
3993
|
+
* const slot = await adapter.getConnection(destinationChain).getSlot()
|
|
3994
|
+
* const expired = isAttestationExpired(attestation, slot)
|
|
3995
|
+
* ```
|
|
3996
|
+
*/
|
|
3997
|
+
declare const isAttestationExpired: (attestation: AttestationMessage, currentBlockNumber: BlockNumberInput) => boolean;
|
|
3998
|
+
/**
|
|
3999
|
+
* Calculates the number of blocks remaining until an attestation expires.
|
|
4000
|
+
*
|
|
4001
|
+
* Returns the difference between the expiration block and the current block number.
|
|
4002
|
+
* Returns `null` if the attestation has `expirationBlock: '0'` (never expires).
|
|
4003
|
+
* Returns `0n` or a negative bigint if the attestation has already expired.
|
|
4004
|
+
*
|
|
4005
|
+
* @param attestation - The attestation message containing expiration block information
|
|
4006
|
+
* @param currentBlockNumber - The current block number on the destination chain (bigint, number, or string)
|
|
4007
|
+
* @returns The number of blocks until expiry as a bigint, or `null` if the attestation never expires
|
|
4008
|
+
* @throws KitError If currentBlockNumber or expirationBlock is invalid
|
|
4009
|
+
*
|
|
4010
|
+
* @example
|
|
4011
|
+
* ```typescript
|
|
4012
|
+
* import { getBlocksUntilExpiry } from '@circle-fin/cctp-v2-provider'
|
|
4013
|
+
*
|
|
4014
|
+
* const publicClient = await adapter.getPublicClient(destinationChain)
|
|
4015
|
+
* const currentBlock = await publicClient.getBlockNumber()
|
|
4016
|
+
* const blocksRemaining = getBlocksUntilExpiry(attestation, currentBlock)
|
|
4017
|
+
*
|
|
4018
|
+
* if (blocksRemaining === null) {
|
|
4019
|
+
* console.log('Attestation never expires')
|
|
4020
|
+
* } else if (blocksRemaining <= 0n) {
|
|
4021
|
+
* console.log('Attestation has expired')
|
|
4022
|
+
* } else {
|
|
4023
|
+
* console.log(`${blocksRemaining} blocks until expiry`)
|
|
4024
|
+
* }
|
|
4025
|
+
* ```
|
|
4026
|
+
*/
|
|
4027
|
+
declare const getBlocksUntilExpiry: (attestation: AttestationMessage, currentBlockNumber: BlockNumberInput) => bigint | null;
|
|
4028
|
+
/**
|
|
4029
|
+
* Determines whether a mint failure was caused by an expired attestation.
|
|
4030
|
+
*
|
|
4031
|
+
* This function inspects the error thrown during a mint operation to detect
|
|
4032
|
+
* if the failure is due to the attestation's expiration block being exceeded.
|
|
4033
|
+
* When this returns `true`, the caller should use `reAttest()` to obtain a
|
|
4034
|
+
* fresh attestation before retrying the mint.
|
|
4035
|
+
*
|
|
4036
|
+
* @param error - The error thrown during the mint operation
|
|
4037
|
+
* @returns `true` if the error indicates the attestation has expired, `false` otherwise
|
|
4038
|
+
*
|
|
4039
|
+
* @example
|
|
4040
|
+
* ```typescript
|
|
4041
|
+
* import { isMintFailureRelatedToAttestation } from '@circle-fin/cctp-v2-provider'
|
|
4042
|
+
*
|
|
4043
|
+
* try {
|
|
4044
|
+
* await mintRequest.execute()
|
|
4045
|
+
* } catch (error) {
|
|
4046
|
+
* if (isMintFailureRelatedToAttestation(error)) {
|
|
4047
|
+
* // Attestation expired - get a fresh one
|
|
4048
|
+
* const freshAttestation = await provider.reAttest(source, burnTxHash)
|
|
4049
|
+
* const newMintRequest = await provider.mint(source, destination, freshAttestation)
|
|
4050
|
+
* await newMintRequest.execute()
|
|
4051
|
+
* } else {
|
|
4052
|
+
* throw error
|
|
4053
|
+
* }
|
|
4054
|
+
* }
|
|
4055
|
+
* ```
|
|
4056
|
+
*/
|
|
4057
|
+
declare const isMintFailureRelatedToAttestation: (error: unknown) => boolean;
|
|
4058
|
+
|
|
4059
|
+
export { CCTPV2BridgingProvider, getBlocksUntilExpiry, getMintRecipientAccount, isAttestationExpired, isMintFailureRelatedToAttestation };
|
|
3833
4060
|
export type { CCTPV2Config };
|