@circle-fin/app-kit 1.12.1 → 1.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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
@@ -2987,6 +2988,8 @@ class KitError extends Error {
2987
2988
  Blockchain["Optimism_Sepolia"] = "Optimism_Sepolia";
2988
2989
  Blockchain["Pharos"] = "Pharos";
2989
2990
  Blockchain["Pharos_Testnet"] = "Pharos_Testnet";
2991
+ Blockchain["Plasma"] = "Plasma";
2992
+ Blockchain["Plasma_Testnet"] = "Plasma_Testnet";
2990
2993
  Blockchain["Polkadot_Asset_Hub"] = "Polkadot_Asset_Hub";
2991
2994
  Blockchain["Polkadot_Westmint"] = "Polkadot_Westmint";
2992
2995
  Blockchain["Plume"] = "Plume";
@@ -3056,6 +3059,7 @@ var BridgeChain;
3056
3059
  BridgeChain["Morph"] = "Morph";
3057
3060
  BridgeChain["Optimism"] = "Optimism";
3058
3061
  BridgeChain["Pharos"] = "Pharos";
3062
+ BridgeChain["Plasma"] = "Plasma";
3059
3063
  BridgeChain["Plume"] = "Plume";
3060
3064
  BridgeChain["Polygon"] = "Polygon";
3061
3065
  BridgeChain["Sei"] = "Sei";
@@ -3082,6 +3086,7 @@ var BridgeChain;
3082
3086
  BridgeChain["Morph_Testnet"] = "Morph_Testnet";
3083
3087
  BridgeChain["Optimism_Sepolia"] = "Optimism_Sepolia";
3084
3088
  BridgeChain["Pharos_Testnet"] = "Pharos_Testnet";
3089
+ BridgeChain["Plasma_Testnet"] = "Plasma_Testnet";
3085
3090
  BridgeChain["Plume_Testnet"] = "Plume_Testnet";
3086
3091
  BridgeChain["Polygon_Amoy_Testnet"] = "Polygon_Amoy_Testnet";
3087
3092
  BridgeChain["Sei_Testnet"] = "Sei_Testnet";
@@ -3539,6 +3544,45 @@ var EarnChain;
3539
3544
  * This program handles minting operations for Gateway transactions
3540
3545
  * on Solana devnet.
3541
3546
  */ const GATEWAY_MINTER_SOLANA_DEVNET = 'GATEmKK2ECL1brEngQZWCgMWPbvrEYqsV6u29dAaHavr';
3547
+ /**
3548
+ * The `TokenMessengerWithFees` proxy contract address for EVM mainnet networks
3549
+ * (all chains except Edge).
3550
+ *
3551
+ * Deployed at a CREATE3-derived address; identical across all mainnet EVM
3552
+ * source chains. Present on any chain that supports the prepaid FORWARD path
3553
+ * via `depositForBurnWithHookAndFees`.
3554
+ */ const TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET = '0x71f54F818671cD0D7ea140Da213e5C8b5C92a408';
3555
+ /**
3556
+ * The `TokenMessengerWithFees` proxy contract address for EVM testnet networks.
3557
+ *
3558
+ * Identical across all testnet EVM source chains. Present on any testnet chain
3559
+ * that supports the prepaid FORWARD path via `depositForBurnWithHookAndFees`.
3560
+ */ const TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET = '0x8745D906D67C346E5eb1aEEED38Eb87F34DF0C0A';
3561
+ /**
3562
+ * The `DepositForHandler` proxy contract address for EVM mainnet networks.
3563
+ *
3564
+ * The handler the GenericExecutor calls on a fast-deposit destination chain to
3565
+ * run a cross-chain deposit into the GatewayWallet. Deployed at the same
3566
+ * address across all mainnet EVM destination chains.
3567
+ */ const DEPOSIT_FOR_HANDLER_EVM_MAINNET = '0x16529813203f77E036576666336554a1210dce4D';
3568
+ /**
3569
+ * The `DepositForHandler` proxy contract address for EVM testnet networks.
3570
+ *
3571
+ * Identical across all testnet EVM destination chains.
3572
+ */ const DEPOSIT_FOR_HANDLER_EVM_TESTNET = '0xD05E7D2E7d30b92c5F17d7d0fC575fce231F1A48';
3573
+ /**
3574
+ * The `GenericExecutor` proxy contract address for EVM mainnet networks.
3575
+ *
3576
+ * The GenericExecutor is the `mintRecipient` and `destinationCaller` on the
3577
+ * destination chain for the CCTP v2 prepaid FORWARD path. It receives the CCTP
3578
+ * mint and calls the `DepositForHandler` to complete the fast deposit.
3579
+ * Deployed at the same address across all mainnet EVM destination chains.
3580
+ */ const GENERIC_EXECUTOR_EVM_MAINNET = '0xFa7be2f04F3Ad4ca969260729c6d45B5625984A7';
3581
+ /**
3582
+ * The `GenericExecutor` proxy contract address for EVM testnet networks.
3583
+ *
3584
+ * Identical across all testnet EVM destination chains.
3585
+ */ const GENERIC_EXECUTOR_EVM_TESTNET = '0xEdC81040756AcCfF070c21D37b265b9D0b5Ba45e';
3542
3586
 
3543
3587
  /**
3544
3588
  * Arc Testnet chain definition
@@ -3576,6 +3620,7 @@ var EarnChain;
3576
3620
  v2: {
3577
3621
  type: 'split',
3578
3622
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
3623
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
3579
3624
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
3580
3625
  confirmations: 1,
3581
3626
  fastConfirmations: 1
@@ -3596,9 +3641,8 @@ var EarnChain;
3596
3641
  v1: {
3597
3642
  wallet: GATEWAY_WALLET_EVM_TESTNET,
3598
3643
  minter: GATEWAY_MINTER_EVM_TESTNET,
3599
- // DepositForHandler the GenericExecutor calls to run a fast cross-chain
3600
- // deposit into the GatewayWallet above.
3601
- depositForHandler: '0xD05E7D2E7d30b92c5F17d7d0fC575fce231F1A48'
3644
+ depositForHandler: DEPOSIT_FOR_HANDLER_EVM_TESTNET,
3645
+ genericExecutor: GENERIC_EXECUTOR_EVM_TESTNET
3602
3646
  }
3603
3647
  },
3604
3648
  forwarderSupported: {
@@ -3643,6 +3687,7 @@ var EarnChain;
3643
3687
  v2: {
3644
3688
  type: 'split',
3645
3689
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
3690
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
3646
3691
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
3647
3692
  confirmations: 65,
3648
3693
  fastConfirmations: 1
@@ -3707,6 +3752,7 @@ var EarnChain;
3707
3752
  v2: {
3708
3753
  type: 'split',
3709
3754
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
3755
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
3710
3756
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
3711
3757
  confirmations: 65,
3712
3758
  fastConfirmations: 1
@@ -3771,6 +3817,7 @@ var EarnChain;
3771
3817
  v2: {
3772
3818
  type: 'split',
3773
3819
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
3820
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
3774
3821
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
3775
3822
  confirmations: 1,
3776
3823
  fastConfirmations: 1
@@ -3790,7 +3837,9 @@ var EarnChain;
3790
3837
  contracts: {
3791
3838
  v1: {
3792
3839
  wallet: GATEWAY_WALLET_EVM_MAINNET,
3793
- minter: GATEWAY_MINTER_EVM_MAINNET
3840
+ minter: GATEWAY_MINTER_EVM_MAINNET,
3841
+ depositForHandler: DEPOSIT_FOR_HANDLER_EVM_MAINNET,
3842
+ genericExecutor: GENERIC_EXECUTOR_EVM_MAINNET
3794
3843
  }
3795
3844
  },
3796
3845
  forwarderSupported: {
@@ -3832,6 +3881,7 @@ var EarnChain;
3832
3881
  v2: {
3833
3882
  type: 'split',
3834
3883
  tokenMessenger: '0x8fe6b999dc680ccfdd5bf7eb0974218be2542daa',
3884
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
3835
3885
  messageTransmitter: '0xe737e5cebeeba77efe34d4aa090756590b1ce275',
3836
3886
  confirmations: 1,
3837
3887
  fastConfirmations: 1
@@ -3853,7 +3903,9 @@ var EarnChain;
3853
3903
  contracts: {
3854
3904
  v1: {
3855
3905
  wallet: GATEWAY_WALLET_EVM_TESTNET,
3856
- minter: GATEWAY_MINTER_EVM_TESTNET
3906
+ minter: GATEWAY_MINTER_EVM_TESTNET,
3907
+ depositForHandler: DEPOSIT_FOR_HANDLER_EVM_TESTNET,
3908
+ genericExecutor: GENERIC_EXECUTOR_EVM_TESTNET
3857
3909
  }
3858
3910
  },
3859
3911
  forwarderSupported: {
@@ -3899,6 +3951,7 @@ var EarnChain;
3899
3951
  v2: {
3900
3952
  type: 'split',
3901
3953
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
3954
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
3902
3955
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
3903
3956
  confirmations: 65,
3904
3957
  fastConfirmations: 1
@@ -3963,6 +4016,7 @@ var EarnChain;
3963
4016
  v2: {
3964
4017
  type: 'split',
3965
4018
  tokenMessenger: '0x8fe6b999dc680ccfdd5bf7eb0974218be2542daa',
4019
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
3966
4020
  messageTransmitter: '0xe737e5cebeeba77efe34d4aa090756590b1ce275',
3967
4021
  confirmations: 65,
3968
4022
  fastConfirmations: 1
@@ -4073,6 +4127,7 @@ var EarnChain;
4073
4127
  v2: {
4074
4128
  type: 'split',
4075
4129
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
4130
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
4076
4131
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
4077
4132
  confirmations: 65,
4078
4133
  fastConfirmations: 1
@@ -4117,6 +4172,7 @@ var EarnChain;
4117
4172
  v2: {
4118
4173
  type: 'split',
4119
4174
  tokenMessenger: '0x8fe6b999dc680ccfdd5bf7eb0974218be2542daa',
4175
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
4120
4176
  messageTransmitter: '0xe737e5cebeeba77efe34d4aa090756590b1ce275',
4121
4177
  confirmations: 65,
4122
4178
  fastConfirmations: 1
@@ -4162,6 +4218,7 @@ var EarnChain;
4162
4218
  v2: {
4163
4219
  type: 'split',
4164
4220
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
4221
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
4165
4222
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
4166
4223
  confirmations: 1,
4167
4224
  fastConfirmations: 1
@@ -4207,6 +4264,7 @@ var EarnChain;
4207
4264
  v2: {
4208
4265
  type: 'split',
4209
4266
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
4267
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
4210
4268
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
4211
4269
  confirmations: 1,
4212
4270
  fastConfirmations: 1
@@ -4252,6 +4310,7 @@ var EarnChain;
4252
4310
  v2: {
4253
4311
  type: 'split',
4254
4312
  tokenMessenger: '0x98706A006bc632Df31CAdFCBD43F38887ce2ca5c',
4313
+ tokenMessengerWithFees: '0x3Ac96675F9a3E6922713e041645D82f3561d3686',
4255
4314
  messageTransmitter: '0x5b61381Fc9e58E70EfC13a4A97516997019198ee',
4256
4315
  confirmations: 65,
4257
4316
  fastConfirmations: 1
@@ -4297,6 +4356,7 @@ var EarnChain;
4297
4356
  v2: {
4298
4357
  type: 'split',
4299
4358
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
4359
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
4300
4360
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
4301
4361
  confirmations: 65,
4302
4362
  fastConfirmations: 1
@@ -4348,6 +4408,7 @@ var EarnChain;
4348
4408
  v2: {
4349
4409
  type: 'split',
4350
4410
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
4411
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
4351
4412
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
4352
4413
  confirmations: 65,
4353
4414
  fastConfirmations: 2
@@ -4412,6 +4473,7 @@ var EarnChain;
4412
4473
  v2: {
4413
4474
  type: 'split',
4414
4475
  tokenMessenger: '0x8fe6b999dc680ccfdd5bf7eb0974218be2542daa',
4476
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
4415
4477
  messageTransmitter: '0xe737e5cebeeba77efe34d4aa090756590b1ce275',
4416
4478
  confirmations: 65,
4417
4479
  fastConfirmations: 2
@@ -4522,6 +4584,7 @@ var EarnChain;
4522
4584
  v2: {
4523
4585
  type: 'split',
4524
4586
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
4587
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
4525
4588
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
4526
4589
  confirmations: 1,
4527
4590
  fastConfirmations: 1
@@ -4581,6 +4644,7 @@ var EarnChain;
4581
4644
  v2: {
4582
4645
  type: 'split',
4583
4646
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
4647
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
4584
4648
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
4585
4649
  confirmations: 1,
4586
4650
  fastConfirmations: 1
@@ -4641,6 +4705,7 @@ var EarnChain;
4641
4705
  v2: {
4642
4706
  type: 'split',
4643
4707
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
4708
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
4644
4709
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
4645
4710
  confirmations: 1,
4646
4711
  fastConfirmations: 1
@@ -4688,6 +4753,7 @@ var EarnChain;
4688
4753
  v2: {
4689
4754
  type: 'split',
4690
4755
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
4756
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
4691
4757
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
4692
4758
  confirmations: 1,
4693
4759
  fastConfirmations: 1
@@ -4735,6 +4801,7 @@ var EarnChain;
4735
4801
  v2: {
4736
4802
  type: 'split',
4737
4803
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
4804
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
4738
4805
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
4739
4806
  confirmations: 65,
4740
4807
  fastConfirmations: 1
@@ -4782,6 +4849,7 @@ var EarnChain;
4782
4849
  v2: {
4783
4850
  type: 'split',
4784
4851
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
4852
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
4785
4853
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
4786
4854
  confirmations: 65,
4787
4855
  fastConfirmations: 1
@@ -4826,6 +4894,7 @@ var EarnChain;
4826
4894
  v2: {
4827
4895
  type: 'split',
4828
4896
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
4897
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
4829
4898
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
4830
4899
  confirmations: 1,
4831
4900
  fastConfirmations: 1
@@ -4871,6 +4940,7 @@ var EarnChain;
4871
4940
  v2: {
4872
4941
  type: 'split',
4873
4942
  tokenMessenger: '0x8fe6b999dc680ccfdd5bf7eb0974218be2542daa',
4943
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
4874
4944
  messageTransmitter: '0xe737e5cebeeba77efe34d4aa090756590b1ce275',
4875
4945
  confirmations: 1,
4876
4946
  fastConfirmations: 1
@@ -4917,6 +4987,7 @@ var EarnChain;
4917
4987
  v2: {
4918
4988
  type: 'split',
4919
4989
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
4990
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
4920
4991
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
4921
4992
  confirmations: 1,
4922
4993
  fastConfirmations: 1
@@ -4964,6 +5035,7 @@ var EarnChain;
4964
5035
  v2: {
4965
5036
  type: 'split',
4966
5037
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
5038
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
4967
5039
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
4968
5040
  confirmations: 1,
4969
5041
  fastConfirmations: 1
@@ -5009,6 +5081,7 @@ var EarnChain;
5009
5081
  v2: {
5010
5082
  type: 'split',
5011
5083
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
5084
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
5012
5085
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
5013
5086
  confirmations: 64,
5014
5087
  fastConfirmations: 1
@@ -5054,6 +5127,7 @@ var EarnChain;
5054
5127
  v2: {
5055
5128
  type: 'split',
5056
5129
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
5130
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
5057
5131
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
5058
5132
  confirmations: 64,
5059
5133
  fastConfirmations: 1
@@ -5230,6 +5304,7 @@ var EarnChain;
5230
5304
  v2: {
5231
5305
  type: 'split',
5232
5306
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
5307
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
5233
5308
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
5234
5309
  confirmations: 65,
5235
5310
  fastConfirmations: 1
@@ -5294,6 +5369,7 @@ var EarnChain;
5294
5369
  v2: {
5295
5370
  type: 'split',
5296
5371
  tokenMessenger: '0x8fe6b999dc680ccfdd5bf7eb0974218be2542daa',
5372
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
5297
5373
  messageTransmitter: '0xe737e5cebeeba77efe34d4aa090756590b1ce275',
5298
5374
  confirmations: 65,
5299
5375
  fastConfirmations: 1
@@ -5353,6 +5429,7 @@ var EarnChain;
5353
5429
  v2: {
5354
5430
  type: 'split',
5355
5431
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
5432
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
5356
5433
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
5357
5434
  confirmations: 1,
5358
5435
  fastConfirmations: 1
@@ -5399,6 +5476,7 @@ var EarnChain;
5399
5476
  v2: {
5400
5477
  type: 'split',
5401
5478
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
5479
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
5402
5480
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
5403
5481
  confirmations: 1,
5404
5482
  fastConfirmations: 1
@@ -5414,6 +5492,98 @@ var EarnChain;
5414
5492
  }
5415
5493
  });
5416
5494
 
5495
+ /**
5496
+ * Plasma Mainnet chain definition
5497
+ * @remarks
5498
+ * This represents the official production network for the Plasma blockchain.
5499
+ * Plasma is an EVM-equivalent Layer 1 blockchain purpose-built for global
5500
+ * stablecoin payments, with deterministic BFT finality (PlasmaBFT/Fast-HotStuff).
5501
+ */ const Plasma = defineChain({
5502
+ type: 'evm',
5503
+ chain: Blockchain.Plasma,
5504
+ name: 'Plasma',
5505
+ title: 'Plasma Mainnet',
5506
+ nativeCurrency: {
5507
+ name: 'Plasma',
5508
+ symbol: 'XPL',
5509
+ decimals: 18
5510
+ },
5511
+ chainId: 9745,
5512
+ isTestnet: false,
5513
+ explorerUrl: 'https://plasmascan.to/tx/{hash}',
5514
+ rpcEndpoints: [
5515
+ 'https://rpc.plasma.to'
5516
+ ],
5517
+ eurcAddress: '0x3EE196E78d4d4248b849B8E1C7F44C5457FAFD2C',
5518
+ usdcAddress: '0x2d661C89D812261039AF9764eceaAee884f5F67F',
5519
+ usdtAddress: null,
5520
+ cctp: {
5521
+ domain: 33,
5522
+ contracts: {
5523
+ v2: {
5524
+ type: 'split',
5525
+ tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
5526
+ messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
5527
+ confirmations: 3,
5528
+ fastConfirmations: 1
5529
+ }
5530
+ },
5531
+ forwarderSupported: {
5532
+ source: false,
5533
+ destination: false
5534
+ }
5535
+ },
5536
+ kitContracts: {
5537
+ bridge: BRIDGE_CONTRACT_EVM_MAINNET
5538
+ }
5539
+ });
5540
+
5541
+ /**
5542
+ * Plasma Testnet chain definition
5543
+ * @remarks
5544
+ * This represents the official test network for the Plasma blockchain.
5545
+ * Plasma is an EVM-equivalent Layer 1 blockchain purpose-built for global
5546
+ * stablecoin payments, with deterministic BFT finality (PlasmaBFT/Fast-HotStuff).
5547
+ */ const PlasmaTestnet = defineChain({
5548
+ type: 'evm',
5549
+ chain: Blockchain.Plasma_Testnet,
5550
+ name: 'Plasma Testnet',
5551
+ title: 'Plasma Testnet',
5552
+ nativeCurrency: {
5553
+ name: 'Plasma',
5554
+ symbol: 'XPL',
5555
+ decimals: 18
5556
+ },
5557
+ chainId: 9746,
5558
+ isTestnet: true,
5559
+ explorerUrl: 'https://testnet.plasmascan.to/tx/{hash}',
5560
+ rpcEndpoints: [
5561
+ 'https://testnet-rpc.plasma.to'
5562
+ ],
5563
+ eurcAddress: '0x98AfA0F93Dd993B736399f9074eDcEBD1985A330',
5564
+ usdcAddress: '0xE67Fb267022cBA8064Dd388CC2FED724F3120D9D',
5565
+ usdtAddress: null,
5566
+ cctp: {
5567
+ domain: 33,
5568
+ contracts: {
5569
+ v2: {
5570
+ type: 'split',
5571
+ tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
5572
+ messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
5573
+ confirmations: 3,
5574
+ fastConfirmations: 1
5575
+ }
5576
+ },
5577
+ forwarderSupported: {
5578
+ source: false,
5579
+ destination: false
5580
+ }
5581
+ },
5582
+ kitContracts: {
5583
+ bridge: BRIDGE_CONTRACT_EVM_TESTNET
5584
+ }
5585
+ });
5586
+
5417
5587
  /**
5418
5588
  * Plume Mainnet chain definition
5419
5589
  * @remarks
@@ -5445,6 +5615,7 @@ var EarnChain;
5445
5615
  v2: {
5446
5616
  type: 'split',
5447
5617
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
5618
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
5448
5619
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
5449
5620
  confirmations: 65,
5450
5621
  fastConfirmations: 1
@@ -5491,6 +5662,7 @@ var EarnChain;
5491
5662
  v2: {
5492
5663
  type: 'split',
5493
5664
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
5665
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
5494
5666
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
5495
5667
  confirmations: 65,
5496
5668
  fastConfirmations: 1
@@ -5592,6 +5764,7 @@ var EarnChain;
5592
5764
  v2: {
5593
5765
  type: 'split',
5594
5766
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
5767
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
5595
5768
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
5596
5769
  confirmations: 33,
5597
5770
  fastConfirmations: 13
@@ -5611,7 +5784,9 @@ var EarnChain;
5611
5784
  contracts: {
5612
5785
  v1: {
5613
5786
  wallet: GATEWAY_WALLET_EVM_MAINNET,
5614
- minter: GATEWAY_MINTER_EVM_MAINNET
5787
+ minter: GATEWAY_MINTER_EVM_MAINNET,
5788
+ depositForHandler: DEPOSIT_FOR_HANDLER_EVM_MAINNET,
5789
+ genericExecutor: GENERIC_EXECUTOR_EVM_MAINNET
5615
5790
  }
5616
5791
  },
5617
5792
  forwarderSupported: {
@@ -5657,6 +5832,7 @@ var EarnChain;
5657
5832
  v2: {
5658
5833
  type: 'split',
5659
5834
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
5835
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
5660
5836
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
5661
5837
  confirmations: 33,
5662
5838
  fastConfirmations: 13
@@ -5675,7 +5851,9 @@ var EarnChain;
5675
5851
  contracts: {
5676
5852
  v1: {
5677
5853
  wallet: GATEWAY_WALLET_EVM_TESTNET,
5678
- minter: GATEWAY_MINTER_EVM_TESTNET
5854
+ minter: GATEWAY_MINTER_EVM_TESTNET,
5855
+ depositForHandler: DEPOSIT_FOR_HANDLER_EVM_TESTNET,
5856
+ genericExecutor: GENERIC_EXECUTOR_EVM_TESTNET
5679
5857
  }
5680
5858
  },
5681
5859
  forwarderSupported: {
@@ -5716,6 +5894,7 @@ var EarnChain;
5716
5894
  v2: {
5717
5895
  type: 'split',
5718
5896
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
5897
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
5719
5898
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
5720
5899
  confirmations: 1,
5721
5900
  fastConfirmations: 1
@@ -5775,6 +5954,7 @@ var EarnChain;
5775
5954
  v2: {
5776
5955
  type: 'split',
5777
5956
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
5957
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
5778
5958
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
5779
5959
  confirmations: 1,
5780
5960
  fastConfirmations: 1
@@ -5832,6 +6012,7 @@ var EarnChain;
5832
6012
  v2: {
5833
6013
  type: 'split',
5834
6014
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
6015
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
5835
6016
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
5836
6017
  confirmations: 1,
5837
6018
  fastConfirmations: 1
@@ -5890,6 +6071,7 @@ var EarnChain;
5890
6071
  v2: {
5891
6072
  type: 'split',
5892
6073
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
6074
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
5893
6075
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
5894
6076
  confirmations: 1,
5895
6077
  fastConfirmations: 1
@@ -6205,6 +6387,7 @@ var EarnChain;
6205
6387
  v2: {
6206
6388
  type: 'split',
6207
6389
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
6390
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
6208
6391
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
6209
6392
  confirmations: 65,
6210
6393
  fastConfirmations: 1
@@ -6269,6 +6452,7 @@ var EarnChain;
6269
6452
  v2: {
6270
6453
  type: 'split',
6271
6454
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
6455
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
6272
6456
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
6273
6457
  confirmations: 65,
6274
6458
  fastConfirmations: 1
@@ -6326,6 +6510,7 @@ var EarnChain;
6326
6510
  v2: {
6327
6511
  type: 'split',
6328
6512
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cF5d',
6513
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
6329
6514
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
6330
6515
  confirmations: 65,
6331
6516
  fastConfirmations: 1
@@ -6385,6 +6570,7 @@ var EarnChain;
6385
6570
  v2: {
6386
6571
  type: 'split',
6387
6572
  tokenMessenger: '0x8fe6b999dc680ccfdd5bf7eb0974218be2542daa',
6573
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
6388
6574
  messageTransmitter: '0xe737e5cebeeba77efe34d4aa090756590b1ce275',
6389
6575
  confirmations: 65,
6390
6576
  fastConfirmations: 1
@@ -6445,6 +6631,7 @@ var EarnChain;
6445
6631
  v2: {
6446
6632
  type: 'split',
6447
6633
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
6634
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
6448
6635
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
6449
6636
  confirmations: 3,
6450
6637
  fastConfirmations: 3
@@ -6490,6 +6677,7 @@ var EarnChain;
6490
6677
  v2: {
6491
6678
  type: 'split',
6492
6679
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
6680
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
6493
6681
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
6494
6682
  confirmations: 3,
6495
6683
  fastConfirmations: 1
@@ -6700,6 +6888,8 @@ var Chains = {
6700
6888
  OptimismSepolia: OptimismSepolia,
6701
6889
  Pharos: Pharos,
6702
6890
  PharosTestnet: PharosTestnet,
6891
+ Plasma: Plasma,
6892
+ PlasmaTestnet: PlasmaTestnet,
6703
6893
  Plume: Plume,
6704
6894
  PlumeTestnet: PlumeTestnet,
6705
6895
  PolkadotAssetHub: PolkadotAssetHub,
@@ -6749,6 +6939,67 @@ var Chains = {
6749
6939
  return chain.cctp?.contracts.v2 !== undefined;
6750
6940
  }
6751
6941
 
6942
+ /**
6943
+ * Chains the Fee Service accepts as a SOURCE for source-paid ("receive-exact")
6944
+ * CCTP v2 fees. An explicit allowlist is required because the
6945
+ * `TokenMessengerWithFees` wrapper address is now shared with the fast-deposit
6946
+ * forwarder path, so wrapper presence no longer implies source-fee support.
6947
+ * Keep in sync with backend coverage.
6948
+ */ new Set([
6949
+ // Mainnet
6950
+ Blockchain.Ethereum,
6951
+ Blockchain.Base,
6952
+ Blockchain.Arbitrum,
6953
+ Blockchain.Unichain,
6954
+ Blockchain.Optimism,
6955
+ Blockchain.Codex,
6956
+ Blockchain.Ink,
6957
+ Blockchain.Plume,
6958
+ Blockchain.Linea,
6959
+ Blockchain.World_Chain,
6960
+ // Testnet counterparts
6961
+ Blockchain.Ethereum_Sepolia,
6962
+ Blockchain.Base_Sepolia,
6963
+ Blockchain.Arbitrum_Sepolia,
6964
+ Blockchain.Unichain_Sepolia,
6965
+ Blockchain.Optimism_Sepolia,
6966
+ Blockchain.Codex_Testnet,
6967
+ Blockchain.Ink_Testnet,
6968
+ Blockchain.Plume_Testnet,
6969
+ Blockchain.Linea_Sepolia,
6970
+ Blockchain.World_Chain_Sepolia
6971
+ ]);
6972
+
6973
+ /**
6974
+ * Temporary allowlist of chains permitted to initiate Gateway fast deposits.
6975
+ * Only chains keyed here are eligible; all others are rejected. Using the
6976
+ * {@link Blockchain} enum keeps entries type-safe and catches typos at compile
6977
+ * time. Remove this allowlist once roll-out is complete.
6978
+ */ new Set([
6979
+ // Mainnet
6980
+ Blockchain.Ethereum,
6981
+ Blockchain.Base,
6982
+ Blockchain.Arbitrum,
6983
+ Blockchain.Unichain,
6984
+ Blockchain.Optimism,
6985
+ Blockchain.Codex,
6986
+ Blockchain.Ink,
6987
+ Blockchain.Plume,
6988
+ Blockchain.Linea,
6989
+ Blockchain.World_Chain,
6990
+ // Testnet counterparts
6991
+ Blockchain.Ethereum_Sepolia,
6992
+ Blockchain.Base_Sepolia,
6993
+ Blockchain.Arbitrum_Sepolia,
6994
+ Blockchain.Unichain_Sepolia,
6995
+ Blockchain.Optimism_Sepolia,
6996
+ Blockchain.Codex_Testnet,
6997
+ Blockchain.Ink_Testnet,
6998
+ Blockchain.Plume_Testnet,
6999
+ Blockchain.Linea_Sepolia,
7000
+ Blockchain.World_Chain_Sepolia
7001
+ ]);
7002
+
6752
7003
  /**
6753
7004
  * Zod schema for validating Gateway v1 contract addresses.
6754
7005
  *
@@ -6770,7 +7021,10 @@ var Chains = {
6770
7021
  }).min(1, 'Gateway minter address cannot be empty.'),
6771
7022
  depositForHandler: zod.z.string({
6772
7023
  invalid_type_error: 'Gateway depositForHandler address must be a string.'
6773
- }).min(1, 'Gateway depositForHandler address cannot be empty.').optional()
7024
+ }).min(1, 'Gateway depositForHandler address cannot be empty.').optional(),
7025
+ genericExecutor: zod.z.string({
7026
+ invalid_type_error: 'Gateway genericExecutor address must be a string.'
7027
+ }).min(1, 'Gateway genericExecutor address cannot be empty.').optional()
6774
7028
  }).strict() // Reject any additional properties not defined in the schema
6775
7029
  ;
6776
7030
  /**
@@ -8741,6 +8995,7 @@ const swapTokenEnumSchema = zod.z.enum([
8741
8995
  [Blockchain.Noble]: 'uusdc',
8742
8996
  [Blockchain.Optimism]: '0x0b2c639c533813f4aa9d7837caf62653d097ff85',
8743
8997
  [Blockchain.Pharos]: '0xC879C018dB60520F4355C26eD1a6D572cdAC1815',
8998
+ [Blockchain.Plasma]: '0x2d661C89D812261039AF9764eceaAee884f5F67F',
8744
8999
  [Blockchain.Plume]: '0x222365EF19F7947e5484218551B56bb3965Aa7aF',
8745
9000
  [Blockchain.Polkadot_Asset_Hub]: '1337',
8746
9001
  [Blockchain.Polygon]: '0x3c499c542cef5e3811e1192ce70d8cc03d5c3359',
@@ -8777,6 +9032,7 @@ const swapTokenEnumSchema = zod.z.enum([
8777
9032
  [Blockchain.Noble_Testnet]: 'uusdc',
8778
9033
  [Blockchain.Optimism_Sepolia]: '0x5fd84259d66Cd46123540766Be93DFE6D43130D7',
8779
9034
  [Blockchain.Pharos_Testnet]: '0xcfC8330f4BCAB529c625D12781b1C19466A9Fc8B',
9035
+ [Blockchain.Plasma_Testnet]: '0xE67Fb267022cBA8064Dd388CC2FED724F3120D9D',
8780
9036
  [Blockchain.Plume_Testnet]: '0xcB5f30e335672893c7eb944B374c196392C19D18',
8781
9037
  [Blockchain.Polkadot_Westmint]: '31337',
8782
9038
  [Blockchain.Polygon_Amoy_Testnet]: '0x41e94eb019c0762f9bfcf9fb1e58725bfb0e7582',
@@ -8839,6 +9095,7 @@ const swapTokenEnumSchema = zod.z.enum([
8839
9095
  [Blockchain.Base]: '0x60a3E35Cc302bFA44Cb288Bc5a4F316Fdb1adb42',
8840
9096
  [Blockchain.Cronos]: '0xA6dE01a2d62C6B5f3525d768f34d276652C554c8',
8841
9097
  [Blockchain.Ethereum]: '0x1aBaEA1f7C830bD89Acc67eC4af516284b1bC33c',
9098
+ [Blockchain.Plasma]: '0x3EE196E78d4d4248b849B8E1C7F44C5457FAFD2C',
8842
9099
  [Blockchain.Solana]: 'HzwqbKZw8HxMN6bF2yFZNrht3c2iXXzpKcFu7uBEDKtr',
8843
9100
  [Blockchain.World_Chain]: '0x1C60ba0A0eD1019e8Eb035E6daF4155A5cE2380B',
8844
9101
  // =========================================================================
@@ -8847,7 +9104,8 @@ const swapTokenEnumSchema = zod.z.enum([
8847
9104
  [Blockchain.Arc_Testnet]: '0x89B50855Aa3bE2F677cD6303Cec089B5F319D72a',
8848
9105
  [Blockchain.Base_Sepolia]: '0x808456652fdb597867f38412077A9182bf77359F',
8849
9106
  [Blockchain.Cronos_Testnet]: '0x31f7538adb53cF16350e6B0c89d03D91b7D12c46',
8850
- [Blockchain.Ethereum_Sepolia]: '0x08210F9170F89Ab7658F0B5E3fF39b0E03C594D4'
9107
+ [Blockchain.Ethereum_Sepolia]: '0x08210F9170F89Ab7658F0B5E3fF39b0E03C594D4',
9108
+ [Blockchain.Plasma_Testnet]: '0x98AfA0F93Dd993B736399f9074eDcEBD1985A330'
8851
9109
  }
8852
9110
  };
8853
9111
 
@@ -9674,7 +9932,7 @@ const swapTokenEnumSchema = zod.z.enum([
9674
9932
  * allowlisted {@link ClientLogPayload} fields (and the allowlisted
9675
9933
  * sub-fields of `errorDetails` / `clientContext`) are copied across.
9676
9934
  * A regressing upstream mapper — or a plain-JS caller that bypasses the
9677
- * type — therefore cannot exfiltrate stray properties (secrets, PII,
9935
+ * type — therefore cannot exfiltrate stray properties (secrets,
9678
9936
  * raw error stacks) through the analytics channel. Optional fields are
9679
9937
  * only included when present so the serialised shape matches the
9680
9938
  * server's strict schema.
@@ -9697,6 +9955,9 @@ const swapTokenEnumSchema = zod.z.enum([
9697
9955
  if (payload.destinationChain !== undefined) safe['destinationChain'] = payload.destinationChain;
9698
9956
  if (payload.tokenIn !== undefined) safe['tokenIn'] = payload.tokenIn;
9699
9957
  if (payload.tokenOut !== undefined) safe['tokenOut'] = payload.tokenOut;
9958
+ if (payload.amountIn !== undefined) safe['amountIn'] = payload.amountIn;
9959
+ if (payload.durationMs !== undefined) safe['durationMs'] = payload.durationMs;
9960
+ if (payload.sourceAddress !== undefined) safe['sourceAddress'] = payload.sourceAddress;
9700
9961
  if (payload.txHash !== undefined) safe['txHash'] = payload.txHash;
9701
9962
  if (payload.correlationId !== undefined) safe['correlationId'] = payload.correlationId;
9702
9963
  if (payload.errorDetails !== undefined) {
@@ -9930,14 +10191,28 @@ const swapTokenEnumSchema = zod.z.enum([
9930
10191
  }
9931
10192
 
9932
10193
  /**
9933
- * Soft signal for the case where building or emitting a telemetry payload
9934
- * threw — for example, a buggy `TelemetryContextResolver`, a regression in
10194
+ * Emit a stable console warning when building or emitting a telemetry payload
10195
+ * throws — for example, a buggy `TelemetryContextResolver`, a regression in
9935
10196
  * `extractErrorDetails`, or a synchronous failure inside `emitAnalyticsLog`
9936
- * before it could swallow the error itself. Logged with a stable prefix so
9937
- * consumers can grep for it. We deliberately do not re-throw: the caller's
9938
- * original operation error must always win.
10197
+ * before it could swallow the error itself. Uses a stable prefix so the
10198
+ * drop is discoverable via grep. Never re-throws: the caller's original
10199
+ * operation error must always win.
9939
10200
  *
9940
10201
  * @internal
10202
+ *
10203
+ * @param eventType - The telemetry event type that was being emitted.
10204
+ * @param cause - The error or value that caused the drop.
10205
+ *
10206
+ * @example
10207
+ * ```typescript
10208
+ * import { warnTelemetryDrop } from '@core/utils'
10209
+ *
10210
+ * try {
10211
+ * void emitAnalyticsLog(payload)
10212
+ * } catch (err) {
10213
+ * warnTelemetryDrop('my_event', err)
10214
+ * }
10215
+ * ```
9941
10216
  */ function warnTelemetryDrop(eventType, cause) {
9942
10217
  try {
9943
10218
  // Pass `cause` as the second console.warn argument rather than
@@ -9977,6 +10252,9 @@ const swapTokenEnumSchema = zod.z.enum([
9977
10252
  ...context?.tokenOut != null && {
9978
10253
  tokenOut: context.tokenOut
9979
10254
  },
10255
+ ...context?.amountIn != null && {
10256
+ amountIn: context.amountIn
10257
+ },
9980
10258
  ...context?.txHash != null && {
9981
10259
  txHash: context.txHash
9982
10260
  },
@@ -10076,7 +10354,7 @@ const swapTokenEnumSchema = zod.z.enum([
10076
10354
  }
10077
10355
 
10078
10356
  var name$2 = "@circle-fin/bridge-kit";
10079
- var version$2 = "1.13.0";
10357
+ var version$2 = "1.14.1";
10080
10358
  var pkg$2 = {
10081
10359
  name: name$2,
10082
10360
  version: version$2};
@@ -10430,7 +10708,7 @@ const READ_ACTION_KEY_SET = new Set(READ_ACTION_KEYS);
10430
10708
  * const result = evmAddressSchema.safeParse(validAddress)
10431
10709
  * console.log(result.success) // true
10432
10710
  * ```
10433
- */ const evmAddressSchema = hexStringSchema.refine((value)=>value.length === 42, 'EVM address must be exactly 42 characters long (0x + 40 hex characters)').transform((value)=>value);
10711
+ */ const evmAddressSchema$1 = hexStringSchema.refine((value)=>value.length === 42, 'EVM address must be exactly 42 characters long (0x + 40 hex characters)').transform((value)=>value);
10434
10712
  /**
10435
10713
  * Schema for validating transaction hashes.
10436
10714
  *
@@ -10967,6 +11245,10 @@ var TransferSpeed;
10967
11245
  token: zod.z.literal('USDC').optional(),
10968
11246
  config: zod.z.object({
10969
11247
  transferSpeed: zod.z.nativeEnum(TransferSpeed).optional(),
11248
+ feePayment: zod.z.enum([
11249
+ 'source',
11250
+ 'destination'
11251
+ ]).optional(),
10970
11252
  maxFee: zod.z.string().min(1, 'Required').pipe(createDecimalStringValidator({
10971
11253
  allowZero: true,
10972
11254
  regexMessage: MAX_FEE_FORMAT_ERROR_MESSAGE,
@@ -10974,7 +11256,8 @@ var TransferSpeed;
10974
11256
  maxDecimals: 6
10975
11257
  })(zod.z.string())).optional(),
10976
11258
  customFee: customFeeSchema.optional()
10977
- }).optional()
11259
+ }).optional(),
11260
+ quote: zod.z.string().regex(/^0x([a-fA-F0-9]{2})+$/, 'must be non-empty 0x hex').optional()
10978
11261
  });
10979
11262
 
10980
11263
  /**
@@ -11036,6 +11319,241 @@ var TransferSpeed;
11036
11319
  message: 'Invalid metrics'
11037
11320
  });
11038
11321
 
11322
+ /**
11323
+ * Omit undefined values from an object.
11324
+ *
11325
+ * @param obj - The object to process.
11326
+ * @returns A new object with undefined values removed.
11327
+ *
11328
+ * @internal
11329
+ * @remarks
11330
+ * Used by both production and mock loggers to ensure consistent behavior.
11331
+ * This prevents undefined values from being serialized in log output,
11332
+ * which can cause issues with some log transports.
11333
+ */ function omitUndefined(obj) {
11334
+ const result = {};
11335
+ for (const [key, value] of Object.entries(obj)){
11336
+ if (value !== undefined) {
11337
+ result[key] = value;
11338
+ }
11339
+ }
11340
+ return result;
11341
+ }
11342
+
11343
+ /**
11344
+ * Default redaction paths for web3/blockchain SDKs.
11345
+ *
11346
+ * @remarks
11347
+ * These paths target common sensitive fields in blockchain applications.
11348
+ * All user fields are nested under `context`, so paths start with `context.`.
11349
+ * Wildcard `*` matches any key at that level.
11350
+ */ const DEFAULT_REDACT_PATHS = [
11351
+ // Generic Credentials
11352
+ 'context.password',
11353
+ 'context.passphrase',
11354
+ 'context.secret',
11355
+ 'context.token',
11356
+ 'context.*.password',
11357
+ 'context.*.passphrase',
11358
+ 'context.*.secret',
11359
+ 'context.*.token',
11360
+ // API Keys & Auth Tokens
11361
+ 'context.apiKey',
11362
+ 'context.apiSecret',
11363
+ 'context.accessToken',
11364
+ 'context.refreshToken',
11365
+ 'context.jwt',
11366
+ 'context.bearerToken',
11367
+ 'context.sessionId',
11368
+ 'context.authorization',
11369
+ 'context.cookie',
11370
+ 'context.*.apiKey',
11371
+ 'context.*.apiSecret',
11372
+ 'context.*.accessToken',
11373
+ 'context.*.refreshToken',
11374
+ 'context.*.jwt',
11375
+ 'context.*.bearerToken',
11376
+ 'context.*.sessionId',
11377
+ 'context.*.authorization',
11378
+ 'context.*.cookie',
11379
+ // Web3 / Crypto Keys
11380
+ 'context.privateKey',
11381
+ 'context.secretKey',
11382
+ 'context.signingKey',
11383
+ 'context.encryptionKey',
11384
+ 'context.*.privateKey',
11385
+ 'context.*.secretKey',
11386
+ 'context.*.signingKey',
11387
+ 'context.*.encryptionKey',
11388
+ // Web3 / Crypto Mnemonics and Seeds
11389
+ 'context.mnemonic',
11390
+ 'context.seed',
11391
+ 'context.seedPhrase',
11392
+ 'context.*.mnemonic',
11393
+ 'context.*.seed',
11394
+ 'context.*.seedPhrase',
11395
+ // OTP / Verification Codes
11396
+ 'context.otp',
11397
+ 'context.verificationCode',
11398
+ 'context.*.otp',
11399
+ 'context.*.verificationCode',
11400
+ // Payment Information
11401
+ 'context.cardNumber',
11402
+ 'context.cvv',
11403
+ 'context.accountNumber',
11404
+ 'context.*.cardNumber',
11405
+ 'context.*.cvv',
11406
+ 'context.*.accountNumber'
11407
+ ];
11408
+ /**
11409
+ * Wrap user fields under `context` to prevent collision with pino internals.
11410
+ *
11411
+ * @param fields - User-provided log fields.
11412
+ * @returns Object with fields nested under `context`, or undefined if empty.
11413
+ *
11414
+ * @remarks
11415
+ * This function handles edge cases by returning undefined for null, undefined,
11416
+ * or empty objects to avoid unnecessary wrapping in log output.
11417
+ * Undefined values are cleaned before wrapping.
11418
+ */ function wrapInContext(fields) {
11419
+ if (!fields) return undefined;
11420
+ // Clean undefined values for consistency and transport compatibility
11421
+ const cleaned = omitUndefined(fields);
11422
+ // Handle edge case: all values were undefined, resulting in empty object
11423
+ const keys = Object.keys(cleaned);
11424
+ if (keys.length === 0) return undefined;
11425
+ return {
11426
+ context: cleaned
11427
+ };
11428
+ }
11429
+ /**
11430
+ * Wrap a pino instance to conform to our Logger interface.
11431
+ *
11432
+ * @param pinoInstance - The pino logger instance to wrap.
11433
+ * @returns A Logger instance conforming to our stable interface.
11434
+ */ function wrapPino(pinoInstance) {
11435
+ return {
11436
+ debug (message, fields) {
11437
+ const wrapped = wrapInContext(fields);
11438
+ if (wrapped) {
11439
+ pinoInstance.debug(wrapped, message);
11440
+ } else {
11441
+ pinoInstance.debug(message);
11442
+ }
11443
+ },
11444
+ info (message, fields) {
11445
+ const wrapped = wrapInContext(fields);
11446
+ if (wrapped) {
11447
+ pinoInstance.info(wrapped, message);
11448
+ } else {
11449
+ pinoInstance.info(message);
11450
+ }
11451
+ },
11452
+ warn (message, fields) {
11453
+ const wrapped = wrapInContext(fields);
11454
+ if (wrapped) {
11455
+ pinoInstance.warn(wrapped, message);
11456
+ } else {
11457
+ pinoInstance.warn(message);
11458
+ }
11459
+ },
11460
+ error (message, fields) {
11461
+ const wrapped = wrapInContext(fields);
11462
+ if (wrapped) {
11463
+ pinoInstance.error(wrapped, message);
11464
+ } else {
11465
+ pinoInstance.error(message);
11466
+ }
11467
+ },
11468
+ child (tags) {
11469
+ // Child bindings stay flat (not wrapped) - they're part of logger's base context
11470
+ const cleaned = omitUndefined(tags);
11471
+ return wrapPino(pinoInstance.child(cleaned));
11472
+ }
11473
+ };
11474
+ }
11475
+ /**
11476
+ * Build pino redact configuration from our simplified options.
11477
+ *
11478
+ * @param redact - The redact configuration option.
11479
+ * @returns Pino-compatible redact configuration or undefined.
11480
+ */ function buildRedactConfig(redact) {
11481
+ // Explicitly disabled
11482
+ if (redact === false) {
11483
+ return undefined;
11484
+ }
11485
+ // Custom paths provided
11486
+ if (Array.isArray(redact)) {
11487
+ return redact.length > 0 ? {
11488
+ paths: redact,
11489
+ censor: '[REDACTED]'
11490
+ } : undefined;
11491
+ }
11492
+ // Default: use web3 sensible defaults
11493
+ return {
11494
+ paths: [
11495
+ ...DEFAULT_REDACT_PATHS
11496
+ ],
11497
+ censor: '[REDACTED]'
11498
+ };
11499
+ }
11500
+ /**
11501
+ * Create a logger backed by pino.
11502
+ *
11503
+ * @param options - Logger options (optional).
11504
+ * @param stream - Destination stream (optional).
11505
+ * @returns A Logger instance.
11506
+ * @throws Error if invalid pino options are provided.
11507
+ *
11508
+ * @remarks
11509
+ * This is a thin wrapper around pino that exposes our stable Logger interface.
11510
+ * Pino handles all transport concerns: JSON, pretty printing, file, remote, browser, etc.
11511
+ *
11512
+ * **Security**: By default, sensitive web3 fields (privateKey, mnemonic, apiKey, etc.)
11513
+ * are automatically redacted from log output. Use `redact: false` to disable.
11514
+ *
11515
+ * @example
11516
+ * ```typescript
11517
+ * import { createLogger } from '@core/runtime'
11518
+ *
11519
+ * // Default: web3 sensitive fields are redacted
11520
+ * const logger = createLogger({ level: 'info' })
11521
+ * logger.info('Signing', { privateKey: '0x123...' })
11522
+ * // Output: { context: { privateKey: '[REDACTED]' }, msg: 'Signing' }
11523
+ *
11524
+ * // Disable redaction (use with caution)
11525
+ * const unsafeLogger = createLogger({ level: 'debug', redact: false })
11526
+ *
11527
+ * // Custom redaction paths
11528
+ * const customLogger = createLogger({
11529
+ * level: 'info',
11530
+ * redact: ['context.mySecret', 'context.*.credentials']
11531
+ * })
11532
+ *
11533
+ * // Pretty output for development
11534
+ * const devLogger = createLogger({
11535
+ * level: 'debug',
11536
+ * transport: { target: 'pino-pretty' }
11537
+ * })
11538
+ *
11539
+ * // Browser logger
11540
+ * const browserLogger = createLogger({
11541
+ * browser: { asObject: true }
11542
+ * })
11543
+ * ```
11544
+ */ function createLogger(options, stream) {
11545
+ const { redact, ...pinoOptions } = options ?? {};
11546
+ // Build redaction config
11547
+ const redactConfig = buildRedactConfig(redact);
11548
+ // Build final pino options, only include redact if defined
11549
+ const finalOptions = redactConfig ? {
11550
+ ...pinoOptions,
11551
+ redact: redactConfig
11552
+ } : pinoOptions;
11553
+ const pinoInstance = pino__default(finalOptions);
11554
+ return wrapPino(pinoInstance);
11555
+ }
11556
+
11039
11557
  // ============================================================================
11040
11558
  // Validation Schema
11041
11559
  // ============================================================================
@@ -11143,6 +11661,9 @@ var TransferSpeed;
11143
11661
  [TransferSpeed.SLOW]: 2000
11144
11662
  });
11145
11663
 
11664
+ createLogger({
11665
+ name: 'provider-cctp-v2'
11666
+ });
11146
11667
  /**
11147
11668
  * All chains that are supported by the CCTP v2 provider.
11148
11669
  *
@@ -11152,13 +11673,206 @@ var TransferSpeed;
11152
11673
  * @internal
11153
11674
  */ Object.values(Chains).filter((chain)=>isCCTPV2Supported(chain));
11154
11675
 
11676
+ /**
11677
+ * Decimal string in token minor units, constrained to be strictly positive.
11678
+ *
11679
+ * @internal
11680
+ */ 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
11681
+ // regex check above fails ("dirty"), so guard BigInt() against throwing on a
11682
+ // non-numeric value before comparing.
11683
+ .refine((value)=>/^\d+$/.test(value) && BigInt(value) > 0n, 'must be greater than zero');
11684
+ /**
11685
+ * A 20-byte EVM address in `0x` hex.
11686
+ *
11687
+ * The MVP prepaid-`FORWARD` `burn/usdc` path targets EVM contracts
11688
+ * (`TokenMessengerWithFees` / `GenericExecutor`), so `feeToken` and
11689
+ * `destinationCaller` are constrained to EVM addresses by design. This is an
11690
+ * intentional scope limit, not a permanent one: it can be widened to other
11691
+ * address formats as the fee service expands to more chains.
11692
+ */ const evmAddressSchema = zod.z.string().regex(/^0x[a-fA-F0-9]{40}$/, 'must be a 20-byte 0x address');
11693
+ /** Even-length `0x` hex (the empty `0x` is allowed). */ const hexSchema = zod.z.string().regex(/^0x([a-fA-F0-9]{2})*$/, 'must be even-length 0x hex');
11694
+ /** Non-empty, even-length `0x` hex. */ const nonEmptyHexSchema = zod.z.string().regex(/^0x([a-fA-F0-9]{2})+$/, 'must be non-empty 0x hex');
11695
+ /** A 32-byte `0x` hex hash. */ const bytes32Schema = zod.z.string().regex(/^0x[a-fA-F0-9]{64}$/, 'must be a 32-byte 0x hash');
11696
+ /** Decimal string in minor units, allowing zero. */ const numericStringSchema = zod.z.string().regex(/^\d+$/, 'must be a non-negative integer string');
11697
+ /** An `https:` URL, used for the optional base-URL override. */ const httpsUrlSchema = zod.z.string().refine((value)=>{
11698
+ try {
11699
+ return new URL(value).protocol === 'https:';
11700
+ } catch {
11701
+ return false;
11702
+ }
11703
+ }, 'must be an https URL');
11704
+ const forwardParamsSchema = zod.z.object({
11705
+ hookData: hexSchema.optional(),
11706
+ destinationCaller: evmAddressSchema.optional()
11707
+ }).strict();
11708
+ const forwardRequestSchema = zod.z.object({
11709
+ type: zod.z.literal('FORWARD'),
11710
+ params: forwardParamsSchema.optional()
11711
+ }).strict();
11712
+ const preFinalityRequestSchema = zod.z.object({
11713
+ type: zod.z.literal('PRE_FINALITY')
11714
+ }).strict();
11715
+ /**
11716
+ * A single quote request item (`FORWARD` or `PRE_FINALITY`).
11717
+ *
11718
+ * @internal
11719
+ */ const feeQuoteRequestSchema = zod.z.discriminatedUnion('type', [
11720
+ forwardRequestSchema,
11721
+ preFinalityRequestSchema
11722
+ ]);
11723
+ /**
11724
+ * A non-empty list of quote request items with unique types.
11725
+ *
11726
+ * @internal
11727
+ */ 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');
11728
+ /**
11729
+ * A structured `Partial<ApiPollingConfig>` polling override.
11730
+ *
11731
+ * Validates the field types callers actually set, so a plain-JS caller passing
11732
+ * `{ timeout: 'soon' }` is rejected at the boundary rather than failing opaquely
11733
+ * inside the transport. Unknown keys pass through so a future `ApiPollingConfig`
11734
+ * field is forwarded rather than silently dropped.
11735
+ */ const apiPollingConfigSchema = zod.z.object({
11736
+ timeout: zod.z.number().int().positive().optional(),
11737
+ maxRetries: zod.z.number().int().nonnegative().optional(),
11738
+ retryDelay: zod.z.number().int().nonnegative().optional(),
11739
+ backoff: zod.z.enum([
11740
+ 'fixed',
11741
+ 'exponential'
11742
+ ]).optional(),
11743
+ maxRetryDelayMs: zod.z.number().int().positive().optional(),
11744
+ headers: zod.z.record(zod.z.string()).optional()
11745
+ }).passthrough();
11746
+ /**
11747
+ * The validatable input for {@link fetchFeeQuote}.
11748
+ *
11749
+ * This is the single source of truth for input validation, including the CCTP
11750
+ * domains and the `isTestnet` environment flag. Validating `isTestnet` at
11751
+ * runtime matters because a plain-JS caller who omits it would otherwise leave
11752
+ * it `undefined`, which is falsy and silently selects the production base URL.
11753
+ * (`buildFeeQuoteUrl` independently re-validates the domains for standalone
11754
+ * callers.)
11755
+ *
11756
+ * @internal
11757
+ */ zod.z.object({
11758
+ sourceDomain: zod.z.number().int().nonnegative(),
11759
+ destinationDomain: zod.z.number().int().nonnegative(),
11760
+ amount: positiveAmountSchema,
11761
+ feeToken: evmAddressSchema.optional(),
11762
+ requests: feeQuoteRequestsSchema,
11763
+ isTestnet: zod.z.boolean(),
11764
+ baseUrl: httpsUrlSchema.optional(),
11765
+ config: apiPollingConfigSchema.optional()
11766
+ }).strict();
11767
+ const feeQuoteItemSchema = zod.z.object({
11768
+ type: zod.z.string().min(1),
11769
+ amount: numericStringSchema,
11770
+ args: zod.z.array(zod.z.string()),
11771
+ argsHash: bytes32Schema
11772
+ }).passthrough();
11773
+ const exchangeRatesSchema = zod.z.object({
11774
+ feeTokenUsd: zod.z.string(),
11775
+ destinationTokenUsd: zod.z.string()
11776
+ }).passthrough();
11777
+ const metadataSchema = zod.z.object({
11778
+ destinationGasPrice: zod.z.string().optional(),
11779
+ exchangeRates: exchangeRatesSchema.optional()
11780
+ }).passthrough();
11781
+ /** The `expiry` object the Quote API nests the quote TTL under. */ const expirySchema = zod.z.discriminatedUnion('mode', [
11782
+ zod.z.object({
11783
+ mode: zod.z.literal('TIMESTAMP'),
11784
+ expiresAt: zod.z.number().int().nonnegative()
11785
+ }).passthrough(),
11786
+ zod.z.object({
11787
+ mode: zod.z.literal('BLOCK_NUMBER'),
11788
+ expiresAtBlock: zod.z.number().int().nonnegative(),
11789
+ blockEstimatedAt: zod.z.number().int().nonnegative().optional()
11790
+ }).passthrough()
11791
+ ]);
11792
+ /**
11793
+ * Schema for a signed fee quote returned by the Quote API.
11794
+ *
11795
+ * @internal
11796
+ */ zod.z.object({
11797
+ // The runtime YAML spec maps signedQuote to a looser `hex` (which allows
11798
+ // an empty `0x`); we keep the stricter non-empty form. Do not relax
11799
+ // without a reason.
11800
+ signedQuote: nonEmptyHexSchema,
11801
+ issuedAt: zod.z.number().int().nonnegative(),
11802
+ // The API returns a mode-specific timestamp or source-block deadline.
11803
+ expiry: expirySchema,
11804
+ feeTotalAmount: numericStringSchema,
11805
+ feeToken: evmAddressSchema,
11806
+ nonce: numericStringSchema,
11807
+ items: zod.z.array(feeQuoteItemSchema),
11808
+ metadata: metadataSchema.optional()
11809
+ }).passthrough();
11810
+ /**
11811
+ * Validates input to {@link validateQuote}.
11812
+ *
11813
+ * @internal
11814
+ */ zod.z.object({
11815
+ sourceDomain: zod.z.number().int().nonnegative(),
11816
+ abiSignature: zod.z.string().min(1),
11817
+ args: zod.z.array(zod.z.union([
11818
+ zod.z.string(),
11819
+ zod.z.array(zod.z.string())
11820
+ ])),
11821
+ isTestnet: zod.z.boolean(),
11822
+ baseUrl: httpsUrlSchema.optional(),
11823
+ config: apiPollingConfigSchema.optional()
11824
+ }).strict();
11825
+ const quoteExpiryStatusSchema = zod.z.discriminatedUnion('mode', [
11826
+ zod.z.object({
11827
+ mode: zod.z.literal('TIMESTAMP'),
11828
+ expired: zod.z.boolean(),
11829
+ secondsRemaining: zod.z.number().int().nonnegative(),
11830
+ expiresAt: zod.z.number().int().nonnegative()
11831
+ }).passthrough(),
11832
+ zod.z.object({
11833
+ mode: zod.z.literal('BLOCK_NUMBER'),
11834
+ expired: zod.z.boolean(),
11835
+ secondsRemaining: zod.z.number().int().nonnegative(),
11836
+ expiresAtBlock: zod.z.number().int().nonnegative(),
11837
+ blockEstimatedAt: zod.z.number().int().nonnegative().optional()
11838
+ }).passthrough()
11839
+ ]);
11840
+ const validateQuoteItemSchema = zod.z.object({
11841
+ type: zod.z.string().min(1),
11842
+ argsMatch: zod.z.boolean(),
11843
+ amount: numericStringSchema.optional(),
11844
+ args: zod.z.array(zod.z.string()).optional(),
11845
+ argsHash: bytes32Schema.optional(),
11846
+ computedArgsHash: bytes32Schema.optional()
11847
+ }).passthrough();
11848
+ /**
11849
+ * Schema for a validate-quote result returned by the Iris `/validate/usdc/:sourceDomain` endpoint.
11850
+ *
11851
+ * The endpoint takes the source domain as a URL path parameter and does not
11852
+ * return it in the response body, so `sourceDomain` is intentionally not part
11853
+ * of this schema.
11854
+ *
11855
+ * @internal
11856
+ */ zod.z.object({
11857
+ signedQuote: nonEmptyHexSchema,
11858
+ expiry: quoteExpiryStatusSchema,
11859
+ feeTotalAmount: numericStringSchema,
11860
+ feeToken: evmAddressSchema,
11861
+ nonce: numericStringSchema,
11862
+ claimable: zod.z.boolean(),
11863
+ // Preserve newly introduced server-side reasons as opaque strings rather
11864
+ // than rejecting the entire safety response before the SDK is updated.
11865
+ failedChecks: zod.z.array(zod.z.string().min(1)),
11866
+ items: zod.z.array(validateQuoteItemSchema)
11867
+ }).passthrough();
11868
+
11155
11869
  /** SDK name used in telemetry payloads. */ resolveKitSdkName(pkg$2.name);
11156
11870
 
11157
11871
  // Auto-register this kit for user agent tracking
11158
11872
  registerKit(`${pkg$2.name}/${pkg$2.version}`);
11159
11873
 
11160
11874
  var name$1 = "@circle-fin/swap-kit";
11161
- var version$1 = "1.5.2";
11875
+ var version$1 = "1.6.1";
11162
11876
  var pkg$1 = {
11163
11877
  name: name$1,
11164
11878
  version: version$1};
@@ -11172,7 +11886,7 @@ const optionalChainIdentifierField = chainIdentifierField.optional();
11172
11886
  * Catches obviously malformed addresses at parse time; chain-specific validation
11173
11887
  * is performed in buildServiceParams.
11174
11888
  */ const destinationAddressSchema = zod.z.union([
11175
- evmAddressSchema,
11889
+ evmAddressSchema$1,
11176
11890
  solanaAddressSchema
11177
11891
  ]);
11178
11892
  /**
@@ -11218,9 +11932,16 @@ const optionalChainIdentifierField = chainIdentifierField.optional();
11218
11932
  message: 'stopLimit must be greater than 0'
11219
11933
  }).optional(),
11220
11934
  customFee: serviceSwapCustomFeeSchema.optional(),
11935
+ apiKey: zod.z.string({
11936
+ invalid_type_error: 'apiKey must be a string'
11937
+ })// Tolerate '' so the `process.env.CIRCLE_API_KEY ?? ''` idiom falls back to
11938
+ // kitKey via resolveApiKey instead of being rejected here.
11939
+ .optional(),
11221
11940
  kitKey: zod.z.string({
11222
11941
  invalid_type_error: 'kitKey must be a string'
11223
- }).min(1, 'kitKey must be a non-empty string').optional(),
11942
+ })// Tolerate '' so an unset kit-key env var yields the permissionless path,
11943
+ // matching buildServiceParams (which already omits an empty credential).
11944
+ .optional(),
11224
11945
  provider: zod.z.string({
11225
11946
  invalid_type_error: 'provider must be a string'
11226
11947
  }).min(1, 'provider must be a non-empty string').optional(),
@@ -11385,23 +12106,49 @@ const optionalChainIdentifierField = chainIdentifierField.optional();
11385
12106
  fees: zod.z.array(serviceSwapFeeSchema).optional()
11386
12107
  }).passthrough();
11387
12108
 
11388
- /** Placeholder used wherever a kit key is scrubbed from logs, traces, or errors. */ const REDACTED_KIT_KEY = '[redacted]';
12109
+ /** Placeholder used wherever a credential is scrubbed from logs, traces, or errors. */ const REDACTED_CREDENTIAL = '[redacted]';
12110
+ /**
12111
+ * Config fields that carry a Stablecoin Service credential.
12112
+ *
12113
+ * `apiKey` is the supported field; `kitKey` is the deprecated alias. Redaction
12114
+ * and credential resolution both read this list so a newly added field is
12115
+ * scrubbed everywhere it needs to be.
12116
+ */ const CREDENTIAL_CONFIG_FIELDS = [
12117
+ 'apiKey',
12118
+ 'kitKey'
12119
+ ];
11389
12120
 
12121
+ /**
12122
+ * Replaces any credential field present on a config with a redaction marker.
12123
+ *
12124
+ * Covers `apiKey` and the deprecated `kitKey`, so adding a credential field
12125
+ * without extending this list cannot silently leak it into a trace. Returns the
12126
+ * config unchanged when it carries no credential.
12127
+ */ const redactCredentialFields = (config)=>{
12128
+ const present = CREDENTIAL_CONFIG_FIELDS.filter((field)=>field in config);
12129
+ if (present.length === 0) {
12130
+ return config;
12131
+ }
12132
+ return present.reduce((acc, field)=>({
12133
+ ...acc,
12134
+ [field]: REDACTED_CREDENTIAL
12135
+ }), {
12136
+ ...config
12137
+ });
12138
+ };
11390
12139
  /**
11391
12140
  * Builds a redacted projection of swap params that is safe to embed in error
11392
12141
  * traces (which may be logged downstream). Allow-lists only non-sensitive
11393
12142
  * fields and drops `from` entirely — `from.adapter` can carry signer/private-key
11394
- * material for signer-backed (viem/ethers) flows — and redacts `config.kitKey`.
12143
+ * material for signer-backed (viem/ethers) flows — and redacts every credential
12144
+ * field on `config`.
11395
12145
  */ const redactSwapParamsForTrace = (params)=>{
11396
12146
  if (typeof params !== 'object' || params === null) {
11397
12147
  return params;
11398
12148
  }
11399
12149
  const record = params;
11400
12150
  const config = record['config'];
11401
- const redactedConfig = typeof config === 'object' && config !== null && 'kitKey' in config ? {
11402
- ...config,
11403
- kitKey: REDACTED_KIT_KEY
11404
- } : config;
12151
+ const redactedConfig = typeof config === 'object' && config !== null ? redactCredentialFields(config) : config;
11405
12152
  return {
11406
12153
  tokenIn: record['tokenIn'],
11407
12154
  tokenOut: record['tokenOut'],
@@ -11485,6 +12232,41 @@ const optionalChainIdentifierField = chainIdentifierField.optional();
11485
12232
  *
11486
12233
  * @internal
11487
12234
  */ const MAX_RATE_ADDRESSES_PER_REQUEST = 100;
12235
+ /**
12236
+ * Environment prefixes carried by Circle platform API keys.
12237
+ *
12238
+ * A Circle API key is `<ENV>_API_KEY:<keyId>:<keySecret>`, where `<ENV>` is one
12239
+ * of these prefixes.
12240
+ *
12241
+ * @internal
12242
+ */ const API_KEY_ENV_PREFIXES = [
12243
+ 'TEST',
12244
+ 'LIVE',
12245
+ 'SAND',
12246
+ 'SANDBOX',
12247
+ 'SMOK',
12248
+ 'PROD',
12249
+ 'STAG',
12250
+ 'DEV'
12251
+ ];
12252
+ /**
12253
+ * Accepted credential formats for Stablecoin Service authentication.
12254
+ *
12255
+ * Matches a Circle platform API key (`<ENV>_API_KEY:<keyId>:<keySecret>`) and
12256
+ * the legacy kit key (`KIT_KEY:<keyId>:<keySecret>`). API keys are the
12257
+ * recommended credential; kit keys remain accepted as the legacy path.
12258
+ *
12259
+ * @remarks
12260
+ * This is a local pre-flight check, not the authority — the Stablecoin Service
12261
+ * validates the credential and answers 401 when it rejects one. The prefix list
12262
+ * is therefore deliberately permissive: a valid key carrying a prefix this SDK
12263
+ * has not been taught about should reach the service and be judged there rather
12264
+ * than be refused locally, since refusing locally is indistinguishable from an
12265
+ * outage to the caller. Kept as the single source of truth so the pattern is
12266
+ * not restated per call site.
12267
+ *
12268
+ * @internal
12269
+ */ const API_KEY_PATTERN = new RegExp(`^(?:KIT_KEY|(?:${API_KEY_ENV_PREFIXES.join('|')})_API_KEY)` + ':[a-zA-Z0-9._-]+:[a-zA-Z0-9._-]+$');
11488
12270
 
11489
12271
  /**
11490
12272
  * Zod schema for validating stop limits.
@@ -11553,13 +12335,14 @@ const optionalChainIdentifierField = chainIdentifierField.optional();
11553
12335
  /**
11554
12336
  * Zod schema for validating API keys.
11555
12337
  *
11556
- * Validates that the API key is a valid API key format.
12338
+ * Accepts a Circle platform API key (`<ENV>_API_KEY:<keyId>:<keySecret>`) and
12339
+ * the legacy kit key (`KIT_KEY:<keyId>:<keySecret>`).
11557
12340
  *
11558
12341
  * @example
11559
12342
  * ```typescript
11560
12343
  * import { apiKeySchema } from '@core/service-client'
11561
12344
  *
11562
- * const result = apiKeySchema.safeParse('KIT_KEY:e84d2546d4e321b2ff427dc988c89503:f84d2548d4e322b2ff427fc989c87503')
12345
+ * const result = apiKeySchema.safeParse('TEST_API_KEY:e84d2546d4e321b2ff427dc988c89503:f84d2548d4e322b2ff427fc989c87503')
11563
12346
  * if (!result.success) {
11564
12347
  * console.error('Invalid API key format:', result.error.issues)
11565
12348
  * }
@@ -11567,7 +12350,7 @@ const optionalChainIdentifierField = chainIdentifierField.optional();
11567
12350
  */ const apiKeySchema = zod.z.string({
11568
12351
  required_error: 'API key is required',
11569
12352
  invalid_type_error: 'Invalid API key format'
11570
- }).regex(/^KIT_KEY:[a-zA-Z0-9._-]+:[a-zA-Z0-9._-]+$/, 'Invalid API key format');
12353
+ }).regex(API_KEY_PATTERN, 'Invalid API key format');
11571
12354
  /**
11572
12355
  * Zod schema for platform fees configuration.
11573
12356
  *
@@ -12088,21 +12871,55 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
12088
12871
  * ```
12089
12872
  */ const isGetTokenRatesResponse = (obj)=>getTokenRatesResponseSchema.safeParse(obj).success;
12090
12873
  /**
12091
- * Assert that a Stablecoin Service kit key is not being supplied from a browser.
12874
+ * Resolve the credential to authenticate a Stablecoin Service request with.
12875
+ *
12876
+ * `apiKey` is the supported field; `kitKey` is the deprecated alias kept for
12877
+ * existing integrations. When both are supplied `apiKey` wins, so a caller
12878
+ * migrating field-by-field cannot be silently pinned to a stale credential.
12092
12879
  *
12093
- * The kit key (`KIT_KEY:<id>:<secret>`) is a server-only secret. Every
12094
- * Stablecoin Service request that attaches an `Authorization: Bearer` header
12095
- * funnels through this package, so calling this guard before that header is
12096
- * built prevents the secret from being sent from and thus bundled into — a
12097
- * client application. In Node.js the check is a no-op, preserving the
12098
- * legitimate "hold the kit key on the server, forward the prepared transaction
12099
- * to the client" flow. When no kit key is supplied the permissionless (keyless)
12100
- * client path remains fully allowed.
12880
+ * An empty-string value is treated as absent on either field. Without this, the
12881
+ * common `process.env.CIRCLE_API_KEY ?? ''` idiom (which yields `''` when the
12882
+ * variable is unset) would either shadow a working `kitKey` or, on a bare
12883
+ * `kitKey: ''`, reach downstream validation as an invalid credential instead of
12884
+ * falling through to the permissionless path.
12885
+ *
12886
+ * @param source - Object carrying either credential field, or neither.
12887
+ * @returns The credential to use, or `undefined` for the permissionless
12888
+ * (keyless) path.
12889
+ *
12890
+ * @example
12891
+ * ```typescript
12892
+ * import { resolveApiKey } from '@core/service-client'
12893
+ *
12894
+ * resolveApiKey({ apiKey: 'TEST_API_KEY:id:secret' }) // 'TEST_API_KEY:id:secret'
12895
+ * resolveApiKey({ kitKey: 'KIT_KEY:id:secret' }) // 'KIT_KEY:id:secret'
12896
+ * resolveApiKey({ apiKey: '', kitKey: 'KIT_KEY:id:secret' }) // 'KIT_KEY:id:secret'
12897
+ * resolveApiKey({ kitKey: '' }) // undefined
12898
+ * resolveApiKey({}) // undefined
12899
+ * ```
12900
+ */ const resolveApiKey = (source)=>{
12901
+ // Treat an empty-string value as absent on either field so the
12902
+ // `env ?? ''` idiom falls through to the next credential (or permissionless).
12903
+ const normalize = (value)=>value !== undefined && value !== '' ? value : undefined;
12904
+ return normalize(source.apiKey) ?? normalize(source.kitKey);
12905
+ };
12906
+ /**
12907
+ * Assert that a Stablecoin Service credential is not supplied from a browser.
12101
12908
  *
12102
- * @param apiKey - The inline kit key for the request, or `undefined` when none
12103
- * was supplied (permissionless mode).
12909
+ * An API key (`<ENV>_API_KEY:<id>:<secret>`) and a legacy kit key
12910
+ * (`KIT_KEY:<id>:<secret>`) are both server-only secrets. Every Stablecoin
12911
+ * Service request that attaches an `Authorization: Bearer` header funnels
12912
+ * through this package, so calling this guard before that header is built
12913
+ * prevents the secret from being sent from — and thus bundled into — a client
12914
+ * application. In Node.js the check is a no-op, preserving the legitimate "hold
12915
+ * the credential on the server, forward the prepared transaction to the client"
12916
+ * flow. When no credential is supplied the permissionless (keyless) client path
12917
+ * remains fully allowed.
12918
+ *
12919
+ * @param apiKey - The inline credential for the request, or `undefined` when
12920
+ * none was supplied (permissionless mode).
12104
12921
  * @returns Nothing.
12105
- * @throws KitError with VALIDATION_FAILED when a kit key is supplied while
12922
+ * @throws KitError with VALIDATION_FAILED when a credential is supplied while
12106
12923
  * running in a browser environment. The secret value is never echoed.
12107
12924
  *
12108
12925
  * @example
@@ -12110,10 +12927,10 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
12110
12927
  * import { assertBrowserSafeApiKey } from '@core/service-client'
12111
12928
  *
12112
12929
  * // Server (Node.js): no-op, request proceeds with the Authorization header.
12113
- * assertBrowserSafeApiKey('KIT_KEY:my-id:my-secret')
12930
+ * assertBrowserSafeApiKey('TEST_API_KEY:my-id:my-secret')
12114
12931
  *
12115
12932
  * // Browser: throws to stop the secret from leaking into the client bundle.
12116
- * assertBrowserSafeApiKey('KIT_KEY:my-id:my-secret')
12933
+ * assertBrowserSafeApiKey('TEST_API_KEY:my-id:my-secret')
12117
12934
  *
12118
12935
  * // Browser, permissionless: allowed.
12119
12936
  * assertBrowserSafeApiKey(undefined)
@@ -12123,7 +12940,7 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
12123
12940
  return;
12124
12941
  }
12125
12942
  if (isBrowserEnvironment()) {
12126
- throw createValidationFailedError$1('kitKey', '[redacted]', 'kitKey must not be provided in a browser environment — it is a server-only secret. Run kit operations that use a kit key on your server, or omit kitKey to use the permissionless (keyless) client path');
12943
+ throw createValidationFailedError$1('apiKey', '[redacted]', 'apiKey must not be provided in a browser environment — it is a server-only secret. Run kit operations that use an API key on your server, or omit apiKey (and the legacy kitKey) to use the permissionless (keyless) client path');
12127
12944
  }
12128
12945
  };
12129
12946
 
@@ -12135,7 +12952,8 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
12135
12952
  *
12136
12953
  * @remarks
12137
12954
  * - Input validation leverages Zod schemas to surface actionable KitErrors.
12138
- * - API key format must match `KIT_KEY:<keyId>:<keySecret>`
12955
+ * - API key format must match `<ENV>_API_KEY:<keyId>:<keySecret>`, or the
12956
+ * legacy `KIT_KEY:<keyId>:<keySecret>`
12139
12957
  *
12140
12958
  * @param params - The create transaction request parameters with API key.
12141
12959
  * @returns A promise that resolves to a typed {@link CreateSwapResponse}.
@@ -12164,7 +12982,7 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
12164
12982
  * recipientAddress: '0x050928e1f9086b20539c767c96909663ff7fbdf2',
12165
12983
  * },
12166
12984
  * },
12167
- * apiKey: 'KIT_KEY:example-key:example-secret',
12985
+ * apiKey: 'TEST_API_KEY:example-key:example-secret',
12168
12986
  * })
12169
12987
  *
12170
12988
  * console.log(`Transaction target: ${transaction.transaction.target}`)
@@ -12183,13 +13001,13 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
12183
13001
  const url = new URL('/v1/stablecoinKits/swap', STABLECOIN_SERVICE_BASE_URL).toString();
12184
13002
  // Remove the API key from the request body
12185
13003
  const { apiKey, ...requestBody } = validatedParams;
12186
- // Never let a server-only kit key leave a browser (no-op in Node.js).
13004
+ // Never let a server-only credential leave a browser (no-op in Node.js).
12187
13005
  assertBrowserSafeApiKey(apiKey);
12188
13006
  const effectiveConfig = {
12189
13007
  ...DEFAULT_CONFIG,
12190
13008
  headers: {
12191
13009
  ...DEFAULT_CONFIG.headers,
12192
- // Permissionless mode: no Authorization header when the kit key is absent.
13010
+ // Permissionless mode: no Authorization header when the credential is absent.
12193
13011
  ...apiKey !== undefined && {
12194
13012
  Authorization: `Bearer ${apiKey}`
12195
13013
  }
@@ -12339,7 +13157,7 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
12339
13157
  }
12340
13158
  // Use validated data
12341
13159
  const validatedParams = result.data;
12342
- // Never let a server-only kit key leave a browser (no-op in Node.js).
13160
+ // Never let a server-only credential leave a browser (no-op in Node.js).
12343
13161
  assertBrowserSafeApiKey(validatedParams.apiKey);
12344
13162
  // Build the API URL
12345
13163
  const url = buildQuoteUrl(validatedParams);
@@ -12348,7 +13166,7 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
12348
13166
  ...DEFAULT_CONFIG,
12349
13167
  headers: {
12350
13168
  ...DEFAULT_CONFIG.headers,
12351
- // Permissionless mode: no Authorization header when the kit key is absent.
13169
+ // Permissionless mode: no Authorization header when the credential is absent.
12352
13170
  ...validatedParams.apiKey !== undefined && {
12353
13171
  Authorization: `Bearer ${validatedParams.apiKey}`
12354
13172
  }
@@ -12413,14 +13231,14 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
12413
13231
  toChain: result.data.toChain
12414
13232
  }
12415
13233
  };
12416
- // Never let a server-only kit key leave a browser (no-op in Node.js).
13234
+ // Never let a server-only credential leave a browser (no-op in Node.js).
12417
13235
  assertBrowserSafeApiKey(validatedParams.apiKey);
12418
13236
  const url = buildSwapStatusUrl(validatedParams);
12419
13237
  const effectiveConfig = {
12420
13238
  ...DEFAULT_CONFIG,
12421
13239
  headers: {
12422
13240
  ...DEFAULT_CONFIG.headers,
12423
- // Permissionless mode: no Authorization header when the kit key is absent.
13241
+ // Permissionless mode: no Authorization header when the credential is absent.
12424
13242
  ...validatedParams.apiKey !== undefined && {
12425
13243
  Authorization: `Bearer ${validatedParams.apiKey}`
12426
13244
  }
@@ -12446,7 +13264,7 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
12446
13264
  * const url = buildTokenRatesUrl({
12447
13265
  * chain: 'Ethereum',
12448
13266
  * addresses: ['0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'],
12449
- * apiKey: 'KIT_KEY:key:secret',
13267
+ * apiKey: 'TEST_API_KEY:key:secret',
12450
13268
  * })
12451
13269
  * // => 'https://api.circle.com/v1/stablecoinKits/rates?chain=Ethereum&addresses=...'
12452
13270
  * ```
@@ -12519,14 +13337,14 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
12519
13337
  addresses: result.data.addresses
12520
13338
  }
12521
13339
  };
12522
- // Never let a server-only kit key leave a browser (no-op in Node.js).
13340
+ // Never let a server-only credential leave a browser (no-op in Node.js).
12523
13341
  assertBrowserSafeApiKey(validatedParams.apiKey);
12524
13342
  const url = buildTokenRatesUrl(validatedParams);
12525
13343
  const effectiveConfig = {
12526
13344
  ...DEFAULT_CONFIG,
12527
13345
  headers: {
12528
13346
  ...DEFAULT_CONFIG.headers,
12529
- // Permissionless mode: no Authorization header when the kit key is absent.
13347
+ // Permissionless mode: no Authorization header when the credential is absent.
12530
13348
  ...validatedParams.apiKey !== undefined && {
12531
13349
  Authorization: `Bearer ${validatedParams.apiKey}`
12532
13350
  }
@@ -12964,7 +13782,7 @@ const abiParameterSchema = zod.z.object({
12964
13782
  */ zod.z.object({
12965
13783
  type: zod.z.literal('evm'),
12966
13784
  abi: abiSchema,
12967
- address: evmAddressSchema,
13785
+ address: evmAddressSchema$1,
12968
13786
  functionName: zod.z.string({
12969
13787
  required_error: 'Function name is required',
12970
13788
  invalid_type_error: 'Function name must be a string'
@@ -13001,7 +13819,7 @@ const abiParameterSchema = zod.z.object({
13001
13819
  * }
13002
13820
  * ```
13003
13821
  */ zod.z.object({
13004
- address: evmAddressSchema,
13822
+ address: evmAddressSchema$1,
13005
13823
  value: zod.z.bigint({
13006
13824
  required_error: 'Value is required for native transfers',
13007
13825
  invalid_type_error: 'Value must be a bigint'
@@ -13533,7 +14351,7 @@ zod.z.object({
13533
14351
  signature: evmSignatureSchema,
13534
14352
  tokenInputs: zod.z.array(zod.z.object({
13535
14353
  permitType: zod.z.nativeEnum(PermitType),
13536
- token: evmAddressSchema,
14354
+ token: evmAddressSchema$1,
13537
14355
  amount: zod.z.bigint().refine((value)=>value >= 0n, {
13538
14356
  message: 'amount must be a non-negative bigint'
13539
14357
  }),
@@ -13794,7 +14612,7 @@ enc.encode('used_transfer_spec_hash');
13794
14612
  });
13795
14613
 
13796
14614
  /**
13797
- * Assert that the kit key is valid for swap operations.
14615
+ * Assert that the credential is valid for swap operations.
13798
14616
  *
13799
14617
  * @remarks
13800
14618
  * This validation is called when swap operations are executed, not at construction time.
@@ -13802,34 +14620,35 @@ enc.encode('used_transfer_spec_hash');
13802
14620
  * at usage time rather than construction time.
13803
14621
  *
13804
14622
  * Validates:
13805
- * - Kit key matches the required format (KIT_KEY:id:secret) when provided.
13806
- * An absent or empty kit key is permitted (permissionless mode) — the swap
13807
- * service now treats the key as optional.
14623
+ * - The credential matches an accepted format when provided — a Circle API key
14624
+ * (`<ENV>_API_KEY:id:secret`) or a legacy kit key (`KIT_KEY:id:secret`).
14625
+ * An absent or empty credential is permitted (permissionless mode) — the swap
14626
+ * service treats the credential as optional.
13808
14627
  *
13809
- * @param kitKey - The inline kit key from the swap operation config (optional)
13810
- * @throws KitError with VALIDATION_FAILED if a kit key is provided but does not
13811
- * match the KIT_KEY:<keyId>:<keySecret> format
14628
+ * @param apiKey - The inline credential from the swap operation config (optional)
14629
+ * @throws KitError with VALIDATION_FAILED if a credential is provided but does
14630
+ * not match an accepted format
13812
14631
  *
13813
14632
  * @example
13814
14633
  * ```typescript
13815
- * import { assertKitKey } from './assertKitKey'
14634
+ * import { assertApiKey } from './assertApiKey'
13816
14635
  *
13817
- * const kitKey = 'KIT_KEY:9d1bd085-bad2-4a2b-ae67-5814b85167c9:secretvalue'
14636
+ * const apiKey = 'TEST_API_KEY:9d1bd085-bad2-4a2b-ae67-5814b85167c9:secretvalue'
13818
14637
  *
13819
- * // Validate kit key before use
13820
- * assertKitKey(kitKey)
14638
+ * // Validate the credential before use
14639
+ * assertApiKey(apiKey)
13821
14640
  * ```
13822
- */ function assertKitKey(kitKey) {
13823
- // Permissionless mode: the swap service treats the kit key as optional, so an
13824
- // absent (or empty) key is valid. Only validate the format when a key is
14641
+ */ function assertApiKey(apiKey) {
14642
+ // Permissionless mode: the swap service treats the credential as optional, so
14643
+ // an absent (or empty) value is valid. Only validate the format when one is
13825
14644
  // actually provided.
13826
- if (!kitKey) {
14645
+ if (!apiKey) {
13827
14646
  return;
13828
14647
  }
13829
- const apiKeyResult = apiKeySchema.safeParse(kitKey);
14648
+ const apiKeyResult = apiKeySchema.safeParse(apiKey);
13830
14649
  if (!apiKeyResult.success) {
13831
14650
  const errors = apiKeyResult.error.issues.map((issue)=>issue.message).join(', ');
13832
- throw createValidationFailedError$1('kitKey', REDACTED_KIT_KEY, `Invalid API key format. ${errors}. Expected format: KIT_KEY:<keyId>:<keySecret>. Get your free Kit Key at: https://developers.circle.com/w3s/keys#kit-keys`);
14651
+ throw createValidationFailedError$1('apiKey', REDACTED_CREDENTIAL, `Invalid API key format. ${errors}. Expected format: <ENV>_API_KEY:<keyId>:<keySecret> (for example TEST_API_KEY:... or LIVE_API_KEY:...). Legacy KIT_KEY:<keyId>:<keySecret> values are still accepted. Get your key at: https://developers.circle.com/w3s/keys`);
13833
14652
  }
13834
14653
  }
13835
14654
 
@@ -14021,7 +14840,7 @@ const TOKEN_REGISTRY$3 = createTokenRegistry();
14021
14840
  }
14022
14841
  // Validate recipient address format matches the chain type
14023
14842
  if (chain.type === 'evm') {
14024
- const result = evmAddressSchema.safeParse(recipientAddress);
14843
+ const result = evmAddressSchema$1.safeParse(recipientAddress);
14025
14844
  if (!result.success) {
14026
14845
  throw createInvalidAddressError(recipientAddress, chain.name, '0x-prefixed 42-character hex string (0x + 40 hex characters)');
14027
14846
  }
@@ -14083,7 +14902,7 @@ function resolveFeePayoutChain(tokenIn, tokenOut, sourceChain, destinationChain)
14083
14902
  * to: '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
14084
14903
  * config: {
14085
14904
  * slippageBps: 300,
14086
- * kitKey: 'KIT_KEY:...:...' // Required inline kit key
14905
+ * apiKey: 'TEST_API_KEY:...:...' // Inline credential (optional)
14087
14906
  * }
14088
14907
  * }
14089
14908
  *
@@ -14121,18 +14940,17 @@ function resolveFeePayoutChain(tokenIn, tokenOut, sourceChain, destinationChain)
14121
14940
  validateResolvedAddress(resolvedTokenInAddress, chain);
14122
14941
  validateResolvedAddress(resolvedTokenOutAddress, destinationChain);
14123
14942
  validateResolvedAddress(to, destinationChain);
14124
- const kitKey = config?.kitKey;
14125
- // Validate the kit key format when one is provided (permissionless otherwise).
14126
- assertKitKey(kitKey);
14943
+ const apiKey = resolveApiKey(config ?? {});
14944
+ // Validate the credential format when one is provided (permissionless
14945
+ // otherwise).
14946
+ assertApiKey(apiKey);
14127
14947
  // Validate custom fee configuration if present
14128
14948
  const customFee = config?.customFee;
14129
14949
  if (customFee !== undefined) {
14130
14950
  const feePayoutChain = resolveFeePayoutChain(tokenIn, tokenOut, chain, destinationChain);
14131
14951
  validateCustomFeeConfig(customFee, feePayoutChain);
14132
14952
  }
14133
- // Build CreateSwapParams for service client
14134
- // Use object spread to conditionally include optional properties
14135
- // Note: Service client expects 'apiKey' field, so we map kitKey → apiKey
14953
+ // Build CreateSwapParams for service client, spreading optional properties.
14136
14954
  const chainName = chain.chain // The API expects the Blockchain enum value format like "World_Chain"
14137
14955
  ;
14138
14956
  const destinationChainName = destinationChain.chain;
@@ -14167,9 +14985,9 @@ function resolveFeePayoutChain(tokenIn, tokenOut, sourceChain, destinationChain)
14167
14985
  }
14168
14986
  }
14169
14987
  },
14170
- // Map kitKey → apiKey for the service client; omitted in permissionless mode.
14171
- ...kitKey ? {
14172
- apiKey: kitKey
14988
+ // Omitted in permissionless mode.
14989
+ ...apiKey ? {
14990
+ apiKey
14173
14991
  } : {}
14174
14992
  };
14175
14993
  }
@@ -16073,9 +16891,9 @@ async function fetchSameChainStatusSnapshot({ isCrossChainSwap, txHash, chain, a
16073
16891
  * ```typescript
16074
16892
  * import { StablecoinServiceSwapProvider } from '@circle-fin/provider-stablecoin-service-swap'
16075
16893
  *
16076
- * // Create provider with developer fee (1 USDC)
16894
+ * // Create provider with developer fee (1 USDC).
16895
+ * // Credentials are supplied per operation via `config.apiKey`, not here.
16077
16896
  * const provider = new StablecoinServiceSwapProvider({
16078
- * kitKey: process.env.STABLECOIN_KIT_API_KEY,
16079
16897
  * customFee: {
16080
16898
  * amount: '1000000', // 1 USDC in base units (6 decimals)
16081
16899
  * recipientAddress: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0'
@@ -16737,9 +17555,7 @@ async function fetchSameChainStatusSnapshot({ isCrossChainSwap, txHash, chain, a
16737
17555
  * import { createAdapterFromPrivateKey } from '@circle-fin/adapter-viem-v2'
16738
17556
  * import { Ethereum } from '@core/chains'
16739
17557
  *
16740
- * const provider = new StablecoinServiceSwapProvider({
16741
- * kitKey: process.env.STABLECOIN_KIT_API_KEY
16742
- * })
17558
+ * const provider = new StablecoinServiceSwapProvider()
16743
17559
  *
16744
17560
  * const adapter = createAdapterFromPrivateKey({
16745
17561
  * privateKey: process.env.PRIVATE_KEY
@@ -17233,7 +18049,7 @@ const optionalSwapChainIdentifierField = swapChainIdentifierField.optional();
17233
18049
  /**
17234
18050
  * Fee recipient address (required).
17235
18051
  * Must be a valid EVM address or Solana address.
17236
- */ recipientAddress: zod.z.string().refine((value)=>evmAddressSchema.safeParse(value).success || solanaAddressSchema.safeParse(value).success, {
18052
+ */ recipientAddress: zod.z.string().refine((value)=>evmAddressSchema$1.safeParse(value).success || solanaAddressSchema.safeParse(value).success, {
17237
18053
  message: 'recipientAddress must be a valid blockchain address: EVM (0x + 40 hex chars) or Solana (base58, 32-44 chars)'
17238
18054
  })
17239
18055
  }).strict();
@@ -17245,7 +18061,8 @@ const optionalSwapChainIdentifierField = swapChainIdentifierField.optional();
17245
18061
  * - slippageBps: Optional positive number for slippage tolerance
17246
18062
  * - stopLimit: Optional decimal string for minimum output
17247
18063
  * - customFee: Optional fee configuration
17248
- * - kitKey: Optional string identifier
18064
+ * - apiKey: Optional credential string
18065
+ * - kitKey: Optional credential string (deprecated alias for apiKey)
17249
18066
  */ const swapConfigSchema = zod.z.object({
17250
18067
  allowanceStrategy: allowanceStrategySchema.optional(),
17251
18068
  slippageBps: zod.z.number().int().min(0).optional(),
@@ -17255,11 +18072,12 @@ const optionalSwapChainIdentifierField = swapChainIdentifierField.optional();
17255
18072
  attributeName: 'stopLimit'
17256
18073
  })(zod.z.string())).optional(),
17257
18074
  customFee: swapCustomFeeSchema.optional(),
18075
+ apiKey: zod.z.string().optional(),
17258
18076
  kitKey: zod.z.string().optional()
17259
18077
  });
17260
18078
  const swapDestinationSchema = zod.z.object({
17261
18079
  chain: optionalSwapChainIdentifierField,
17262
- recipientAddress: zod.z.string().refine((value)=>evmAddressSchema.safeParse(value).success || solanaAddressSchema.safeParse(value).success, {
18080
+ recipientAddress: zod.z.string().refine((value)=>evmAddressSchema$1.safeParse(value).success || solanaAddressSchema.safeParse(value).success, {
17263
18081
  message: 'recipientAddress must be a valid blockchain address: EVM (0x + 40 hex chars) or Solana (base58, 32-44 chars)'
17264
18082
  }).optional()
17265
18083
  }).strict();
@@ -19366,7 +20184,8 @@ const transformAmount = (value, direction, decimals)=>formatUnits(value, decimal
19366
20184
  /**
19367
20185
  * Helper to format the config section of a swap result, transforming fee amounts.
19368
20186
  *
19369
- * Strips sensitive fields like kitKey from the config before returning.
20187
+ * Strips the credential fields (`apiKey` and the deprecated `kitKey`) from the
20188
+ * config before returning, so a result is safe to log or serialize.
19370
20189
  *
19371
20190
  * @param config - The swap config from the provider.
19372
20191
  * @param outputTokenTransform - The amount transformer for output-token-denominated values (fees and amountOut).
@@ -19375,11 +20194,11 @@ const transformAmount = (value, direction, decimals)=>formatUnits(value, decimal
19375
20194
  if (!config) {
19376
20195
  return undefined;
19377
20196
  }
19378
- // Remove kitKey from the config
19379
- const cloneConfig = {
19380
- ...config
19381
- };
19382
- delete cloneConfig.kitKey;
20197
+ // Rebuild the config without any credential field. Filtering entries rather
20198
+ // than deleting them avoids reading the deprecated `kitKey` property
20199
+ // directly, and keeps the credential list in one place.
20200
+ const credentialFields = CREDENTIAL_CONFIG_FIELDS;
20201
+ const cloneConfig = Object.fromEntries(Object.entries(config).filter(([key])=>!credentialFields.includes(key)));
19383
20202
  if (Object.keys(cloneConfig).length === 0) {
19384
20203
  return undefined;
19385
20204
  }
@@ -19580,9 +20399,9 @@ const transformAmount = (value, direction, decimals)=>formatUnits(value, decimal
19580
20399
  try {
19581
20400
  // Step 1: Build quote params directly (no need for buildServiceParams)
19582
20401
  // Use chain.chain (Blockchain enum value like "World_Chain") not chain.name
19583
- // The kit key is optional (permissionless mode); when absent the quote is
19584
- // fetched without an Authorization header.
19585
- const kitKey = params.config?.kitKey;
20402
+ // The credential is optional (permissionless mode); when absent the quote
20403
+ // is fetched without an Authorization header.
20404
+ const apiKey = resolveApiKey(params.config ?? {});
19586
20405
  // Resolve token aliases to addresses for the quote API
19587
20406
  // The quote endpoint requires resolved addresses, not aliases like 'USDC'
19588
20407
  const chain = params.from.chain;
@@ -19607,8 +20426,8 @@ const transformAmount = (value, direction, decimals)=>formatUnits(value, decimal
19607
20426
  ...params.config?.slippageBps !== undefined && {
19608
20427
  slippageBps: params.config.slippageBps
19609
20428
  },
19610
- ...kitKey ? {
19611
- apiKey: kitKey
20429
+ ...apiKey ? {
20430
+ apiKey
19612
20431
  } : {}
19613
20432
  };
19614
20433
  // Step 2: Get quote from service
@@ -20012,7 +20831,7 @@ const sleep$1 = async (ms)=>new Promise((resolve)=>setTimeout(resolve, ms));
20012
20831
  * the service returns `receivingTokenDecimals`. When decimals are missing
20013
20832
  * the field is omitted entirely (never raw base units).
20014
20833
  *
20015
- * @param params - `txHash`, `chainIn`, optional `chainOut`, and `kitKey`.
20834
+ * @param params - `txHash`, `chainIn`, optional `chainOut`, and `apiKey`.
20016
20835
  * @returns A single snapshot of the swap's status.
20017
20836
  * @throws \{KitError\} If `chainIn` or `chainOut` is malformed.
20018
20837
  *
@@ -20028,7 +20847,7 @@ const sleep$1 = async (ms)=>new Promise((resolve)=>setTimeout(resolve, ms));
20028
20847
  * txHash: result.txHash,
20029
20848
  * chainIn: result.chainIn,
20030
20849
  * chainOut: result.chainOut,
20031
- * kitKey: process.env.KIT_KEY ?? '',
20850
+ * apiKey: process.env.CIRCLE_API_KEY,
20032
20851
  * })
20033
20852
  * while (status.progress.status === 'PENDING') {
20034
20853
  * await new Promise((r) => setTimeout(r, 3_000))
@@ -20036,7 +20855,7 @@ const sleep$1 = async (ms)=>new Promise((resolve)=>setTimeout(resolve, ms));
20036
20855
  * txHash: result.txHash,
20037
20856
  * chainIn: result.chainIn,
20038
20857
  * chainOut: result.chainOut,
20039
- * kitKey: process.env.KIT_KEY ?? '',
20858
+ * apiKey: process.env.CIRCLE_API_KEY,
20040
20859
  * })
20041
20860
  * }
20042
20861
  *
@@ -20054,14 +20873,15 @@ const sleep$1 = async (ms)=>new Promise((resolve)=>setTimeout(resolve, ms));
20054
20873
  const chainIn = normalizeChain(params.chainIn, 'chainIn');
20055
20874
  const chainOut = params.chainOut === undefined ? undefined : normalizeChain(params.chainOut, 'chainOut');
20056
20875
  const isCrossChain = chainOut !== undefined && chainOut !== chainIn;
20876
+ const apiKey = resolveApiKey(params);
20057
20877
  const request = {
20058
20878
  txHash: params.txHash,
20059
20879
  chain: chainIn,
20060
20880
  ...isCrossChain && {
20061
20881
  toChain: chainOut
20062
20882
  },
20063
- ...params.kitKey ? {
20064
- apiKey: params.kitKey
20883
+ ...apiKey ? {
20884
+ apiKey
20065
20885
  } : {}
20066
20886
  };
20067
20887
  let raw = await getSwapStatus$1(request);
@@ -20140,9 +20960,9 @@ const isResultShape = (params)=>'result' in params;
20140
20960
  *
20141
20961
  * Two parameter shapes are accepted:
20142
20962
  *
20143
- * - Pass the {@link SwapResult} directly: `{ result, kitKey, ... }`.
20963
+ * - Pass the {@link SwapResult} directly: `{ result, apiKey, ... }`.
20144
20964
  * Cleanest when chaining off `kit.swap()`.
20145
- * - Pass discrete fields: `{ txHash, chainIn, chainOut?, kitKey, ... }`.
20965
+ * - Pass discrete fields: `{ txHash, chainIn, chainOut?, apiKey, ... }`.
20146
20966
  * Useful for resuming an in-flight swap from a persisted record.
20147
20967
  *
20148
20968
  * @param params - Wait configuration. See {@link WaitForSwapParams}.
@@ -20162,7 +20982,7 @@ const isResultShape = (params)=>'result' in params;
20162
20982
  *
20163
20983
  * const final = await waitForSwap({
20164
20984
  * result,
20165
- * kitKey: process.env.KIT_KEY ?? '',
20985
+ * apiKey: process.env.CIRCLE_API_KEY,
20166
20986
  * onProgress: (snapshot) => {
20167
20987
  * console.log(snapshot.progress.substatus ?? snapshot.progress.status)
20168
20988
  * },
@@ -20180,7 +21000,7 @@ const isResultShape = (params)=>'result' in params;
20180
21000
  * txHash: '0x…',
20181
21001
  * chainIn: 'Ethereum',
20182
21002
  * chainOut: 'Base',
20183
- * kitKey: process.env.KIT_KEY ?? '',
21003
+ * apiKey: process.env.CIRCLE_API_KEY,
20184
21004
  * })
20185
21005
  * ```
20186
21006
  */ async function waitForSwap(params) {
@@ -20196,14 +21016,15 @@ const isResultShape = (params)=>'result' in params;
20196
21016
  const chainOut = isResultShape(params) ? params.result.chainOut : params.chainOut;
20197
21017
  // Delegate parameter validation (txHash, chainIn, chainOut) to
20198
21018
  // getSwapStatus so the same rules apply to both helpers.
21019
+ const apiKey = resolveApiKey(params);
20199
21020
  const statusParams = {
20200
21021
  txHash,
20201
21022
  chainIn,
20202
21023
  ...chainOut !== undefined && {
20203
21024
  chainOut
20204
21025
  },
20205
- ...params.kitKey ? {
20206
- kitKey: params.kitKey
21026
+ ...apiKey ? {
21027
+ apiKey
20207
21028
  } : {}
20208
21029
  };
20209
21030
  const deadline = Date.now() + timeoutMs;
@@ -20327,7 +21148,7 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
20327
21148
  *
20328
21149
  * @param context - SwapKit context (provides the `TokenRegistry` used for
20329
21150
  * symbol resolution).
20330
- * @param params - `chain`, optional `tokens`, and `kitKey`.
21151
+ * @param params - `chain`, optional `tokens`, and `apiKey`.
20331
21152
  * @returns A nested map of `[chain][address] → { priceUSD, fetchedAt }`.
20332
21153
  * @throws \{KitError\} If `chain` cannot be resolved, `tokens` exceeds 100
20333
21154
  * entries, or any entry is neither a registered symbol nor a
@@ -20342,7 +21163,7 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
20342
21163
  * const { rates } = await getTokenRates(context, {
20343
21164
  * chain: Blockchain.Ethereum,
20344
21165
  * tokens: ['USDC', 'EURC', 'NATIVE'],
20345
- * kitKey: process.env.KIT_KEY ?? '',
21166
+ * apiKey: process.env.CIRCLE_API_KEY,
20346
21167
  * })
20347
21168
  *
20348
21169
  * const usdc = rates['Ethereum']?.['0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48']
@@ -20363,10 +21184,11 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
20363
21184
  // valid Blockchain enum string, so `getChainByEnum` is guaranteed to resolve.
20364
21185
  const chainDef = getChainByEnum(chain);
20365
21186
  const resolvedAddresses = params.tokens?.map((entry, index)=>resolveTokenEntry(entry, index, chain, chainDef, context));
21187
+ const apiKey = resolveApiKey(params);
20366
21188
  return getTokenRates$1({
20367
21189
  chain,
20368
- ...params.kitKey ? {
20369
- apiKey: params.kitKey
21190
+ ...apiKey ? {
21191
+ apiKey
20370
21192
  } : {},
20371
21193
  ...resolvedAddresses !== undefined && {
20372
21194
  addresses: resolvedAddresses
@@ -20997,7 +21819,7 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
20997
21819
  * is formatted as a human-readable decimal string; when decimals are
20998
21820
  * missing the field is omitted entirely (never raw base units).
20999
21821
  *
21000
- * @param params - `txHash`, `chainIn`, optional `chainOut`, and `kitKey`.
21822
+ * @param params - `txHash`, `chainIn`, optional `chainOut`, and `apiKey`.
21001
21823
  * @returns A snapshot of the swap's status at the time of the call.
21002
21824
  * @throws \{KitError\} If `chainIn` or `chainOut` is malformed.
21003
21825
  *
@@ -21010,7 +21832,7 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
21010
21832
  * txHash: result.txHash,
21011
21833
  * chainIn: result.chainIn,
21012
21834
  * chainOut: result.chainOut,
21013
- * kitKey: process.env.KIT_KEY ?? '',
21835
+ * apiKey: process.env.CIRCLE_API_KEY,
21014
21836
  * })
21015
21837
  * console.log(status.progress.status, status.progress.substatus)
21016
21838
  * ```
@@ -21022,7 +21844,7 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
21022
21844
  * txHash: result.txHash,
21023
21845
  * chainIn: result.chainIn,
21024
21846
  * chainOut: result.chainOut,
21025
- * kitKey: process.env.KIT_KEY ?? '',
21847
+ * apiKey: process.env.CIRCLE_API_KEY,
21026
21848
  * })
21027
21849
  * while (status.progress.status === 'PENDING') {
21028
21850
  * await new Promise((r) => setTimeout(r, 3_000))
@@ -21030,7 +21852,7 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
21030
21852
  * txHash: result.txHash,
21031
21853
  * chainIn: result.chainIn,
21032
21854
  * chainOut: result.chainOut,
21033
- * kitKey: process.env.KIT_KEY ?? '',
21855
+ * apiKey: process.env.CIRCLE_API_KEY,
21034
21856
  * })
21035
21857
  * }
21036
21858
  *
@@ -21061,7 +21883,7 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
21061
21883
  * 5xx, etc.) surface unchanged so the caller can decide whether to
21062
21884
  * retry the whole wait. The wait itself only emits a timeout error.
21063
21885
  *
21064
- * @param params - Wait configuration including identifiers, kit key,
21886
+ * @param params - Wait configuration including identifiers, API key,
21065
21887
  * optional `timeoutMs`, and an optional `onProgress`
21066
21888
  * callback fired on every successful poll.
21067
21889
  * @returns The first terminal {@link SwapStatusResult} observed.
@@ -21080,7 +21902,7 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
21080
21902
  *
21081
21903
  * const final = await kit.waitForSwap({
21082
21904
  * result,
21083
- * kitKey: process.env.KIT_KEY ?? '',
21905
+ * apiKey: process.env.CIRCLE_API_KEY,
21084
21906
  * onProgress: (snap) => console.log(snap.progress.substatus ?? snap.progress.status),
21085
21907
  * })
21086
21908
  *
@@ -21098,7 +21920,7 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
21098
21920
  * txHash: persisted.txHash,
21099
21921
  * chainIn: persisted.chainIn,
21100
21922
  * chainOut: persisted.chainOut,
21101
- * kitKey: process.env.KIT_KEY ?? '',
21923
+ * apiKey: process.env.CIRCLE_API_KEY,
21102
21924
  * })
21103
21925
  * ```
21104
21926
  */ async waitForSwap(params) {
@@ -21132,7 +21954,7 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
21132
21954
  * not cache a rate for the native asset on that chain, the response simply
21133
21955
  * omits the address.
21134
21956
  *
21135
- * @param params - `chain`, optional `tokens`, and `kitKey`.
21957
+ * @param params - `chain`, optional `tokens`, and `apiKey`.
21136
21958
  * @returns A nested map of `[chain][address] → { priceUSD, fetchedAt }`.
21137
21959
  * @throws \{KitError\} If `chain` is malformed, `tokens` exceeds 100
21138
21960
  * entries, or any entry is neither a registered symbol nor a
@@ -21144,7 +21966,7 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
21144
21966
  * const { rates } = await kit.getTokenRates({
21145
21967
  * chain: 'Ethereum',
21146
21968
  * tokens: ['USDC', 'EURC', 'NATIVE'],
21147
- * kitKey: process.env.KIT_KEY ?? '',
21969
+ * apiKey: process.env.CIRCLE_API_KEY,
21148
21970
  * })
21149
21971
  *
21150
21972
  * const usdc = rates['Ethereum']?.['0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48']
@@ -21158,7 +21980,7 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
21158
21980
  * chain: 'Ethereum',
21159
21981
  * // 'USDC' (registry symbol) + raw USDT address
21160
21982
  * tokens: ['USDC', '0xdAC17F958D2ee523a2206206994597C13D831ec7'],
21161
- * kitKey: process.env.KIT_KEY ?? '',
21983
+ * apiKey: process.env.CIRCLE_API_KEY,
21162
21984
  * })
21163
21985
  * ```
21164
21986
  *
@@ -21167,7 +21989,7 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
21167
21989
  * ```typescript
21168
21990
  * const { rates } = await kit.getTokenRates({
21169
21991
  * chain: 'Base',
21170
- * kitKey: process.env.KIT_KEY ?? '',
21992
+ * apiKey: process.env.CIRCLE_API_KEY,
21171
21993
  * })
21172
21994
  * ```
21173
21995
  */ async getTokenRates(params) {
@@ -21422,7 +22244,7 @@ registerKit(`${pkg$1.name}/${pkg$1.version}`);
21422
22244
  };
21423
22245
 
21424
22246
  var name = "@circle-fin/earn-kit";
21425
- var version = "1.5.1";
22247
+ var version = "1.6.1";
21426
22248
  var pkg = {
21427
22249
  name: name,
21428
22250
  version: version};
@@ -21494,7 +22316,7 @@ function isNonNegativeBigIntLike(value) {
21494
22316
  }
21495
22317
  }
21496
22318
  const hexSignatureSchema = evmSignatureSchema;
21497
- const hexAddressSchema = evmAddressSchema;
22319
+ const hexAddressSchema = evmAddressSchema$1;
21498
22320
  // '0x' prefix + 32 bytes * 2 hex chars.
21499
22321
  const BYTES32_HEX_LENGTH = 66;
21500
22322
  const bridgeFeeTokenSchema = hexAddressSchema;
@@ -22399,7 +23221,7 @@ createTokenRegistry();
22399
23221
  * fast instead of round-tripping to the service.
22400
23222
  *
22401
23223
  * @internal
22402
- */ const recipientEvmAddressSchema = evmAddressSchema.refine((address)=>!ZERO_EVM_ADDRESS_REGEX.test(address), 'address must not be the zero address').refine(isValidEip55Checksum, 'address has an invalid EIP-55 checksum');
23224
+ */ const recipientEvmAddressSchema = evmAddressSchema$1.refine((address)=>!ZERO_EVM_ADDRESS_REGEX.test(address), 'address must not be the zero address').refine(isValidEip55Checksum, 'address has an invalid EIP-55 checksum');
22403
23225
  /**
22404
23226
  * Schema for the adapter context within earn operations.
22405
23227
  *
@@ -22431,19 +23253,39 @@ const sourceAdapterContextSchema = zod.z.object({
22431
23253
  /**
22432
23254
  * Schema for the EarnConfig options.
22433
23255
  *
22434
- * Validate the optional Kit Key field using the standard `apiKeySchema`
22435
- * format (`KIT_KEY:<keyId>:<keySecret>`). When omitted, the SDK
22436
- * operates in permissionless mode. `baseUrl` overrides the Earn Service
22437
- * endpoint (e.g. staging); `batchTransactions: false` opts out of atomic
22438
- * batched execution. Both are forwarded to the provider, so this `.strict()`
22439
- * schema must accept them or a valid config object is rejected.
23256
+ * Validate the *resolved* credential using the standard `apiKeySchema` format
23257
+ * (`<ENV>_API_KEY:<keyId>:<keySecret>`, or a legacy
23258
+ * `KIT_KEY:<keyId>:<keySecret>`). `apiKey` takes precedence over the deprecated
23259
+ * `kitKey`, so a malformed `kitKey` that is being ignored must not fail a config
23260
+ * that supplies a valid `apiKey` (and vice versa) only the credential that
23261
+ * would actually be sent is format-checked. When neither is supplied the SDK
23262
+ * operates in permissionless mode. `baseUrl` overrides the Earn Service endpoint
23263
+ * (e.g. staging); `batchTransactions: false` opts out of atomic batched
23264
+ * execution. All are forwarded to the provider, so this `.strict()` schema must
23265
+ * accept them or a valid config object is rejected.
22440
23266
  *
22441
23267
  * @internal
22442
23268
  */ const earnConfigSchema = zod.z.object({
22443
- kitKey: apiKeySchema.optional(),
23269
+ apiKey: zod.z.string().optional(),
23270
+ kitKey: zod.z.string().optional(),
22444
23271
  baseUrl: zod.z.string().optional(),
22445
23272
  batchTransactions: zod.z.boolean().optional()
22446
- }).strict();
23273
+ }).strict().superRefine((config, ctx)=>{
23274
+ const credential = resolveApiKey(config);
23275
+ if (credential === undefined) {
23276
+ return;
23277
+ }
23278
+ const result = apiKeySchema.safeParse(credential);
23279
+ if (!result.success) {
23280
+ ctx.addIssue({
23281
+ code: zod.z.ZodIssueCode.custom,
23282
+ path: [
23283
+ credential === config.apiKey ? 'apiKey' : 'kitKey'
23284
+ ],
23285
+ message: result.error.issues[0]?.message ?? 'Invalid API key format'
23286
+ });
23287
+ }
23288
+ });
22447
23289
  /**
22448
23290
  * Canonical decimal form: a leading digit with no leading zeros (a single
22449
23291
  * '0' is only allowed immediately before the decimal point). Rejects the
@@ -22515,7 +23357,7 @@ const sourceAdapterContextSchema = zod.z.object({
22515
23357
  * currently supports EVM vault addresses on Arc Testnet.
22516
23358
  *
22517
23359
  * @internal
22518
- */ const vaultAddressSchema = evmAddressSchema.refine(isValidEip55Checksum, 'address has an invalid EIP-55 checksum');
23360
+ */ const vaultAddressSchema = evmAddressSchema$1.refine(isValidEip55Checksum, 'address has an invalid EIP-55 checksum');
22519
23361
  /**
22520
23362
  * Validation schema for VaultQuery.
22521
23363
  *
@@ -22790,7 +23632,7 @@ const sameChainGetDepositQuoteParamsSchema = zod.z.object({
22790
23632
  const crossChainGetDepositQuoteParamsSchema = zod.z.object({
22791
23633
  from: sourceAdapterContextSchema,
22792
23634
  chain: earnBridgeDestinationChainIdentifierSchema,
22793
- address: evmAddressSchema,
23635
+ address: evmAddressSchema$1,
22794
23636
  vaultAddress: vaultAddressSchema,
22795
23637
  amount: amountSchema,
22796
23638
  transferSpeed: zod.z.enum([