@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/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright (c) 2025, Circle Internet Group, Inc. All rights reserved.
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 Adapters wallet (e.g. program-derived authorities).
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 networks default compute budget applies.
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
- export { CCTPV2BridgingProvider, getMintRecipientAccount };
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 };