@circle-fin/app-kit 1.14.0 → 1.15.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.
Files changed (53) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/README.md +3 -3
  3. package/bridge.cjs +7464 -454
  4. package/bridge.d.cts +585 -61
  5. package/bridge.d.mts +585 -61
  6. package/bridge.d.ts +585 -61
  7. package/bridge.mjs +7464 -454
  8. package/chains.cjs +146 -5
  9. package/chains.d.cts +108 -2
  10. package/chains.d.mts +108 -2
  11. package/chains.d.ts +108 -2
  12. package/chains.mjs +146 -6
  13. package/context.d.cts +522 -57
  14. package/context.d.mts +522 -57
  15. package/context.d.ts +522 -57
  16. package/earn.cjs +478 -181
  17. package/earn.d.cts +522 -57
  18. package/earn.d.mts +522 -57
  19. package/earn.d.ts +522 -57
  20. package/earn.mjs +478 -181
  21. package/estimateBridge.cjs +7464 -457
  22. package/estimateBridge.d.cts +643 -82
  23. package/estimateBridge.d.mts +643 -82
  24. package/estimateBridge.d.ts +643 -82
  25. package/estimateBridge.mjs +7464 -457
  26. package/estimateSwap.cjs +528 -185
  27. package/estimateSwap.d.cts +522 -57
  28. package/estimateSwap.d.mts +522 -57
  29. package/estimateSwap.d.ts +522 -57
  30. package/estimateSwap.mjs +528 -185
  31. package/index.cjs +11548 -2936
  32. package/index.d.cts +5073 -1738
  33. package/index.d.mts +5073 -1738
  34. package/index.d.ts +5073 -1738
  35. package/index.mjs +11547 -2937
  36. package/package.json +17 -6
  37. package/server.cjs +10040 -0
  38. package/server.cjs.map +1 -0
  39. package/server.d.cts +2467 -0
  40. package/server.d.mts +2467 -0
  41. package/server.d.ts +2467 -0
  42. package/server.mjs +10028 -0
  43. package/server.mjs.map +1 -0
  44. package/swap.cjs +528 -185
  45. package/swap.d.cts +522 -57
  46. package/swap.d.mts +522 -57
  47. package/swap.d.ts +522 -57
  48. package/swap.mjs +528 -185
  49. package/unifiedBalance.cjs +742 -44
  50. package/unifiedBalance.d.cts +223 -1
  51. package/unifiedBalance.d.mts +223 -1
  52. package/unifiedBalance.d.ts +223 -1
  53. package/unifiedBalance.mjs +742 -44
package/swap.cjs CHANGED
@@ -733,6 +733,38 @@ class KitError extends Error {
733
733
  name: 'INPUT_AMOUNT_OUT_OF_RANGE',
734
734
  type: 'INPUT'
735
735
  },
736
+ /**
737
+ * Protocol fee is denominated in a token that is not supported for the
738
+ * route (only the native gas token and the route's supported fee tokens,
739
+ * such as USDC, are accepted).
740
+ */ UNSUPPORTED_FEE_TOKEN: {
741
+ code: 1014,
742
+ name: 'INPUT_UNSUPPORTED_FEE_TOKEN',
743
+ type: 'INPUT'
744
+ },
745
+ /** Retry / resume is not supported by this provider for the given result */ RETRY_NOT_SUPPORTED: {
746
+ code: 1015,
747
+ name: 'INPUT_RETRY_NOT_SUPPORTED',
748
+ type: 'INPUT'
749
+ },
750
+ /** Bridge-step analysis for retry is not supported by this provider */ STEP_ANALYSIS_NOT_SUPPORTED: {
751
+ code: 1016,
752
+ name: 'INPUT_STEP_ANALYSIS_NOT_SUPPORTED',
753
+ type: 'INPUT'
754
+ },
755
+ /**
756
+ * A kit operation name collides with a reserved event-subscription
757
+ * method (`on` / `off`) at kit construction.
758
+ */ RESERVED_OPERATION_NAME: {
759
+ code: 1000,
760
+ name: 'INPUT_RESERVED_OPERATION_NAME',
761
+ type: 'INPUT'
762
+ },
763
+ /** A kit was constructed with a missing / undefined operation factory */ MISSING_OPERATION: {
764
+ code: 1017,
765
+ name: 'INPUT_MISSING_OPERATION',
766
+ type: 'INPUT'
767
+ },
736
768
  /** General validation failure for complex validation rules */ VALIDATION_FAILED: {
737
769
  code: 1098,
738
770
  name: 'INPUT_VALIDATION_FAILED',
@@ -943,8 +975,7 @@ class KitError extends Error {
943
975
  code: 8002,
944
976
  name: 'SERVICE_UNKNOWN_ERROR',
945
977
  type: 'SERVICE'
946
- }
947
- };
978
+ }};
948
979
 
949
980
  /**
950
981
  * Creates error for unsupported swap route.
@@ -1171,7 +1202,7 @@ class KitError extends Error {
1171
1202
  * import { createValidationErrorFromZod } from '@core/errors'
1172
1203
  *
1173
1204
  * function validateBridgeParams(params: unknown): asserts params is BridgeParams {
1174
- * const result = bridgeParamsSchema.safeParse(params)
1205
+ * const result = usdcBridgeParamsSchema.safeParse(params)
1175
1206
  * if (!result.success) {
1176
1207
  * throw createValidationErrorFromZod(result.error, 'bridge parameters')
1177
1208
  * }
@@ -2949,9 +2980,10 @@ class KitError extends Error {
2949
2980
  Blockchain["Algorand_Testnet"] = "Algorand_Testnet";
2950
2981
  Blockchain["Aptos"] = "Aptos";
2951
2982
  Blockchain["Aptos_Testnet"] = "Aptos_Testnet";
2952
- Blockchain["Arc_Testnet"] = "Arc_Testnet";
2953
2983
  Blockchain["Arbitrum"] = "Arbitrum";
2954
2984
  Blockchain["Arbitrum_Sepolia"] = "Arbitrum_Sepolia";
2985
+ Blockchain["Arc"] = "Arc";
2986
+ Blockchain["Arc_Testnet"] = "Arc_Testnet";
2955
2987
  Blockchain["Avalanche"] = "Avalanche";
2956
2988
  Blockchain["Avalanche_Fuji"] = "Avalanche_Fuji";
2957
2989
  Blockchain["Base"] = "Base";
@@ -3038,6 +3070,7 @@ var SwapChain;
3038
3070
  SwapChain["XDC"] = "XDC";
3039
3071
  SwapChain["HyperEVM"] = "HyperEVM";
3040
3072
  SwapChain["Monad"] = "Monad";
3073
+ SwapChain["Arc"] = "Arc";
3041
3074
  // Testnet chains with swap support
3042
3075
  SwapChain["Arc_Testnet"] = "Arc_Testnet";
3043
3076
  })(SwapChain || (SwapChain = {}));
@@ -3045,6 +3078,7 @@ var BridgeChain;
3045
3078
  (function(BridgeChain) {
3046
3079
  // Mainnet chains with CCTPv2 support
3047
3080
  BridgeChain["Arbitrum"] = "Arbitrum";
3081
+ BridgeChain["Arc"] = "Arc";
3048
3082
  BridgeChain["Avalanche"] = "Avalanche";
3049
3083
  BridgeChain["Base"] = "Base";
3050
3084
  BridgeChain["Codex"] = "Codex";
@@ -3100,6 +3134,7 @@ var BridgeChain;
3100
3134
  var UnifiedBalanceChain;
3101
3135
  (function(UnifiedBalanceChain) {
3102
3136
  // Mainnet chains with Gateway V1 support
3137
+ UnifiedBalanceChain["Arc"] = "Arc";
3103
3138
  UnifiedBalanceChain["Arbitrum"] = "Arbitrum";
3104
3139
  UnifiedBalanceChain["Avalanche"] = "Avalanche";
3105
3140
  UnifiedBalanceChain["Base"] = "Base";
@@ -3129,6 +3164,7 @@ var UnifiedBalanceChain;
3129
3164
  })(UnifiedBalanceChain || (UnifiedBalanceChain = {}));
3130
3165
  var EarnChain;
3131
3166
  (function(EarnChain) {
3167
+ EarnChain["Arc"] = "Arc";
3132
3168
  EarnChain["Arc_Testnet"] = "Arc_Testnet";
3133
3169
  })(EarnChain || (EarnChain = {}));
3134
3170
  /**
@@ -3145,8 +3181,11 @@ var EarnChain;
3145
3181
  * console.log(EARN_BRIDGE_SOURCE_BLOCKCHAINS.join(', '))
3146
3182
  * ```
3147
3183
  */ const EARN_BRIDGE_SOURCE_BLOCKCHAINS = [
3184
+ "Arbitrum",
3148
3185
  "Arbitrum_Sepolia",
3186
+ "Base",
3149
3187
  "Base_Sepolia",
3188
+ "Ethereum",
3150
3189
  "Ethereum_Sepolia"
3151
3190
  ];
3152
3191
  /**
@@ -3160,6 +3199,7 @@ var EarnChain;
3160
3199
  * console.log(EARN_BRIDGE_DESTINATION_BLOCKCHAINS.join(', '))
3161
3200
  * ```
3162
3201
  */ const EARN_BRIDGE_DESTINATION_BLOCKCHAINS = [
3202
+ "Arc",
3163
3203
  "Arc_Testnet"
3164
3204
  ];
3165
3205
 
@@ -3476,6 +3516,25 @@ var EarnChain;
3476
3516
  * EVM-compatible chains. Use this address when deploying or testing
3477
3517
  * cross-chain USDC transfers on test networks.
3478
3518
  */ const BRIDGE_CONTRACT_EVM_TESTNET = '0xC5567a5E3370d4DBfB0540025078e283e36A363d';
3519
+ /**
3520
+ * The CrossChainTokenService (CCTPx) service address for EVM testnet networks.
3521
+ *
3522
+ * This service coordinates CCTPx cross-chain token operations on testnet
3523
+ * environments and is shared by every EVM test network CCTPx supports. Read the
3524
+ * chain definitions via `isCCTPXSupported` rather than trusting a list here,
3525
+ * which goes stale as deployments land.
3526
+ */ const CCTPX_SERVICE_ADDRESS_EVM_TESTNET = '0x63753E722bd2C2A5DF6EE19C5106662208B81077';
3527
+ /**
3528
+ * CrossChainTokenService (CCTS) proxy address for CCTPx on EVM **mainnet**.
3529
+ *
3530
+ * @remarks
3531
+ * A distinct deployment from {@link CCTPX_SERVICE_ADDRESS_EVM_TESTNET}, shared
3532
+ * by every EVM mainnet chain that CCTPx supports. A chain becomes
3533
+ * CCTPx-eligible only once its definition carries this as
3534
+ * `cctpx.serviceAddress`, and a route additionally needs both of its endpoints
3535
+ * eligible — so adding a chain here is the deliberate, reviewable step that
3536
+ * opens mainnet CCTPx for it.
3537
+ */ const CCTPX_SERVICE_ADDRESS_EVM_MAINNET = '0x431871229103b780868f8C6BB820cd16ECf942BC';
3479
3538
  /**
3480
3539
  * The bridge contract address for EVM mainnet networks.
3481
3540
  *
@@ -3584,6 +3643,76 @@ var EarnChain;
3584
3643
  * Identical across all testnet EVM destination chains.
3585
3644
  */ const GENERIC_EXECUTOR_EVM_TESTNET = '0xEdC81040756AcCfF070c21D37b265b9D0b5Ba45e';
3586
3645
 
3646
+ /**
3647
+ * Arc Mainnet chain definition
3648
+ * @remarks
3649
+ * This represents the official production network for the Arc blockchain,
3650
+ * Circle's EVM-compatible Layer-1 designed for stablecoin finance
3651
+ * and asset tokenization. Arc uses USDC as the native gas token and
3652
+ * features the Malachite Byzantine Fault Tolerant (BFT) consensus
3653
+ * engine for sub-second finality.
3654
+ */ const Arc = defineChain({
3655
+ type: 'evm',
3656
+ chain: Blockchain.Arc,
3657
+ name: 'Arc',
3658
+ title: 'Arc Mainnet',
3659
+ nativeCurrency: {
3660
+ name: 'USDC',
3661
+ symbol: 'USDC',
3662
+ // Arc uses native USDC with 18 decimals for gas payments (EVM standard).
3663
+ // Note: The ERC-20 USDC contract at usdcAddress uses 6 decimals.
3664
+ // See: https://docs.arc.network/arc/references/contract-addresses
3665
+ decimals: 18
3666
+ },
3667
+ chainId: 5042,
3668
+ isTestnet: false,
3669
+ explorerUrl: 'https://explorer.arc.io/tx/{hash}',
3670
+ rpcEndpoints: [
3671
+ 'https://rpc.mainnet.arc.io/'
3672
+ ],
3673
+ eurcAddress: '0xbEf5f6d51CB62b58e6A8f77868681825C6fe21c1',
3674
+ usdcAddress: '0x3600000000000000000000000000000000000000',
3675
+ usdtAddress: null,
3676
+ cctp: {
3677
+ domain: 26,
3678
+ contracts: {
3679
+ v2: {
3680
+ type: 'split',
3681
+ tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
3682
+ messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
3683
+ confirmations: 1,
3684
+ fastConfirmations: 1
3685
+ }
3686
+ },
3687
+ forwarderSupported: {
3688
+ source: false,
3689
+ destination: true
3690
+ }
3691
+ },
3692
+ cctpx: {
3693
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
3694
+ },
3695
+ kitContracts: {
3696
+ bridge: BRIDGE_CONTRACT_EVM_MAINNET,
3697
+ adapter: ADAPTER_CONTRACT_EVM_MAINNET
3698
+ },
3699
+ gateway: {
3700
+ domain: 26,
3701
+ contracts: {
3702
+ v1: {
3703
+ wallet: GATEWAY_WALLET_EVM_MAINNET,
3704
+ minter: GATEWAY_MINTER_EVM_MAINNET,
3705
+ depositForHandler: DEPOSIT_FOR_HANDLER_EVM_MAINNET,
3706
+ genericExecutor: GENERIC_EXECUTOR_EVM_MAINNET
3707
+ }
3708
+ },
3709
+ forwarderSupported: {
3710
+ source: true,
3711
+ destination: true
3712
+ }
3713
+ }
3714
+ });
3715
+
3587
3716
  /**
3588
3717
  * Arc Testnet chain definition
3589
3718
  * @remarks
@@ -3631,6 +3760,9 @@ var EarnChain;
3631
3760
  destination: true
3632
3761
  }
3633
3762
  },
3763
+ cctpx: {
3764
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
3765
+ },
3634
3766
  kitContracts: {
3635
3767
  bridge: BRIDGE_CONTRACT_EVM_TESTNET,
3636
3768
  adapter: ADAPTER_CONTRACT_EVM_TESTNET
@@ -3698,6 +3830,9 @@ var EarnChain;
3698
3830
  destination: true
3699
3831
  }
3700
3832
  },
3833
+ cctpx: {
3834
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
3835
+ },
3701
3836
  kitContracts: {
3702
3837
  bridge: BRIDGE_CONTRACT_EVM_MAINNET,
3703
3838
  adapter: ADAPTER_CONTRACT_EVM_MAINNET
@@ -3763,6 +3898,9 @@ var EarnChain;
3763
3898
  destination: true
3764
3899
  }
3765
3900
  },
3901
+ cctpx: {
3902
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
3903
+ },
3766
3904
  kitContracts: {
3767
3905
  bridge: BRIDGE_CONTRACT_EVM_TESTNET,
3768
3906
  adapter: ADAPTER_CONTRACT_EVM_TESTNET
@@ -3828,6 +3966,9 @@ var EarnChain;
3828
3966
  destination: true
3829
3967
  }
3830
3968
  },
3969
+ cctpx: {
3970
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
3971
+ },
3831
3972
  kitContracts: {
3832
3973
  bridge: BRIDGE_CONTRACT_EVM_MAINNET,
3833
3974
  adapter: ADAPTER_CONTRACT_EVM_MAINNET
@@ -3895,6 +4036,9 @@ var EarnChain;
3895
4036
  rpcEndpoints: [
3896
4037
  'https://api.avax-test.network/ext/bc/C/rpc'
3897
4038
  ],
4039
+ cctpx: {
4040
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
4041
+ },
3898
4042
  kitContracts: {
3899
4043
  bridge: BRIDGE_CONTRACT_EVM_TESTNET
3900
4044
  },
@@ -3962,6 +4106,9 @@ var EarnChain;
3962
4106
  destination: true
3963
4107
  }
3964
4108
  },
4109
+ cctpx: {
4110
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
4111
+ },
3965
4112
  kitContracts: {
3966
4113
  bridge: BRIDGE_CONTRACT_EVM_MAINNET,
3967
4114
  adapter: ADAPTER_CONTRACT_EVM_MAINNET
@@ -4027,6 +4174,9 @@ var EarnChain;
4027
4174
  destination: true
4028
4175
  }
4029
4176
  },
4177
+ cctpx: {
4178
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
4179
+ },
4030
4180
  kitContracts: {
4031
4181
  bridge: BRIDGE_CONTRACT_EVM_TESTNET,
4032
4182
  adapter: ADAPTER_CONTRACT_EVM_TESTNET
@@ -4419,6 +4569,9 @@ var EarnChain;
4419
4569
  destination: true
4420
4570
  }
4421
4571
  },
4572
+ cctpx: {
4573
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
4574
+ },
4422
4575
  kitContracts: {
4423
4576
  bridge: BRIDGE_CONTRACT_EVM_MAINNET,
4424
4577
  adapter: ADAPTER_CONTRACT_EVM_MAINNET
@@ -4484,6 +4637,9 @@ var EarnChain;
4484
4637
  destination: true
4485
4638
  }
4486
4639
  },
4640
+ cctpx: {
4641
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
4642
+ },
4487
4643
  kitContracts: {
4488
4644
  bridge: BRIDGE_CONTRACT_EVM_TESTNET,
4489
4645
  adapter: ADAPTER_CONTRACT_EVM_TESTNET
@@ -5315,6 +5471,9 @@ var EarnChain;
5315
5471
  destination: true
5316
5472
  }
5317
5473
  },
5474
+ cctpx: {
5475
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
5476
+ },
5318
5477
  kitContracts: {
5319
5478
  bridge: BRIDGE_CONTRACT_EVM_MAINNET,
5320
5479
  adapter: ADAPTER_CONTRACT_EVM_MAINNET
@@ -5380,6 +5539,9 @@ var EarnChain;
5380
5539
  destination: true
5381
5540
  }
5382
5541
  },
5542
+ cctpx: {
5543
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
5544
+ },
5383
5545
  kitContracts: {
5384
5546
  bridge: BRIDGE_CONTRACT_EVM_TESTNET
5385
5547
  },
@@ -5775,6 +5937,9 @@ var EarnChain;
5775
5937
  destination: true
5776
5938
  }
5777
5939
  },
5940
+ cctpx: {
5941
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
5942
+ },
5778
5943
  kitContracts: {
5779
5944
  bridge: BRIDGE_CONTRACT_EVM_MAINNET,
5780
5945
  adapter: ADAPTER_CONTRACT_EVM_MAINNET
@@ -5843,6 +6008,9 @@ var EarnChain;
5843
6008
  destination: true
5844
6009
  }
5845
6010
  },
6011
+ cctpx: {
6012
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
6013
+ },
5846
6014
  kitContracts: {
5847
6015
  bridge: BRIDGE_CONTRACT_EVM_TESTNET
5848
6016
  },
@@ -6851,6 +7019,7 @@ var Chains = {
6851
7019
  AptosTestnet: AptosTestnet,
6852
7020
  Arbitrum: Arbitrum,
6853
7021
  ArbitrumSepolia: ArbitrumSepolia,
7022
+ Arc: Arc,
6854
7023
  ArcTestnet: ArcTestnet,
6855
7024
  Avalanche: Avalanche,
6856
7025
  AvalancheFuji: AvalancheFuji,
@@ -7108,6 +7277,7 @@ var Chains = {
7108
7277
  usdcAddress: zod.z.string().nullable(),
7109
7278
  usdtAddress: zod.z.string().nullable(),
7110
7279
  cctp: zod.z.any().nullable(),
7280
+ cctpx: zod.z.any().optional(),
7111
7281
  kitContracts: zod.z.object({
7112
7282
  bridge: zod.z.string().optional(),
7113
7283
  adapter: zod.z.string().optional()
@@ -7313,14 +7483,15 @@ const EARN_BRIDGE_DESTINATION_CHAIN_VALUES = EARN_BRIDGE_DESTINATION_BLOCKCHAINS
7313
7483
  * Zod schema for validating the source chain of a cross-chain Earn deposit.
7314
7484
  *
7315
7485
  * Accept a supported source Blockchain value, a matching string literal, or a
7316
- * ChainDefinition for a supported source chain. Source chains are Ethereum
7317
- * Sepolia, Arbitrum Sepolia, and Base Sepolia.
7486
+ * ChainDefinition for a supported source chain. Source chains are Ethereum,
7487
+ * Arbitrum, and Base (mainnet and testnet).
7318
7488
  *
7319
7489
  * @example
7320
7490
  * ```typescript
7321
7491
  * import { earnBridgeSourceChainIdentifierSchema } from '@core/chains'
7322
7492
  *
7323
7493
  * // Valid
7494
+ * earnBridgeSourceChainIdentifierSchema.parse('Ethereum')
7324
7495
  * earnBridgeSourceChainIdentifierSchema.parse('Ethereum_Sepolia')
7325
7496
  *
7326
7497
  * // Invalid (throws ZodError)
@@ -7339,14 +7510,15 @@ const EARN_BRIDGE_DESTINATION_CHAIN_VALUES = EARN_BRIDGE_DESTINATION_BLOCKCHAINS
7339
7510
  * deposit.
7340
7511
  *
7341
7512
  * Accept a supported destination Blockchain value, a matching string literal,
7342
- * or a ChainDefinition for a supported destination chain. Currently only Arc
7343
- * Testnet is supported.
7513
+ * or a ChainDefinition for a supported destination chain. Arc (mainnet) and
7514
+ * Arc Testnet are supported.
7344
7515
  *
7345
7516
  * @example
7346
7517
  * ```typescript
7347
7518
  * import { earnBridgeDestinationChainIdentifierSchema } from '@core/chains'
7348
7519
  *
7349
7520
  * // Valid
7521
+ * earnBridgeDestinationChainIdentifierSchema.parse('Arc')
7350
7522
  * earnBridgeDestinationChainIdentifierSchema.parse('Arc_Testnet')
7351
7523
  *
7352
7524
  * // Invalid (throws ZodError)
@@ -7524,7 +7696,10 @@ const swapTokenEnumSchema = zod.z.enum([
7524
7696
  * Get decimal places for a supported swap token.
7525
7697
  *
7526
7698
  * @param token - Swap token symbol
7527
- * @returns Number of decimals, or null for NATIVE (chain-specific)
7699
+ * @returns Number of decimals; `null` for NATIVE (chain-specific) or when the
7700
+ * symbol is not in the swap registry. Callers must not read `null` as
7701
+ * "use the chain's native decimals" — for a CCTPx token that would scale
7702
+ * an 8-decimal amount as 18.
7528
7703
  *
7529
7704
  * @example
7530
7705
  * ```typescript
@@ -7536,6 +7711,15 @@ const swapTokenEnumSchema = zod.z.enum([
7536
7711
  * ```
7537
7712
  */ function getSwapTokenDecimals(token) {
7538
7713
  if (token === NATIVE_TOKEN) return null;
7714
+ // Membership is checked rather than assumed: callers reach this through
7715
+ // `formatAmount`/`parseAmount` with a plain `string` token, so a value
7716
+ // outside the registry (a provider's own symbol, or a bytes32 id) is
7717
+ // reachable at runtime despite what the parameter type says. A bare index
7718
+ // would throw a raw TypeError from inside the formatter; `null` lets the
7719
+ // caller raise its own "could not determine decimals" error instead.
7720
+ if (!Object.hasOwn(SWAP_TOKEN_REGISTRY, token)) {
7721
+ return null;
7722
+ }
7539
7723
  return SWAP_TOKEN_REGISTRY[token].decimals;
7540
7724
  }
7541
7725
  /**
@@ -8977,6 +9161,7 @@ const swapTokenEnumSchema = zod.z.enum([
8977
9161
  // Mainnets (alphabetically sorted)
8978
9162
  // =========================================================================
8979
9163
  [Blockchain.Arbitrum]: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
9164
+ [Blockchain.Arc]: '0x3600000000000000000000000000000000000000',
8980
9165
  [Blockchain.Avalanche]: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',
8981
9166
  [Blockchain.Base]: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
8982
9167
  [Blockchain.Celo]: '0xcebA9300f2b948710d2653dD7B07f33A8B32118C',
@@ -9091,6 +9276,7 @@ const swapTokenEnumSchema = zod.z.enum([
9091
9276
  // =========================================================================
9092
9277
  // Mainnets
9093
9278
  // =========================================================================
9279
+ [Blockchain.Arc]: '0xbEf5f6d51CB62b58e6A8f77868681825C6fe21c1',
9094
9280
  [Blockchain.Avalanche]: '0xc891EB4cbdEFf6e073e859e987815Ed1505c2ACD',
9095
9281
  [Blockchain.Base]: '0x60a3E35Cc302bFA44Cb288Bc5a4F316Fdb1adb42',
9096
9282
  [Blockchain.Cronos]: '0xA6dE01a2d62C6B5f3525d768f34d276652C554c8',
@@ -9334,6 +9520,7 @@ const swapTokenEnumSchema = zod.z.enum([
9334
9520
  // =========================================================================
9335
9521
  // Mainnets
9336
9522
  // =========================================================================
9523
+ [Blockchain.Arc]: '0x171A4217b86A807A64eB94757Db6849fb4bDbAA0',
9337
9524
  [Blockchain.Ethereum]: '0x72DFB2E44f59C5AD2bAFE84314E5b99a7cd5075E',
9338
9525
  // =========================================================================
9339
9526
  // Testnets
@@ -9426,13 +9613,28 @@ const swapTokenEnumSchema = zod.z.enum([
9426
9613
  }
9427
9614
 
9428
9615
  /**
9429
- * Check if a selector is a raw token selector (object form).
9616
+ * Type guard: narrows a {@link TokenSelector} to a {@link RawTokenSelector}.
9430
9617
  *
9431
9618
  * @param selector - The token selector to check.
9432
- * @returns True if the selector is a raw token selector.
9619
+ * @returns `true` if `selector` is a raw token selector (object with `locator`).
9620
+ *
9621
+ * @example
9622
+ * ```typescript
9623
+ * if (isRawSelector(selector)) {
9624
+ * console.log(selector.locator)
9625
+ * }
9626
+ * ```
9433
9627
  */ function isRawSelector(selector) {
9434
- return typeof selector === 'object' && 'locator' in selector;
9628
+ // `typeof null === 'object'` (a JS quirk) and `'locator' in null`
9629
+ // throws, so the explicit `null` check is required at this exported
9630
+ // guard for JS consumers passing nullish values. The lint rule sees
9631
+ // the parameter typed as `TokenSelector` (no null) and flags the
9632
+ // check as unnecessary — disabled because the check IS necessary at
9633
+ // runtime even though TypeScript can prove it dead statically.
9634
+ return typeof selector === 'object' && // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
9635
+ selector !== null && 'locator' in selector;
9435
9636
  }
9637
+
9436
9638
  /**
9437
9639
  * Normalize a symbol to uppercase for case-insensitive lookup.
9438
9640
  *
@@ -9620,7 +9822,7 @@ const swapTokenEnumSchema = zod.z.enum([
9620
9822
  if (typeof selector === 'string') {
9621
9823
  return resolveSymbol(selector, chainId);
9622
9824
  }
9623
- throw createTokenResolutionError(`Invalid selector type: ${typeof selector}. Expected string or object with locator.`, selector, chainId);
9825
+ throw createTokenResolutionError(`Invalid selector type: ${typeof selector}. Expected a token symbol or a raw selector (with locator).`, selector, chainId);
9624
9826
  },
9625
9827
  resolveByAddress (address, chainId) {
9626
9828
  if (!address || typeof address !== 'string') {
@@ -9742,9 +9944,17 @@ const swapTokenEnumSchema = zod.z.enum([
9742
9944
  *
9743
9945
  * // Native token (chain-derived decimals)
9744
9946
  * formatAmount({ value: '3141592000000000000', token: 'NATIVE', chain: Ethereum }) // "3.141592"
9947
+ *
9948
+ * // Explicit decimals (skips all registry lookups)
9949
+ * formatAmount({ value: '100000000', token: 'USDC', decimals: 8 }) // "1"
9745
9950
  * ```
9746
9951
  */ const formatAmount = (params)=>{
9747
9952
  const { value, token, tokens } = params;
9953
+ // Explicit decimals win — used when the caller resolved decimals itself
9954
+ // (e.g. through a provider) for a token outside the built-in registries.
9955
+ if (params.decimals !== undefined) {
9956
+ return formatUnits(value, params.decimals);
9957
+ }
9748
9958
  // Handle NATIVE token first (chain-specific decimals)
9749
9959
  if (token === 'NATIVE') {
9750
9960
  if (params.chain === undefined) {
@@ -10354,7 +10564,7 @@ const swapTokenEnumSchema = zod.z.enum([
10354
10564
  }
10355
10565
 
10356
10566
  var name$2 = "@circle-fin/bridge-kit";
10357
- var version$2 = "1.14.1";
10567
+ var version$2 = "1.15.0";
10358
10568
  var pkg$2 = {
10359
10569
  name: name$2,
10360
10570
  version: version$2};
@@ -11053,7 +11263,72 @@ var TransferSpeed;
11053
11263
  */ recipientAddress: zod.z.string().trim().min(1, 'Fee recipient must be a non-empty string').optional()
11054
11264
  }).strict();
11055
11265
  /**
11056
- * Schema for validating bridge parameters.
11266
+ * Factory for the bridge-params Zod schema, parameterized by the token
11267
+ * validator. The base schema enforces all non-token fields (amount,
11268
+ * source, destination, config); callers supply the Zod schema for the
11269
+ * `token` field, allowing each provider to validate the token type it
11270
+ * accepts.
11271
+ *
11272
+ * @param tokenSchema - Zod schema applied to the `token` field. Pass
11273
+ * `z.literal('USDC')` for USDC-only validation, or any
11274
+ * provider-specific schema (e.g. a `0x`-prefixed hex regex) for
11275
+ * providers that accept a different token type.
11276
+ * @param config - Required. `maxDecimals` caps the decimal precision
11277
+ * permitted in `amount` and `config.maxFee`. Pass the widest value
11278
+ * any of the provider's tokens require — `6` for USDC-only, `18`
11279
+ * for an ERC-20 family that includes wETH, etc. The schema is a
11280
+ * coarse syntactic gate; narrower per-token precision is enforced
11281
+ * by the provider downstream.
11282
+ * @returns A Zod object schema whose `token` field is validated by
11283
+ * `tokenSchema` and whose other fields (`amount`, `source`,
11284
+ * `destination`, `config`) are validated against the shared bridge
11285
+ * contract. Use `.safeParse` / `.parse` directly, or feed the schema
11286
+ * to {@link parseOrThrow} from `@core/utils` to surface validation
11287
+ * failures as `KitError` with the canonical
11288
+ * `INPUT_VALIDATION_FAILED` code.
11289
+ *
11290
+ * @example
11291
+ * ```typescript
11292
+ * import { createBridgeParamsSchema, z } from '@core/provider'
11293
+ *
11294
+ * const usdcSchema = createBridgeParamsSchema(z.literal('USDC'), { maxDecimals: 6 })
11295
+ * const hexSchema = createBridgeParamsSchema(
11296
+ * z.string().regex(/^0x[0-9a-fA-F]{64}$/),
11297
+ * { maxDecimals: 18 },
11298
+ * )
11299
+ * ```
11300
+ */ // The full inferred return type of `z.object({...})` here is
11301
+ // effectively impossible to spell out by hand without re-stating every
11302
+ // field's schema. TypeScript infers it from the body — callers receive
11303
+ // a precise Zod schema type via inference, and the explicit-return
11304
+ // rules are disabled for that reason.
11305
+ // eslint-disable-next-line @typescript-eslint/explicit-function-return-type, @typescript-eslint/explicit-module-boundary-types
11306
+ function createBridgeParamsSchema(tokenSchema, config) {
11307
+ const { maxDecimals } = config;
11308
+ return zod.z.object({
11309
+ amount: zod.z.string().min(1, 'Required').pipe(createDecimalStringValidator({
11310
+ allowZero: false,
11311
+ regexMessage: AMOUNT_FORMAT_ERROR_MESSAGE,
11312
+ attributeName: 'amount',
11313
+ maxDecimals
11314
+ })(zod.z.string())),
11315
+ source: walletContextSchema,
11316
+ destination: bridgeDestinationSchema$1,
11317
+ token: tokenSchema,
11318
+ config: zod.z.object({
11319
+ transferSpeed: zod.z.nativeEnum(TransferSpeed).optional(),
11320
+ maxFee: zod.z.string().pipe(createDecimalStringValidator({
11321
+ allowZero: true,
11322
+ regexMessage: MAX_FEE_FORMAT_ERROR_MESSAGE,
11323
+ attributeName: 'maxFee',
11324
+ maxDecimals
11325
+ })(zod.z.string())).optional(),
11326
+ customFee: customFeeSchema.optional()
11327
+ })
11328
+ });
11329
+ }
11330
+ /**
11331
+ * Schema for validating bridge parameters with USDC as the token.
11057
11332
  * This ensures all required fields are present and properly typed.
11058
11333
  * A bridge must include:
11059
11334
  * - A valid amount (non-empty numeric string \> 0)
@@ -11061,11 +11336,15 @@ var TransferSpeed;
11061
11336
  * - USDC as the token
11062
11337
  * - Optional config with transfer speed and max fee settings
11063
11338
  *
11339
+ * Providers that accept a non-USDC token type should call
11340
+ * {@link createBridgeParamsSchema} with their own token schema rather
11341
+ * than reusing this constant.
11342
+ *
11064
11343
  * @throws KitError if validation fails
11065
11344
  *
11066
11345
  * @example
11067
11346
  * ```typescript
11068
- * import { bridgeParamsSchema } from '@core/provider'
11347
+ * import { usdcBridgeParamsSchema } from '@core/provider'
11069
11348
  *
11070
11349
  * const validBridge = {
11071
11350
  * amount: '100.50',
@@ -11090,175 +11369,43 @@ var TransferSpeed;
11090
11369
  * }
11091
11370
  * }
11092
11371
  *
11093
- * const result = bridgeParamsSchema.safeParse(validBridge)
11372
+ * const result = usdcBridgeParamsSchema.safeParse(validBridge)
11094
11373
  * console.log(result.success) // true
11095
11374
  * ```
11096
- */ zod.z.object({
11097
- amount: zod.z.string().min(1, 'Required').pipe(createDecimalStringValidator({
11098
- allowZero: false,
11099
- regexMessage: AMOUNT_FORMAT_ERROR_MESSAGE,
11100
- attributeName: 'amount',
11101
- maxDecimals: 6
11102
- })(zod.z.string())),
11103
- source: walletContextSchema,
11104
- destination: bridgeDestinationSchema$1,
11105
- token: zod.z.literal('USDC'),
11106
- config: zod.z.object({
11107
- transferSpeed: zod.z.nativeEnum(TransferSpeed).optional(),
11108
- maxFee: zod.z.string().pipe(createDecimalStringValidator({
11109
- allowZero: true,
11110
- regexMessage: MAX_FEE_FORMAT_ERROR_MESSAGE,
11111
- attributeName: 'maxFee',
11112
- maxDecimals: 6
11113
- })(zod.z.string())).optional(),
11114
- customFee: customFeeSchema.optional()
11115
- })
11375
+ */ createBridgeParamsSchema(zod.z.literal('USDC'), {
11376
+ maxDecimals: 6
11116
11377
  });
11117
11378
 
11118
- /**
11119
- * Creates a Zod superRefine validator for recipient address format validation.
11120
- * Validates that the address format matches the expected format for the chain type.
11121
- *
11122
- * @returns A superRefine function that validates recipientAddress against chain type
11123
- */ function createRecipientAddressValidator() {
11124
- return (data, ctx)=>{
11125
- const chain = data.chain;
11126
- if (chain === null) {
11127
- return;
11128
- }
11129
- if (!isValidAddressForChain(data.recipientAddress, chain)) {
11130
- const chainInfo = extractChainInfo(chain);
11131
- ctx.addIssue({
11132
- code: zod.z.ZodIssueCode.custom,
11133
- path: [
11134
- 'recipientAddress'
11135
- ],
11136
- message: `Invalid address format for ${String(chainInfo.name)}. Expected ${chainInfo.expectedAddressFormat}, but received: ${data.recipientAddress}`
11137
- });
11138
- }
11139
- };
11140
- }
11141
- /**
11142
- * Schema for validating AdapterContext for bridge operations.
11143
- * Must always contain both adapter and chain explicitly.
11144
- *
11145
- * Optionally includes address for developer-controlled adapters.
11146
- */ const adapterContextSchema$3 = zod.z.object({
11147
- adapter: adapterSchema,
11148
- chain: bridgeChainIdentifierSchema,
11149
- address: zod.z.string().optional()
11150
- });
11151
- /**
11152
- * Schema for validating BridgeDestinationWithAddress objects.
11153
- * Contains an explicit recipientAddress along with adapter and chain.
11154
- * The address format is validated based on the chain type (EVM or Solana).
11155
- */ const bridgeDestinationWithAddressSchema = adapterContextSchema$3.extend({
11156
- recipientAddress: zod.z.string().min(1, 'Recipient address is required'),
11157
- useForwarder: zod.z.boolean().optional()
11158
- }).superRefine(createRecipientAddressValidator());
11159
- /**
11160
- * Schema for validating AdapterContext with optional useForwarder.
11161
- * Extends adapterContextSchema with the useForwarder flag.
11162
- */ const adapterContextWithForwarderSchema = adapterContextSchema$3.extend({
11163
- useForwarder: zod.z.boolean().optional()
11164
- });
11165
- /**
11166
- * Schema for validating ForwarderDestination objects.
11167
- * Used when useForwarder is true and no adapter is provided.
11168
- * Requires chain, recipientAddress, and useForwarder: true.
11169
- *
11170
- * When using this destination type:
11171
- * - The mint step completes when the IRIS API confirms forwardState === 'CONFIRMED'
11172
- * - No on-chain transaction confirmation is performed (no adapter available)
11173
- * - The mint step's data field will be undefined (no transaction receipt)
11174
- */ const forwarderDestinationSchema = zod.z.object({
11175
- chain: bridgeChainIdentifierSchema,
11176
- recipientAddress: zod.z.string().min(1, 'Recipient address is required'),
11177
- useForwarder: zod.z.literal(true)
11178
- }).strict().superRefine(createRecipientAddressValidator());
11179
- /**
11180
- * Schema for validating BridgeDestination union type.
11181
- * Supports three destination configurations:
11182
- * - BridgeDestinationWithAddress (adapter with explicit recipient)
11183
- * - ForwarderDestination (no adapter, requires useForwarder: true and recipientAddress)
11184
- * - AdapterContext with optional useForwarder (adapter for default recipient)
11185
- *
11186
- * When using ForwarderDestination (no adapter):
11187
- * - The mint step completes when the IRIS API confirms forwardState === 'CONFIRMED'
11188
- * - No on-chain transaction confirmation is performed
11189
- *
11190
- * The order matters: we check the more specific schemas first.
11191
- * This ensures that objects with specific fields are matched correctly.
11192
- */ const bridgeDestinationSchema = zod.z.union([
11193
- bridgeDestinationWithAddressSchema,
11194
- forwarderDestinationSchema,
11195
- adapterContextWithForwarderSchema.strict()
11196
- ]);
11197
- /**
11198
- * Schema for validating bridge parameters with chain identifiers.
11199
- * This extends the core provider's schema but adapts it for the bridge kit's
11200
- * more flexible interface that accepts chain identifiers.
11201
- *
11202
- * The schema validates:
11203
- * - From adapter context (must always include both adapter and chain)
11204
- * - To bridge destination (AdapterContext or BridgeDestinationWithAddress)
11205
- * - Amount is a non-empty numeric string \> 0
11206
- * - Token is optional and defaults to 'USDC'
11207
- * - Optional config parameters (transfer speed, max fee)
11208
- *
11209
- * @example
11210
- * ```typescript
11211
- * import { bridgeParamsWithChainIdentifierSchema } from '@circle-fin/bridge-kit'
11212
- *
11213
- * const params = {
11214
- * from: {
11215
- * adapter: sourceAdapter,
11216
- * chain: 'Ethereum'
11217
- * },
11218
- * to: {
11219
- * adapter: destAdapter,
11220
- * chain: 'Base'
11221
- * },
11222
- * amount: '100.50',
11223
- * token: 'USDC',
11224
- * config: {
11225
- * transferSpeed: 'FAST'
11226
- * }
11227
- * }
11228
- *
11229
- * const result = bridgeParamsWithChainIdentifierSchema.safeParse(params)
11230
- * if (result.success) {
11231
- * console.log('Parameters are valid')
11232
- * } else {
11233
- * console.error('Validation failed:', result.error)
11234
- * }
11235
- * ```
11236
- */ zod.z.object({
11237
- from: adapterContextSchema$3.strict(),
11238
- to: bridgeDestinationSchema,
11239
- amount: zod.z.string().min(1, 'Required').pipe(createDecimalStringValidator({
11240
- allowZero: false,
11241
- regexMessage: AMOUNT_FORMAT_ERROR_MESSAGE,
11242
- attributeName: 'amount',
11243
- maxDecimals: 6
11244
- })(zod.z.string())),
11245
- token: zod.z.literal('USDC').optional(),
11246
- config: zod.z.object({
11247
- transferSpeed: zod.z.nativeEnum(TransferSpeed).optional(),
11248
- feePayment: zod.z.enum([
11249
- 'source',
11250
- 'destination'
11251
- ]).optional(),
11252
- maxFee: zod.z.string().min(1, 'Required').pipe(createDecimalStringValidator({
11253
- allowZero: true,
11254
- regexMessage: MAX_FEE_FORMAT_ERROR_MESSAGE,
11255
- attributeName: 'maxFee',
11256
- maxDecimals: 6
11257
- })(zod.z.string())).optional(),
11258
- customFee: customFeeSchema.optional()
11259
- }).optional(),
11260
- quote: zod.z.string().regex(/^0x([a-fA-F0-9]{2})+$/, 'must be non-empty 0x hex').optional()
11261
- });
11379
+ // ----------------------------------------------------------------------------
11380
+ // IRIS API base URLs
11381
+ // ----------------------------------------------------------------------------
11382
+ // ----------------------------------------------------------------------------
11383
+ // Known token symbols (DX convenience)
11384
+ // ----------------------------------------------------------------------------
11385
+ //
11386
+ // These constants back symbol -> id resolution as a convenience: a caller may
11387
+ // pass a known symbol instead of a raw bytes32 id. They do NOT gate
11388
+ // routability.
11389
+ /**
11390
+ * Display symbols the provider recognizes as a convenience for callers.
11391
+ *
11392
+ * A consumer may pass one of these symbols instead of a raw bytes32 token
11393
+ * id; the provider resolves it to the symbol's canonical bytes32 id via
11394
+ * {@link KNOWN_TOKEN_IDS_BY_NETWORK} (a symbol can map to more than one
11395
+ * bridge, so the map pins the canonical one). This list does NOT gate
11396
+ * routability: any token the IRIS registry lists with deployments on both
11397
+ * endpoints routes when passed by its bytes32 id, whether listed here or
11398
+ * not.
11399
+ *
11400
+ * @example
11401
+ * ```typescript
11402
+ * for (const symbol of KNOWN_TOKEN_SYMBOLS) console.log(symbol)
11403
+ * ```
11404
+ */ const KNOWN_TOKEN_SYMBOLS = [
11405
+ 'cirBTC',
11406
+ 'wETH',
11407
+ 'EURC'
11408
+ ];
11262
11409
 
11263
11410
  /**
11264
11411
  * Define a schema for runtime logger interfaces.
@@ -11633,6 +11780,186 @@ var TransferSpeed;
11633
11780
  clock: zod.z.any().optional()
11634
11781
  }).passthrough();
11635
11782
 
11783
+ /**
11784
+ * Creates a Zod superRefine validator for recipient address format validation.
11785
+ * Validates that the address format matches the expected format for the chain type.
11786
+ *
11787
+ * @returns A superRefine function that validates recipientAddress against chain type
11788
+ */ function createRecipientAddressValidator() {
11789
+ return (data, ctx)=>{
11790
+ const chain = data.chain;
11791
+ if (chain === null) {
11792
+ return;
11793
+ }
11794
+ if (!isValidAddressForChain(data.recipientAddress, chain)) {
11795
+ const chainInfo = extractChainInfo(chain);
11796
+ ctx.addIssue({
11797
+ code: zod.z.ZodIssueCode.custom,
11798
+ path: [
11799
+ 'recipientAddress'
11800
+ ],
11801
+ message: `Invalid address format for ${String(chainInfo.name)}. Expected ${chainInfo.expectedAddressFormat}, but received: ${data.recipientAddress}`
11802
+ });
11803
+ }
11804
+ };
11805
+ }
11806
+ /**
11807
+ * Schema for `BridgeParams.token`.
11808
+ *
11809
+ * Accept `'USDC'`, a symbol from {@link KNOWN_TOKEN_SYMBOLS}, or a bytes32 id
11810
+ * (`0x` plus exactly 64 hex characters). Reject unknown symbols, malformed ids,
11811
+ * and `{ provider, id }` objects. A custom extra provider cannot introduce a
11812
+ * new symbol through this field — only a bytes32 id.
11813
+ *
11814
+ * Omit the field to default to `'USDC'`.
11815
+ */ const bridgeTokenSchema = zod.z.union([
11816
+ zod.z.enum([
11817
+ 'USDC',
11818
+ ...KNOWN_TOKEN_SYMBOLS
11819
+ ]),
11820
+ zod.z.string().regex(/^0x[0-9a-fA-F]{64}$/, 'Token id must be a bytes32 (0x-prefixed, 64 hex chars)')
11821
+ ]);
11822
+ /**
11823
+ * Schema for validating AdapterContext for bridge operations.
11824
+ * Must always contain both adapter and chain explicitly.
11825
+ *
11826
+ * Optionally includes address for developer-controlled adapters.
11827
+ */ const adapterContextSchema$3 = zod.z.object({
11828
+ adapter: adapterSchema,
11829
+ chain: bridgeChainIdentifierSchema,
11830
+ address: zod.z.string().optional()
11831
+ });
11832
+ /**
11833
+ * Schema for validating BridgeDestinationWithAddress objects.
11834
+ * Contains an explicit recipientAddress along with adapter and chain.
11835
+ * The address format is validated based on the chain type (EVM or Solana).
11836
+ */ const bridgeDestinationWithAddressSchema = adapterContextSchema$3.extend({
11837
+ recipientAddress: zod.z.string().min(1, 'Recipient address is required'),
11838
+ useForwarder: zod.z.boolean().optional()
11839
+ }).superRefine(createRecipientAddressValidator());
11840
+ /**
11841
+ * Schema for validating AdapterContext with optional useForwarder.
11842
+ * Extends adapterContextSchema with the useForwarder flag.
11843
+ */ const adapterContextWithForwarderSchema = adapterContextSchema$3.extend({
11844
+ useForwarder: zod.z.boolean().optional()
11845
+ });
11846
+ /**
11847
+ * Schema for validating ForwarderDestination objects.
11848
+ * Used when useForwarder is true and no adapter is provided.
11849
+ * Requires chain, recipientAddress, and useForwarder: true.
11850
+ *
11851
+ * When using this destination type:
11852
+ * - The mint step completes when the IRIS API confirms forwardState === 'CONFIRMED'
11853
+ * - No on-chain transaction confirmation is performed (no adapter available)
11854
+ * - The mint step's data field will be undefined (no transaction receipt)
11855
+ */ const forwarderDestinationSchema = zod.z.object({
11856
+ chain: bridgeChainIdentifierSchema,
11857
+ recipientAddress: zod.z.string().min(1, 'Recipient address is required'),
11858
+ useForwarder: zod.z.literal(true)
11859
+ }).strict().superRefine(createRecipientAddressValidator());
11860
+ /**
11861
+ * Schema for validating BridgeDestination union type.
11862
+ * Supports three destination configurations:
11863
+ * - BridgeDestinationWithAddress (adapter with explicit recipient)
11864
+ * - ForwarderDestination (no adapter, requires useForwarder: true and recipientAddress)
11865
+ * - AdapterContext with optional useForwarder (adapter for default recipient)
11866
+ *
11867
+ * When using ForwarderDestination (no adapter):
11868
+ * - The mint step completes when the IRIS API confirms forwardState === 'CONFIRMED'
11869
+ * - No on-chain transaction confirmation is performed
11870
+ *
11871
+ * The order matters: we check the more specific schemas first.
11872
+ * This ensures that objects with specific fields are matched correctly.
11873
+ */ const bridgeDestinationSchema = zod.z.union([
11874
+ bridgeDestinationWithAddressSchema,
11875
+ forwarderDestinationSchema,
11876
+ adapterContextWithForwarderSchema.strict()
11877
+ ]);
11878
+ /**
11879
+ * Schema for validating bridge parameters with chain identifiers.
11880
+ * This extends the core provider's schema but adapts it for the bridge kit's
11881
+ * more flexible interface that accepts chain identifiers.
11882
+ *
11883
+ * The schema validates:
11884
+ * - From adapter context (must always include both adapter and chain)
11885
+ * - To bridge destination (AdapterContext or BridgeDestinationWithAddress)
11886
+ * - Amount is a non-empty numeric string \> 0
11887
+ * - Token is optional and defaults to 'USDC'
11888
+ * - Optional config parameters (transfer speed, max fee)
11889
+ *
11890
+ * @example
11891
+ * ```typescript
11892
+ * import { bridgeParamsWithChainIdentifierSchema } from '@circle-fin/bridge-kit'
11893
+ *
11894
+ * const params = {
11895
+ * from: {
11896
+ * adapter: sourceAdapter,
11897
+ * chain: 'Ethereum'
11898
+ * },
11899
+ * to: {
11900
+ * adapter: destAdapter,
11901
+ * chain: 'Base'
11902
+ * },
11903
+ * amount: '100.50',
11904
+ * token: 'USDC',
11905
+ * config: {
11906
+ * transferSpeed: 'FAST'
11907
+ * }
11908
+ * }
11909
+ *
11910
+ * const result = bridgeParamsWithChainIdentifierSchema.safeParse(params)
11911
+ * if (result.success) {
11912
+ * console.log('Parameters are valid')
11913
+ * } else {
11914
+ * console.error('Validation failed:', result.error)
11915
+ * }
11916
+ * ```
11917
+ */ zod.z.object({
11918
+ from: adapterContextSchema$3.strict(),
11919
+ to: bridgeDestinationSchema,
11920
+ amount: zod.z.string().min(1, 'Required').pipe(createDecimalStringValidator({
11921
+ allowZero: false,
11922
+ regexMessage: AMOUNT_FORMAT_ERROR_MESSAGE,
11923
+ attributeName: 'amount',
11924
+ // Widest precision any routable token needs (wETH = 18). This gate is
11925
+ // token-agnostic and runs before the route provider is known, so it
11926
+ // can only cap coarsely; the token's exact precision is enforced later
11927
+ // at the scaling boundary (`BridgeKit.scaleResolvedAmount`). USDC (6)
11928
+ // and every narrower token stay valid.
11929
+ maxDecimals: 18
11930
+ })(zod.z.string())),
11931
+ token: bridgeTokenSchema.optional(),
11932
+ config: zod.z.object({
11933
+ transferSpeed: zod.z.nativeEnum(TransferSpeed).optional(),
11934
+ feePayment: zod.z.enum([
11935
+ 'source',
11936
+ 'destination'
11937
+ ]).optional(),
11938
+ maxFee: zod.z.string().min(1, 'Required').pipe(createDecimalStringValidator({
11939
+ allowZero: true,
11940
+ regexMessage: MAX_FEE_FORMAT_ERROR_MESSAGE,
11941
+ attributeName: 'maxFee',
11942
+ // See `amount` above: widest routable precision (18); the exact
11943
+ // per-token precision is enforced at the scaling boundary.
11944
+ maxDecimals: 18
11945
+ })(zod.z.string())).optional(),
11946
+ customFee: customFeeSchema.optional()
11947
+ }).optional(),
11948
+ // Top-level (not nested under `config`) to mirror `BridgeParams.quote`.
11949
+ //
11950
+ // `z.unknown()` rather than a shape: the quote belongs to whichever provider
11951
+ // issued it, and a route is matched to a provider only after these
11952
+ // parameters are validated, so there is no one shape to check here.
11953
+ //
11954
+ // It also keeps the value intact. This object strips unknown keys, so a
11955
+ // nested `z.object()` would clone the quote and drop every key not listed —
11956
+ // losing a field the issuing provider added, between `estimate` and
11957
+ // `bridge`. Shape is checked where the quote is consumed instead: CCTPx
11958
+ // against its own envelope schema, and the receive-exact path in
11959
+ // `sourceFees.ts` before it calls the Fee Service.
11960
+ quote: zod.z.unknown().optional()
11961
+ });
11962
+
11636
11963
  /**
11637
11964
  * The ASCII "cctp-forward" magic, hex-encoded (no `0x`), that a forward-friendly
11638
11965
  * hookData must start with.
@@ -11872,7 +12199,7 @@ const validateQuoteItemSchema = zod.z.object({
11872
12199
  registerKit(`${pkg$2.name}/${pkg$2.version}`);
11873
12200
 
11874
12201
  var name$1 = "@circle-fin/swap-kit";
11875
- var version$1 = "1.6.1";
12202
+ var version$1 = "1.7.0";
11876
12203
  var pkg$1 = {
11877
12204
  name: name$1,
11878
12205
  version: version$1};
@@ -15133,6 +15460,11 @@ function resolveFeePayoutChain(tokenIn, tokenOut, sourceChain, destinationChain)
15133
15460
  name: 'USDC',
15134
15461
  version: '2'
15135
15462
  },
15463
+ Arc: {
15464
+ chainId: Arc.chainId,
15465
+ name: 'USDC',
15466
+ version: '2'
15467
+ },
15136
15468
  Arc_Testnet: {
15137
15469
  chainId: ArcTestnet.chainId,
15138
15470
  name: 'USDC',
@@ -22244,7 +22576,7 @@ registerKit(`${pkg$1.name}/${pkg$1.version}`);
22244
22576
  };
22245
22577
 
22246
22578
  var name = "@circle-fin/earn-kit";
22247
- var version = "1.6.1";
22579
+ var version = "1.7.0";
22248
22580
  var pkg = {
22249
22581
  name: name,
22250
22582
  version: version};
@@ -22259,18 +22591,22 @@ var pkg = {
22259
22591
  *
22260
22592
  * @internal
22261
22593
  */ const CHAIN_TO_API = {
22594
+ [Blockchain.Arc]: 'ARC',
22262
22595
  [Blockchain.Arc_Testnet]: 'ARC-TESTNET'
22263
22596
  };
22264
22597
  /**
22265
22598
  * Map SDK source chain identifiers to bridge source-chain strings.
22266
22599
  *
22267
- * Cross-chain Earn deposits currently support Ethereum Sepolia, Arbitrum
22268
- * Sepolia, and Base Sepolia as source chains.
22600
+ * Cross-chain Earn deposits support Ethereum, Arbitrum, and Base (mainnet
22601
+ * and testnet) as source chains.
22269
22602
  *
22270
22603
  * @internal
22271
22604
  */ ({
22605
+ [Blockchain.Arbitrum]: 'ARB',
22272
22606
  [Blockchain.Arbitrum_Sepolia]: 'ARB-SEPOLIA',
22607
+ [Blockchain.Base]: 'BASE',
22273
22608
  [Blockchain.Base_Sepolia]: 'BASE-SEPOLIA',
22609
+ [Blockchain.Ethereum]: 'ETH',
22274
22610
  [Blockchain.Ethereum_Sepolia]: 'ETH-SEPOLIA'
22275
22611
  });
22276
22612
  /**
@@ -22281,13 +22617,20 @@ var pkg = {
22281
22617
  *
22282
22618
  * @internal
22283
22619
  */ ({
22620
+ [Blockchain.Arc]: CHAIN_TO_API[Blockchain.Arc],
22284
22621
  [Blockchain.Arc_Testnet]: CHAIN_TO_API[Blockchain.Arc_Testnet]
22285
22622
  });
22286
22623
  ({
22624
+ [Blockchain.Arbitrum]: {
22625
+ },
22287
22626
  [Blockchain.Arbitrum_Sepolia]: {
22288
22627
  },
22628
+ [Blockchain.Base]: {
22629
+ },
22289
22630
  [Blockchain.Base_Sepolia]: {
22290
22631
  },
22632
+ [Blockchain.Ethereum]: {
22633
+ },
22291
22634
  [Blockchain.Ethereum_Sepolia]: {
22292
22635
  }
22293
22636
  });