@circle-fin/app-kit 1.13.0 → 1.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/CHANGELOG.md +122 -0
  2. package/README.md +3 -3
  3. package/bridge.cjs +8388 -515
  4. package/bridge.d.cts +640 -61
  5. package/bridge.d.mts +640 -61
  6. package/bridge.d.ts +640 -61
  7. package/bridge.mjs +8389 -516
  8. package/chains.cjs +275 -15
  9. package/chains.d.cts +117 -2
  10. package/chains.d.mts +117 -2
  11. package/chains.d.ts +117 -2
  12. package/chains.mjs +275 -16
  13. package/context.d.cts +577 -57
  14. package/context.d.mts +577 -57
  15. package/context.d.ts +577 -57
  16. package/earn.cjs +973 -271
  17. package/earn.d.cts +577 -57
  18. package/earn.d.mts +577 -57
  19. package/earn.d.ts +577 -57
  20. package/earn.mjs +919 -221
  21. package/estimateBridge.cjs +8388 -518
  22. package/estimateBridge.d.cts +704 -82
  23. package/estimateBridge.d.mts +704 -82
  24. package/estimateBridge.d.ts +704 -82
  25. package/estimateBridge.mjs +8390 -520
  26. package/estimateSwap.cjs +982 -237
  27. package/estimateSwap.d.cts +577 -57
  28. package/estimateSwap.d.mts +577 -57
  29. package/estimateSwap.d.ts +577 -57
  30. package/estimateSwap.mjs +981 -237
  31. package/index.cjs +21401 -8522
  32. package/index.d.cts +6045 -2149
  33. package/index.d.mts +6045 -2149
  34. package/index.d.ts +6045 -2149
  35. package/index.mjs +21401 -8524
  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 +982 -237
  45. package/swap.d.cts +577 -57
  46. package/swap.d.mts +577 -57
  47. package/swap.d.ts +577 -57
  48. package/swap.mjs +981 -237
  49. package/unifiedBalance.cjs +20510 -7599
  50. package/unifiedBalance.d.cts +807 -201
  51. package/unifiedBalance.d.mts +807 -201
  52. package/unifiedBalance.d.ts +807 -201
  53. package/unifiedBalance.mjs +20513 -7603
package/estimateSwap.cjs CHANGED
@@ -30,7 +30,7 @@ if (typeof window !== 'undefined' && typeof window.Buffer === 'undefined') {
30
30
 
31
31
 
32
32
  var zod = require('zod');
33
- require('pino');
33
+ var pino = require('pino');
34
34
  var bytes = require('@ethersproject/bytes');
35
35
  require('@ethersproject/abi');
36
36
  var address = require('@ethersproject/address');
@@ -45,6 +45,7 @@ var keccak256 = require('@ethersproject/keccak256');
45
45
 
46
46
  function _interopDefault (e) { return e && e.__esModule ? e.default : e; }
47
47
 
48
+ var pino__default = /*#__PURE__*/_interopDefault(pino);
48
49
  var bs58__default = /*#__PURE__*/_interopDefault(bs58);
49
50
 
50
51
  // Import global type declarations
@@ -732,6 +733,38 @@ class KitError extends Error {
732
733
  name: 'INPUT_AMOUNT_OUT_OF_RANGE',
733
734
  type: 'INPUT'
734
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
+ },
735
768
  /** General validation failure for complex validation rules */ VALIDATION_FAILED: {
736
769
  code: 1098,
737
770
  name: 'INPUT_VALIDATION_FAILED',
@@ -942,8 +975,7 @@ class KitError extends Error {
942
975
  code: 8002,
943
976
  name: 'SERVICE_UNKNOWN_ERROR',
944
977
  type: 'SERVICE'
945
- }
946
- };
978
+ }};
947
979
 
948
980
  /**
949
981
  * Creates error for unsupported swap route.
@@ -1170,7 +1202,7 @@ class KitError extends Error {
1170
1202
  * import { createValidationErrorFromZod } from '@core/errors'
1171
1203
  *
1172
1204
  * function validateBridgeParams(params: unknown): asserts params is BridgeParams {
1173
- * const result = bridgeParamsSchema.safeParse(params)
1205
+ * const result = usdcBridgeParamsSchema.safeParse(params)
1174
1206
  * if (!result.success) {
1175
1207
  * throw createValidationErrorFromZod(result.error, 'bridge parameters')
1176
1208
  * }
@@ -2948,9 +2980,10 @@ class KitError extends Error {
2948
2980
  Blockchain["Algorand_Testnet"] = "Algorand_Testnet";
2949
2981
  Blockchain["Aptos"] = "Aptos";
2950
2982
  Blockchain["Aptos_Testnet"] = "Aptos_Testnet";
2951
- Blockchain["Arc_Testnet"] = "Arc_Testnet";
2952
2983
  Blockchain["Arbitrum"] = "Arbitrum";
2953
2984
  Blockchain["Arbitrum_Sepolia"] = "Arbitrum_Sepolia";
2985
+ Blockchain["Arc"] = "Arc";
2986
+ Blockchain["Arc_Testnet"] = "Arc_Testnet";
2954
2987
  Blockchain["Avalanche"] = "Avalanche";
2955
2988
  Blockchain["Avalanche_Fuji"] = "Avalanche_Fuji";
2956
2989
  Blockchain["Base"] = "Base";
@@ -3037,6 +3070,7 @@ var SwapChain;
3037
3070
  SwapChain["XDC"] = "XDC";
3038
3071
  SwapChain["HyperEVM"] = "HyperEVM";
3039
3072
  SwapChain["Monad"] = "Monad";
3073
+ SwapChain["Arc"] = "Arc";
3040
3074
  // Testnet chains with swap support
3041
3075
  SwapChain["Arc_Testnet"] = "Arc_Testnet";
3042
3076
  })(SwapChain || (SwapChain = {}));
@@ -3044,6 +3078,7 @@ var BridgeChain;
3044
3078
  (function(BridgeChain) {
3045
3079
  // Mainnet chains with CCTPv2 support
3046
3080
  BridgeChain["Arbitrum"] = "Arbitrum";
3081
+ BridgeChain["Arc"] = "Arc";
3047
3082
  BridgeChain["Avalanche"] = "Avalanche";
3048
3083
  BridgeChain["Base"] = "Base";
3049
3084
  BridgeChain["Codex"] = "Codex";
@@ -3099,6 +3134,7 @@ var BridgeChain;
3099
3134
  var UnifiedBalanceChain;
3100
3135
  (function(UnifiedBalanceChain) {
3101
3136
  // Mainnet chains with Gateway V1 support
3137
+ UnifiedBalanceChain["Arc"] = "Arc";
3102
3138
  UnifiedBalanceChain["Arbitrum"] = "Arbitrum";
3103
3139
  UnifiedBalanceChain["Avalanche"] = "Avalanche";
3104
3140
  UnifiedBalanceChain["Base"] = "Base";
@@ -3128,6 +3164,7 @@ var UnifiedBalanceChain;
3128
3164
  })(UnifiedBalanceChain || (UnifiedBalanceChain = {}));
3129
3165
  var EarnChain;
3130
3166
  (function(EarnChain) {
3167
+ EarnChain["Arc"] = "Arc";
3131
3168
  EarnChain["Arc_Testnet"] = "Arc_Testnet";
3132
3169
  })(EarnChain || (EarnChain = {}));
3133
3170
  /**
@@ -3144,8 +3181,11 @@ var EarnChain;
3144
3181
  * console.log(EARN_BRIDGE_SOURCE_BLOCKCHAINS.join(', '))
3145
3182
  * ```
3146
3183
  */ const EARN_BRIDGE_SOURCE_BLOCKCHAINS = [
3184
+ "Arbitrum",
3147
3185
  "Arbitrum_Sepolia",
3186
+ "Base",
3148
3187
  "Base_Sepolia",
3188
+ "Ethereum",
3149
3189
  "Ethereum_Sepolia"
3150
3190
  ];
3151
3191
  /**
@@ -3159,6 +3199,7 @@ var EarnChain;
3159
3199
  * console.log(EARN_BRIDGE_DESTINATION_BLOCKCHAINS.join(', '))
3160
3200
  * ```
3161
3201
  */ const EARN_BRIDGE_DESTINATION_BLOCKCHAINS = [
3202
+ "Arc",
3162
3203
  "Arc_Testnet"
3163
3204
  ];
3164
3205
 
@@ -3475,6 +3516,25 @@ var EarnChain;
3475
3516
  * EVM-compatible chains. Use this address when deploying or testing
3476
3517
  * cross-chain USDC transfers on test networks.
3477
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';
3478
3538
  /**
3479
3539
  * The bridge contract address for EVM mainnet networks.
3480
3540
  *
@@ -3543,8 +3603,115 @@ var EarnChain;
3543
3603
  * This program handles minting operations for Gateway transactions
3544
3604
  * on Solana devnet.
3545
3605
  */ const GATEWAY_MINTER_SOLANA_DEVNET = 'GATEmKK2ECL1brEngQZWCgMWPbvrEYqsV6u29dAaHavr';
3546
- /** TokenMessengerWithFees address shared by enabled EVM mainnet sources. */ const TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET = '0x71f54F818671cD0D7ea140Da213e5C8b5C92a408';
3547
- /** TokenMessengerWithFees address shared by enabled EVM testnet sources. */ const TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET = '0x8745D906D67C346E5eb1aEEED38Eb87F34DF0C0A';
3606
+ /**
3607
+ * The `TokenMessengerWithFees` proxy contract address for EVM mainnet networks
3608
+ * (all chains except Edge).
3609
+ *
3610
+ * Deployed at a CREATE3-derived address; identical across all mainnet EVM
3611
+ * source chains. Present on any chain that supports the prepaid FORWARD path
3612
+ * via `depositForBurnWithHookAndFees`.
3613
+ */ const TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET = '0x71f54F818671cD0D7ea140Da213e5C8b5C92a408';
3614
+ /**
3615
+ * The `TokenMessengerWithFees` proxy contract address for EVM testnet networks.
3616
+ *
3617
+ * Identical across all testnet EVM source chains. Present on any testnet chain
3618
+ * that supports the prepaid FORWARD path via `depositForBurnWithHookAndFees`.
3619
+ */ const TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET = '0x8745D906D67C346E5eb1aEEED38Eb87F34DF0C0A';
3620
+ /**
3621
+ * The `DepositForHandler` proxy contract address for EVM mainnet networks.
3622
+ *
3623
+ * The handler the GenericExecutor calls on a fast-deposit destination chain to
3624
+ * run a cross-chain deposit into the GatewayWallet. Deployed at the same
3625
+ * address across all mainnet EVM destination chains.
3626
+ */ const DEPOSIT_FOR_HANDLER_EVM_MAINNET = '0x16529813203f77E036576666336554a1210dce4D';
3627
+ /**
3628
+ * The `DepositForHandler` proxy contract address for EVM testnet networks.
3629
+ *
3630
+ * Identical across all testnet EVM destination chains.
3631
+ */ const DEPOSIT_FOR_HANDLER_EVM_TESTNET = '0xD05E7D2E7d30b92c5F17d7d0fC575fce231F1A48';
3632
+ /**
3633
+ * The `GenericExecutor` proxy contract address for EVM mainnet networks.
3634
+ *
3635
+ * The GenericExecutor is the `mintRecipient` and `destinationCaller` on the
3636
+ * destination chain for the CCTP v2 prepaid FORWARD path. It receives the CCTP
3637
+ * mint and calls the `DepositForHandler` to complete the fast deposit.
3638
+ * Deployed at the same address across all mainnet EVM destination chains.
3639
+ */ const GENERIC_EXECUTOR_EVM_MAINNET = '0xFa7be2f04F3Ad4ca969260729c6d45B5625984A7';
3640
+ /**
3641
+ * The `GenericExecutor` proxy contract address for EVM testnet networks.
3642
+ *
3643
+ * Identical across all testnet EVM destination chains.
3644
+ */ const GENERIC_EXECUTOR_EVM_TESTNET = '0xEdC81040756AcCfF070c21D37b265b9D0b5Ba45e';
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
+ });
3548
3715
 
3549
3716
  /**
3550
3717
  * Arc Testnet chain definition
@@ -3593,6 +3760,9 @@ var EarnChain;
3593
3760
  destination: true
3594
3761
  }
3595
3762
  },
3763
+ cctpx: {
3764
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
3765
+ },
3596
3766
  kitContracts: {
3597
3767
  bridge: BRIDGE_CONTRACT_EVM_TESTNET,
3598
3768
  adapter: ADAPTER_CONTRACT_EVM_TESTNET
@@ -3603,9 +3773,8 @@ var EarnChain;
3603
3773
  v1: {
3604
3774
  wallet: GATEWAY_WALLET_EVM_TESTNET,
3605
3775
  minter: GATEWAY_MINTER_EVM_TESTNET,
3606
- // DepositForHandler the GenericExecutor calls to run a fast cross-chain
3607
- // deposit into the GatewayWallet above.
3608
- depositForHandler: '0xD05E7D2E7d30b92c5F17d7d0fC575fce231F1A48'
3776
+ depositForHandler: DEPOSIT_FOR_HANDLER_EVM_TESTNET,
3777
+ genericExecutor: GENERIC_EXECUTOR_EVM_TESTNET
3609
3778
  }
3610
3779
  },
3611
3780
  forwarderSupported: {
@@ -3661,6 +3830,9 @@ var EarnChain;
3661
3830
  destination: true
3662
3831
  }
3663
3832
  },
3833
+ cctpx: {
3834
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
3835
+ },
3664
3836
  kitContracts: {
3665
3837
  bridge: BRIDGE_CONTRACT_EVM_MAINNET,
3666
3838
  adapter: ADAPTER_CONTRACT_EVM_MAINNET
@@ -3726,6 +3898,9 @@ var EarnChain;
3726
3898
  destination: true
3727
3899
  }
3728
3900
  },
3901
+ cctpx: {
3902
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
3903
+ },
3729
3904
  kitContracts: {
3730
3905
  bridge: BRIDGE_CONTRACT_EVM_TESTNET,
3731
3906
  adapter: ADAPTER_CONTRACT_EVM_TESTNET
@@ -3791,6 +3966,9 @@ var EarnChain;
3791
3966
  destination: true
3792
3967
  }
3793
3968
  },
3969
+ cctpx: {
3970
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
3971
+ },
3794
3972
  kitContracts: {
3795
3973
  bridge: BRIDGE_CONTRACT_EVM_MAINNET,
3796
3974
  adapter: ADAPTER_CONTRACT_EVM_MAINNET
@@ -3800,7 +3978,9 @@ var EarnChain;
3800
3978
  contracts: {
3801
3979
  v1: {
3802
3980
  wallet: GATEWAY_WALLET_EVM_MAINNET,
3803
- minter: GATEWAY_MINTER_EVM_MAINNET
3981
+ minter: GATEWAY_MINTER_EVM_MAINNET,
3982
+ depositForHandler: DEPOSIT_FOR_HANDLER_EVM_MAINNET,
3983
+ genericExecutor: GENERIC_EXECUTOR_EVM_MAINNET
3804
3984
  }
3805
3985
  },
3806
3986
  forwarderSupported: {
@@ -3856,6 +4036,9 @@ var EarnChain;
3856
4036
  rpcEndpoints: [
3857
4037
  'https://api.avax-test.network/ext/bc/C/rpc'
3858
4038
  ],
4039
+ cctpx: {
4040
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
4041
+ },
3859
4042
  kitContracts: {
3860
4043
  bridge: BRIDGE_CONTRACT_EVM_TESTNET
3861
4044
  },
@@ -3864,7 +4047,9 @@ var EarnChain;
3864
4047
  contracts: {
3865
4048
  v1: {
3866
4049
  wallet: GATEWAY_WALLET_EVM_TESTNET,
3867
- minter: GATEWAY_MINTER_EVM_TESTNET
4050
+ minter: GATEWAY_MINTER_EVM_TESTNET,
4051
+ depositForHandler: DEPOSIT_FOR_HANDLER_EVM_TESTNET,
4052
+ genericExecutor: GENERIC_EXECUTOR_EVM_TESTNET
3868
4053
  }
3869
4054
  },
3870
4055
  forwarderSupported: {
@@ -3921,6 +4106,9 @@ var EarnChain;
3921
4106
  destination: true
3922
4107
  }
3923
4108
  },
4109
+ cctpx: {
4110
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
4111
+ },
3924
4112
  kitContracts: {
3925
4113
  bridge: BRIDGE_CONTRACT_EVM_MAINNET,
3926
4114
  adapter: ADAPTER_CONTRACT_EVM_MAINNET
@@ -3986,6 +4174,9 @@ var EarnChain;
3986
4174
  destination: true
3987
4175
  }
3988
4176
  },
4177
+ cctpx: {
4178
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
4179
+ },
3989
4180
  kitContracts: {
3990
4181
  bridge: BRIDGE_CONTRACT_EVM_TESTNET,
3991
4182
  adapter: ADAPTER_CONTRACT_EVM_TESTNET
@@ -4177,6 +4368,7 @@ var EarnChain;
4177
4368
  v2: {
4178
4369
  type: 'split',
4179
4370
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
4371
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
4180
4372
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
4181
4373
  confirmations: 1,
4182
4374
  fastConfirmations: 1
@@ -4222,6 +4414,7 @@ var EarnChain;
4222
4414
  v2: {
4223
4415
  type: 'split',
4224
4416
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
4417
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
4225
4418
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
4226
4419
  confirmations: 1,
4227
4420
  fastConfirmations: 1
@@ -4267,6 +4460,7 @@ var EarnChain;
4267
4460
  v2: {
4268
4461
  type: 'split',
4269
4462
  tokenMessenger: '0x98706A006bc632Df31CAdFCBD43F38887ce2ca5c',
4463
+ tokenMessengerWithFees: '0x3Ac96675F9a3E6922713e041645D82f3561d3686',
4270
4464
  messageTransmitter: '0x5b61381Fc9e58E70EfC13a4A97516997019198ee',
4271
4465
  confirmations: 65,
4272
4466
  fastConfirmations: 1
@@ -4312,6 +4506,7 @@ var EarnChain;
4312
4506
  v2: {
4313
4507
  type: 'split',
4314
4508
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
4509
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
4315
4510
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
4316
4511
  confirmations: 65,
4317
4512
  fastConfirmations: 1
@@ -4374,6 +4569,9 @@ var EarnChain;
4374
4569
  destination: true
4375
4570
  }
4376
4571
  },
4572
+ cctpx: {
4573
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
4574
+ },
4377
4575
  kitContracts: {
4378
4576
  bridge: BRIDGE_CONTRACT_EVM_MAINNET,
4379
4577
  adapter: ADAPTER_CONTRACT_EVM_MAINNET
@@ -4439,6 +4637,9 @@ var EarnChain;
4439
4637
  destination: true
4440
4638
  }
4441
4639
  },
4640
+ cctpx: {
4641
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
4642
+ },
4442
4643
  kitContracts: {
4443
4644
  bridge: BRIDGE_CONTRACT_EVM_TESTNET,
4444
4645
  adapter: ADAPTER_CONTRACT_EVM_TESTNET
@@ -4660,6 +4861,7 @@ var EarnChain;
4660
4861
  v2: {
4661
4862
  type: 'split',
4662
4863
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
4864
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
4663
4865
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
4664
4866
  confirmations: 1,
4665
4867
  fastConfirmations: 1
@@ -4707,6 +4909,7 @@ var EarnChain;
4707
4909
  v2: {
4708
4910
  type: 'split',
4709
4911
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
4912
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
4710
4913
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
4711
4914
  confirmations: 1,
4712
4915
  fastConfirmations: 1
@@ -4988,6 +5191,7 @@ var EarnChain;
4988
5191
  v2: {
4989
5192
  type: 'split',
4990
5193
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
5194
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
4991
5195
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
4992
5196
  confirmations: 1,
4993
5197
  fastConfirmations: 1
@@ -5033,6 +5237,7 @@ var EarnChain;
5033
5237
  v2: {
5034
5238
  type: 'split',
5035
5239
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
5240
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
5036
5241
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
5037
5242
  confirmations: 64,
5038
5243
  fastConfirmations: 1
@@ -5078,6 +5283,7 @@ var EarnChain;
5078
5283
  v2: {
5079
5284
  type: 'split',
5080
5285
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
5286
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
5081
5287
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
5082
5288
  confirmations: 64,
5083
5289
  fastConfirmations: 1
@@ -5265,6 +5471,9 @@ var EarnChain;
5265
5471
  destination: true
5266
5472
  }
5267
5473
  },
5474
+ cctpx: {
5475
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
5476
+ },
5268
5477
  kitContracts: {
5269
5478
  bridge: BRIDGE_CONTRACT_EVM_MAINNET,
5270
5479
  adapter: ADAPTER_CONTRACT_EVM_MAINNET
@@ -5330,6 +5539,9 @@ var EarnChain;
5330
5539
  destination: true
5331
5540
  }
5332
5541
  },
5542
+ cctpx: {
5543
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
5544
+ },
5333
5545
  kitContracts: {
5334
5546
  bridge: BRIDGE_CONTRACT_EVM_TESTNET
5335
5547
  },
@@ -5379,6 +5591,7 @@ var EarnChain;
5379
5591
  v2: {
5380
5592
  type: 'split',
5381
5593
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
5594
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
5382
5595
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
5383
5596
  confirmations: 1,
5384
5597
  fastConfirmations: 1
@@ -5425,6 +5638,7 @@ var EarnChain;
5425
5638
  v2: {
5426
5639
  type: 'split',
5427
5640
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
5641
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
5428
5642
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
5429
5643
  confirmations: 1,
5430
5644
  fastConfirmations: 1
@@ -5723,6 +5937,9 @@ var EarnChain;
5723
5937
  destination: true
5724
5938
  }
5725
5939
  },
5940
+ cctpx: {
5941
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_MAINNET
5942
+ },
5726
5943
  kitContracts: {
5727
5944
  bridge: BRIDGE_CONTRACT_EVM_MAINNET,
5728
5945
  adapter: ADAPTER_CONTRACT_EVM_MAINNET
@@ -5732,7 +5949,9 @@ var EarnChain;
5732
5949
  contracts: {
5733
5950
  v1: {
5734
5951
  wallet: GATEWAY_WALLET_EVM_MAINNET,
5735
- minter: GATEWAY_MINTER_EVM_MAINNET
5952
+ minter: GATEWAY_MINTER_EVM_MAINNET,
5953
+ depositForHandler: DEPOSIT_FOR_HANDLER_EVM_MAINNET,
5954
+ genericExecutor: GENERIC_EXECUTOR_EVM_MAINNET
5736
5955
  }
5737
5956
  },
5738
5957
  forwarderSupported: {
@@ -5789,6 +6008,9 @@ var EarnChain;
5789
6008
  destination: true
5790
6009
  }
5791
6010
  },
6011
+ cctpx: {
6012
+ serviceAddress: CCTPX_SERVICE_ADDRESS_EVM_TESTNET
6013
+ },
5792
6014
  kitContracts: {
5793
6015
  bridge: BRIDGE_CONTRACT_EVM_TESTNET
5794
6016
  },
@@ -5797,7 +6019,9 @@ var EarnChain;
5797
6019
  contracts: {
5798
6020
  v1: {
5799
6021
  wallet: GATEWAY_WALLET_EVM_TESTNET,
5800
- minter: GATEWAY_MINTER_EVM_TESTNET
6022
+ minter: GATEWAY_MINTER_EVM_TESTNET,
6023
+ depositForHandler: DEPOSIT_FOR_HANDLER_EVM_TESTNET,
6024
+ genericExecutor: GENERIC_EXECUTOR_EVM_TESTNET
5801
6025
  }
5802
6026
  },
5803
6027
  forwarderSupported: {
@@ -6795,6 +7019,7 @@ var Chains = {
6795
7019
  AptosTestnet: AptosTestnet,
6796
7020
  Arbitrum: Arbitrum,
6797
7021
  ArbitrumSepolia: ArbitrumSepolia,
7022
+ Arc: Arc,
6798
7023
  ArcTestnet: ArcTestnet,
6799
7024
  Avalanche: Avalanche,
6800
7025
  AvalancheFuji: AvalancheFuji,
@@ -6883,6 +7108,67 @@ var Chains = {
6883
7108
  return chain.cctp?.contracts.v2 !== undefined;
6884
7109
  }
6885
7110
 
7111
+ /**
7112
+ * Chains the Fee Service accepts as a SOURCE for source-paid ("receive-exact")
7113
+ * CCTP v2 fees. An explicit allowlist is required because the
7114
+ * `TokenMessengerWithFees` wrapper address is now shared with the fast-deposit
7115
+ * forwarder path, so wrapper presence no longer implies source-fee support.
7116
+ * Keep in sync with backend coverage.
7117
+ */ new Set([
7118
+ // Mainnet
7119
+ Blockchain.Ethereum,
7120
+ Blockchain.Base,
7121
+ Blockchain.Arbitrum,
7122
+ Blockchain.Unichain,
7123
+ Blockchain.Optimism,
7124
+ Blockchain.Codex,
7125
+ Blockchain.Ink,
7126
+ Blockchain.Plume,
7127
+ Blockchain.Linea,
7128
+ Blockchain.World_Chain,
7129
+ // Testnet counterparts
7130
+ Blockchain.Ethereum_Sepolia,
7131
+ Blockchain.Base_Sepolia,
7132
+ Blockchain.Arbitrum_Sepolia,
7133
+ Blockchain.Unichain_Sepolia,
7134
+ Blockchain.Optimism_Sepolia,
7135
+ Blockchain.Codex_Testnet,
7136
+ Blockchain.Ink_Testnet,
7137
+ Blockchain.Plume_Testnet,
7138
+ Blockchain.Linea_Sepolia,
7139
+ Blockchain.World_Chain_Sepolia
7140
+ ]);
7141
+
7142
+ /**
7143
+ * Temporary allowlist of chains permitted to initiate Gateway fast deposits.
7144
+ * Only chains keyed here are eligible; all others are rejected. Using the
7145
+ * {@link Blockchain} enum keeps entries type-safe and catches typos at compile
7146
+ * time. Remove this allowlist once roll-out is complete.
7147
+ */ new Set([
7148
+ // Mainnet
7149
+ Blockchain.Ethereum,
7150
+ Blockchain.Base,
7151
+ Blockchain.Arbitrum,
7152
+ Blockchain.Unichain,
7153
+ Blockchain.Optimism,
7154
+ Blockchain.Codex,
7155
+ Blockchain.Ink,
7156
+ Blockchain.Plume,
7157
+ Blockchain.Linea,
7158
+ Blockchain.World_Chain,
7159
+ // Testnet counterparts
7160
+ Blockchain.Ethereum_Sepolia,
7161
+ Blockchain.Base_Sepolia,
7162
+ Blockchain.Arbitrum_Sepolia,
7163
+ Blockchain.Unichain_Sepolia,
7164
+ Blockchain.Optimism_Sepolia,
7165
+ Blockchain.Codex_Testnet,
7166
+ Blockchain.Ink_Testnet,
7167
+ Blockchain.Plume_Testnet,
7168
+ Blockchain.Linea_Sepolia,
7169
+ Blockchain.World_Chain_Sepolia
7170
+ ]);
7171
+
6886
7172
  /**
6887
7173
  * Zod schema for validating Gateway v1 contract addresses.
6888
7174
  *
@@ -6904,7 +7190,10 @@ var Chains = {
6904
7190
  }).min(1, 'Gateway minter address cannot be empty.'),
6905
7191
  depositForHandler: zod.z.string({
6906
7192
  invalid_type_error: 'Gateway depositForHandler address must be a string.'
6907
- }).min(1, 'Gateway depositForHandler address cannot be empty.').optional()
7193
+ }).min(1, 'Gateway depositForHandler address cannot be empty.').optional(),
7194
+ genericExecutor: zod.z.string({
7195
+ invalid_type_error: 'Gateway genericExecutor address must be a string.'
7196
+ }).min(1, 'Gateway genericExecutor address cannot be empty.').optional()
6908
7197
  }).strict() // Reject any additional properties not defined in the schema
6909
7198
  ;
6910
7199
  /**
@@ -6988,6 +7277,7 @@ var Chains = {
6988
7277
  usdcAddress: zod.z.string().nullable(),
6989
7278
  usdtAddress: zod.z.string().nullable(),
6990
7279
  cctp: zod.z.any().nullable(),
7280
+ cctpx: zod.z.any().optional(),
6991
7281
  kitContracts: zod.z.object({
6992
7282
  bridge: zod.z.string().optional(),
6993
7283
  adapter: zod.z.string().optional()
@@ -7193,14 +7483,15 @@ const EARN_BRIDGE_DESTINATION_CHAIN_VALUES = EARN_BRIDGE_DESTINATION_BLOCKCHAINS
7193
7483
  * Zod schema for validating the source chain of a cross-chain Earn deposit.
7194
7484
  *
7195
7485
  * Accept a supported source Blockchain value, a matching string literal, or a
7196
- * ChainDefinition for a supported source chain. Source chains are Ethereum
7197
- * Sepolia, Arbitrum Sepolia, and Base Sepolia.
7486
+ * ChainDefinition for a supported source chain. Source chains are Ethereum,
7487
+ * Arbitrum, and Base (mainnet and testnet).
7198
7488
  *
7199
7489
  * @example
7200
7490
  * ```typescript
7201
7491
  * import { earnBridgeSourceChainIdentifierSchema } from '@core/chains'
7202
7492
  *
7203
7493
  * // Valid
7494
+ * earnBridgeSourceChainIdentifierSchema.parse('Ethereum')
7204
7495
  * earnBridgeSourceChainIdentifierSchema.parse('Ethereum_Sepolia')
7205
7496
  *
7206
7497
  * // Invalid (throws ZodError)
@@ -7219,14 +7510,15 @@ const EARN_BRIDGE_DESTINATION_CHAIN_VALUES = EARN_BRIDGE_DESTINATION_BLOCKCHAINS
7219
7510
  * deposit.
7220
7511
  *
7221
7512
  * Accept a supported destination Blockchain value, a matching string literal,
7222
- * or a ChainDefinition for a supported destination chain. Currently only Arc
7223
- * Testnet is supported.
7513
+ * or a ChainDefinition for a supported destination chain. Arc (mainnet) and
7514
+ * Arc Testnet are supported.
7224
7515
  *
7225
7516
  * @example
7226
7517
  * ```typescript
7227
7518
  * import { earnBridgeDestinationChainIdentifierSchema } from '@core/chains'
7228
7519
  *
7229
7520
  * // Valid
7521
+ * earnBridgeDestinationChainIdentifierSchema.parse('Arc')
7230
7522
  * earnBridgeDestinationChainIdentifierSchema.parse('Arc_Testnet')
7231
7523
  *
7232
7524
  * // Invalid (throws ZodError)
@@ -7404,7 +7696,10 @@ const swapTokenEnumSchema = zod.z.enum([
7404
7696
  * Get decimal places for a supported swap token.
7405
7697
  *
7406
7698
  * @param token - Swap token symbol
7407
- * @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.
7408
7703
  *
7409
7704
  * @example
7410
7705
  * ```typescript
@@ -7416,6 +7711,15 @@ const swapTokenEnumSchema = zod.z.enum([
7416
7711
  * ```
7417
7712
  */ function getSwapTokenDecimals(token) {
7418
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
+ }
7419
7723
  return SWAP_TOKEN_REGISTRY[token].decimals;
7420
7724
  }
7421
7725
  /**
@@ -8857,6 +9161,7 @@ const swapTokenEnumSchema = zod.z.enum([
8857
9161
  // Mainnets (alphabetically sorted)
8858
9162
  // =========================================================================
8859
9163
  [Blockchain.Arbitrum]: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
9164
+ [Blockchain.Arc]: '0x3600000000000000000000000000000000000000',
8860
9165
  [Blockchain.Avalanche]: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',
8861
9166
  [Blockchain.Base]: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
8862
9167
  [Blockchain.Celo]: '0xcebA9300f2b948710d2653dD7B07f33A8B32118C',
@@ -8971,6 +9276,7 @@ const swapTokenEnumSchema = zod.z.enum([
8971
9276
  // =========================================================================
8972
9277
  // Mainnets
8973
9278
  // =========================================================================
9279
+ [Blockchain.Arc]: '0xbEf5f6d51CB62b58e6A8f77868681825C6fe21c1',
8974
9280
  [Blockchain.Avalanche]: '0xc891EB4cbdEFf6e073e859e987815Ed1505c2ACD',
8975
9281
  [Blockchain.Base]: '0x60a3E35Cc302bFA44Cb288Bc5a4F316Fdb1adb42',
8976
9282
  [Blockchain.Cronos]: '0xA6dE01a2d62C6B5f3525d768f34d276652C554c8',
@@ -9214,6 +9520,7 @@ const swapTokenEnumSchema = zod.z.enum([
9214
9520
  // =========================================================================
9215
9521
  // Mainnets
9216
9522
  // =========================================================================
9523
+ [Blockchain.Arc]: '0x171A4217b86A807A64eB94757Db6849fb4bDbAA0',
9217
9524
  [Blockchain.Ethereum]: '0x72DFB2E44f59C5AD2bAFE84314E5b99a7cd5075E',
9218
9525
  // =========================================================================
9219
9526
  // Testnets
@@ -9306,13 +9613,28 @@ const swapTokenEnumSchema = zod.z.enum([
9306
9613
  }
9307
9614
 
9308
9615
  /**
9309
- * Check if a selector is a raw token selector (object form).
9616
+ * Type guard: narrows a {@link TokenSelector} to a {@link RawTokenSelector}.
9310
9617
  *
9311
9618
  * @param selector - The token selector to check.
9312
- * @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
+ * ```
9313
9627
  */ function isRawSelector(selector) {
9314
- 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;
9315
9636
  }
9637
+
9316
9638
  /**
9317
9639
  * Normalize a symbol to uppercase for case-insensitive lookup.
9318
9640
  *
@@ -9500,7 +9822,7 @@ const swapTokenEnumSchema = zod.z.enum([
9500
9822
  if (typeof selector === 'string') {
9501
9823
  return resolveSymbol(selector, chainId);
9502
9824
  }
9503
- 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);
9504
9826
  },
9505
9827
  resolveByAddress (address, chainId) {
9506
9828
  if (!address || typeof address !== 'string') {
@@ -9622,9 +9944,17 @@ const swapTokenEnumSchema = zod.z.enum([
9622
9944
  *
9623
9945
  * // Native token (chain-derived decimals)
9624
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"
9625
9950
  * ```
9626
9951
  */ const formatAmount = (params)=>{
9627
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
+ }
9628
9958
  // Handle NATIVE token first (chain-specific decimals)
9629
9959
  if (token === 'NATIVE') {
9630
9960
  if (params.chain === undefined) {
@@ -9812,7 +10142,7 @@ const swapTokenEnumSchema = zod.z.enum([
9812
10142
  * allowlisted {@link ClientLogPayload} fields (and the allowlisted
9813
10143
  * sub-fields of `errorDetails` / `clientContext`) are copied across.
9814
10144
  * A regressing upstream mapper — or a plain-JS caller that bypasses the
9815
- * type — therefore cannot exfiltrate stray properties (secrets, PII,
10145
+ * type — therefore cannot exfiltrate stray properties (secrets,
9816
10146
  * raw error stacks) through the analytics channel. Optional fields are
9817
10147
  * only included when present so the serialised shape matches the
9818
10148
  * server's strict schema.
@@ -9835,6 +10165,9 @@ const swapTokenEnumSchema = zod.z.enum([
9835
10165
  if (payload.destinationChain !== undefined) safe['destinationChain'] = payload.destinationChain;
9836
10166
  if (payload.tokenIn !== undefined) safe['tokenIn'] = payload.tokenIn;
9837
10167
  if (payload.tokenOut !== undefined) safe['tokenOut'] = payload.tokenOut;
10168
+ if (payload.amountIn !== undefined) safe['amountIn'] = payload.amountIn;
10169
+ if (payload.durationMs !== undefined) safe['durationMs'] = payload.durationMs;
10170
+ if (payload.sourceAddress !== undefined) safe['sourceAddress'] = payload.sourceAddress;
9838
10171
  if (payload.txHash !== undefined) safe['txHash'] = payload.txHash;
9839
10172
  if (payload.correlationId !== undefined) safe['correlationId'] = payload.correlationId;
9840
10173
  if (payload.errorDetails !== undefined) {
@@ -10068,14 +10401,28 @@ const swapTokenEnumSchema = zod.z.enum([
10068
10401
  }
10069
10402
 
10070
10403
  /**
10071
- * Soft signal for the case where building or emitting a telemetry payload
10072
- * threw — for example, a buggy `TelemetryContextResolver`, a regression in
10404
+ * Emit a stable console warning when building or emitting a telemetry payload
10405
+ * throws — for example, a buggy `TelemetryContextResolver`, a regression in
10073
10406
  * `extractErrorDetails`, or a synchronous failure inside `emitAnalyticsLog`
10074
- * before it could swallow the error itself. Logged with a stable prefix so
10075
- * consumers can grep for it. We deliberately do not re-throw: the caller's
10076
- * original operation error must always win.
10407
+ * before it could swallow the error itself. Uses a stable prefix so the
10408
+ * drop is discoverable via grep. Never re-throws: the caller's original
10409
+ * operation error must always win.
10077
10410
  *
10078
10411
  * @internal
10412
+ *
10413
+ * @param eventType - The telemetry event type that was being emitted.
10414
+ * @param cause - The error or value that caused the drop.
10415
+ *
10416
+ * @example
10417
+ * ```typescript
10418
+ * import { warnTelemetryDrop } from '@core/utils'
10419
+ *
10420
+ * try {
10421
+ * void emitAnalyticsLog(payload)
10422
+ * } catch (err) {
10423
+ * warnTelemetryDrop('my_event', err)
10424
+ * }
10425
+ * ```
10079
10426
  */ function warnTelemetryDrop(eventType, cause) {
10080
10427
  try {
10081
10428
  // Pass `cause` as the second console.warn argument rather than
@@ -10115,6 +10462,9 @@ const swapTokenEnumSchema = zod.z.enum([
10115
10462
  ...context?.tokenOut != null && {
10116
10463
  tokenOut: context.tokenOut
10117
10464
  },
10465
+ ...context?.amountIn != null && {
10466
+ amountIn: context.amountIn
10467
+ },
10118
10468
  ...context?.txHash != null && {
10119
10469
  txHash: context.txHash
10120
10470
  },
@@ -10214,7 +10564,7 @@ const swapTokenEnumSchema = zod.z.enum([
10214
10564
  }
10215
10565
 
10216
10566
  var name$2 = "@circle-fin/bridge-kit";
10217
- var version$2 = "1.14.0";
10567
+ var version$2 = "1.15.0";
10218
10568
  var pkg$2 = {
10219
10569
  name: name$2,
10220
10570
  version: version$2};
@@ -10913,67 +11263,522 @@ var TransferSpeed;
10913
11263
  */ recipientAddress: zod.z.string().trim().min(1, 'Fee recipient must be a non-empty string').optional()
10914
11264
  }).strict();
10915
11265
  /**
10916
- * Schema for validating bridge parameters.
10917
- * This ensures all required fields are present and properly typed.
10918
- * A bridge must include:
10919
- * - A valid amount (non-empty numeric string \> 0)
10920
- * - Valid source and destination wallet contexts
10921
- * - USDC as the token
10922
- * - Optional config with transfer speed and max fee settings
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.
11332
+ * This ensures all required fields are present and properly typed.
11333
+ * A bridge must include:
11334
+ * - A valid amount (non-empty numeric string \> 0)
11335
+ * - Valid source and destination wallet contexts
11336
+ * - USDC as the token
11337
+ * - Optional config with transfer speed and max fee settings
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
+ *
11343
+ * @throws KitError if validation fails
11344
+ *
11345
+ * @example
11346
+ * ```typescript
11347
+ * import { usdcBridgeParamsSchema } from '@core/provider'
11348
+ *
11349
+ * const validBridge = {
11350
+ * amount: '100.50',
11351
+ * source: {
11352
+ * adapter: sourceAdapter,
11353
+ * address: '0xSourceAddress',
11354
+ * chain: sourceChain
11355
+ * },
11356
+ * destination: {
11357
+ * adapter: destAdapter,
11358
+ * address: '0xDestAddress',
11359
+ * chain: destChain
11360
+ * },
11361
+ * token: 'USDC',
11362
+ * config: {
11363
+ * transferSpeed: 'FAST',
11364
+ * maxFee: '1.5', // Must use dot as decimal separator
11365
+ * customFee: {
11366
+ * value: '0.5', // Must use dot as decimal separator
11367
+ * recipientAddress: '0x1234567890123456789012345678901234567890'
11368
+ * }
11369
+ * }
11370
+ * }
11371
+ *
11372
+ * const result = usdcBridgeParamsSchema.safeParse(validBridge)
11373
+ * console.log(result.success) // true
11374
+ * ```
11375
+ */ createBridgeParamsSchema(zod.z.literal('USDC'), {
11376
+ maxDecimals: 6
11377
+ });
11378
+
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
+ ];
11409
+
11410
+ /**
11411
+ * Define a schema for runtime logger interfaces.
11412
+ *
11413
+ * @remarks
11414
+ * Validate that a runtime logger provides the minimal methods expected by the SDK.
11415
+ *
11416
+ * @example
11417
+ * ```typescript
11418
+ * import { loggerSchema } from '@core/runtime'
11419
+ *
11420
+ * const logger = {
11421
+ * debug: () => undefined,
11422
+ * info: () => undefined,
11423
+ * warn: () => undefined,
11424
+ * error: () => undefined,
11425
+ * child: () => logger,
11426
+ * }
11427
+ *
11428
+ * loggerSchema.parse(logger)
11429
+ * ```
11430
+ */ const loggerSchema = zod.z.custom((value)=>{
11431
+ if (value === null || typeof value !== 'object') {
11432
+ return false;
11433
+ }
11434
+ const record = value;
11435
+ return typeof record['debug'] === 'function' && typeof record['info'] === 'function' && typeof record['warn'] === 'function' && typeof record['error'] === 'function' && typeof record['child'] === 'function';
11436
+ }, {
11437
+ message: 'Invalid logger'
11438
+ });
11439
+
11440
+ /**
11441
+ * Define a schema for runtime metrics interfaces.
11442
+ *
11443
+ * @remarks
11444
+ * Validate that a metrics implementation exposes the minimal API expected by the runtime.
11445
+ *
11446
+ * @example
11447
+ * ```typescript
11448
+ * import { metricsSchema } from '@core/runtime'
11449
+ *
11450
+ * const metrics = {
11451
+ * counter: () => ({ inc: () => undefined }),
11452
+ * histogram: () => ({ observe: () => undefined }),
11453
+ * timer: () => ({ start: () => () => undefined }),
11454
+ * child: () => metrics,
11455
+ * }
11456
+ *
11457
+ * metricsSchema.parse(metrics)
11458
+ * ```
11459
+ */ const metricsSchema = zod.z.custom((value)=>{
11460
+ if (value === null || typeof value !== 'object') {
11461
+ return false;
11462
+ }
11463
+ const record = value;
11464
+ return typeof record['counter'] === 'function' && typeof record['histogram'] === 'function' && typeof record['timer'] === 'function' && typeof record['child'] === 'function';
11465
+ }, {
11466
+ message: 'Invalid metrics'
11467
+ });
11468
+
11469
+ /**
11470
+ * Omit undefined values from an object.
11471
+ *
11472
+ * @param obj - The object to process.
11473
+ * @returns A new object with undefined values removed.
11474
+ *
11475
+ * @internal
11476
+ * @remarks
11477
+ * Used by both production and mock loggers to ensure consistent behavior.
11478
+ * This prevents undefined values from being serialized in log output,
11479
+ * which can cause issues with some log transports.
11480
+ */ function omitUndefined(obj) {
11481
+ const result = {};
11482
+ for (const [key, value] of Object.entries(obj)){
11483
+ if (value !== undefined) {
11484
+ result[key] = value;
11485
+ }
11486
+ }
11487
+ return result;
11488
+ }
11489
+
11490
+ /**
11491
+ * Default redaction paths for web3/blockchain SDKs.
11492
+ *
11493
+ * @remarks
11494
+ * These paths target common sensitive fields in blockchain applications.
11495
+ * All user fields are nested under `context`, so paths start with `context.`.
11496
+ * Wildcard `*` matches any key at that level.
11497
+ */ const DEFAULT_REDACT_PATHS = [
11498
+ // Generic Credentials
11499
+ 'context.password',
11500
+ 'context.passphrase',
11501
+ 'context.secret',
11502
+ 'context.token',
11503
+ 'context.*.password',
11504
+ 'context.*.passphrase',
11505
+ 'context.*.secret',
11506
+ 'context.*.token',
11507
+ // API Keys & Auth Tokens
11508
+ 'context.apiKey',
11509
+ 'context.apiSecret',
11510
+ 'context.accessToken',
11511
+ 'context.refreshToken',
11512
+ 'context.jwt',
11513
+ 'context.bearerToken',
11514
+ 'context.sessionId',
11515
+ 'context.authorization',
11516
+ 'context.cookie',
11517
+ 'context.*.apiKey',
11518
+ 'context.*.apiSecret',
11519
+ 'context.*.accessToken',
11520
+ 'context.*.refreshToken',
11521
+ 'context.*.jwt',
11522
+ 'context.*.bearerToken',
11523
+ 'context.*.sessionId',
11524
+ 'context.*.authorization',
11525
+ 'context.*.cookie',
11526
+ // Web3 / Crypto Keys
11527
+ 'context.privateKey',
11528
+ 'context.secretKey',
11529
+ 'context.signingKey',
11530
+ 'context.encryptionKey',
11531
+ 'context.*.privateKey',
11532
+ 'context.*.secretKey',
11533
+ 'context.*.signingKey',
11534
+ 'context.*.encryptionKey',
11535
+ // Web3 / Crypto Mnemonics and Seeds
11536
+ 'context.mnemonic',
11537
+ 'context.seed',
11538
+ 'context.seedPhrase',
11539
+ 'context.*.mnemonic',
11540
+ 'context.*.seed',
11541
+ 'context.*.seedPhrase',
11542
+ // OTP / Verification Codes
11543
+ 'context.otp',
11544
+ 'context.verificationCode',
11545
+ 'context.*.otp',
11546
+ 'context.*.verificationCode',
11547
+ // Payment Information
11548
+ 'context.cardNumber',
11549
+ 'context.cvv',
11550
+ 'context.accountNumber',
11551
+ 'context.*.cardNumber',
11552
+ 'context.*.cvv',
11553
+ 'context.*.accountNumber'
11554
+ ];
11555
+ /**
11556
+ * Wrap user fields under `context` to prevent collision with pino internals.
11557
+ *
11558
+ * @param fields - User-provided log fields.
11559
+ * @returns Object with fields nested under `context`, or undefined if empty.
11560
+ *
11561
+ * @remarks
11562
+ * This function handles edge cases by returning undefined for null, undefined,
11563
+ * or empty objects to avoid unnecessary wrapping in log output.
11564
+ * Undefined values are cleaned before wrapping.
11565
+ */ function wrapInContext(fields) {
11566
+ if (!fields) return undefined;
11567
+ // Clean undefined values for consistency and transport compatibility
11568
+ const cleaned = omitUndefined(fields);
11569
+ // Handle edge case: all values were undefined, resulting in empty object
11570
+ const keys = Object.keys(cleaned);
11571
+ if (keys.length === 0) return undefined;
11572
+ return {
11573
+ context: cleaned
11574
+ };
11575
+ }
11576
+ /**
11577
+ * Wrap a pino instance to conform to our Logger interface.
11578
+ *
11579
+ * @param pinoInstance - The pino logger instance to wrap.
11580
+ * @returns A Logger instance conforming to our stable interface.
11581
+ */ function wrapPino(pinoInstance) {
11582
+ return {
11583
+ debug (message, fields) {
11584
+ const wrapped = wrapInContext(fields);
11585
+ if (wrapped) {
11586
+ pinoInstance.debug(wrapped, message);
11587
+ } else {
11588
+ pinoInstance.debug(message);
11589
+ }
11590
+ },
11591
+ info (message, fields) {
11592
+ const wrapped = wrapInContext(fields);
11593
+ if (wrapped) {
11594
+ pinoInstance.info(wrapped, message);
11595
+ } else {
11596
+ pinoInstance.info(message);
11597
+ }
11598
+ },
11599
+ warn (message, fields) {
11600
+ const wrapped = wrapInContext(fields);
11601
+ if (wrapped) {
11602
+ pinoInstance.warn(wrapped, message);
11603
+ } else {
11604
+ pinoInstance.warn(message);
11605
+ }
11606
+ },
11607
+ error (message, fields) {
11608
+ const wrapped = wrapInContext(fields);
11609
+ if (wrapped) {
11610
+ pinoInstance.error(wrapped, message);
11611
+ } else {
11612
+ pinoInstance.error(message);
11613
+ }
11614
+ },
11615
+ child (tags) {
11616
+ // Child bindings stay flat (not wrapped) - they're part of logger's base context
11617
+ const cleaned = omitUndefined(tags);
11618
+ return wrapPino(pinoInstance.child(cleaned));
11619
+ }
11620
+ };
11621
+ }
11622
+ /**
11623
+ * Build pino redact configuration from our simplified options.
11624
+ *
11625
+ * @param redact - The redact configuration option.
11626
+ * @returns Pino-compatible redact configuration or undefined.
11627
+ */ function buildRedactConfig(redact) {
11628
+ // Explicitly disabled
11629
+ if (redact === false) {
11630
+ return undefined;
11631
+ }
11632
+ // Custom paths provided
11633
+ if (Array.isArray(redact)) {
11634
+ return redact.length > 0 ? {
11635
+ paths: redact,
11636
+ censor: '[REDACTED]'
11637
+ } : undefined;
11638
+ }
11639
+ // Default: use web3 sensible defaults
11640
+ return {
11641
+ paths: [
11642
+ ...DEFAULT_REDACT_PATHS
11643
+ ],
11644
+ censor: '[REDACTED]'
11645
+ };
11646
+ }
11647
+ /**
11648
+ * Create a logger backed by pino.
11649
+ *
11650
+ * @param options - Logger options (optional).
11651
+ * @param stream - Destination stream (optional).
11652
+ * @returns A Logger instance.
11653
+ * @throws Error if invalid pino options are provided.
11654
+ *
11655
+ * @remarks
11656
+ * This is a thin wrapper around pino that exposes our stable Logger interface.
11657
+ * Pino handles all transport concerns: JSON, pretty printing, file, remote, browser, etc.
11658
+ *
11659
+ * **Security**: By default, sensitive web3 fields (privateKey, mnemonic, apiKey, etc.)
11660
+ * are automatically redacted from log output. Use `redact: false` to disable.
11661
+ *
11662
+ * @example
11663
+ * ```typescript
11664
+ * import { createLogger } from '@core/runtime'
11665
+ *
11666
+ * // Default: web3 sensitive fields are redacted
11667
+ * const logger = createLogger({ level: 'info' })
11668
+ * logger.info('Signing', { privateKey: '0x123...' })
11669
+ * // Output: { context: { privateKey: '[REDACTED]' }, msg: 'Signing' }
11670
+ *
11671
+ * // Disable redaction (use with caution)
11672
+ * const unsafeLogger = createLogger({ level: 'debug', redact: false })
11673
+ *
11674
+ * // Custom redaction paths
11675
+ * const customLogger = createLogger({
11676
+ * level: 'info',
11677
+ * redact: ['context.mySecret', 'context.*.credentials']
11678
+ * })
11679
+ *
11680
+ * // Pretty output for development
11681
+ * const devLogger = createLogger({
11682
+ * level: 'debug',
11683
+ * transport: { target: 'pino-pretty' }
11684
+ * })
11685
+ *
11686
+ * // Browser logger
11687
+ * const browserLogger = createLogger({
11688
+ * browser: { asObject: true }
11689
+ * })
11690
+ * ```
11691
+ */ function createLogger(options, stream) {
11692
+ const { redact, ...pinoOptions } = options ?? {};
11693
+ // Build redaction config
11694
+ const redactConfig = buildRedactConfig(redact);
11695
+ // Build final pino options, only include redact if defined
11696
+ const finalOptions = redactConfig ? {
11697
+ ...pinoOptions,
11698
+ redact: redactConfig
11699
+ } : pinoOptions;
11700
+ const pinoInstance = pino__default(finalOptions);
11701
+ return wrapPino(pinoInstance);
11702
+ }
11703
+
11704
+ // ============================================================================
11705
+ // Validation Schema
11706
+ // ============================================================================
11707
+ /**
11708
+ * Schema for validating {@link RuntimeOptions}.
11709
+ *
11710
+ * @remarks
11711
+ * Used internally by {@link createRuntime} to validate options from JS consumers.
11712
+ * Exported for advanced use cases where manual validation is needed.
11713
+ */ zod.z.object({
11714
+ logger: loggerSchema.optional(),
11715
+ metrics: metricsSchema.optional()
11716
+ }).passthrough();
11717
+
11718
+ // ============================================================================
11719
+ // Validation Schemas
11720
+ // ============================================================================
11721
+ /**
11722
+ * Schema for validating Caller.
11723
+ */ const callerSchema = zod.z.object({
11724
+ type: zod.z.string(),
11725
+ name: zod.z.string(),
11726
+ version: zod.z.string().optional()
11727
+ });
11728
+ /**
11729
+ * Schema for validating InvocationMeta input.
11730
+ */ zod.z.object({
11731
+ traceId: zod.z.string().optional(),
11732
+ runtime: zod.z.object({}).passthrough().optional(),
11733
+ tokens: zod.z.object({}).passthrough().optional(),
11734
+ callers: zod.z.array(callerSchema).optional(),
11735
+ signal: zod.z.instanceof(AbortSignal).optional()
11736
+ }).strict();
11737
+
11738
+ /**
11739
+ * Runtime package providing cross-cutting infrastructure for SDK operations.
10923
11740
  *
10924
- * @throws KitError if validation fails
11741
+ * @remarks
11742
+ * This package provides the core runtime infrastructure including:
11743
+ *
11744
+ * - **Runtime**: Complete container for logger, metrics, events, and clock
11745
+ * - **ExecutionContext**: Context for middleware with observability surface
11746
+ * - **Logger**: Isomorphic structured logging via {@link createLogger}
11747
+ * - **Events**: Type-safe event bus with {@link createEventBus}
11748
+ * - **Pipeline**: Middleware-based operation execution with {@link createPipeline}
11749
+ * - **Metrics**: Pluggable metrics collection with dimensional tags
10925
11750
  *
10926
11751
  * @example
10927
11752
  * ```typescript
10928
- * import { bridgeParamsSchema } from '@core/provider'
11753
+ * import {
11754
+ * createRuntime,
11755
+ * createExecutionContext,
11756
+ * createOpId,
11757
+ * createTraceId,
11758
+ * type Runtime,
11759
+ * type ExecutionContext,
11760
+ * } from '@core/runtime'
10929
11761
  *
10930
- * const validBridge = {
10931
- * amount: '100.50',
10932
- * source: {
10933
- * adapter: sourceAdapter,
10934
- * address: '0xSourceAddress',
10935
- * chain: sourceChain
10936
- * },
10937
- * destination: {
10938
- * adapter: destAdapter,
10939
- * address: '0xDestAddress',
10940
- * chain: destChain
10941
- * },
10942
- * token: 'USDC',
10943
- * config: {
10944
- * transferSpeed: 'FAST',
10945
- * maxFee: '1.5', // Must use dot as decimal separator
10946
- * customFee: {
10947
- * value: '0.5', // Must use dot as decimal separator
10948
- * recipientAddress: '0x1234567890123456789012345678901234567890'
10949
- * }
10950
- * }
10951
- * }
11762
+ * // Create a complete runtime
11763
+ * const runtime = createRuntime()
10952
11764
  *
10953
- * const result = bridgeParamsSchema.safeParse(validBridge)
10954
- * console.log(result.success) // true
11765
+ * // All services are guaranteed present
11766
+ * runtime.logger.info('Starting operation')
11767
+ * runtime.metrics.counter('requests').inc()
11768
+ * runtime.events.emit({ name: 'operation.started' })
10955
11769
  * ```
10956
- */ zod.z.object({
10957
- amount: zod.z.string().min(1, 'Required').pipe(createDecimalStringValidator({
10958
- allowZero: false,
10959
- regexMessage: AMOUNT_FORMAT_ERROR_MESSAGE,
10960
- attributeName: 'amount',
10961
- maxDecimals: 6
10962
- })(zod.z.string())),
10963
- source: walletContextSchema,
10964
- destination: bridgeDestinationSchema$1,
10965
- token: zod.z.literal('USDC'),
10966
- config: zod.z.object({
10967
- transferSpeed: zod.z.nativeEnum(TransferSpeed).optional(),
10968
- maxFee: zod.z.string().pipe(createDecimalStringValidator({
10969
- allowZero: true,
10970
- regexMessage: MAX_FEE_FORMAT_ERROR_MESSAGE,
10971
- attributeName: 'maxFee',
10972
- maxDecimals: 6
10973
- })(zod.z.string())).optional(),
10974
- customFee: customFeeSchema.optional()
10975
- })
10976
- });
11770
+ *
11771
+ * @packageDocumentation
11772
+ */ // Core types
11773
+ // Clock - expose defaultClock for backward compatibility
11774
+ /** Clock validation schema (backward compatibility). */ zod.z.custom((val)=>val !== null && typeof val === 'object' && 'now' in val && typeof val['now'] === 'function');
11775
+ /** EventBus validation schema (backward compatibility). */ zod.z.custom((val)=>val !== null && typeof val === 'object' && 'emit' in val && typeof val['emit'] === 'function');
11776
+ /** Runtime validation schema (backward compatibility). */ zod.z.object({
11777
+ logger: zod.z.any().optional(),
11778
+ events: zod.z.any().optional(),
11779
+ metrics: zod.z.any().optional(),
11780
+ clock: zod.z.any().optional()
11781
+ }).passthrough();
10977
11782
 
10978
11783
  /**
10979
11784
  * Creates a Zod superRefine validator for recipient address format validation.
@@ -10998,6 +11803,22 @@ var TransferSpeed;
10998
11803
  }
10999
11804
  };
11000
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
+ ]);
11001
11822
  /**
11002
11823
  * Schema for validating AdapterContext for bridge operations.
11003
11824
  * Must always contain both adapter and chain explicitly.
@@ -11100,9 +11921,14 @@ var TransferSpeed;
11100
11921
  allowZero: false,
11101
11922
  regexMessage: AMOUNT_FORMAT_ERROR_MESSAGE,
11102
11923
  attributeName: 'amount',
11103
- maxDecimals: 6
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
11104
11930
  })(zod.z.string())),
11105
- token: zod.z.literal('USDC').optional(),
11931
+ token: bridgeTokenSchema.optional(),
11106
11932
  config: zod.z.object({
11107
11933
  transferSpeed: zod.z.nativeEnum(TransferSpeed).optional(),
11108
11934
  feePayment: zod.z.enum([
@@ -11113,150 +11939,26 @@ var TransferSpeed;
11113
11939
  allowZero: true,
11114
11940
  regexMessage: MAX_FEE_FORMAT_ERROR_MESSAGE,
11115
11941
  attributeName: 'maxFee',
11116
- maxDecimals: 6
11942
+ // See `amount` above: widest routable precision (18); the exact
11943
+ // per-token precision is enforced at the scaling boundary.
11944
+ maxDecimals: 18
11117
11945
  })(zod.z.string())).optional(),
11118
11946
  customFee: customFeeSchema.optional()
11119
11947
  }).optional(),
11120
- quote: zod.z.string().regex(/^0x([a-fA-F0-9]{2})+$/, 'must be non-empty 0x hex').optional()
11121
- });
11122
-
11123
- /**
11124
- * Define a schema for runtime logger interfaces.
11125
- *
11126
- * @remarks
11127
- * Validate that a runtime logger provides the minimal methods expected by the SDK.
11128
- *
11129
- * @example
11130
- * ```typescript
11131
- * import { loggerSchema } from '@core/runtime'
11132
- *
11133
- * const logger = {
11134
- * debug: () => undefined,
11135
- * info: () => undefined,
11136
- * warn: () => undefined,
11137
- * error: () => undefined,
11138
- * child: () => logger,
11139
- * }
11140
- *
11141
- * loggerSchema.parse(logger)
11142
- * ```
11143
- */ const loggerSchema = zod.z.custom((value)=>{
11144
- if (value === null || typeof value !== 'object') {
11145
- return false;
11146
- }
11147
- const record = value;
11148
- return typeof record['debug'] === 'function' && typeof record['info'] === 'function' && typeof record['warn'] === 'function' && typeof record['error'] === 'function' && typeof record['child'] === 'function';
11149
- }, {
11150
- message: 'Invalid logger'
11151
- });
11152
-
11153
- /**
11154
- * Define a schema for runtime metrics interfaces.
11155
- *
11156
- * @remarks
11157
- * Validate that a metrics implementation exposes the minimal API expected by the runtime.
11158
- *
11159
- * @example
11160
- * ```typescript
11161
- * import { metricsSchema } from '@core/runtime'
11162
- *
11163
- * const metrics = {
11164
- * counter: () => ({ inc: () => undefined }),
11165
- * histogram: () => ({ observe: () => undefined }),
11166
- * timer: () => ({ start: () => () => undefined }),
11167
- * child: () => metrics,
11168
- * }
11169
- *
11170
- * metricsSchema.parse(metrics)
11171
- * ```
11172
- */ const metricsSchema = zod.z.custom((value)=>{
11173
- if (value === null || typeof value !== 'object') {
11174
- return false;
11175
- }
11176
- const record = value;
11177
- return typeof record['counter'] === 'function' && typeof record['histogram'] === 'function' && typeof record['timer'] === 'function' && typeof record['child'] === 'function';
11178
- }, {
11179
- message: 'Invalid metrics'
11180
- });
11181
-
11182
- // ============================================================================
11183
- // Validation Schema
11184
- // ============================================================================
11185
- /**
11186
- * Schema for validating {@link RuntimeOptions}.
11187
- *
11188
- * @remarks
11189
- * Used internally by {@link createRuntime} to validate options from JS consumers.
11190
- * Exported for advanced use cases where manual validation is needed.
11191
- */ zod.z.object({
11192
- logger: loggerSchema.optional(),
11193
- metrics: metricsSchema.optional()
11194
- }).passthrough();
11195
-
11196
- // ============================================================================
11197
- // Validation Schemas
11198
- // ============================================================================
11199
- /**
11200
- * Schema for validating Caller.
11201
- */ const callerSchema = zod.z.object({
11202
- type: zod.z.string(),
11203
- name: zod.z.string(),
11204
- version: zod.z.string().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()
11205
11961
  });
11206
- /**
11207
- * Schema for validating InvocationMeta input.
11208
- */ zod.z.object({
11209
- traceId: zod.z.string().optional(),
11210
- runtime: zod.z.object({}).passthrough().optional(),
11211
- tokens: zod.z.object({}).passthrough().optional(),
11212
- callers: zod.z.array(callerSchema).optional(),
11213
- signal: zod.z.instanceof(AbortSignal).optional()
11214
- }).strict();
11215
-
11216
- /**
11217
- * Runtime package providing cross-cutting infrastructure for SDK operations.
11218
- *
11219
- * @remarks
11220
- * This package provides the core runtime infrastructure including:
11221
- *
11222
- * - **Runtime**: Complete container for logger, metrics, events, and clock
11223
- * - **ExecutionContext**: Context for middleware with observability surface
11224
- * - **Logger**: Isomorphic structured logging via {@link createLogger}
11225
- * - **Events**: Type-safe event bus with {@link createEventBus}
11226
- * - **Pipeline**: Middleware-based operation execution with {@link createPipeline}
11227
- * - **Metrics**: Pluggable metrics collection with dimensional tags
11228
- *
11229
- * @example
11230
- * ```typescript
11231
- * import {
11232
- * createRuntime,
11233
- * createExecutionContext,
11234
- * createOpId,
11235
- * createTraceId,
11236
- * type Runtime,
11237
- * type ExecutionContext,
11238
- * } from '@core/runtime'
11239
- *
11240
- * // Create a complete runtime
11241
- * const runtime = createRuntime()
11242
- *
11243
- * // All services are guaranteed present
11244
- * runtime.logger.info('Starting operation')
11245
- * runtime.metrics.counter('requests').inc()
11246
- * runtime.events.emit({ name: 'operation.started' })
11247
- * ```
11248
- *
11249
- * @packageDocumentation
11250
- */ // Core types
11251
- // Clock - expose defaultClock for backward compatibility
11252
- /** Clock validation schema (backward compatibility). */ zod.z.custom((val)=>val !== null && typeof val === 'object' && 'now' in val && typeof val['now'] === 'function');
11253
- /** EventBus validation schema (backward compatibility). */ zod.z.custom((val)=>val !== null && typeof val === 'object' && 'emit' in val && typeof val['emit'] === 'function');
11254
- /** Runtime validation schema (backward compatibility). */ zod.z.object({
11255
- logger: zod.z.any().optional(),
11256
- events: zod.z.any().optional(),
11257
- metrics: zod.z.any().optional(),
11258
- clock: zod.z.any().optional()
11259
- }).passthrough();
11260
11962
 
11261
11963
  /**
11262
11964
  * The ASCII "cctp-forward" magic, hex-encoded (no `0x`), that a forward-friendly
@@ -11286,6 +11988,9 @@ var TransferSpeed;
11286
11988
  [TransferSpeed.SLOW]: 2000
11287
11989
  });
11288
11990
 
11991
+ createLogger({
11992
+ name: 'provider-cctp-v2'
11993
+ });
11289
11994
  /**
11290
11995
  * All chains that are supported by the CCTP v2 provider.
11291
11996
  *
@@ -11295,7 +12000,11 @@ var TransferSpeed;
11295
12000
  * @internal
11296
12001
  */ Object.values(Chains).filter((chain)=>isCCTPV2Supported(chain));
11297
12002
 
11298
- /** Decimal string in token minor units, constrained to be strictly positive. */ const positiveAmountSchema = zod.z.string().regex(/^\d+$/, 'must be a non-negative integer string')// Re-check the digit shape here: zod still runs this refinement when the
12003
+ /**
12004
+ * Decimal string in token minor units, constrained to be strictly positive.
12005
+ *
12006
+ * @internal
12007
+ */ const positiveAmountSchema = zod.z.string().regex(/^\d+$/, 'must be a non-negative integer string')// Re-check the digit shape here: zod still runs this refinement when the
11299
12008
  // regex check above fails ("dirty"), so guard BigInt() against throwing on a
11300
12009
  // non-numeric value before comparing.
11301
12010
  .refine((value)=>/^\d+$/.test(value) && BigInt(value) > 0n, 'must be greater than zero');
@@ -11330,11 +12039,19 @@ const forwardRequestSchema = zod.z.object({
11330
12039
  const preFinalityRequestSchema = zod.z.object({
11331
12040
  type: zod.z.literal('PRE_FINALITY')
11332
12041
  }).strict();
11333
- /** A single quote request item (`FORWARD` or `PRE_FINALITY`). */ const feeQuoteRequestSchema = zod.z.discriminatedUnion('type', [
12042
+ /**
12043
+ * A single quote request item (`FORWARD` or `PRE_FINALITY`).
12044
+ *
12045
+ * @internal
12046
+ */ const feeQuoteRequestSchema = zod.z.discriminatedUnion('type', [
11334
12047
  forwardRequestSchema,
11335
12048
  preFinalityRequestSchema
11336
12049
  ]);
11337
- /** A non-empty list of quote request items with unique types. */ const feeQuoteRequestsSchema = zod.z.array(feeQuoteRequestSchema).min(1, 'at least one request item is required').refine((items)=>new Set(items.map((item)=>item.type)).size === items.length, 'request item types must be unique');
12050
+ /**
12051
+ * A non-empty list of quote request items with unique types.
12052
+ *
12053
+ * @internal
12054
+ */ const feeQuoteRequestsSchema = zod.z.array(feeQuoteRequestSchema).min(1, 'at least one request item is required').refine((items)=>new Set(items.map((item)=>item.type)).size === items.length, 'request item types must be unique');
11338
12055
  /**
11339
12056
  * A structured `Partial<ApiPollingConfig>` polling override.
11340
12057
  *
@@ -11362,6 +12079,8 @@ const preFinalityRequestSchema = zod.z.object({
11362
12079
  * it `undefined`, which is falsy and silently selects the production base URL.
11363
12080
  * (`buildFeeQuoteUrl` independently re-validates the domains for standalone
11364
12081
  * callers.)
12082
+ *
12083
+ * @internal
11365
12084
  */ zod.z.object({
11366
12085
  sourceDomain: zod.z.number().int().nonnegative(),
11367
12086
  destinationDomain: zod.z.number().int().nonnegative(),
@@ -11397,7 +12116,11 @@ const metadataSchema = zod.z.object({
11397
12116
  blockEstimatedAt: zod.z.number().int().nonnegative().optional()
11398
12117
  }).passthrough()
11399
12118
  ]);
11400
- /** Schema for a signed fee quote returned by the Quote API. */ zod.z.object({
12119
+ /**
12120
+ * Schema for a signed fee quote returned by the Quote API.
12121
+ *
12122
+ * @internal
12123
+ */ zod.z.object({
11401
12124
  // The runtime YAML spec maps signedQuote to a looser `hex` (which allows
11402
12125
  // an empty `0x`); we keep the stricter non-empty form. Do not relax
11403
12126
  // without a reason.
@@ -11411,7 +12134,11 @@ const metadataSchema = zod.z.object({
11411
12134
  items: zod.z.array(feeQuoteItemSchema),
11412
12135
  metadata: metadataSchema.optional()
11413
12136
  }).passthrough();
11414
- /** Validate input to {@link validateQuote}. */ zod.z.object({
12137
+ /**
12138
+ * Validates input to {@link validateQuote}.
12139
+ *
12140
+ * @internal
12141
+ */ zod.z.object({
11415
12142
  sourceDomain: zod.z.number().int().nonnegative(),
11416
12143
  abiSignature: zod.z.string().min(1),
11417
12144
  args: zod.z.array(zod.z.union([
@@ -11446,11 +12173,13 @@ const validateQuoteItemSchema = zod.z.object({
11446
12173
  computedArgsHash: bytes32Schema.optional()
11447
12174
  }).passthrough();
11448
12175
  /**
11449
- * Schema for a response from the Quote API validation endpoint.
12176
+ * Schema for a validate-quote result returned by the Iris `/validate/usdc/:sourceDomain` endpoint.
11450
12177
  *
11451
12178
  * The endpoint takes the source domain as a URL path parameter and does not
11452
12179
  * return it in the response body, so `sourceDomain` is intentionally not part
11453
12180
  * of this schema.
12181
+ *
12182
+ * @internal
11454
12183
  */ zod.z.object({
11455
12184
  signedQuote: nonEmptyHexSchema,
11456
12185
  expiry: quoteExpiryStatusSchema,
@@ -11470,7 +12199,7 @@ const validateQuoteItemSchema = zod.z.object({
11470
12199
  registerKit(`${pkg$2.name}/${pkg$2.version}`);
11471
12200
 
11472
12201
  var name$1 = "@circle-fin/swap-kit";
11473
- var version$1 = "1.6.0";
12202
+ var version$1 = "1.7.0";
11474
12203
  var pkg$1 = {
11475
12204
  name: name$1,
11476
12205
  version: version$1};
@@ -14731,6 +15460,11 @@ function resolveFeePayoutChain(tokenIn, tokenOut, sourceChain, destinationChain)
14731
15460
  name: 'USDC',
14732
15461
  version: '2'
14733
15462
  },
15463
+ Arc: {
15464
+ chainId: Arc.chainId,
15465
+ name: 'USDC',
15466
+ version: '2'
15467
+ },
14734
15468
  Arc_Testnet: {
14735
15469
  chainId: ArcTestnet.chainId,
14736
15470
  name: 'USDC',
@@ -21842,7 +22576,7 @@ registerKit(`${pkg$1.name}/${pkg$1.version}`);
21842
22576
  };
21843
22577
 
21844
22578
  var name = "@circle-fin/earn-kit";
21845
- var version = "1.6.0";
22579
+ var version = "1.7.0";
21846
22580
  var pkg = {
21847
22581
  name: name,
21848
22582
  version: version};
@@ -21857,18 +22591,22 @@ var pkg = {
21857
22591
  *
21858
22592
  * @internal
21859
22593
  */ const CHAIN_TO_API = {
22594
+ [Blockchain.Arc]: 'ARC',
21860
22595
  [Blockchain.Arc_Testnet]: 'ARC-TESTNET'
21861
22596
  };
21862
22597
  /**
21863
22598
  * Map SDK source chain identifiers to bridge source-chain strings.
21864
22599
  *
21865
- * Cross-chain Earn deposits currently support Ethereum Sepolia, Arbitrum
21866
- * Sepolia, and Base Sepolia as source chains.
22600
+ * Cross-chain Earn deposits support Ethereum, Arbitrum, and Base (mainnet
22601
+ * and testnet) as source chains.
21867
22602
  *
21868
22603
  * @internal
21869
22604
  */ ({
22605
+ [Blockchain.Arbitrum]: 'ARB',
21870
22606
  [Blockchain.Arbitrum_Sepolia]: 'ARB-SEPOLIA',
22607
+ [Blockchain.Base]: 'BASE',
21871
22608
  [Blockchain.Base_Sepolia]: 'BASE-SEPOLIA',
22609
+ [Blockchain.Ethereum]: 'ETH',
21872
22610
  [Blockchain.Ethereum_Sepolia]: 'ETH-SEPOLIA'
21873
22611
  });
21874
22612
  /**
@@ -21879,13 +22617,20 @@ var pkg = {
21879
22617
  *
21880
22618
  * @internal
21881
22619
  */ ({
22620
+ [Blockchain.Arc]: CHAIN_TO_API[Blockchain.Arc],
21882
22621
  [Blockchain.Arc_Testnet]: CHAIN_TO_API[Blockchain.Arc_Testnet]
21883
22622
  });
21884
22623
  ({
22624
+ [Blockchain.Arbitrum]: {
22625
+ },
21885
22626
  [Blockchain.Arbitrum_Sepolia]: {
21886
22627
  },
22628
+ [Blockchain.Base]: {
22629
+ },
21887
22630
  [Blockchain.Base_Sepolia]: {
21888
22631
  },
22632
+ [Blockchain.Ethereum]: {
22633
+ },
21889
22634
  [Blockchain.Ethereum_Sepolia]: {
21890
22635
  }
21891
22636
  });