@circle-fin/bridge-kit 1.1.2 → 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
@@ -400,10 +400,16 @@ type KitContractType = 'bridge';
400
400
  */
401
401
  type KitContracts = Partial<Record<KitContractType, string>>;
402
402
  /**
403
- * Enumeration of all blockchains supported by this library.
403
+ * Enumeration of all blockchains known to this library.
404
+ *
405
+ * This enum contains every blockchain that has a chain definition, regardless
406
+ * of whether bridging is currently supported. For chains that support bridging
407
+ * via CCTPv2, see {@link BridgeChain}.
408
+ *
404
409
  * @enum
405
410
  * @category Enums
406
- * @description Provides string identifiers for each supported blockchain.
411
+ * @description Provides string identifiers for each blockchain with a definition.
412
+ * @see {@link BridgeChain} for the subset of chains that support CCTPv2 bridging.
407
413
  */
408
414
  declare enum Blockchain {
409
415
  Algorand = "Algorand",
@@ -462,6 +468,143 @@ declare enum Blockchain {
462
468
  ZKSync_Era = "ZKSync_Era",
463
469
  ZKSync_Sepolia = "ZKSync_Sepolia"
464
470
  }
471
+ /**
472
+ * Enumeration of blockchains that support cross-chain bridging via CCTPv2.
473
+ *
474
+ * The enum is derived from the full {@link Blockchain} enum but filtered to only
475
+ * include chains with active CCTPv2 support. When new chains gain CCTPv2 support,
476
+ * they are added to this enum.
477
+ *
478
+ * @enum
479
+ * @category Enums
480
+ *
481
+ * @remarks
482
+ * - This enum is the **canonical source** of bridging-supported chains.
483
+ * - Use this enum (or its string literals) in `kit.bridge()` calls for type safety.
484
+ * - Attempting to use a chain not in this enum will produce a TypeScript compile error.
485
+ *
486
+ * @example
487
+ * ```typescript
488
+ * import { BridgeKit, BridgeChain } from '@circle-fin/bridge-kit'
489
+ *
490
+ * const kit = new BridgeKit()
491
+ *
492
+ * // ✅ Valid - autocomplete suggests only supported chains
493
+ * await kit.bridge({
494
+ * from: { adapter, chain: BridgeChain.Ethereum },
495
+ * to: { adapter, chain: BridgeChain.Base },
496
+ * amount: '100'
497
+ * })
498
+ *
499
+ * // ✅ Also valid - string literals work with autocomplete
500
+ * await kit.bridge({
501
+ * from: { adapter, chain: 'Ethereum_Sepolia' },
502
+ * to: { adapter, chain: 'Base_Sepolia' },
503
+ * amount: '100'
504
+ * })
505
+ *
506
+ * // ❌ Compile error - Algorand is not in BridgeChain
507
+ * await kit.bridge({
508
+ * from: { adapter, chain: 'Algorand' }, // TypeScript error!
509
+ * to: { adapter, chain: 'Base' },
510
+ * amount: '100'
511
+ * })
512
+ * ```
513
+ *
514
+ * @see {@link Blockchain} for the complete list of all known blockchains.
515
+ * @see {@link BridgeChainIdentifier} for the type that accepts these values.
516
+ */
517
+ declare enum BridgeChain {
518
+ Arbitrum = "Arbitrum",
519
+ Avalanche = "Avalanche",
520
+ Base = "Base",
521
+ Codex = "Codex",
522
+ Ethereum = "Ethereum",
523
+ HyperEVM = "HyperEVM",
524
+ Ink = "Ink",
525
+ Linea = "Linea",
526
+ Optimism = "Optimism",
527
+ Plume = "Plume",
528
+ Polygon = "Polygon",
529
+ Sei = "Sei",
530
+ Solana = "Solana",
531
+ Sonic = "Sonic",
532
+ Unichain = "Unichain",
533
+ World_Chain = "World_Chain",
534
+ XDC = "XDC",
535
+ Arc_Testnet = "Arc_Testnet",
536
+ Arbitrum_Sepolia = "Arbitrum_Sepolia",
537
+ Avalanche_Fuji = "Avalanche_Fuji",
538
+ Base_Sepolia = "Base_Sepolia",
539
+ Codex_Testnet = "Codex_Testnet",
540
+ Ethereum_Sepolia = "Ethereum_Sepolia",
541
+ HyperEVM_Testnet = "HyperEVM_Testnet",
542
+ Ink_Testnet = "Ink_Testnet",
543
+ Linea_Sepolia = "Linea_Sepolia",
544
+ Optimism_Sepolia = "Optimism_Sepolia",
545
+ Plume_Testnet = "Plume_Testnet",
546
+ Polygon_Amoy_Testnet = "Polygon_Amoy_Testnet",
547
+ Sei_Testnet = "Sei_Testnet",
548
+ Solana_Devnet = "Solana_Devnet",
549
+ Sonic_Testnet = "Sonic_Testnet",
550
+ Unichain_Sepolia = "Unichain_Sepolia",
551
+ World_Chain_Sepolia = "World_Chain_Sepolia",
552
+ XDC_Apothem = "XDC_Apothem"
553
+ }
554
+ /**
555
+ * Type representing valid bridge chain identifiers.
556
+ *
557
+ * This type constrains chain parameters to only accept chains that support CCTPv2 bridging
558
+ *
559
+ * Accepts:
560
+ * - A {@link BridgeChain} enum value (e.g., `BridgeChain.Ethereum`)
561
+ * - A string literal matching a BridgeChain value (e.g., `'Ethereum'`)
562
+ * - A {@link ChainDefinition} object for a supported chain
563
+ *
564
+ * @example
565
+ * ```typescript
566
+ * import type { BridgeChainIdentifier } from '@circle-fin/bridge-kit'
567
+ * import { BridgeChain } from '@circle-fin/bridge-kit'
568
+ * import { Solana } from '@circle-fin/bridge-kit/chains'
569
+ *
570
+ * // All of these are valid BridgeChainIdentifier values:
571
+ * const chain1: BridgeChainIdentifier = BridgeChain.Ethereum
572
+ * const chain2: BridgeChainIdentifier = 'Base_Sepolia'
573
+ * const chain3: BridgeChainIdentifier = Solana // ChainDefinition
574
+ *
575
+ * // This will cause a TypeScript error:
576
+ * const chain4: BridgeChainIdentifier = 'Algorand' // Error!
577
+ * ```
578
+ *
579
+ * @see {@link BridgeChain} for the enum of supported chains.
580
+ * @see {@link ChainIdentifier} for the less restrictive type accepting all chains.
581
+ */
582
+ type BridgeChainIdentifier = ChainDefinition | BridgeChain | `${BridgeChain}`;
583
+
584
+ /**
585
+ * Resolves a flexible chain identifier to a ChainDefinition.
586
+ *
587
+ * This function handles all three supported formats:
588
+ * - ChainDefinition objects (passed through unchanged)
589
+ * - Blockchain enum values (resolved via getChainByEnum)
590
+ * - String literals of blockchain values (resolved via getChainByEnum)
591
+ *
592
+ * @param chainIdentifier - The chain identifier to resolve
593
+ * @returns The resolved ChainDefinition object
594
+ * @throws Error if the chain identifier cannot be resolved
595
+ *
596
+ * @example
597
+ * ```typescript
598
+ * import { resolveChainIdentifier } from '@core/chains'
599
+ * import { Blockchain, Ethereum } from '@core/chains'
600
+ *
601
+ * // All of these resolve to the same ChainDefinition:
602
+ * const chain1 = resolveChainIdentifier(Ethereum)
603
+ * const chain2 = resolveChainIdentifier(Blockchain.Ethereum)
604
+ * const chain3 = resolveChainIdentifier('Ethereum')
605
+ * ```
606
+ */
607
+ declare function resolveChainIdentifier(chainIdentifier: ChainIdentifier): ChainDefinition;
465
608
 
466
609
  /**
467
610
  * Core type definitions for blockchain transaction execution and gas estimation.
@@ -1878,10 +2021,9 @@ declare class ActionRegistry {
1878
2021
  * @param params - The parameters to pass to the action handler.
1879
2022
  * @param context - The resolved operation context with concrete chain and address values.
1880
2023
  * @returns A promise resolving to the prepared chain request.
1881
- *
1882
- * @throws {Error} When action parameter is not a valid string.
2024
+ * @throws {KitError} When the handler execution fails with a structured error.
1883
2025
  * @throws {Error} When no handler is registered for the specified action.
1884
- * @throws {Error} When the handler execution fails.
2026
+ * @throws {Error} When the handler execution fails with an unstructured error.
1885
2027
  *
1886
2028
  * @example
1887
2029
  * ```typescript
@@ -2591,6 +2733,14 @@ interface BridgeResult {
2591
2733
  address: string;
2592
2734
  /** The destination blockchain network */
2593
2735
  chain: ChainDefinition;
2736
+ /**
2737
+ * Optional custom recipient address for minted funds.
2738
+ *
2739
+ * When provided during the bridge operation, minted tokens are sent to this
2740
+ * address instead of the destination address. This field is preserved in the
2741
+ * result for retry operations to maintain consistency with the original burn.
2742
+ */
2743
+ recipientAddress?: string;
2594
2744
  };
2595
2745
  /** Array of steps that were executed during the bridge process */
2596
2746
  steps: BridgeStep[];
@@ -2680,6 +2830,40 @@ interface BridgeConfig {
2680
2830
  maxFee?: string;
2681
2831
  /**
2682
2832
  * The custom fee to charge for the transfer.
2833
+ *
2834
+ * Whatever value you provide here is **added on top of the transfer amount**. The user must have
2835
+ * enough balance for `amount + customFee`, and the wallet signs for that total on the source
2836
+ * chain. The custom fee is split automatically:
2837
+ *
2838
+ * - 10% routes to Circle.
2839
+ * - 90% routes to your `recipientAddress`.
2840
+ *
2841
+ * The original transfer amount proceeds through CCTPv2 unchanged, and the protocol fee (1–14 bps
2842
+ * in FAST mode, 0% in STANDARD) is taken from that transfer amount.
2843
+ *
2844
+ * @example
2845
+ * ```typescript
2846
+ * import type { BridgeConfig } from '@core/provider'
2847
+ *
2848
+ * const config: BridgeConfig = {
2849
+ * customFee: {
2850
+ * value: '5', // 5 USDC developer fee
2851
+ * recipientAddress: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0',
2852
+ * },
2853
+ * }
2854
+ *
2855
+ * // Fee flow for a 100 USDC transfer with 5 USDC custom fee:
2856
+ * // Source chain (Ethereum):
2857
+ * // - Wallet debits: 105 USDC total (100 transfer + 5 custom fee)
2858
+ * // - Custom fee split: 0.5 USDC (10%) → Circle, 4.5 USDC (90%) → your recipientAddress
2859
+ * // - Amount sent to CCTPv2: 100 USDC (unchanged)
2860
+ * //
2861
+ * // Destination chain (Base):
2862
+ * // - CCTPv2 FAST fee (example: 1 bps): ~0.01 USDC deducted
2863
+ * // - User receives: ~99.99 USDC
2864
+ * //
2865
+ * // Note: Actual CCTP fees vary by route (1-14 bps for FAST, 0 bps for STANDARD)
2866
+ * ```
2683
2867
  */
2684
2868
  customFee?: CustomFee | undefined;
2685
2869
  }
@@ -2722,6 +2906,10 @@ interface CustomFee {
2722
2906
  * bridge transfer. The fee recipient address **must be a valid address for
2723
2907
  * the source chain** of the bridge transfer.
2724
2908
  *
2909
+ * @remarks
2910
+ * Circle automatically receives 10% of every custom fee; the remaining 90% is
2911
+ * sent to this `recipientAddress`.
2912
+ *
2725
2913
  * For example: if bridging from Ethereum to Solana, pass an EVM address like
2726
2914
  * `"0x1234567890123456789012345678901234567890"` because the source chain
2727
2915
  * is Ethereum.
@@ -2744,6 +2932,7 @@ interface CustomFee {
2744
2932
  * and address requirements are enforced at compile time based on adapter capabilities.
2745
2933
  *
2746
2934
  * @typeParam TAdapterCapabilities - The adapter capabilities type to derive address requirements from
2935
+ * @typeParam TChainIdentifier - The chain identifier type constraint (defaults to ChainIdentifier)
2747
2936
  *
2748
2937
  * @example
2749
2938
  * ```typescript
@@ -2762,11 +2951,11 @@ interface CustomFee {
2762
2951
  * }
2763
2952
  * ```
2764
2953
  */
2765
- type AdapterContext<TAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities> = {
2954
+ type AdapterContext<TAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities, TChainIdentifier extends ChainIdentifier = ChainIdentifier> = {
2766
2955
  /** The adapter instance for blockchain operations */
2767
2956
  adapter: Adapter<TAdapterCapabilities>;
2768
2957
  /** The chain reference, which can be a ChainDefinition, Blockchain enum, or string literal */
2769
- chain: ChainIdentifier;
2958
+ chain: TChainIdentifier;
2770
2959
  } & AddressField<ExtractAddressContext<TAdapterCapabilities>>;
2771
2960
  /**
2772
2961
  * Represents a bridge destination with an explicit custom recipient address.
@@ -2777,6 +2966,7 @@ type AdapterContext<TAdapterCapabilities extends AdapterCapabilities = AdapterCa
2777
2966
  * the destination adapter.
2778
2967
  *
2779
2968
  * @typeParam TCapabilities - The adapter capabilities type for the destination adapter
2969
+ * @typeParam TChainIdentifier - The chain identifier type constraint (defaults to ChainIdentifier)
2780
2970
  *
2781
2971
  * @remarks
2782
2972
  * The `recipientAddress` must be a valid address format for the destination chain
@@ -2797,7 +2987,7 @@ type AdapterContext<TAdapterCapabilities extends AdapterCapabilities = AdapterCa
2797
2987
  * }
2798
2988
  * ```
2799
2989
  */
2800
- type BridgeDestinationWithAddress<TCapabilities extends AdapterCapabilities = AdapterCapabilities> = AdapterContext<TCapabilities> & {
2990
+ type BridgeDestinationWithAddress<TCapabilities extends AdapterCapabilities = AdapterCapabilities, TChainIdentifier extends ChainIdentifier = ChainIdentifier> = AdapterContext<TCapabilities, TChainIdentifier> & {
2801
2991
  /**
2802
2992
  * The custom recipient address on the destination chain.
2803
2993
  *
@@ -2809,8 +2999,11 @@ type BridgeDestinationWithAddress<TCapabilities extends AdapterCapabilities = Ad
2809
2999
  /**
2810
3000
  * Union type representing a bridge destination.
2811
3001
  * Can be either an AdapterContext (for default recipient) or BridgeDestinationWithAddress (for explicit recipient).
3002
+ *
3003
+ * @typeParam TAdapterCapabilities - The adapter capabilities type for the destination adapter
3004
+ * @typeParam TChainIdentifier - The chain identifier type constraint (defaults to ChainIdentifier)
2812
3005
  */
2813
- type BridgeDestination<TAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities> = AdapterContext<TAdapterCapabilities> | BridgeDestinationWithAddress<TAdapterCapabilities>;
3006
+ type BridgeDestination<TAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities, TChainIdentifier extends ChainIdentifier = ChainIdentifier> = AdapterContext<TAdapterCapabilities, TChainIdentifier> | BridgeDestinationWithAddress<TAdapterCapabilities, TChainIdentifier>;
2814
3007
  /**
2815
3008
  * Context for retry operations containing source and destination adapter contexts.
2816
3009
  *
@@ -2953,7 +3146,7 @@ declare abstract class BridgingProvider<TProviderActions = Record<string, unknow
2953
3146
  * @param token - The token to bridge (currently only USDC is supported)
2954
3147
  * @param config - Optional bridge configuration including speed and fee settings
2955
3148
  * @returns Promise resolving to the bridge result with transaction details and steps
2956
- * @throws {ValidationError} If the parameters are invalid
3149
+ * @throws {KitError} If the parameters are invalid
2957
3150
  * @throws {UnsupportedRouteError} If the route is not supported
2958
3151
  * @throws {BridgeError} If the bridge operation fails
2959
3152
  *
@@ -2978,7 +3171,7 @@ declare abstract class BridgingProvider<TProviderActions = Record<string, unknow
2978
3171
  *
2979
3172
  * @param params - The bridge parameters for cost estimation
2980
3173
  * @returns Promise resolving to the cost estimate including gas and protocol fees
2981
- * @throws {ValidationError} If the parameters are invalid
3174
+ * @throws {KitError} If the parameters are invalid
2982
3175
  * @throws {UnsupportedRouteError} If the route is not supported
2983
3176
  *
2984
3177
  * @example
@@ -3104,44 +3297,62 @@ declare abstract class BridgingProvider<TProviderActions = Record<string, unknow
3104
3297
  analyzeStepsForRetry(steps: BridgeStep[]): StepAnalysisResult;
3105
3298
  }
3106
3299
 
3300
+ type FeeFunction<TFromAdapterCapabilities extends AdapterCapabilities, TToAdapterCapabilities extends AdapterCapabilities> = (params: BridgeParams$1<TFromAdapterCapabilities, TToAdapterCapabilities>) => Promise<string> | string;
3301
+ type FeeRecipientFunction<TFromAdapterCapabilities extends AdapterCapabilities, TToAdapterCapabilities extends AdapterCapabilities> = (feePayoutChain: ChainDefinition, params: BridgeParams$1<TFromAdapterCapabilities, TToAdapterCapabilities>) => Promise<string> | string;
3107
3302
  /**
3108
3303
  * Custom fee policy for BridgeKit.
3109
3304
  *
3110
- * Provides hooks to calculate an absolute fee (in smallest unit string)
3111
- * and to resolve the fee recipient address on the source chain.
3305
+ * Provides hooks to calculate an absolute custom fee and resolve the fee recipient address
3306
+ * on the source chain. The returned fee is **added on top of the transfer amount** (the wallet signs for
3307
+ * `amount + customFee`). Once collected, the custom fee is split:
3308
+ *
3309
+ * - **10%** automatically routes to Circle.
3310
+ * - **90%** routes to your supplied `recipientAddress`.
3311
+ *
3312
+ * The entire transfer amount still flows through CCTPv2, which then charges its own protocol fee.
3313
+ *
3314
+ * Use `computeFee` (recommended) for human-readable amounts, or `calculateFee` (deprecated)
3315
+ * for smallest-unit amounts. Only one should be provided.
3112
3316
  *
3113
3317
  * @example
3114
3318
  * ```typescript
3115
3319
  * import type { CustomFeePolicy, BridgeParams } from '@circle-fin/bridge-kit'
3116
3320
  *
3117
3321
  * const policy: CustomFeePolicy = {
3118
- * // Charge 1 USDC on Solana, 0 on Ethereum, else 2 USDC
3119
- * calculateFee: (params: BridgeParams): string => {
3120
- * if (params.from.chain.type === 'solana') return '1000000'
3121
- * if (params.from.chain.name === 'Ethereum') return '0'
3122
- * return '2000000'
3123
- * },
3124
- * // Return a valid fee recipient for the source chain
3125
- * resolveFeeRecipientAddress: (feePayoutChain): string => {
3126
- * if (feePayoutChain.type === 'solana') {
3127
- * return 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'
3128
- * }
3129
- * return '0x1234567890123456789012345678901234567890'
3322
+ * // computeFee receives human-readable amounts (e.g., '100' for 100 USDC)
3323
+ * computeFee: (params: BridgeParams) => {
3324
+ * const amount = parseFloat(params.amount)
3325
+ *
3326
+ * // 1% fee, capped between 5-50 USDC
3327
+ * const fee = Math.min(Math.max(amount * 0.01, 5), 50)
3328
+ * return fee.toFixed(6)
3130
3329
  * },
3330
+ * resolveFeeRecipientAddress: (feePayoutChain) =>
3331
+ * feePayoutChain.type === 'solana'
3332
+ * ? 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'
3333
+ * : '0x1234567890123456789012345678901234567890',
3131
3334
  * }
3132
3335
  * ```
3133
3336
  */
3134
- interface CustomFeePolicy {
3337
+ type CustomFeePolicy = {
3135
3338
  /**
3136
3339
  * A function that returns the fee to charge for the bridge transfer.
3137
- * The value returned from the function represents an absolute fee in the smallest unit of the token.
3138
- * It **does not** represent a percentage fee, only an absolute value.
3139
- *
3140
- * For example: if you want to charge 1 USDC, you would return `'1000000'`.
3340
+ * The value returned from the function represents an absolute fee.
3341
+ * The returned fee is **added on top of the transfer amount**. For example, returning
3342
+ * `'5'` (5 USDC) for a 100 USDC transfer causes the wallet to debit 105 USDC total.
3343
+ * CCTPv2 still processes the full 100 USDC transfer amount, while the custom fee is split
3344
+ * 10%/90% between Circle and your fee recipient.
3141
3345
  *
3142
- * Note: returning `'0'` will result in no fee being charged.
3346
+ * @example
3347
+ * ```typescript
3348
+ * computeFee: (params) => {
3349
+ * const amount = parseFloat(params.amount)
3350
+ * return (amount * 0.01).toString() // 1% fee
3351
+ * }
3352
+ * ```
3143
3353
  */
3144
- calculateFee: <TFromAdapterCapabilities extends AdapterCapabilities, TToAdapterCapabilities extends AdapterCapabilities>(params: BridgeParams$1<TFromAdapterCapabilities, TToAdapterCapabilities>) => Promise<string> | string;
3354
+ computeFee: FeeFunction<AdapterCapabilities, AdapterCapabilities>;
3355
+ calculateFee?: never;
3145
3356
  /**
3146
3357
  * A function that returns the fee recipient for a bridge transfer.
3147
3358
  * The value returned from the function represents the address that will receive the fee on the source chain of the bridge transfer.
@@ -3150,18 +3361,27 @@ interface CustomFeePolicy {
3150
3361
  * For example: if you are bridging from Ethereum to Solana you would return `'0x1234567890123456789012345678901234567890'`,
3151
3362
  * because the source chain of the bridge transfer is Ethereum.
3152
3363
  */
3153
- resolveFeeRecipientAddress: <TFromAdapterCapabilities extends AdapterCapabilities, TToAdapterCapabilities extends AdapterCapabilities>(
3364
+ resolveFeeRecipientAddress: FeeRecipientFunction<AdapterCapabilities, AdapterCapabilities>;
3365
+ } | {
3366
+ computeFee?: never;
3154
3367
  /**
3155
- * The chain definition for the chain on which the fee is paid (the source chain).
3156
- * For example, when bridging from Ethereum to Base, the fee payout chain is Ethereum,
3157
- * since the bridging originates on Ethereum and the fee is taken on the source chain.
3368
+ * Calculate the fee to charge for the bridge transfer using smallest-unit amounts.
3369
+ *
3370
+ * @deprecated Use `computeFee` instead, which receives human-readable amounts.
3371
+ *
3372
+ * The `params.amount` is in smallest units (e.g., `'100000000'` for 100 USDC).
3158
3373
  */
3159
- feePayoutChain: ChainDefinition,
3374
+ calculateFee: FeeFunction<AdapterCapabilities, AdapterCapabilities>;
3160
3375
  /**
3161
- * The bridge parameters.
3376
+ * A function that returns the fee recipient for a bridge transfer.
3377
+ * The value returned from the function represents the address that will receive the fee on the source chain of the bridge transfer.
3378
+ * The fee recipient address **must be a valid address for the source chain** of the bridge transfer.
3379
+ *
3380
+ * For example: if you are bridging from Ethereum to Solana you would return `'0x1234567890123456789012345678901234567890'`,
3381
+ * because the source chain of the bridge transfer is Ethereum.
3162
3382
  */
3163
- params: BridgeParams$1<TFromAdapterCapabilities, TToAdapterCapabilities>) => Promise<string> | string;
3164
- }
3383
+ resolveFeeRecipientAddress: FeeRecipientFunction<AdapterCapabilities, AdapterCapabilities>;
3384
+ };
3165
3385
  /**
3166
3386
  * Parameters for initiating a cross-chain USDC bridge transfer.
3167
3387
  *
@@ -3173,46 +3393,69 @@ interface CustomFeePolicy {
3173
3393
  * - The `config` field allows customization of bridge behavior (e.g., transfer speed).
3174
3394
  * - The `token` field is optional and defaults to 'USDC'; other tokens are not currently supported.
3175
3395
  *
3176
- * @typeParam TChainDefinition - The chain definition type for advanced usage (defaults to {@link ChainDefinition}).
3396
+ * @typeParam TFromAdapterCapabilities - The source adapter capabilities type.
3397
+ * @typeParam TToAdapterCapabilities - The destination adapter capabilities type.
3177
3398
  *
3178
3399
  * @example
3179
3400
  * ```typescript
3401
+ * import { BridgeKit, BridgeChain } from '@circle-fin/bridge-kit'
3402
+ *
3403
+ * const kit = new BridgeKit()
3404
+ *
3405
+ * // Using BridgeChain enum values (full autocomplete support)
3180
3406
  * const params: BridgeParams = {
3181
- * from: { adapter: sourceAdapter, chain: 'Ethereum' },
3182
- * to: { adapter: destAdapter, chain: 'Base' },
3407
+ * from: { adapter: sourceAdapter, chain: BridgeChain.Ethereum },
3408
+ * to: { adapter: destAdapter, chain: BridgeChain.Base },
3183
3409
  * amount: '10.5',
3184
- * // Optional:
3185
3410
  * config: { transferSpeed: 'FAST' },
3186
3411
  * token: 'USDC'
3187
3412
  * }
3188
3413
  *
3189
- * // Or with explicit recipient address:
3414
+ * // Using string literals (also works with autocomplete)
3415
+ * const params2: BridgeParams = {
3416
+ * from: { adapter: sourceAdapter, chain: 'Ethereum_Sepolia' },
3417
+ * to: { adapter: destAdapter, chain: 'Base_Sepolia' },
3418
+ * amount: '10.5'
3419
+ * }
3420
+ *
3421
+ * // With explicit recipient address:
3190
3422
  * const paramsWithAddress: BridgeParams = {
3191
- * from: { adapter: sourceAdapter, chain: 'Ethereum' },
3423
+ * from: { adapter: sourceAdapter, chain: BridgeChain.Ethereum },
3192
3424
  * to: {
3193
3425
  * recipientAddress: '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
3194
- * adapter: destAdapter, chain: 'Base'
3426
+ * adapter: destAdapter,
3427
+ * chain: BridgeChain.Base
3195
3428
  * },
3196
3429
  * amount: '10.5'
3197
3430
  * }
3431
+ *
3432
+ * // ❌ Compile error - Algorand is not a supported bridge chain
3433
+ * const invalidParams: BridgeParams = {
3434
+ * from: { adapter: sourceAdapter, chain: 'Algorand' }, // TypeScript error!
3435
+ * to: { adapter: destAdapter, chain: 'Base' },
3436
+ * amount: '10.5'
3437
+ * }
3198
3438
  * ```
3439
+ *
3440
+ * @see {@link BridgeChain} for the enum of supported chains.
3441
+ * @see {@link BridgeChainIdentifier} for the type of valid chain values.
3199
3442
  */
3200
3443
  interface BridgeParams<TFromAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities, TToAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities> {
3201
3444
  /**
3202
3445
  * The source adapter context (wallet and chain) for the transfer.
3203
3446
  */
3204
- from: AdapterContext<TFromAdapterCapabilities>;
3447
+ from: AdapterContext<TFromAdapterCapabilities, BridgeChainIdentifier>;
3205
3448
  /**
3206
- * The destination for the transfer, supporting explicit or derived recipient addresses.
3449
+ * The destination for the transfer, supporting explicit or derived recipient addresses
3207
3450
  */
3208
- to: BridgeDestination<TToAdapterCapabilities>;
3451
+ to: BridgeDestination<TToAdapterCapabilities, BridgeChainIdentifier>;
3209
3452
  /**
3210
- * The amount to transfer.
3453
+ * The amount to transfer
3211
3454
  */
3212
3455
  amount: string;
3213
3456
  /**
3214
3457
  * Optional bridge configuration (e.g., transfer speed).
3215
- * If omitted, defaults will be used.
3458
+ * If omitted, defaults will be used
3216
3459
  */
3217
3460
  config?: BridgeConfig;
3218
3461
  /**
@@ -3250,8 +3493,9 @@ declare const getDefaultProviders: () => readonly [CCTPV2BridgingProvider];
3250
3493
  *
3251
3494
  * // Set custom fee policy using the setter method
3252
3495
  * kit.setCustomFeePolicy({
3253
- * calculateFee: (params: BridgeParams): string => {
3254
- * return '1000000' // 1 USDC
3496
+ * computeFee: (params: BridgeParams): string => {
3497
+ * const amount = parseFloat(params.amount)
3498
+ * return (amount * 0.01).toFixed(6) // 1% fee
3255
3499
  * },
3256
3500
  * resolveFeeRecipientAddress: (chain: ChainDefinition): string => {
3257
3501
  * return '0x1234567890123456789012345678901234567890'
@@ -3410,18 +3654,18 @@ type FlexibleBridgingProvider = BridgingProvider<any>;
3410
3654
  *
3411
3655
  * @param params - The bridge parameters containing source, destination, amount, and token
3412
3656
  * @returns Promise resolving to the bridge result with transaction details and steps
3413
- * @throws {ValidationError} If the parameters are invalid
3657
+ * @throws {KitError} If the parameters are invalid
3414
3658
  * @throws {BridgeError} If the bridging process fails
3415
3659
  * @throws {UnsupportedRouteError} If the route is not supported
3416
3660
  *
3417
3661
  * @example
3418
3662
  * ```typescript
3419
3663
  * import { BridgeKit } from '@circle-fin/bridge-kit'
3420
- * import { createAdapterFromPrivateKey } from '@circle-fin/adapter-viem-v2'
3664
+ * import { createViemAdapterFromPrivateKey } from '@circle-fin/adapter-viem-v2'
3421
3665
  *
3422
3666
  * // Create kit with default CCTPv2 provider
3423
3667
  * const kit = new BridgeKit()
3424
- * const adapter = createAdapterFromPrivateKey({ privateKey: '0x...' })
3668
+ * const adapter = createViemAdapterFromPrivateKey({ privateKey: '0x...' })
3425
3669
  *
3426
3670
  * // Execute cross-chain transfer
3427
3671
  * const result = await kit.bridge({
@@ -3542,18 +3786,18 @@ declare class BridgeKit<TExtraProviders extends FlexibleBridgingProvider[] = []>
3542
3786
  *
3543
3787
  * @param params - The transfer parameters containing source, destination, amount, and token
3544
3788
  * @returns Promise resolving to the transfer result with transaction details and steps
3545
- * @throws {ValidationError} When any parameter validation fails.
3789
+ * @throws {KitError} When any parameter validation fails.
3546
3790
  * @throws {Error} When CCTPv2 does not support the specified route.
3547
3791
  *
3548
3792
  * @example
3549
3793
  * ```typescript
3550
3794
  * import { BridgeKit } from '@circle-fin/bridge-kit'
3551
- * import { createAdapterFromPrivateKey } from '@circle-fin/adapter-viem-v2'
3795
+ * import { createViemAdapterFromPrivateKey } from '@circle-fin/adapter-viem-v2'
3552
3796
  *
3553
3797
  * const kit = new BridgeKit()
3554
3798
  *
3555
3799
  * // Create a single adapter that can work across chains
3556
- * const adapter = createAdapterFromPrivateKey({
3800
+ * const adapter = createViemAdapterFromPrivateKey({
3557
3801
  * privateKey: process.env.PRIVATE_KEY,
3558
3802
  * })
3559
3803
  *
@@ -3612,10 +3856,14 @@ declare class BridgeKit<TExtraProviders extends FlexibleBridgingProvider[] = []>
3612
3856
  * @example
3613
3857
  * ```typescript
3614
3858
  * import { BridgeKit } from '@circle-fin/bridge-kit'
3615
- * import { createAdapterFromPrivateKey } from '@circle-fin/adapter-viem-v2'
3859
+ * import { createViemAdapterFromPrivateKey } from '@circle-fin/adapter-viem-v2'
3616
3860
  *
3617
3861
  * const kit = new BridgeKit()
3618
3862
  *
3863
+ * // Create adapters for source and destination chains
3864
+ * const sourceAdapter = createViemAdapterFromPrivateKey({ privateKey: '...' })
3865
+ * const destAdapter = createViemAdapterFromPrivateKey({ privateKey: '...' })
3866
+ *
3619
3867
  * // Assume we have a failed bridge result from a previous operation
3620
3868
  * const failedResult: BridgeResult = {
3621
3869
  * state: 'error',
@@ -3651,7 +3899,7 @@ declare class BridgeKit<TExtraProviders extends FlexibleBridgingProvider[] = []>
3651
3899
  * as the bridge method but stops before execution.
3652
3900
  * @param params - The bridge parameters for cost estimation
3653
3901
  * @returns Promise resolving to detailed cost breakdown including gas estimates
3654
- * @throws {ValidationError} When the parameters are invalid.
3902
+ * @throws {KitError} When the parameters are invalid.
3655
3903
  * @throws {UnsupportedRouteError} When the route is not supported.
3656
3904
  *
3657
3905
  * @example
@@ -3736,40 +3984,61 @@ declare class BridgeKit<TExtraProviders extends FlexibleBridgingProvider[] = []>
3736
3984
  */
3737
3985
  private mergeCustomFeeConfig;
3738
3986
  /**
3739
- * Sets the custom fee policy for the kit.
3987
+ * Resolve the custom fee for a bridge transfer.
3740
3988
  *
3741
- * Ensures the fee is represented in the smallest unit of the token.
3742
- * - If the token is USDC, the fee is converted to base units (6 decimals).
3743
- * - If the token is not USDC, the fee is returned as is.
3989
+ * Checks which fee function the user provided and executes accordingly:
3990
+ * - `computeFee`: receives human-readable amounts, returns human-readable fee
3991
+ * - `calculateFee` (deprecated): receives smallest units, returns smallest units
3744
3992
  *
3745
- * This allows developers to specify the kit-level fee in base units (e.g., USDC: 1, ETH: 0.000001),
3746
- * and the kit will handle conversion to the smallest unit as needed.
3993
+ * @param providerParams - The resolved bridge parameters (amounts in smallest units).
3994
+ * @returns The resolved fee in smallest units, or undefined if no fee policy is set.
3995
+ */
3996
+ private resolveFee;
3997
+ /**
3998
+ * Set the custom fee policy for the kit.
3999
+ *
4000
+ * Use `computeFee` (recommended) for human-readable amounts, or `calculateFee`
4001
+ * (deprecated) for smallest-unit amounts. Only one should be provided.
4002
+ *
4003
+ * ```text
4004
+ * Transfer amount (user input, e.g., 1,000 USDC)
4005
+ * ↓ Wallet signs for transfer + custom fee (e.g., 1,000 + 10 = 1,010 USDC)
4006
+ * ↓ Custom fee split (10% Circle, 90% your recipientAddress wallet)
4007
+ * ↓ Full transfer amount (1,000 USDC) forwarded to CCTPv2
4008
+ * ↓ CCTPv2 protocol fee (e.g., 0.1 USDC) deducted from transfer amount
4009
+ * ↓ User receives funds on destination chain (e.g., 999.9 USDC)
4010
+ * ```
3747
4011
  *
3748
4012
  * @param customFeePolicy - The custom fee policy to set.
3749
- * @throws {ValidationError} If the custom fee policy is invalid or missing required functions
4013
+ * @throws {KitError} If the custom fee policy is invalid or missing required functions
3750
4014
  *
3751
4015
  * @example
3752
4016
  * ```typescript
3753
4017
  * import { BridgeKit } from '@circle-fin/bridge-kit'
3754
- * import { Blockchain } from '@core/chains'
3755
4018
  *
3756
4019
  * const kit = new BridgeKit()
3757
4020
  *
3758
4021
  * kit.setCustomFeePolicy({
3759
- * calculateFee: (params) => {
3760
- * // Return decimal string - kit converts to smallest units automatically
3761
- * // '0.1' becomes '100000' (0.1 USDC with 6 decimals)
3762
- * return params.source.chain.chain === Blockchain.Ethereum_Sepolia
3763
- * ? '0.1' // 0.1 USDC
3764
- * : '0.2'; // 0.2 USDC
4022
+ * // computeFee receives human-readable amounts (e.g., '100' for 100 USDC)
4023
+ * computeFee: (params) => {
4024
+ * const amount = parseFloat(params.amount)
4025
+ *
4026
+ * // 1% fee, bounded to 5-50 USDC
4027
+ * const fee = Math.min(Math.max(amount * 0.01, 5), 50)
4028
+ * return fee.toFixed(6)
3765
4029
  * },
3766
- * resolveFeeRecipientAddress: (feePayoutChain, params) => {
3767
- * // Return valid address for the source chain
3768
- * return params.source.chain.chain === Blockchain.Ethereum_Sepolia
3769
- * ? '0x23f9a5BEA7B92a0638520607407BC7f0310aEeD4'
3770
- * : '0x1E1A18B7bD95bcFcFb4d6E245D289C1e95547b35';
4030
+ * resolveFeeRecipientAddress: (feePayoutChain) => {
4031
+ * return feePayoutChain.type === 'solana'
4032
+ * ? '9xQeWvG816bUx9EP9MnZ4buHh3A6E2dFQa4Xz6V7C7Gn'
4033
+ * : '0x23f9a5BEA7B92a0638520607407BC7f0310aEeD4'
3771
4034
  * },
3772
- * });
4035
+ * })
4036
+ *
4037
+ * // 100 USDC transfer + 5 USDC custom fee results:
4038
+ * // - Wallet signs for 105 USDC total.
4039
+ * // - Circle receives 0.5 USDC (10% share of the custom fee).
4040
+ * // - Your recipientAddress wallet receives 4.5 USDC.
4041
+ * // - CCTPv2 processes 100 USDC and later deducts its own protocol fee.
3773
4042
  * ```
3774
4043
  */
3775
4044
  setCustomFeePolicy(customFeePolicy: CustomFeePolicy): void;
@@ -4350,5 +4619,5 @@ declare function getErrorMessage(error: unknown): string;
4350
4619
  */
4351
4620
  declare function getErrorCode(error: unknown): number | null;
4352
4621
 
4353
- export { Blockchain, BridgeKit, KitError, TransferSpeed, bridgeParamsWithChainIdentifierSchema, getErrorCode, getErrorMessage, isFatalError, isInputError, isKitError, isRetryableError, setExternalPrefix };
4354
- export type { ActionHandler, AdapterContext, BridgeConfig, BridgeKitConfig, BridgeParams, BridgeResult, ChainDefinition, ChainIdentifier, CustomFeePolicy, ErrorDetails, EstimateResult, Recoverability };
4622
+ export { Blockchain, BridgeChain, BridgeKit, KitError, TransferSpeed, bridgeParamsWithChainIdentifierSchema, getErrorCode, getErrorMessage, isFatalError, isInputError, isKitError, isRetryableError, resolveChainIdentifier, setExternalPrefix };
4623
+ export type { ActionHandler, AdapterContext, BridgeChainIdentifier, BridgeConfig, BridgeKitConfig, BridgeParams, BridgeResult, ChainDefinition, ChainIdentifier, CustomFeePolicy, ErrorDetails, EstimateResult, Recoverability };