@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.mjs CHANGED
@@ -726,6 +726,38 @@ class KitError extends Error {
726
726
  name: 'INPUT_AMOUNT_OUT_OF_RANGE',
727
727
  type: 'INPUT'
728
728
  },
729
+ /**
730
+ * Protocol fee is denominated in a token that is not supported for the
731
+ * route (only the native gas token and the route's supported fee tokens,
732
+ * such as USDC, are accepted).
733
+ */ UNSUPPORTED_FEE_TOKEN: {
734
+ code: 1014,
735
+ name: 'INPUT_UNSUPPORTED_FEE_TOKEN',
736
+ type: 'INPUT'
737
+ },
738
+ /** Retry / resume is not supported by this provider for the given result */ RETRY_NOT_SUPPORTED: {
739
+ code: 1015,
740
+ name: 'INPUT_RETRY_NOT_SUPPORTED',
741
+ type: 'INPUT'
742
+ },
743
+ /** Bridge-step analysis for retry is not supported by this provider */ STEP_ANALYSIS_NOT_SUPPORTED: {
744
+ code: 1016,
745
+ name: 'INPUT_STEP_ANALYSIS_NOT_SUPPORTED',
746
+ type: 'INPUT'
747
+ },
748
+ /**
749
+ * A kit operation name collides with a reserved event-subscription
750
+ * method (`on` / `off`) at kit construction.
751
+ */ RESERVED_OPERATION_NAME: {
752
+ code: 1000,
753
+ name: 'INPUT_RESERVED_OPERATION_NAME',
754
+ type: 'INPUT'
755
+ },
756
+ /** A kit was constructed with a missing / undefined operation factory */ MISSING_OPERATION: {
757
+ code: 1017,
758
+ name: 'INPUT_MISSING_OPERATION',
759
+ type: 'INPUT'
760
+ },
729
761
  /** General validation failure for complex validation rules */ VALIDATION_FAILED: {
730
762
  code: 1098,
731
763
  name: 'INPUT_VALIDATION_FAILED',
@@ -936,8 +968,7 @@ class KitError extends Error {
936
968
  code: 8002,
937
969
  name: 'SERVICE_UNKNOWN_ERROR',
938
970
  type: 'SERVICE'
939
- }
940
- };
971
+ }};
941
972
 
942
973
  /**
943
974
  * Creates error for unsupported swap route.
@@ -1164,7 +1195,7 @@ class KitError extends Error {
1164
1195
  * import { createValidationErrorFromZod } from '@core/errors'
1165
1196
  *
1166
1197
  * function validateBridgeParams(params: unknown): asserts params is BridgeParams {
1167
- * const result = bridgeParamsSchema.safeParse(params)
1198
+ * const result = usdcBridgeParamsSchema.safeParse(params)
1168
1199
  * if (!result.success) {
1169
1200
  * throw createValidationErrorFromZod(result.error, 'bridge parameters')
1170
1201
  * }
@@ -2942,9 +2973,10 @@ class KitError extends Error {
2942
2973
  Blockchain["Algorand_Testnet"] = "Algorand_Testnet";
2943
2974
  Blockchain["Aptos"] = "Aptos";
2944
2975
  Blockchain["Aptos_Testnet"] = "Aptos_Testnet";
2945
- Blockchain["Arc_Testnet"] = "Arc_Testnet";
2946
2976
  Blockchain["Arbitrum"] = "Arbitrum";
2947
2977
  Blockchain["Arbitrum_Sepolia"] = "Arbitrum_Sepolia";
2978
+ Blockchain["Arc"] = "Arc";
2979
+ Blockchain["Arc_Testnet"] = "Arc_Testnet";
2948
2980
  Blockchain["Avalanche"] = "Avalanche";
2949
2981
  Blockchain["Avalanche_Fuji"] = "Avalanche_Fuji";
2950
2982
  Blockchain["Base"] = "Base";
@@ -3031,6 +3063,7 @@ var SwapChain;
3031
3063
  SwapChain["XDC"] = "XDC";
3032
3064
  SwapChain["HyperEVM"] = "HyperEVM";
3033
3065
  SwapChain["Monad"] = "Monad";
3066
+ SwapChain["Arc"] = "Arc";
3034
3067
  // Testnet chains with swap support
3035
3068
  SwapChain["Arc_Testnet"] = "Arc_Testnet";
3036
3069
  })(SwapChain || (SwapChain = {}));
@@ -3038,6 +3071,7 @@ var BridgeChain;
3038
3071
  (function(BridgeChain) {
3039
3072
  // Mainnet chains with CCTPv2 support
3040
3073
  BridgeChain["Arbitrum"] = "Arbitrum";
3074
+ BridgeChain["Arc"] = "Arc";
3041
3075
  BridgeChain["Avalanche"] = "Avalanche";
3042
3076
  BridgeChain["Base"] = "Base";
3043
3077
  BridgeChain["Codex"] = "Codex";
@@ -3093,6 +3127,7 @@ var BridgeChain;
3093
3127
  var UnifiedBalanceChain;
3094
3128
  (function(UnifiedBalanceChain) {
3095
3129
  // Mainnet chains with Gateway V1 support
3130
+ UnifiedBalanceChain["Arc"] = "Arc";
3096
3131
  UnifiedBalanceChain["Arbitrum"] = "Arbitrum";
3097
3132
  UnifiedBalanceChain["Avalanche"] = "Avalanche";
3098
3133
  UnifiedBalanceChain["Base"] = "Base";
@@ -3122,6 +3157,7 @@ var UnifiedBalanceChain;
3122
3157
  })(UnifiedBalanceChain || (UnifiedBalanceChain = {}));
3123
3158
  var EarnChain;
3124
3159
  (function(EarnChain) {
3160
+ EarnChain["Arc"] = "Arc";
3125
3161
  EarnChain["Arc_Testnet"] = "Arc_Testnet";
3126
3162
  })(EarnChain || (EarnChain = {}));
3127
3163
  /**
@@ -3138,8 +3174,11 @@ var EarnChain;
3138
3174
  * console.log(EARN_BRIDGE_SOURCE_BLOCKCHAINS.join(', '))
3139
3175
  * ```
3140
3176
  */ const EARN_BRIDGE_SOURCE_BLOCKCHAINS = [
3177
+ "Arbitrum",
3141
3178
  "Arbitrum_Sepolia",
3179
+ "Base",
3142
3180
  "Base_Sepolia",
3181
+ "Ethereum",
3143
3182
  "Ethereum_Sepolia"
3144
3183
  ];
3145
3184
  /**
@@ -3153,6 +3192,7 @@ var EarnChain;
3153
3192
  * console.log(EARN_BRIDGE_DESTINATION_BLOCKCHAINS.join(', '))
3154
3193
  * ```
3155
3194
  */ const EARN_BRIDGE_DESTINATION_BLOCKCHAINS = [
3195
+ "Arc",
3156
3196
  "Arc_Testnet"
3157
3197
  ];
3158
3198
 
@@ -3469,6 +3509,25 @@ var EarnChain;
3469
3509
  * EVM-compatible chains. Use this address when deploying or testing
3470
3510
  * cross-chain USDC transfers on test networks.
3471
3511
  */ const BRIDGE_CONTRACT_EVM_TESTNET = '0xC5567a5E3370d4DBfB0540025078e283e36A363d';
3512
+ /**
3513
+ * The CrossChainTokenService (CCTPx) service address for EVM testnet networks.
3514
+ *
3515
+ * This service coordinates CCTPx cross-chain token operations on testnet
3516
+ * environments and is shared by every EVM test network CCTPx supports. Read the
3517
+ * chain definitions via `isCCTPXSupported` rather than trusting a list here,
3518
+ * which goes stale as deployments land.
3519
+ */ const CCTPX_SERVICE_ADDRESS_EVM_TESTNET = '0x63753E722bd2C2A5DF6EE19C5106662208B81077';
3520
+ /**
3521
+ * CrossChainTokenService (CCTS) proxy address for CCTPx on EVM **mainnet**.
3522
+ *
3523
+ * @remarks
3524
+ * A distinct deployment from {@link CCTPX_SERVICE_ADDRESS_EVM_TESTNET}, shared
3525
+ * by every EVM mainnet chain that CCTPx supports. A chain becomes
3526
+ * CCTPx-eligible only once its definition carries this as
3527
+ * `cctpx.serviceAddress`, and a route additionally needs both of its endpoints
3528
+ * eligible — so adding a chain here is the deliberate, reviewable step that
3529
+ * opens mainnet CCTPx for it.
3530
+ */ const CCTPX_SERVICE_ADDRESS_EVM_MAINNET = '0x431871229103b780868f8C6BB820cd16ECf942BC';
3472
3531
  /**
3473
3532
  * The bridge contract address for EVM mainnet networks.
3474
3533
  *
@@ -3577,6 +3636,76 @@ var EarnChain;
3577
3636
  * Identical across all testnet EVM destination chains.
3578
3637
  */ const GENERIC_EXECUTOR_EVM_TESTNET = '0xEdC81040756AcCfF070c21D37b265b9D0b5Ba45e';
3579
3638
 
3639
+ /**
3640
+ * Arc Mainnet chain definition
3641
+ * @remarks
3642
+ * This represents the official production network for the Arc blockchain,
3643
+ * Circle's EVM-compatible Layer-1 designed for stablecoin finance
3644
+ * and asset tokenization. Arc uses USDC as the native gas token and
3645
+ * features the Malachite Byzantine Fault Tolerant (BFT) consensus
3646
+ * engine for sub-second finality.
3647
+ */ const Arc = defineChain({
3648
+ type: 'evm',
3649
+ chain: Blockchain.Arc,
3650
+ name: 'Arc',
3651
+ title: 'Arc Mainnet',
3652
+ nativeCurrency: {
3653
+ name: 'USDC',
3654
+ symbol: 'USDC',
3655
+ // Arc uses native USDC with 18 decimals for gas payments (EVM standard).
3656
+ // Note: The ERC-20 USDC contract at usdcAddress uses 6 decimals.
3657
+ // See: https://docs.arc.network/arc/references/contract-addresses
3658
+ decimals: 18
3659
+ },
3660
+ chainId: 5042,
3661
+ isTestnet: false,
3662
+ explorerUrl: 'https://explorer.arc.io/tx/{hash}',
3663
+ rpcEndpoints: [
3664
+ 'https://rpc.mainnet.arc.io/'
3665
+ ],
3666
+ eurcAddress: '0xbEf5f6d51CB62b58e6A8f77868681825C6fe21c1',
3667
+ usdcAddress: '0x3600000000000000000000000000000000000000',
3668
+ usdtAddress: null,
3669
+ cctp: {
3670
+ domain: 26,
3671
+ contracts: {
3672
+ v2: {
3673
+ type: 'split',
3674
+ tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
3675
+ messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
3676
+ confirmations: 1,
3677
+ fastConfirmations: 1
3678
+ }
3679
+ },
3680
+ forwarderSupported: {
3681
+ source: false,
3682
+ destination: true
3683
+ }
3684
+ },
3685
+ cctpx: {
3686
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
3687
+ },
3688
+ kitContracts: {
3689
+ bridge: BRIDGE_CONTRACT_EVM_MAINNET,
3690
+ adapter: ADAPTER_CONTRACT_EVM_MAINNET
3691
+ },
3692
+ gateway: {
3693
+ domain: 26,
3694
+ contracts: {
3695
+ v1: {
3696
+ wallet: GATEWAY_WALLET_EVM_MAINNET,
3697
+ minter: GATEWAY_MINTER_EVM_MAINNET,
3698
+ depositForHandler: DEPOSIT_FOR_HANDLER_EVM_MAINNET,
3699
+ genericExecutor: GENERIC_EXECUTOR_EVM_MAINNET
3700
+ }
3701
+ },
3702
+ forwarderSupported: {
3703
+ source: true,
3704
+ destination: true
3705
+ }
3706
+ }
3707
+ });
3708
+
3580
3709
  /**
3581
3710
  * Arc Testnet chain definition
3582
3711
  * @remarks
@@ -3624,6 +3753,9 @@ var EarnChain;
3624
3753
  destination: true
3625
3754
  }
3626
3755
  },
3756
+ cctpx: {
3757
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
3758
+ },
3627
3759
  kitContracts: {
3628
3760
  bridge: BRIDGE_CONTRACT_EVM_TESTNET,
3629
3761
  adapter: ADAPTER_CONTRACT_EVM_TESTNET
@@ -3691,6 +3823,9 @@ var EarnChain;
3691
3823
  destination: true
3692
3824
  }
3693
3825
  },
3826
+ cctpx: {
3827
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
3828
+ },
3694
3829
  kitContracts: {
3695
3830
  bridge: BRIDGE_CONTRACT_EVM_MAINNET,
3696
3831
  adapter: ADAPTER_CONTRACT_EVM_MAINNET
@@ -3756,6 +3891,9 @@ var EarnChain;
3756
3891
  destination: true
3757
3892
  }
3758
3893
  },
3894
+ cctpx: {
3895
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
3896
+ },
3759
3897
  kitContracts: {
3760
3898
  bridge: BRIDGE_CONTRACT_EVM_TESTNET,
3761
3899
  adapter: ADAPTER_CONTRACT_EVM_TESTNET
@@ -3821,6 +3959,9 @@ var EarnChain;
3821
3959
  destination: true
3822
3960
  }
3823
3961
  },
3962
+ cctpx: {
3963
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
3964
+ },
3824
3965
  kitContracts: {
3825
3966
  bridge: BRIDGE_CONTRACT_EVM_MAINNET,
3826
3967
  adapter: ADAPTER_CONTRACT_EVM_MAINNET
@@ -3888,6 +4029,9 @@ var EarnChain;
3888
4029
  rpcEndpoints: [
3889
4030
  'https://api.avax-test.network/ext/bc/C/rpc'
3890
4031
  ],
4032
+ cctpx: {
4033
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
4034
+ },
3891
4035
  kitContracts: {
3892
4036
  bridge: BRIDGE_CONTRACT_EVM_TESTNET
3893
4037
  },
@@ -3955,6 +4099,9 @@ var EarnChain;
3955
4099
  destination: true
3956
4100
  }
3957
4101
  },
4102
+ cctpx: {
4103
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
4104
+ },
3958
4105
  kitContracts: {
3959
4106
  bridge: BRIDGE_CONTRACT_EVM_MAINNET,
3960
4107
  adapter: ADAPTER_CONTRACT_EVM_MAINNET
@@ -4020,6 +4167,9 @@ var EarnChain;
4020
4167
  destination: true
4021
4168
  }
4022
4169
  },
4170
+ cctpx: {
4171
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
4172
+ },
4023
4173
  kitContracts: {
4024
4174
  bridge: BRIDGE_CONTRACT_EVM_TESTNET,
4025
4175
  adapter: ADAPTER_CONTRACT_EVM_TESTNET
@@ -4412,6 +4562,9 @@ var EarnChain;
4412
4562
  destination: true
4413
4563
  }
4414
4564
  },
4565
+ cctpx: {
4566
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
4567
+ },
4415
4568
  kitContracts: {
4416
4569
  bridge: BRIDGE_CONTRACT_EVM_MAINNET,
4417
4570
  adapter: ADAPTER_CONTRACT_EVM_MAINNET
@@ -4477,6 +4630,9 @@ var EarnChain;
4477
4630
  destination: true
4478
4631
  }
4479
4632
  },
4633
+ cctpx: {
4634
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
4635
+ },
4480
4636
  kitContracts: {
4481
4637
  bridge: BRIDGE_CONTRACT_EVM_TESTNET,
4482
4638
  adapter: ADAPTER_CONTRACT_EVM_TESTNET
@@ -5308,6 +5464,9 @@ var EarnChain;
5308
5464
  destination: true
5309
5465
  }
5310
5466
  },
5467
+ cctpx: {
5468
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
5469
+ },
5311
5470
  kitContracts: {
5312
5471
  bridge: BRIDGE_CONTRACT_EVM_MAINNET,
5313
5472
  adapter: ADAPTER_CONTRACT_EVM_MAINNET
@@ -5373,6 +5532,9 @@ var EarnChain;
5373
5532
  destination: true
5374
5533
  }
5375
5534
  },
5535
+ cctpx: {
5536
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
5537
+ },
5376
5538
  kitContracts: {
5377
5539
  bridge: BRIDGE_CONTRACT_EVM_TESTNET
5378
5540
  },
@@ -5768,6 +5930,9 @@ var EarnChain;
5768
5930
  destination: true
5769
5931
  }
5770
5932
  },
5933
+ cctpx: {
5934
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
5935
+ },
5771
5936
  kitContracts: {
5772
5937
  bridge: BRIDGE_CONTRACT_EVM_MAINNET,
5773
5938
  adapter: ADAPTER_CONTRACT_EVM_MAINNET
@@ -5836,6 +6001,9 @@ var EarnChain;
5836
6001
  destination: true
5837
6002
  }
5838
6003
  },
6004
+ cctpx: {
6005
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
6006
+ },
5839
6007
  kitContracts: {
5840
6008
  bridge: BRIDGE_CONTRACT_EVM_TESTNET
5841
6009
  },
@@ -6844,6 +7012,7 @@ var Chains = /*#__PURE__*/Object.freeze({
6844
7012
  AptosTestnet: AptosTestnet,
6845
7013
  Arbitrum: Arbitrum,
6846
7014
  ArbitrumSepolia: ArbitrumSepolia,
7015
+ Arc: Arc,
6847
7016
  ArcTestnet: ArcTestnet,
6848
7017
  Avalanche: Avalanche,
6849
7018
  AvalancheFuji: AvalancheFuji,
@@ -7101,6 +7270,7 @@ var Chains = /*#__PURE__*/Object.freeze({
7101
7270
  usdcAddress: z.string().nullable(),
7102
7271
  usdtAddress: z.string().nullable(),
7103
7272
  cctp: z.any().nullable(),
7273
+ cctpx: z.any().optional(),
7104
7274
  kitContracts: z.object({
7105
7275
  bridge: z.string().optional(),
7106
7276
  adapter: z.string().optional()
@@ -7306,14 +7476,15 @@ const EARN_BRIDGE_DESTINATION_CHAIN_VALUES = EARN_BRIDGE_DESTINATION_BLOCKCHAINS
7306
7476
  * Zod schema for validating the source chain of a cross-chain Earn deposit.
7307
7477
  *
7308
7478
  * Accept a supported source Blockchain value, a matching string literal, or a
7309
- * ChainDefinition for a supported source chain. Source chains are Ethereum
7310
- * Sepolia, Arbitrum Sepolia, and Base Sepolia.
7479
+ * ChainDefinition for a supported source chain. Source chains are Ethereum,
7480
+ * Arbitrum, and Base (mainnet and testnet).
7311
7481
  *
7312
7482
  * @example
7313
7483
  * ```typescript
7314
7484
  * import { earnBridgeSourceChainIdentifierSchema } from '@core/chains'
7315
7485
  *
7316
7486
  * // Valid
7487
+ * earnBridgeSourceChainIdentifierSchema.parse('Ethereum')
7317
7488
  * earnBridgeSourceChainIdentifierSchema.parse('Ethereum_Sepolia')
7318
7489
  *
7319
7490
  * // Invalid (throws ZodError)
@@ -7332,14 +7503,15 @@ const EARN_BRIDGE_DESTINATION_CHAIN_VALUES = EARN_BRIDGE_DESTINATION_BLOCKCHAINS
7332
7503
  * deposit.
7333
7504
  *
7334
7505
  * Accept a supported destination Blockchain value, a matching string literal,
7335
- * or a ChainDefinition for a supported destination chain. Currently only Arc
7336
- * Testnet is supported.
7506
+ * or a ChainDefinition for a supported destination chain. Arc (mainnet) and
7507
+ * Arc Testnet are supported.
7337
7508
  *
7338
7509
  * @example
7339
7510
  * ```typescript
7340
7511
  * import { earnBridgeDestinationChainIdentifierSchema } from '@core/chains'
7341
7512
  *
7342
7513
  * // Valid
7514
+ * earnBridgeDestinationChainIdentifierSchema.parse('Arc')
7343
7515
  * earnBridgeDestinationChainIdentifierSchema.parse('Arc_Testnet')
7344
7516
  *
7345
7517
  * // Invalid (throws ZodError)
@@ -7517,7 +7689,10 @@ const swapTokenEnumSchema = z.enum([
7517
7689
  * Get decimal places for a supported swap token.
7518
7690
  *
7519
7691
  * @param token - Swap token symbol
7520
- * @returns Number of decimals, or null for NATIVE (chain-specific)
7692
+ * @returns Number of decimals; `null` for NATIVE (chain-specific) or when the
7693
+ * symbol is not in the swap registry. Callers must not read `null` as
7694
+ * "use the chain's native decimals" — for a CCTPx token that would scale
7695
+ * an 8-decimal amount as 18.
7521
7696
  *
7522
7697
  * @example
7523
7698
  * ```typescript
@@ -7529,6 +7704,15 @@ const swapTokenEnumSchema = z.enum([
7529
7704
  * ```
7530
7705
  */ function getSwapTokenDecimals(token) {
7531
7706
  if (token === NATIVE_TOKEN) return null;
7707
+ // Membership is checked rather than assumed: callers reach this through
7708
+ // `formatAmount`/`parseAmount` with a plain `string` token, so a value
7709
+ // outside the registry (a provider's own symbol, or a bytes32 id) is
7710
+ // reachable at runtime despite what the parameter type says. A bare index
7711
+ // would throw a raw TypeError from inside the formatter; `null` lets the
7712
+ // caller raise its own "could not determine decimals" error instead.
7713
+ if (!Object.hasOwn(SWAP_TOKEN_REGISTRY, token)) {
7714
+ return null;
7715
+ }
7532
7716
  return SWAP_TOKEN_REGISTRY[token].decimals;
7533
7717
  }
7534
7718
  /**
@@ -8970,6 +9154,7 @@ const swapTokenEnumSchema = z.enum([
8970
9154
  // Mainnets (alphabetically sorted)
8971
9155
  // =========================================================================
8972
9156
  [Blockchain.Arbitrum]: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
9157
+ [Blockchain.Arc]: '0x3600000000000000000000000000000000000000',
8973
9158
  [Blockchain.Avalanche]: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',
8974
9159
  [Blockchain.Base]: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
8975
9160
  [Blockchain.Celo]: '0xcebA9300f2b948710d2653dD7B07f33A8B32118C',
@@ -9084,6 +9269,7 @@ const swapTokenEnumSchema = z.enum([
9084
9269
  // =========================================================================
9085
9270
  // Mainnets
9086
9271
  // =========================================================================
9272
+ [Blockchain.Arc]: '0xbEf5f6d51CB62b58e6A8f77868681825C6fe21c1',
9087
9273
  [Blockchain.Avalanche]: '0xc891EB4cbdEFf6e073e859e987815Ed1505c2ACD',
9088
9274
  [Blockchain.Base]: '0x60a3E35Cc302bFA44Cb288Bc5a4F316Fdb1adb42',
9089
9275
  [Blockchain.Cronos]: '0xA6dE01a2d62C6B5f3525d768f34d276652C554c8',
@@ -9327,6 +9513,7 @@ const swapTokenEnumSchema = z.enum([
9327
9513
  // =========================================================================
9328
9514
  // Mainnets
9329
9515
  // =========================================================================
9516
+ [Blockchain.Arc]: '0x171A4217b86A807A64eB94757Db6849fb4bDbAA0',
9330
9517
  [Blockchain.Ethereum]: '0x72DFB2E44f59C5AD2bAFE84314E5b99a7cd5075E',
9331
9518
  // =========================================================================
9332
9519
  // Testnets
@@ -9419,13 +9606,28 @@ const swapTokenEnumSchema = z.enum([
9419
9606
  }
9420
9607
 
9421
9608
  /**
9422
- * Check if a selector is a raw token selector (object form).
9609
+ * Type guard: narrows a {@link TokenSelector} to a {@link RawTokenSelector}.
9423
9610
  *
9424
9611
  * @param selector - The token selector to check.
9425
- * @returns True if the selector is a raw token selector.
9612
+ * @returns `true` if `selector` is a raw token selector (object with `locator`).
9613
+ *
9614
+ * @example
9615
+ * ```typescript
9616
+ * if (isRawSelector(selector)) {
9617
+ * console.log(selector.locator)
9618
+ * }
9619
+ * ```
9426
9620
  */ function isRawSelector(selector) {
9427
- return typeof selector === 'object' && 'locator' in selector;
9621
+ // `typeof null === 'object'` (a JS quirk) and `'locator' in null`
9622
+ // throws, so the explicit `null` check is required at this exported
9623
+ // guard for JS consumers passing nullish values. The lint rule sees
9624
+ // the parameter typed as `TokenSelector` (no null) and flags the
9625
+ // check as unnecessary — disabled because the check IS necessary at
9626
+ // runtime even though TypeScript can prove it dead statically.
9627
+ return typeof selector === 'object' && // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
9628
+ selector !== null && 'locator' in selector;
9428
9629
  }
9630
+
9429
9631
  /**
9430
9632
  * Normalize a symbol to uppercase for case-insensitive lookup.
9431
9633
  *
@@ -9613,7 +9815,7 @@ const swapTokenEnumSchema = z.enum([
9613
9815
  if (typeof selector === 'string') {
9614
9816
  return resolveSymbol(selector, chainId);
9615
9817
  }
9616
- throw createTokenResolutionError(`Invalid selector type: ${typeof selector}. Expected string or object with locator.`, selector, chainId);
9818
+ throw createTokenResolutionError(`Invalid selector type: ${typeof selector}. Expected a token symbol or a raw selector (with locator).`, selector, chainId);
9617
9819
  },
9618
9820
  resolveByAddress (address, chainId) {
9619
9821
  if (!address || typeof address !== 'string') {
@@ -9735,9 +9937,17 @@ const swapTokenEnumSchema = z.enum([
9735
9937
  *
9736
9938
  * // Native token (chain-derived decimals)
9737
9939
  * formatAmount({ value: '3141592000000000000', token: 'NATIVE', chain: Ethereum }) // "3.141592"
9940
+ *
9941
+ * // Explicit decimals (skips all registry lookups)
9942
+ * formatAmount({ value: '100000000', token: 'USDC', decimals: 8 }) // "1"
9738
9943
  * ```
9739
9944
  */ const formatAmount = (params)=>{
9740
9945
  const { value, token, tokens } = params;
9946
+ // Explicit decimals win — used when the caller resolved decimals itself
9947
+ // (e.g. through a provider) for a token outside the built-in registries.
9948
+ if (params.decimals !== undefined) {
9949
+ return formatUnits(value, params.decimals);
9950
+ }
9741
9951
  // Handle NATIVE token first (chain-specific decimals)
9742
9952
  if (token === 'NATIVE') {
9743
9953
  if (params.chain === undefined) {
@@ -10347,7 +10557,7 @@ const swapTokenEnumSchema = z.enum([
10347
10557
  }
10348
10558
 
10349
10559
  var name$2 = "@circle-fin/bridge-kit";
10350
- var version$2 = "1.14.1";
10560
+ var version$2 = "1.15.0";
10351
10561
  var pkg$2 = {
10352
10562
  name: name$2,
10353
10563
  version: version$2};
@@ -11046,7 +11256,72 @@ var TransferSpeed;
11046
11256
  */ recipientAddress: z.string().trim().min(1, 'Fee recipient must be a non-empty string').optional()
11047
11257
  }).strict();
11048
11258
  /**
11049
- * Schema for validating bridge parameters.
11259
+ * Factory for the bridge-params Zod schema, parameterized by the token
11260
+ * validator. The base schema enforces all non-token fields (amount,
11261
+ * source, destination, config); callers supply the Zod schema for the
11262
+ * `token` field, allowing each provider to validate the token type it
11263
+ * accepts.
11264
+ *
11265
+ * @param tokenSchema - Zod schema applied to the `token` field. Pass
11266
+ * `z.literal('USDC')` for USDC-only validation, or any
11267
+ * provider-specific schema (e.g. a `0x`-prefixed hex regex) for
11268
+ * providers that accept a different token type.
11269
+ * @param config - Required. `maxDecimals` caps the decimal precision
11270
+ * permitted in `amount` and `config.maxFee`. Pass the widest value
11271
+ * any of the provider's tokens require — `6` for USDC-only, `18`
11272
+ * for an ERC-20 family that includes wETH, etc. The schema is a
11273
+ * coarse syntactic gate; narrower per-token precision is enforced
11274
+ * by the provider downstream.
11275
+ * @returns A Zod object schema whose `token` field is validated by
11276
+ * `tokenSchema` and whose other fields (`amount`, `source`,
11277
+ * `destination`, `config`) are validated against the shared bridge
11278
+ * contract. Use `.safeParse` / `.parse` directly, or feed the schema
11279
+ * to {@link parseOrThrow} from `@core/utils` to surface validation
11280
+ * failures as `KitError` with the canonical
11281
+ * `INPUT_VALIDATION_FAILED` code.
11282
+ *
11283
+ * @example
11284
+ * ```typescript
11285
+ * import { createBridgeParamsSchema, z } from '@core/provider'
11286
+ *
11287
+ * const usdcSchema = createBridgeParamsSchema(z.literal('USDC'), { maxDecimals: 6 })
11288
+ * const hexSchema = createBridgeParamsSchema(
11289
+ * z.string().regex(/^0x[0-9a-fA-F]{64}$/),
11290
+ * { maxDecimals: 18 },
11291
+ * )
11292
+ * ```
11293
+ */ // The full inferred return type of `z.object({...})` here is
11294
+ // effectively impossible to spell out by hand without re-stating every
11295
+ // field's schema. TypeScript infers it from the body — callers receive
11296
+ // a precise Zod schema type via inference, and the explicit-return
11297
+ // rules are disabled for that reason.
11298
+ // eslint-disable-next-line @typescript-eslint/explicit-function-return-type, @typescript-eslint/explicit-module-boundary-types
11299
+ function createBridgeParamsSchema(tokenSchema, config) {
11300
+ const { maxDecimals } = config;
11301
+ return z.object({
11302
+ amount: z.string().min(1, 'Required').pipe(createDecimalStringValidator({
11303
+ allowZero: false,
11304
+ regexMessage: AMOUNT_FORMAT_ERROR_MESSAGE,
11305
+ attributeName: 'amount',
11306
+ maxDecimals
11307
+ })(z.string())),
11308
+ source: walletContextSchema,
11309
+ destination: bridgeDestinationSchema$1,
11310
+ token: tokenSchema,
11311
+ config: z.object({
11312
+ transferSpeed: z.nativeEnum(TransferSpeed).optional(),
11313
+ maxFee: z.string().pipe(createDecimalStringValidator({
11314
+ allowZero: true,
11315
+ regexMessage: MAX_FEE_FORMAT_ERROR_MESSAGE,
11316
+ attributeName: 'maxFee',
11317
+ maxDecimals
11318
+ })(z.string())).optional(),
11319
+ customFee: customFeeSchema.optional()
11320
+ })
11321
+ });
11322
+ }
11323
+ /**
11324
+ * Schema for validating bridge parameters with USDC as the token.
11050
11325
  * This ensures all required fields are present and properly typed.
11051
11326
  * A bridge must include:
11052
11327
  * - A valid amount (non-empty numeric string \> 0)
@@ -11054,11 +11329,15 @@ var TransferSpeed;
11054
11329
  * - USDC as the token
11055
11330
  * - Optional config with transfer speed and max fee settings
11056
11331
  *
11332
+ * Providers that accept a non-USDC token type should call
11333
+ * {@link createBridgeParamsSchema} with their own token schema rather
11334
+ * than reusing this constant.
11335
+ *
11057
11336
  * @throws KitError if validation fails
11058
11337
  *
11059
11338
  * @example
11060
11339
  * ```typescript
11061
- * import { bridgeParamsSchema } from '@core/provider'
11340
+ * import { usdcBridgeParamsSchema } from '@core/provider'
11062
11341
  *
11063
11342
  * const validBridge = {
11064
11343
  * amount: '100.50',
@@ -11083,175 +11362,43 @@ var TransferSpeed;
11083
11362
  * }
11084
11363
  * }
11085
11364
  *
11086
- * const result = bridgeParamsSchema.safeParse(validBridge)
11365
+ * const result = usdcBridgeParamsSchema.safeParse(validBridge)
11087
11366
  * console.log(result.success) // true
11088
11367
  * ```
11089
- */ z.object({
11090
- amount: z.string().min(1, 'Required').pipe(createDecimalStringValidator({
11091
- allowZero: false,
11092
- regexMessage: AMOUNT_FORMAT_ERROR_MESSAGE,
11093
- attributeName: 'amount',
11094
- maxDecimals: 6
11095
- })(z.string())),
11096
- source: walletContextSchema,
11097
- destination: bridgeDestinationSchema$1,
11098
- token: z.literal('USDC'),
11099
- config: z.object({
11100
- transferSpeed: z.nativeEnum(TransferSpeed).optional(),
11101
- maxFee: z.string().pipe(createDecimalStringValidator({
11102
- allowZero: true,
11103
- regexMessage: MAX_FEE_FORMAT_ERROR_MESSAGE,
11104
- attributeName: 'maxFee',
11105
- maxDecimals: 6
11106
- })(z.string())).optional(),
11107
- customFee: customFeeSchema.optional()
11108
- })
11368
+ */ createBridgeParamsSchema(z.literal('USDC'), {
11369
+ maxDecimals: 6
11109
11370
  });
11110
11371
 
11111
- /**
11112
- * Creates a Zod superRefine validator for recipient address format validation.
11113
- * Validates that the address format matches the expected format for the chain type.
11114
- *
11115
- * @returns A superRefine function that validates recipientAddress against chain type
11116
- */ function createRecipientAddressValidator() {
11117
- return (data, ctx)=>{
11118
- const chain = data.chain;
11119
- if (chain === null) {
11120
- return;
11121
- }
11122
- if (!isValidAddressForChain(data.recipientAddress, chain)) {
11123
- const chainInfo = extractChainInfo(chain);
11124
- ctx.addIssue({
11125
- code: z.ZodIssueCode.custom,
11126
- path: [
11127
- 'recipientAddress'
11128
- ],
11129
- message: `Invalid address format for ${String(chainInfo.name)}. Expected ${chainInfo.expectedAddressFormat}, but received: ${data.recipientAddress}`
11130
- });
11131
- }
11132
- };
11133
- }
11134
- /**
11135
- * Schema for validating AdapterContext for bridge operations.
11136
- * Must always contain both adapter and chain explicitly.
11137
- *
11138
- * Optionally includes address for developer-controlled adapters.
11139
- */ const adapterContextSchema$3 = z.object({
11140
- adapter: adapterSchema,
11141
- chain: bridgeChainIdentifierSchema,
11142
- address: z.string().optional()
11143
- });
11144
- /**
11145
- * Schema for validating BridgeDestinationWithAddress objects.
11146
- * Contains an explicit recipientAddress along with adapter and chain.
11147
- * The address format is validated based on the chain type (EVM or Solana).
11148
- */ const bridgeDestinationWithAddressSchema = adapterContextSchema$3.extend({
11149
- recipientAddress: z.string().min(1, 'Recipient address is required'),
11150
- useForwarder: z.boolean().optional()
11151
- }).superRefine(createRecipientAddressValidator());
11152
- /**
11153
- * Schema for validating AdapterContext with optional useForwarder.
11154
- * Extends adapterContextSchema with the useForwarder flag.
11155
- */ const adapterContextWithForwarderSchema = adapterContextSchema$3.extend({
11156
- useForwarder: z.boolean().optional()
11157
- });
11158
- /**
11159
- * Schema for validating ForwarderDestination objects.
11160
- * Used when useForwarder is true and no adapter is provided.
11161
- * Requires chain, recipientAddress, and useForwarder: true.
11162
- *
11163
- * When using this destination type:
11164
- * - The mint step completes when the IRIS API confirms forwardState === 'CONFIRMED'
11165
- * - No on-chain transaction confirmation is performed (no adapter available)
11166
- * - The mint step's data field will be undefined (no transaction receipt)
11167
- */ const forwarderDestinationSchema = z.object({
11168
- chain: bridgeChainIdentifierSchema,
11169
- recipientAddress: z.string().min(1, 'Recipient address is required'),
11170
- useForwarder: z.literal(true)
11171
- }).strict().superRefine(createRecipientAddressValidator());
11172
- /**
11173
- * Schema for validating BridgeDestination union type.
11174
- * Supports three destination configurations:
11175
- * - BridgeDestinationWithAddress (adapter with explicit recipient)
11176
- * - ForwarderDestination (no adapter, requires useForwarder: true and recipientAddress)
11177
- * - AdapterContext with optional useForwarder (adapter for default recipient)
11178
- *
11179
- * When using ForwarderDestination (no adapter):
11180
- * - The mint step completes when the IRIS API confirms forwardState === 'CONFIRMED'
11181
- * - No on-chain transaction confirmation is performed
11182
- *
11183
- * The order matters: we check the more specific schemas first.
11184
- * This ensures that objects with specific fields are matched correctly.
11185
- */ const bridgeDestinationSchema = z.union([
11186
- bridgeDestinationWithAddressSchema,
11187
- forwarderDestinationSchema,
11188
- adapterContextWithForwarderSchema.strict()
11189
- ]);
11190
- /**
11191
- * Schema for validating bridge parameters with chain identifiers.
11192
- * This extends the core provider's schema but adapts it for the bridge kit's
11193
- * more flexible interface that accepts chain identifiers.
11194
- *
11195
- * The schema validates:
11196
- * - From adapter context (must always include both adapter and chain)
11197
- * - To bridge destination (AdapterContext or BridgeDestinationWithAddress)
11198
- * - Amount is a non-empty numeric string \> 0
11199
- * - Token is optional and defaults to 'USDC'
11200
- * - Optional config parameters (transfer speed, max fee)
11201
- *
11202
- * @example
11203
- * ```typescript
11204
- * import { bridgeParamsWithChainIdentifierSchema } from '@circle-fin/bridge-kit'
11205
- *
11206
- * const params = {
11207
- * from: {
11208
- * adapter: sourceAdapter,
11209
- * chain: 'Ethereum'
11210
- * },
11211
- * to: {
11212
- * adapter: destAdapter,
11213
- * chain: 'Base'
11214
- * },
11215
- * amount: '100.50',
11216
- * token: 'USDC',
11217
- * config: {
11218
- * transferSpeed: 'FAST'
11219
- * }
11220
- * }
11221
- *
11222
- * const result = bridgeParamsWithChainIdentifierSchema.safeParse(params)
11223
- * if (result.success) {
11224
- * console.log('Parameters are valid')
11225
- * } else {
11226
- * console.error('Validation failed:', result.error)
11227
- * }
11228
- * ```
11229
- */ z.object({
11230
- from: adapterContextSchema$3.strict(),
11231
- to: bridgeDestinationSchema,
11232
- amount: z.string().min(1, 'Required').pipe(createDecimalStringValidator({
11233
- allowZero: false,
11234
- regexMessage: AMOUNT_FORMAT_ERROR_MESSAGE,
11235
- attributeName: 'amount',
11236
- maxDecimals: 6
11237
- })(z.string())),
11238
- token: z.literal('USDC').optional(),
11239
- config: z.object({
11240
- transferSpeed: z.nativeEnum(TransferSpeed).optional(),
11241
- feePayment: z.enum([
11242
- 'source',
11243
- 'destination'
11244
- ]).optional(),
11245
- maxFee: z.string().min(1, 'Required').pipe(createDecimalStringValidator({
11246
- allowZero: true,
11247
- regexMessage: MAX_FEE_FORMAT_ERROR_MESSAGE,
11248
- attributeName: 'maxFee',
11249
- maxDecimals: 6
11250
- })(z.string())).optional(),
11251
- customFee: customFeeSchema.optional()
11252
- }).optional(),
11253
- quote: z.string().regex(/^0x([a-fA-F0-9]{2})+$/, 'must be non-empty 0x hex').optional()
11254
- });
11372
+ // ----------------------------------------------------------------------------
11373
+ // IRIS API base URLs
11374
+ // ----------------------------------------------------------------------------
11375
+ // ----------------------------------------------------------------------------
11376
+ // Known token symbols (DX convenience)
11377
+ // ----------------------------------------------------------------------------
11378
+ //
11379
+ // These constants back symbol -> id resolution as a convenience: a caller may
11380
+ // pass a known symbol instead of a raw bytes32 id. They do NOT gate
11381
+ // routability.
11382
+ /**
11383
+ * Display symbols the provider recognizes as a convenience for callers.
11384
+ *
11385
+ * A consumer may pass one of these symbols instead of a raw bytes32 token
11386
+ * id; the provider resolves it to the symbol's canonical bytes32 id via
11387
+ * {@link KNOWN_TOKEN_IDS_BY_NETWORK} (a symbol can map to more than one
11388
+ * bridge, so the map pins the canonical one). This list does NOT gate
11389
+ * routability: any token the IRIS registry lists with deployments on both
11390
+ * endpoints routes when passed by its bytes32 id, whether listed here or
11391
+ * not.
11392
+ *
11393
+ * @example
11394
+ * ```typescript
11395
+ * for (const symbol of KNOWN_TOKEN_SYMBOLS) console.log(symbol)
11396
+ * ```
11397
+ */ const KNOWN_TOKEN_SYMBOLS = [
11398
+ 'cirBTC',
11399
+ 'wETH',
11400
+ 'EURC'
11401
+ ];
11255
11402
 
11256
11403
  /**
11257
11404
  * Define a schema for runtime logger interfaces.
@@ -11626,6 +11773,186 @@ var TransferSpeed;
11626
11773
  clock: z.any().optional()
11627
11774
  }).passthrough();
11628
11775
 
11776
+ /**
11777
+ * Creates a Zod superRefine validator for recipient address format validation.
11778
+ * Validates that the address format matches the expected format for the chain type.
11779
+ *
11780
+ * @returns A superRefine function that validates recipientAddress against chain type
11781
+ */ function createRecipientAddressValidator() {
11782
+ return (data, ctx)=>{
11783
+ const chain = data.chain;
11784
+ if (chain === null) {
11785
+ return;
11786
+ }
11787
+ if (!isValidAddressForChain(data.recipientAddress, chain)) {
11788
+ const chainInfo = extractChainInfo(chain);
11789
+ ctx.addIssue({
11790
+ code: z.ZodIssueCode.custom,
11791
+ path: [
11792
+ 'recipientAddress'
11793
+ ],
11794
+ message: `Invalid address format for ${String(chainInfo.name)}. Expected ${chainInfo.expectedAddressFormat}, but received: ${data.recipientAddress}`
11795
+ });
11796
+ }
11797
+ };
11798
+ }
11799
+ /**
11800
+ * Schema for `BridgeParams.token`.
11801
+ *
11802
+ * Accept `'USDC'`, a symbol from {@link KNOWN_TOKEN_SYMBOLS}, or a bytes32 id
11803
+ * (`0x` plus exactly 64 hex characters). Reject unknown symbols, malformed ids,
11804
+ * and `{ provider, id }` objects. A custom extra provider cannot introduce a
11805
+ * new symbol through this field — only a bytes32 id.
11806
+ *
11807
+ * Omit the field to default to `'USDC'`.
11808
+ */ const bridgeTokenSchema = z.union([
11809
+ z.enum([
11810
+ 'USDC',
11811
+ ...KNOWN_TOKEN_SYMBOLS
11812
+ ]),
11813
+ z.string().regex(/^0x[0-9a-fA-F]{64}$/, 'Token id must be a bytes32 (0x-prefixed, 64 hex chars)')
11814
+ ]);
11815
+ /**
11816
+ * Schema for validating AdapterContext for bridge operations.
11817
+ * Must always contain both adapter and chain explicitly.
11818
+ *
11819
+ * Optionally includes address for developer-controlled adapters.
11820
+ */ const adapterContextSchema$3 = z.object({
11821
+ adapter: adapterSchema,
11822
+ chain: bridgeChainIdentifierSchema,
11823
+ address: z.string().optional()
11824
+ });
11825
+ /**
11826
+ * Schema for validating BridgeDestinationWithAddress objects.
11827
+ * Contains an explicit recipientAddress along with adapter and chain.
11828
+ * The address format is validated based on the chain type (EVM or Solana).
11829
+ */ const bridgeDestinationWithAddressSchema = adapterContextSchema$3.extend({
11830
+ recipientAddress: z.string().min(1, 'Recipient address is required'),
11831
+ useForwarder: z.boolean().optional()
11832
+ }).superRefine(createRecipientAddressValidator());
11833
+ /**
11834
+ * Schema for validating AdapterContext with optional useForwarder.
11835
+ * Extends adapterContextSchema with the useForwarder flag.
11836
+ */ const adapterContextWithForwarderSchema = adapterContextSchema$3.extend({
11837
+ useForwarder: z.boolean().optional()
11838
+ });
11839
+ /**
11840
+ * Schema for validating ForwarderDestination objects.
11841
+ * Used when useForwarder is true and no adapter is provided.
11842
+ * Requires chain, recipientAddress, and useForwarder: true.
11843
+ *
11844
+ * When using this destination type:
11845
+ * - The mint step completes when the IRIS API confirms forwardState === 'CONFIRMED'
11846
+ * - No on-chain transaction confirmation is performed (no adapter available)
11847
+ * - The mint step's data field will be undefined (no transaction receipt)
11848
+ */ const forwarderDestinationSchema = z.object({
11849
+ chain: bridgeChainIdentifierSchema,
11850
+ recipientAddress: z.string().min(1, 'Recipient address is required'),
11851
+ useForwarder: z.literal(true)
11852
+ }).strict().superRefine(createRecipientAddressValidator());
11853
+ /**
11854
+ * Schema for validating BridgeDestination union type.
11855
+ * Supports three destination configurations:
11856
+ * - BridgeDestinationWithAddress (adapter with explicit recipient)
11857
+ * - ForwarderDestination (no adapter, requires useForwarder: true and recipientAddress)
11858
+ * - AdapterContext with optional useForwarder (adapter for default recipient)
11859
+ *
11860
+ * When using ForwarderDestination (no adapter):
11861
+ * - The mint step completes when the IRIS API confirms forwardState === 'CONFIRMED'
11862
+ * - No on-chain transaction confirmation is performed
11863
+ *
11864
+ * The order matters: we check the more specific schemas first.
11865
+ * This ensures that objects with specific fields are matched correctly.
11866
+ */ const bridgeDestinationSchema = z.union([
11867
+ bridgeDestinationWithAddressSchema,
11868
+ forwarderDestinationSchema,
11869
+ adapterContextWithForwarderSchema.strict()
11870
+ ]);
11871
+ /**
11872
+ * Schema for validating bridge parameters with chain identifiers.
11873
+ * This extends the core provider's schema but adapts it for the bridge kit's
11874
+ * more flexible interface that accepts chain identifiers.
11875
+ *
11876
+ * The schema validates:
11877
+ * - From adapter context (must always include both adapter and chain)
11878
+ * - To bridge destination (AdapterContext or BridgeDestinationWithAddress)
11879
+ * - Amount is a non-empty numeric string \> 0
11880
+ * - Token is optional and defaults to 'USDC'
11881
+ * - Optional config parameters (transfer speed, max fee)
11882
+ *
11883
+ * @example
11884
+ * ```typescript
11885
+ * import { bridgeParamsWithChainIdentifierSchema } from '@circle-fin/bridge-kit'
11886
+ *
11887
+ * const params = {
11888
+ * from: {
11889
+ * adapter: sourceAdapter,
11890
+ * chain: 'Ethereum'
11891
+ * },
11892
+ * to: {
11893
+ * adapter: destAdapter,
11894
+ * chain: 'Base'
11895
+ * },
11896
+ * amount: '100.50',
11897
+ * token: 'USDC',
11898
+ * config: {
11899
+ * transferSpeed: 'FAST'
11900
+ * }
11901
+ * }
11902
+ *
11903
+ * const result = bridgeParamsWithChainIdentifierSchema.safeParse(params)
11904
+ * if (result.success) {
11905
+ * console.log('Parameters are valid')
11906
+ * } else {
11907
+ * console.error('Validation failed:', result.error)
11908
+ * }
11909
+ * ```
11910
+ */ z.object({
11911
+ from: adapterContextSchema$3.strict(),
11912
+ to: bridgeDestinationSchema,
11913
+ amount: z.string().min(1, 'Required').pipe(createDecimalStringValidator({
11914
+ allowZero: false,
11915
+ regexMessage: AMOUNT_FORMAT_ERROR_MESSAGE,
11916
+ attributeName: 'amount',
11917
+ // Widest precision any routable token needs (wETH = 18). This gate is
11918
+ // token-agnostic and runs before the route provider is known, so it
11919
+ // can only cap coarsely; the token's exact precision is enforced later
11920
+ // at the scaling boundary (`BridgeKit.scaleResolvedAmount`). USDC (6)
11921
+ // and every narrower token stay valid.
11922
+ maxDecimals: 18
11923
+ })(z.string())),
11924
+ token: bridgeTokenSchema.optional(),
11925
+ config: z.object({
11926
+ transferSpeed: z.nativeEnum(TransferSpeed).optional(),
11927
+ feePayment: z.enum([
11928
+ 'source',
11929
+ 'destination'
11930
+ ]).optional(),
11931
+ maxFee: z.string().min(1, 'Required').pipe(createDecimalStringValidator({
11932
+ allowZero: true,
11933
+ regexMessage: MAX_FEE_FORMAT_ERROR_MESSAGE,
11934
+ attributeName: 'maxFee',
11935
+ // See `amount` above: widest routable precision (18); the exact
11936
+ // per-token precision is enforced at the scaling boundary.
11937
+ maxDecimals: 18
11938
+ })(z.string())).optional(),
11939
+ customFee: customFeeSchema.optional()
11940
+ }).optional(),
11941
+ // Top-level (not nested under `config`) to mirror `BridgeParams.quote`.
11942
+ //
11943
+ // `z.unknown()` rather than a shape: the quote belongs to whichever provider
11944
+ // issued it, and a route is matched to a provider only after these
11945
+ // parameters are validated, so there is no one shape to check here.
11946
+ //
11947
+ // It also keeps the value intact. This object strips unknown keys, so a
11948
+ // nested `z.object()` would clone the quote and drop every key not listed —
11949
+ // losing a field the issuing provider added, between `estimate` and
11950
+ // `bridge`. Shape is checked where the quote is consumed instead: CCTPx
11951
+ // against its own envelope schema, and the receive-exact path in
11952
+ // `sourceFees.ts` before it calls the Fee Service.
11953
+ quote: z.unknown().optional()
11954
+ });
11955
+
11629
11956
  /**
11630
11957
  * The ASCII "cctp-forward" magic, hex-encoded (no `0x`), that a forward-friendly
11631
11958
  * hookData must start with.
@@ -11865,7 +12192,7 @@ const validateQuoteItemSchema = z.object({
11865
12192
  registerKit(`${pkg$2.name}/${pkg$2.version}`);
11866
12193
 
11867
12194
  var name$1 = "@circle-fin/swap-kit";
11868
- var version$1 = "1.6.1";
12195
+ var version$1 = "1.7.0";
11869
12196
  var pkg$1 = {
11870
12197
  name: name$1,
11871
12198
  version: version$1};
@@ -15126,6 +15453,11 @@ function resolveFeePayoutChain(tokenIn, tokenOut, sourceChain, destinationChain)
15126
15453
  name: 'USDC',
15127
15454
  version: '2'
15128
15455
  },
15456
+ Arc: {
15457
+ chainId: Arc.chainId,
15458
+ name: 'USDC',
15459
+ version: '2'
15460
+ },
15129
15461
  Arc_Testnet: {
15130
15462
  chainId: ArcTestnet.chainId,
15131
15463
  name: 'USDC',
@@ -22237,7 +22569,7 @@ registerKit(`${pkg$1.name}/${pkg$1.version}`);
22237
22569
  };
22238
22570
 
22239
22571
  var name = "@circle-fin/earn-kit";
22240
- var version = "1.6.1";
22572
+ var version = "1.7.0";
22241
22573
  var pkg = {
22242
22574
  name: name,
22243
22575
  version: version};
@@ -22252,18 +22584,22 @@ var pkg = {
22252
22584
  *
22253
22585
  * @internal
22254
22586
  */ const CHAIN_TO_API = {
22587
+ [Blockchain.Arc]: 'ARC',
22255
22588
  [Blockchain.Arc_Testnet]: 'ARC-TESTNET'
22256
22589
  };
22257
22590
  /**
22258
22591
  * Map SDK source chain identifiers to bridge source-chain strings.
22259
22592
  *
22260
- * Cross-chain Earn deposits currently support Ethereum Sepolia, Arbitrum
22261
- * Sepolia, and Base Sepolia as source chains.
22593
+ * Cross-chain Earn deposits support Ethereum, Arbitrum, and Base (mainnet
22594
+ * and testnet) as source chains.
22262
22595
  *
22263
22596
  * @internal
22264
22597
  */ ({
22598
+ [Blockchain.Arbitrum]: 'ARB',
22265
22599
  [Blockchain.Arbitrum_Sepolia]: 'ARB-SEPOLIA',
22600
+ [Blockchain.Base]: 'BASE',
22266
22601
  [Blockchain.Base_Sepolia]: 'BASE-SEPOLIA',
22602
+ [Blockchain.Ethereum]: 'ETH',
22267
22603
  [Blockchain.Ethereum_Sepolia]: 'ETH-SEPOLIA'
22268
22604
  });
22269
22605
  /**
@@ -22274,13 +22610,20 @@ var pkg = {
22274
22610
  *
22275
22611
  * @internal
22276
22612
  */ ({
22613
+ [Blockchain.Arc]: CHAIN_TO_API[Blockchain.Arc],
22277
22614
  [Blockchain.Arc_Testnet]: CHAIN_TO_API[Blockchain.Arc_Testnet]
22278
22615
  });
22279
22616
  ({
22617
+ [Blockchain.Arbitrum]: {
22618
+ },
22280
22619
  [Blockchain.Arbitrum_Sepolia]: {
22281
22620
  },
22621
+ [Blockchain.Base]: {
22622
+ },
22282
22623
  [Blockchain.Base_Sepolia]: {
22283
22624
  },
22625
+ [Blockchain.Ethereum]: {
22626
+ },
22284
22627
  [Blockchain.Ethereum_Sepolia]: {
22285
22628
  }
22286
22629
  });