@circle-fin/app-kit 1.12.0 → 1.13.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/earn.cjs CHANGED
@@ -2349,6 +2349,8 @@ function getOptionalString(value) {
2349
2349
  Blockchain["Optimism_Sepolia"] = "Optimism_Sepolia";
2350
2350
  Blockchain["Pharos"] = "Pharos";
2351
2351
  Blockchain["Pharos_Testnet"] = "Pharos_Testnet";
2352
+ Blockchain["Plasma"] = "Plasma";
2353
+ Blockchain["Plasma_Testnet"] = "Plasma_Testnet";
2352
2354
  Blockchain["Polkadot_Asset_Hub"] = "Polkadot_Asset_Hub";
2353
2355
  Blockchain["Polkadot_Westmint"] = "Polkadot_Westmint";
2354
2356
  Blockchain["Plume"] = "Plume";
@@ -2418,6 +2420,7 @@ var BridgeChain;
2418
2420
  BridgeChain["Morph"] = "Morph";
2419
2421
  BridgeChain["Optimism"] = "Optimism";
2420
2422
  BridgeChain["Pharos"] = "Pharos";
2423
+ BridgeChain["Plasma"] = "Plasma";
2421
2424
  BridgeChain["Plume"] = "Plume";
2422
2425
  BridgeChain["Polygon"] = "Polygon";
2423
2426
  BridgeChain["Sei"] = "Sei";
@@ -2444,6 +2447,7 @@ var BridgeChain;
2444
2447
  BridgeChain["Morph_Testnet"] = "Morph_Testnet";
2445
2448
  BridgeChain["Optimism_Sepolia"] = "Optimism_Sepolia";
2446
2449
  BridgeChain["Pharos_Testnet"] = "Pharos_Testnet";
2450
+ BridgeChain["Plasma_Testnet"] = "Plasma_Testnet";
2447
2451
  BridgeChain["Plume_Testnet"] = "Plume_Testnet";
2448
2452
  BridgeChain["Polygon_Amoy_Testnet"] = "Polygon_Amoy_Testnet";
2449
2453
  BridgeChain["Sei_Testnet"] = "Sei_Testnet";
@@ -2890,6 +2894,8 @@ var EarnChain;
2890
2894
  * This program handles minting operations for Gateway transactions
2891
2895
  * on Solana devnet.
2892
2896
  */ const GATEWAY_MINTER_SOLANA_DEVNET = 'GATEmKK2ECL1brEngQZWCgMWPbvrEYqsV6u29dAaHavr';
2897
+ /** TokenMessengerWithFees address shared by enabled EVM mainnet sources. */ const TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET = '0x71f54F818671cD0D7ea140Da213e5C8b5C92a408';
2898
+ /** TokenMessengerWithFees address shared by enabled EVM testnet sources. */ const TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET = '0x8745D906D67C346E5eb1aEEED38Eb87F34DF0C0A';
2893
2899
 
2894
2900
  /**
2895
2901
  * Arc Testnet chain definition
@@ -2927,6 +2933,7 @@ var EarnChain;
2927
2933
  v2: {
2928
2934
  type: 'split',
2929
2935
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
2936
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
2930
2937
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
2931
2938
  confirmations: 1,
2932
2939
  fastConfirmations: 1
@@ -2994,6 +3001,7 @@ var EarnChain;
2994
3001
  v2: {
2995
3002
  type: 'split',
2996
3003
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
3004
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
2997
3005
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
2998
3006
  confirmations: 65,
2999
3007
  fastConfirmations: 1
@@ -3058,6 +3066,7 @@ var EarnChain;
3058
3066
  v2: {
3059
3067
  type: 'split',
3060
3068
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
3069
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
3061
3070
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
3062
3071
  confirmations: 65,
3063
3072
  fastConfirmations: 1
@@ -3122,6 +3131,7 @@ var EarnChain;
3122
3131
  v2: {
3123
3132
  type: 'split',
3124
3133
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
3134
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
3125
3135
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
3126
3136
  confirmations: 1,
3127
3137
  fastConfirmations: 1
@@ -3183,6 +3193,7 @@ var EarnChain;
3183
3193
  v2: {
3184
3194
  type: 'split',
3185
3195
  tokenMessenger: '0x8fe6b999dc680ccfdd5bf7eb0974218be2542daa',
3196
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
3186
3197
  messageTransmitter: '0xe737e5cebeeba77efe34d4aa090756590b1ce275',
3187
3198
  confirmations: 1,
3188
3199
  fastConfirmations: 1
@@ -3250,6 +3261,7 @@ var EarnChain;
3250
3261
  v2: {
3251
3262
  type: 'split',
3252
3263
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
3264
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
3253
3265
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
3254
3266
  confirmations: 65,
3255
3267
  fastConfirmations: 1
@@ -3314,6 +3326,7 @@ var EarnChain;
3314
3326
  v2: {
3315
3327
  type: 'split',
3316
3328
  tokenMessenger: '0x8fe6b999dc680ccfdd5bf7eb0974218be2542daa',
3329
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
3317
3330
  messageTransmitter: '0xe737e5cebeeba77efe34d4aa090756590b1ce275',
3318
3331
  confirmations: 65,
3319
3332
  fastConfirmations: 1
@@ -3424,6 +3437,7 @@ var EarnChain;
3424
3437
  v2: {
3425
3438
  type: 'split',
3426
3439
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
3440
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
3427
3441
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
3428
3442
  confirmations: 65,
3429
3443
  fastConfirmations: 1
@@ -3468,6 +3482,7 @@ var EarnChain;
3468
3482
  v2: {
3469
3483
  type: 'split',
3470
3484
  tokenMessenger: '0x8fe6b999dc680ccfdd5bf7eb0974218be2542daa',
3485
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
3471
3486
  messageTransmitter: '0xe737e5cebeeba77efe34d4aa090756590b1ce275',
3472
3487
  confirmations: 65,
3473
3488
  fastConfirmations: 1
@@ -3699,6 +3714,7 @@ var EarnChain;
3699
3714
  v2: {
3700
3715
  type: 'split',
3701
3716
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
3717
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
3702
3718
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
3703
3719
  confirmations: 65,
3704
3720
  fastConfirmations: 2
@@ -3763,6 +3779,7 @@ var EarnChain;
3763
3779
  v2: {
3764
3780
  type: 'split',
3765
3781
  tokenMessenger: '0x8fe6b999dc680ccfdd5bf7eb0974218be2542daa',
3782
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
3766
3783
  messageTransmitter: '0xe737e5cebeeba77efe34d4aa090756590b1ce275',
3767
3784
  confirmations: 65,
3768
3785
  fastConfirmations: 2
@@ -3873,6 +3890,7 @@ var EarnChain;
3873
3890
  v2: {
3874
3891
  type: 'split',
3875
3892
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
3893
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
3876
3894
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
3877
3895
  confirmations: 1,
3878
3896
  fastConfirmations: 1
@@ -3932,6 +3950,7 @@ var EarnChain;
3932
3950
  v2: {
3933
3951
  type: 'split',
3934
3952
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
3953
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
3935
3954
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
3936
3955
  confirmations: 1,
3937
3956
  fastConfirmations: 1
@@ -4086,6 +4105,7 @@ var EarnChain;
4086
4105
  v2: {
4087
4106
  type: 'split',
4088
4107
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
4108
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
4089
4109
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
4090
4110
  confirmations: 65,
4091
4111
  fastConfirmations: 1
@@ -4133,6 +4153,7 @@ var EarnChain;
4133
4153
  v2: {
4134
4154
  type: 'split',
4135
4155
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
4156
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
4136
4157
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
4137
4158
  confirmations: 65,
4138
4159
  fastConfirmations: 1
@@ -4177,6 +4198,7 @@ var EarnChain;
4177
4198
  v2: {
4178
4199
  type: 'split',
4179
4200
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
4201
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
4180
4202
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
4181
4203
  confirmations: 1,
4182
4204
  fastConfirmations: 1
@@ -4222,6 +4244,7 @@ var EarnChain;
4222
4244
  v2: {
4223
4245
  type: 'split',
4224
4246
  tokenMessenger: '0x8fe6b999dc680ccfdd5bf7eb0974218be2542daa',
4247
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
4225
4248
  messageTransmitter: '0xe737e5cebeeba77efe34d4aa090756590b1ce275',
4226
4249
  confirmations: 1,
4227
4250
  fastConfirmations: 1
@@ -4268,6 +4291,7 @@ var EarnChain;
4268
4291
  v2: {
4269
4292
  type: 'split',
4270
4293
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
4294
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
4271
4295
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
4272
4296
  confirmations: 1,
4273
4297
  fastConfirmations: 1
@@ -4581,6 +4605,7 @@ var EarnChain;
4581
4605
  v2: {
4582
4606
  type: 'split',
4583
4607
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
4608
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
4584
4609
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
4585
4610
  confirmations: 65,
4586
4611
  fastConfirmations: 1
@@ -4645,6 +4670,7 @@ var EarnChain;
4645
4670
  v2: {
4646
4671
  type: 'split',
4647
4672
  tokenMessenger: '0x8fe6b999dc680ccfdd5bf7eb0974218be2542daa',
4673
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
4648
4674
  messageTransmitter: '0xe737e5cebeeba77efe34d4aa090756590b1ce275',
4649
4675
  confirmations: 65,
4650
4676
  fastConfirmations: 1
@@ -4765,6 +4791,98 @@ var EarnChain;
4765
4791
  }
4766
4792
  });
4767
4793
 
4794
+ /**
4795
+ * Plasma Mainnet chain definition
4796
+ * @remarks
4797
+ * This represents the official production network for the Plasma blockchain.
4798
+ * Plasma is an EVM-equivalent Layer 1 blockchain purpose-built for global
4799
+ * stablecoin payments, with deterministic BFT finality (PlasmaBFT/Fast-HotStuff).
4800
+ */ const Plasma = defineChain({
4801
+ type: 'evm',
4802
+ chain: Blockchain.Plasma,
4803
+ name: 'Plasma',
4804
+ title: 'Plasma Mainnet',
4805
+ nativeCurrency: {
4806
+ name: 'Plasma',
4807
+ symbol: 'XPL',
4808
+ decimals: 18
4809
+ },
4810
+ chainId: 9745,
4811
+ isTestnet: false,
4812
+ explorerUrl: 'https://plasmascan.to/tx/{hash}',
4813
+ rpcEndpoints: [
4814
+ 'https://rpc.plasma.to'
4815
+ ],
4816
+ eurcAddress: '0x3EE196E78d4d4248b849B8E1C7F44C5457FAFD2C',
4817
+ usdcAddress: '0x2d661C89D812261039AF9764eceaAee884f5F67F',
4818
+ usdtAddress: null,
4819
+ cctp: {
4820
+ domain: 33,
4821
+ contracts: {
4822
+ v2: {
4823
+ type: 'split',
4824
+ tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
4825
+ messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
4826
+ confirmations: 3,
4827
+ fastConfirmations: 1
4828
+ }
4829
+ },
4830
+ forwarderSupported: {
4831
+ source: false,
4832
+ destination: false
4833
+ }
4834
+ },
4835
+ kitContracts: {
4836
+ bridge: BRIDGE_CONTRACT_EVM_MAINNET
4837
+ }
4838
+ });
4839
+
4840
+ /**
4841
+ * Plasma Testnet chain definition
4842
+ * @remarks
4843
+ * This represents the official test network for the Plasma blockchain.
4844
+ * Plasma is an EVM-equivalent Layer 1 blockchain purpose-built for global
4845
+ * stablecoin payments, with deterministic BFT finality (PlasmaBFT/Fast-HotStuff).
4846
+ */ const PlasmaTestnet = defineChain({
4847
+ type: 'evm',
4848
+ chain: Blockchain.Plasma_Testnet,
4849
+ name: 'Plasma Testnet',
4850
+ title: 'Plasma Testnet',
4851
+ nativeCurrency: {
4852
+ name: 'Plasma',
4853
+ symbol: 'XPL',
4854
+ decimals: 18
4855
+ },
4856
+ chainId: 9746,
4857
+ isTestnet: true,
4858
+ explorerUrl: 'https://testnet.plasmascan.to/tx/{hash}',
4859
+ rpcEndpoints: [
4860
+ 'https://testnet-rpc.plasma.to'
4861
+ ],
4862
+ eurcAddress: '0x98AfA0F93Dd993B736399f9074eDcEBD1985A330',
4863
+ usdcAddress: '0xE67Fb267022cBA8064Dd388CC2FED724F3120D9D',
4864
+ usdtAddress: null,
4865
+ cctp: {
4866
+ domain: 33,
4867
+ contracts: {
4868
+ v2: {
4869
+ type: 'split',
4870
+ tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
4871
+ messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
4872
+ confirmations: 3,
4873
+ fastConfirmations: 1
4874
+ }
4875
+ },
4876
+ forwarderSupported: {
4877
+ source: false,
4878
+ destination: false
4879
+ }
4880
+ },
4881
+ kitContracts: {
4882
+ bridge: BRIDGE_CONTRACT_EVM_TESTNET
4883
+ }
4884
+ });
4885
+
4768
4886
  /**
4769
4887
  * Plume Mainnet chain definition
4770
4888
  * @remarks
@@ -4796,6 +4914,7 @@ var EarnChain;
4796
4914
  v2: {
4797
4915
  type: 'split',
4798
4916
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
4917
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
4799
4918
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
4800
4919
  confirmations: 65,
4801
4920
  fastConfirmations: 1
@@ -4842,6 +4961,7 @@ var EarnChain;
4842
4961
  v2: {
4843
4962
  type: 'split',
4844
4963
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
4964
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
4845
4965
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
4846
4966
  confirmations: 65,
4847
4967
  fastConfirmations: 1
@@ -4943,6 +5063,7 @@ var EarnChain;
4943
5063
  v2: {
4944
5064
  type: 'split',
4945
5065
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
5066
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
4946
5067
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
4947
5068
  confirmations: 33,
4948
5069
  fastConfirmations: 13
@@ -5008,6 +5129,7 @@ var EarnChain;
5008
5129
  v2: {
5009
5130
  type: 'split',
5010
5131
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
5132
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
5011
5133
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
5012
5134
  confirmations: 33,
5013
5135
  fastConfirmations: 13
@@ -5067,6 +5189,7 @@ var EarnChain;
5067
5189
  v2: {
5068
5190
  type: 'split',
5069
5191
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
5192
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
5070
5193
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
5071
5194
  confirmations: 1,
5072
5195
  fastConfirmations: 1
@@ -5126,6 +5249,7 @@ var EarnChain;
5126
5249
  v2: {
5127
5250
  type: 'split',
5128
5251
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
5252
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
5129
5253
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
5130
5254
  confirmations: 1,
5131
5255
  fastConfirmations: 1
@@ -5183,6 +5307,7 @@ var EarnChain;
5183
5307
  v2: {
5184
5308
  type: 'split',
5185
5309
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
5310
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
5186
5311
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
5187
5312
  confirmations: 1,
5188
5313
  fastConfirmations: 1
@@ -5241,6 +5366,7 @@ var EarnChain;
5241
5366
  v2: {
5242
5367
  type: 'split',
5243
5368
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
5369
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
5244
5370
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
5245
5371
  confirmations: 1,
5246
5372
  fastConfirmations: 1
@@ -5556,6 +5682,7 @@ var EarnChain;
5556
5682
  v2: {
5557
5683
  type: 'split',
5558
5684
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
5685
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
5559
5686
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
5560
5687
  confirmations: 65,
5561
5688
  fastConfirmations: 1
@@ -5620,6 +5747,7 @@ var EarnChain;
5620
5747
  v2: {
5621
5748
  type: 'split',
5622
5749
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
5750
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
5623
5751
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
5624
5752
  confirmations: 65,
5625
5753
  fastConfirmations: 1
@@ -5677,6 +5805,7 @@ var EarnChain;
5677
5805
  v2: {
5678
5806
  type: 'split',
5679
5807
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cF5d',
5808
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
5680
5809
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
5681
5810
  confirmations: 65,
5682
5811
  fastConfirmations: 1
@@ -5736,6 +5865,7 @@ var EarnChain;
5736
5865
  v2: {
5737
5866
  type: 'split',
5738
5867
  tokenMessenger: '0x8fe6b999dc680ccfdd5bf7eb0974218be2542daa',
5868
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
5739
5869
  messageTransmitter: '0xe737e5cebeeba77efe34d4aa090756590b1ce275',
5740
5870
  confirmations: 65,
5741
5871
  fastConfirmations: 1
@@ -5796,6 +5926,7 @@ var EarnChain;
5796
5926
  v2: {
5797
5927
  type: 'split',
5798
5928
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
5929
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
5799
5930
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
5800
5931
  confirmations: 3,
5801
5932
  fastConfirmations: 3
@@ -5841,6 +5972,7 @@ var EarnChain;
5841
5972
  v2: {
5842
5973
  type: 'split',
5843
5974
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
5975
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
5844
5976
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
5845
5977
  confirmations: 3,
5846
5978
  fastConfirmations: 1
@@ -6051,6 +6183,8 @@ var Chains = {
6051
6183
  OptimismSepolia: OptimismSepolia,
6052
6184
  Pharos: Pharos,
6053
6185
  PharosTestnet: PharosTestnet,
6186
+ Plasma: Plasma,
6187
+ PlasmaTestnet: PlasmaTestnet,
6054
6188
  Plume: Plume,
6055
6189
  PlumeTestnet: PlumeTestnet,
6056
6190
  PolkadotAssetHub: PolkadotAssetHub,
@@ -7507,6 +7641,7 @@ const swapTokenEnumSchema = zod.z.enum([
7507
7641
  [Blockchain.Noble]: 'uusdc',
7508
7642
  [Blockchain.Optimism]: '0x0b2c639c533813f4aa9d7837caf62653d097ff85',
7509
7643
  [Blockchain.Pharos]: '0xC879C018dB60520F4355C26eD1a6D572cdAC1815',
7644
+ [Blockchain.Plasma]: '0x2d661C89D812261039AF9764eceaAee884f5F67F',
7510
7645
  [Blockchain.Plume]: '0x222365EF19F7947e5484218551B56bb3965Aa7aF',
7511
7646
  [Blockchain.Polkadot_Asset_Hub]: '1337',
7512
7647
  [Blockchain.Polygon]: '0x3c499c542cef5e3811e1192ce70d8cc03d5c3359',
@@ -7527,6 +7662,7 @@ const swapTokenEnumSchema = zod.z.enum([
7527
7662
  [Blockchain.Arbitrum_Sepolia]: '0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d',
7528
7663
  [Blockchain.Avalanche_Fuji]: '0x5425890298aed601595a70AB815c96711a31Bc65',
7529
7664
  [Blockchain.Base_Sepolia]: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',
7665
+ [Blockchain.Celo_Alfajores_Testnet]: '0x2F25deB3848C207fc8E0c34035B3Ba7fC157602B',
7530
7666
  [Blockchain.Codex_Testnet]: '0x6d7f141b6819C2c9CC2f818e6ad549E7Ca090F8f',
7531
7667
  [Blockchain.Cronos_Testnet]: '0xEb33dc5fac03833e132593659e1dE7256aB59794',
7532
7668
  [Blockchain.Edge_Testnet]: '0x2d9F7CAD728051AA35Ecdc472a14cf8cDF5CFD6B',
@@ -7542,6 +7678,7 @@ const swapTokenEnumSchema = zod.z.enum([
7542
7678
  [Blockchain.Noble_Testnet]: 'uusdc',
7543
7679
  [Blockchain.Optimism_Sepolia]: '0x5fd84259d66Cd46123540766Be93DFE6D43130D7',
7544
7680
  [Blockchain.Pharos_Testnet]: '0xcfC8330f4BCAB529c625D12781b1C19466A9Fc8B',
7681
+ [Blockchain.Plasma_Testnet]: '0xE67Fb267022cBA8064Dd388CC2FED724F3120D9D',
7545
7682
  [Blockchain.Plume_Testnet]: '0xcB5f30e335672893c7eb944B374c196392C19D18',
7546
7683
  [Blockchain.Polkadot_Westmint]: '31337',
7547
7684
  [Blockchain.Polygon_Amoy_Testnet]: '0x41e94eb019c0762f9bfcf9fb1e58725bfb0e7582',
@@ -7604,6 +7741,7 @@ const swapTokenEnumSchema = zod.z.enum([
7604
7741
  [Blockchain.Base]: '0x60a3E35Cc302bFA44Cb288Bc5a4F316Fdb1adb42',
7605
7742
  [Blockchain.Cronos]: '0xA6dE01a2d62C6B5f3525d768f34d276652C554c8',
7606
7743
  [Blockchain.Ethereum]: '0x1aBaEA1f7C830bD89Acc67eC4af516284b1bC33c',
7744
+ [Blockchain.Plasma]: '0x3EE196E78d4d4248b849B8E1C7F44C5457FAFD2C',
7607
7745
  [Blockchain.Solana]: 'HzwqbKZw8HxMN6bF2yFZNrht3c2iXXzpKcFu7uBEDKtr',
7608
7746
  [Blockchain.World_Chain]: '0x1C60ba0A0eD1019e8Eb035E6daF4155A5cE2380B',
7609
7747
  // =========================================================================
@@ -7612,7 +7750,8 @@ const swapTokenEnumSchema = zod.z.enum([
7612
7750
  [Blockchain.Arc_Testnet]: '0x89B50855Aa3bE2F677cD6303Cec089B5F319D72a',
7613
7751
  [Blockchain.Base_Sepolia]: '0x808456652fdb597867f38412077A9182bf77359F',
7614
7752
  [Blockchain.Cronos_Testnet]: '0x31f7538adb53cF16350e6B0c89d03D91b7D12c46',
7615
- [Blockchain.Ethereum_Sepolia]: '0x08210F9170F89Ab7658F0B5E3fF39b0E03C594D4'
7753
+ [Blockchain.Ethereum_Sepolia]: '0x08210F9170F89Ab7658F0B5E3fF39b0E03C594D4',
7754
+ [Blockchain.Plasma_Testnet]: '0x98AfA0F93Dd993B736399f9074eDcEBD1985A330'
7616
7755
  }
7617
7756
  };
7618
7757
 
@@ -8695,7 +8834,7 @@ const swapTokenEnumSchema = zod.z.enum([
8695
8834
  }
8696
8835
 
8697
8836
  var name$3 = "@circle-fin/bridge-kit";
8698
- var version$3 = "1.13.0";
8837
+ var version$3 = "1.14.0";
8699
8838
  var pkg$3 = {
8700
8839
  name: name$3,
8701
8840
  version: version$3};
@@ -8748,6 +8887,179 @@ var pkg$3 = {
8748
8887
  }
8749
8888
  });
8750
8889
 
8890
+ /**
8891
+ * Canonical list of actions that do not prepare or submit transactions.
8892
+ *
8893
+ * @internal
8894
+ */ const READ_ACTION_KEYS = [
8895
+ 'token.allowance',
8896
+ 'token.balanceOf',
8897
+ 'token.name',
8898
+ 'native.balanceOf',
8899
+ 'usdc.allowance',
8900
+ 'usdc.balanceOf',
8901
+ 'usdc.name',
8902
+ 'gateway.v1.isDelegate',
8903
+ 'gateway.v1.withdrawingBalance',
8904
+ 'gateway.v1.withdrawalBlock',
8905
+ 'gateway.v1.signBurnIntents'
8906
+ ];
8907
+ const READ_ACTION_KEY_SET = new Set(READ_ACTION_KEYS);
8908
+ /**
8909
+ * Check whether a runtime value identifies a read action.
8910
+ *
8911
+ * @param action - The value to classify.
8912
+ * @returns Whether the value is a registered read-action key.
8913
+ *
8914
+ * @example
8915
+ * ```typescript
8916
+ * import { isReadActionKey } from '@core/adapter'
8917
+ *
8918
+ * if (isReadActionKey(value)) {
8919
+ * await adapter.readAction(value, params, context)
8920
+ * }
8921
+ * ```
8922
+ *
8923
+ * @internal
8924
+ */ function isReadActionKey(action) {
8925
+ return READ_ACTION_KEY_SET.has(action);
8926
+ }
8927
+
8928
+ /**
8929
+ * Create the standard error for a missing or non-read action.
8930
+ *
8931
+ * @param action - The unsupported action value.
8932
+ * @returns A fatal unsupported-action error.
8933
+ *
8934
+ * @internal
8935
+ */ function createUnsupportedReadActionError(action) {
8936
+ return new KitError({
8937
+ ...InputError.UNSUPPORTED_ACTION,
8938
+ recoverability: 'FATAL',
8939
+ message: `Read action "${String(action)}" is not registered in this adapter.`
8940
+ });
8941
+ }
8942
+ /**
8943
+ * Execute a read through the adapter's dedicated read seam when available.
8944
+ *
8945
+ * @remarks
8946
+ * Fall back to the legacy `prepareAction().execute()` contract so providers
8947
+ * remain runtime-compatible with adapter versions released before `readAction`.
8948
+ * Consumers must upgrade their adapter package for reads to bypass custom
8949
+ * `prepareAction` wrappers.
8950
+ *
8951
+ * @typeParam TAdapterCapabilities - The adapter capabilities type.
8952
+ * @typeParam TActionKey - The read action key.
8953
+ * @param adapter - The adapter that owns the read action.
8954
+ * @param action - The read action to execute.
8955
+ * @param params - The parameters for the read action.
8956
+ * @param ctx - The operation context.
8957
+ * @returns The raw read-action result.
8958
+ * @throws {KitError} When `action` is not a supported read-action key.
8959
+ *
8960
+ * @example
8961
+ * ```typescript
8962
+ * import { executeAdapterReadAction } from '@core/adapter'
8963
+ * import { Ethereum } from '@core/chains'
8964
+ *
8965
+ * const allowance = await executeAdapterReadAction(
8966
+ * adapter,
8967
+ * 'token.allowance',
8968
+ * { tokenAddress, delegate },
8969
+ * { chain: Ethereum },
8970
+ * )
8971
+ * ```
8972
+ *
8973
+ * @internal
8974
+ */ async function executeAdapterReadAction(adapter, action, params, ctx) {
8975
+ if (!isReadActionKey(action)) {
8976
+ throw createUnsupportedReadActionError(action);
8977
+ }
8978
+ const runtimeAdapter = adapter;
8979
+ if (typeof runtimeAdapter.readAction === 'function') {
8980
+ return runtimeAdapter.readAction(action, params, ctx);
8981
+ }
8982
+ let request;
8983
+ try {
8984
+ request = await adapter.prepareAction(action, params, ctx);
8985
+ } catch (error) {
8986
+ if (error instanceof Error && error.message === `Action ${action} is not supported`) {
8987
+ throw createUnsupportedReadActionError(action);
8988
+ }
8989
+ throw error;
8990
+ }
8991
+ return request.execute();
8992
+ }
8993
+ /**
8994
+ * Read and parse a token allowance while supporting older adapter versions.
8995
+ *
8996
+ * @remarks
8997
+ * Prefer the adapter's dedicated read seam and fall back to the legacy
8998
+ * `prepareAction().execute()` contract when the runtime adapter predates it.
8999
+ *
9000
+ * @typeParam TAdapterCapabilities - The adapter capabilities type.
9001
+ * @param adapter - The adapter that owns the allowance action.
9002
+ * @param params - The token and delegate whose allowance is being read.
9003
+ * @param ctx - The operation context.
9004
+ * @returns The non-negative allowance in token base units.
9005
+ * @throws {KitError} When the action is unsupported or its response is malformed.
9006
+ *
9007
+ * @example
9008
+ * ```typescript
9009
+ * import { readTokenAllowance } from '@core/adapter'
9010
+ * import { Ethereum } from '@core/chains'
9011
+ *
9012
+ * const allowance = await readTokenAllowance(
9013
+ * adapter,
9014
+ * { tokenAddress, delegate },
9015
+ * { chain: Ethereum },
9016
+ * )
9017
+ * ```
9018
+ *
9019
+ * @internal
9020
+ */ async function readTokenAllowance(adapter, params, ctx) {
9021
+ return parseAllowanceResponse(await executeAdapterReadAction(adapter, 'token.allowance', params, ctx));
9022
+ }
9023
+ /**
9024
+ * Parse a raw token allowance response into base units.
9025
+ *
9026
+ * @param allowanceRaw - The adapter response, optionally wrapped as an Amount output.
9027
+ * @returns The non-negative allowance as a bigint, or zero for a missing value.
9028
+ * @throws {KitError} When the response cannot represent a non-negative bigint.
9029
+ *
9030
+ * @example
9031
+ * ```typescript
9032
+ * import { parseAllowanceResponse } from '@core/adapter'
9033
+ *
9034
+ * const allowance = parseAllowanceResponse({ amount: { raw: 1000000n } })
9035
+ * ```
9036
+ */ function parseAllowanceResponse(allowanceRaw) {
9037
+ let value = allowanceRaw;
9038
+ if (typeof value === 'object' && value !== null && 'amount' in value) {
9039
+ const amount = value.amount;
9040
+ if (typeof amount === 'object' && amount !== null && 'raw' in amount) {
9041
+ value = amount.raw;
9042
+ }
9043
+ }
9044
+ if (value === undefined || value === null) {
9045
+ return 0n;
9046
+ }
9047
+ let allowance;
9048
+ if (typeof value === 'bigint') {
9049
+ allowance = value;
9050
+ } else if (typeof value === 'string') {
9051
+ try {
9052
+ allowance = BigInt(value);
9053
+ } catch {
9054
+ allowance = undefined;
9055
+ }
9056
+ }
9057
+ if (allowance === undefined || allowance < 0n) {
9058
+ throw createValidationFailedError('token.allowance', value, 'token.allowance response must be a non-negative bigint-compatible string or bigint');
9059
+ }
9060
+ return allowance;
9061
+ }
9062
+
8751
9063
  /**
8752
9064
  * Schema for validating hexadecimal strings with '0x' prefix.
8753
9065
  *
@@ -8797,7 +9109,7 @@ var pkg$3 = {
8797
9109
  * const result = evmAddressSchema.safeParse(validAddress)
8798
9110
  * console.log(result.success) // true
8799
9111
  * ```
8800
- */ const evmAddressSchema = hexStringSchema.refine((value)=>value.length === 42, 'EVM address must be exactly 42 characters long (0x + 40 hex characters)').transform((value)=>value);
9112
+ */ const evmAddressSchema$1 = hexStringSchema.refine((value)=>value.length === 42, 'EVM address must be exactly 42 characters long (0x + 40 hex characters)').transform((value)=>value);
8801
9113
  /**
8802
9114
  * Schema for validating transaction hashes.
8803
9115
  *
@@ -9334,6 +9646,10 @@ var TransferSpeed;
9334
9646
  token: zod.z.literal('USDC').optional(),
9335
9647
  config: zod.z.object({
9336
9648
  transferSpeed: zod.z.nativeEnum(TransferSpeed).optional(),
9649
+ feePayment: zod.z.enum([
9650
+ 'source',
9651
+ 'destination'
9652
+ ]).optional(),
9337
9653
  maxFee: zod.z.string().min(1, 'Required').pipe(createDecimalStringValidator({
9338
9654
  allowZero: true,
9339
9655
  regexMessage: MAX_FEE_FORMAT_ERROR_MESSAGE,
@@ -9341,7 +9657,8 @@ var TransferSpeed;
9341
9657
  maxDecimals: 6
9342
9658
  })(zod.z.string())).optional(),
9343
9659
  customFee: customFeeSchema.optional()
9344
- }).optional()
9660
+ }).optional(),
9661
+ quote: zod.z.string().regex(/^0x([a-fA-F0-9]{2})+$/, 'must be non-empty 0x hex').optional()
9345
9662
  });
9346
9663
 
9347
9664
  // ============================================================================
@@ -9565,13 +9882,182 @@ var TransferSpeed;
9565
9882
  * @internal
9566
9883
  */ Object.values(Chains).filter((chain)=>isCCTPV2Supported(chain));
9567
9884
 
9885
+ /** Decimal string in token minor units, constrained to be strictly positive. */ const positiveAmountSchema = zod.z.string().regex(/^\d+$/, 'must be a non-negative integer string')// Re-check the digit shape here: zod still runs this refinement when the
9886
+ // regex check above fails ("dirty"), so guard BigInt() against throwing on a
9887
+ // non-numeric value before comparing.
9888
+ .refine((value)=>/^\d+$/.test(value) && BigInt(value) > 0n, 'must be greater than zero');
9889
+ /**
9890
+ * A 20-byte EVM address in `0x` hex.
9891
+ *
9892
+ * The MVP prepaid-`FORWARD` `burn/usdc` path targets EVM contracts
9893
+ * (`TokenMessengerWithFees` / `GenericExecutor`), so `feeToken` and
9894
+ * `destinationCaller` are constrained to EVM addresses by design. This is an
9895
+ * intentional scope limit, not a permanent one: it can be widened to other
9896
+ * address formats as the fee service expands to more chains.
9897
+ */ const evmAddressSchema = zod.z.string().regex(/^0x[a-fA-F0-9]{40}$/, 'must be a 20-byte 0x address');
9898
+ /** 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');
9899
+ /** Non-empty, even-length `0x` hex. */ const nonEmptyHexSchema = zod.z.string().regex(/^0x([a-fA-F0-9]{2})+$/, 'must be non-empty 0x hex');
9900
+ /** 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');
9901
+ /** Decimal string in minor units, allowing zero. */ const numericStringSchema = zod.z.string().regex(/^\d+$/, 'must be a non-negative integer string');
9902
+ /** An `https:` URL, used for the optional base-URL override. */ const httpsUrlSchema = zod.z.string().refine((value)=>{
9903
+ try {
9904
+ return new URL(value).protocol === 'https:';
9905
+ } catch {
9906
+ return false;
9907
+ }
9908
+ }, 'must be an https URL');
9909
+ const forwardParamsSchema = zod.z.object({
9910
+ hookData: hexSchema.optional(),
9911
+ destinationCaller: evmAddressSchema.optional()
9912
+ }).strict();
9913
+ const forwardRequestSchema = zod.z.object({
9914
+ type: zod.z.literal('FORWARD'),
9915
+ params: forwardParamsSchema.optional()
9916
+ }).strict();
9917
+ const preFinalityRequestSchema = zod.z.object({
9918
+ type: zod.z.literal('PRE_FINALITY')
9919
+ }).strict();
9920
+ /** A single quote request item (`FORWARD` or `PRE_FINALITY`). */ const feeQuoteRequestSchema = zod.z.discriminatedUnion('type', [
9921
+ forwardRequestSchema,
9922
+ preFinalityRequestSchema
9923
+ ]);
9924
+ /** A non-empty list of quote request items with unique types. */ const feeQuoteRequestsSchema = zod.z.array(feeQuoteRequestSchema).min(1, 'at least one request item is required').refine((items)=>new Set(items.map((item)=>item.type)).size === items.length, 'request item types must be unique');
9925
+ /**
9926
+ * A structured `Partial<ApiPollingConfig>` polling override.
9927
+ *
9928
+ * Validates the field types callers actually set, so a plain-JS caller passing
9929
+ * `{ timeout: 'soon' }` is rejected at the boundary rather than failing opaquely
9930
+ * inside the transport. Unknown keys pass through so a future `ApiPollingConfig`
9931
+ * field is forwarded rather than silently dropped.
9932
+ */ const apiPollingConfigSchema = zod.z.object({
9933
+ timeout: zod.z.number().int().positive().optional(),
9934
+ maxRetries: zod.z.number().int().nonnegative().optional(),
9935
+ retryDelay: zod.z.number().int().nonnegative().optional(),
9936
+ backoff: zod.z.enum([
9937
+ 'fixed',
9938
+ 'exponential'
9939
+ ]).optional(),
9940
+ maxRetryDelayMs: zod.z.number().int().positive().optional(),
9941
+ headers: zod.z.record(zod.z.string()).optional()
9942
+ }).passthrough();
9943
+ /**
9944
+ * The validatable input for {@link fetchFeeQuote}.
9945
+ *
9946
+ * This is the single source of truth for input validation, including the CCTP
9947
+ * domains and the `isTestnet` environment flag. Validating `isTestnet` at
9948
+ * runtime matters because a plain-JS caller who omits it would otherwise leave
9949
+ * it `undefined`, which is falsy and silently selects the production base URL.
9950
+ * (`buildFeeQuoteUrl` independently re-validates the domains for standalone
9951
+ * callers.)
9952
+ */ zod.z.object({
9953
+ sourceDomain: zod.z.number().int().nonnegative(),
9954
+ destinationDomain: zod.z.number().int().nonnegative(),
9955
+ amount: positiveAmountSchema,
9956
+ feeToken: evmAddressSchema.optional(),
9957
+ requests: feeQuoteRequestsSchema,
9958
+ isTestnet: zod.z.boolean(),
9959
+ baseUrl: httpsUrlSchema.optional(),
9960
+ config: apiPollingConfigSchema.optional()
9961
+ }).strict();
9962
+ const feeQuoteItemSchema = zod.z.object({
9963
+ type: zod.z.string().min(1),
9964
+ amount: numericStringSchema,
9965
+ args: zod.z.array(zod.z.string()),
9966
+ argsHash: bytes32Schema
9967
+ }).passthrough();
9968
+ const exchangeRatesSchema = zod.z.object({
9969
+ feeTokenUsd: zod.z.string(),
9970
+ destinationTokenUsd: zod.z.string()
9971
+ }).passthrough();
9972
+ const metadataSchema = zod.z.object({
9973
+ destinationGasPrice: zod.z.string().optional(),
9974
+ exchangeRates: exchangeRatesSchema.optional()
9975
+ }).passthrough();
9976
+ /** The `expiry` object the Quote API nests the quote TTL under. */ const expirySchema = zod.z.discriminatedUnion('mode', [
9977
+ zod.z.object({
9978
+ mode: zod.z.literal('TIMESTAMP'),
9979
+ expiresAt: zod.z.number().int().nonnegative()
9980
+ }).passthrough(),
9981
+ zod.z.object({
9982
+ mode: zod.z.literal('BLOCK_NUMBER'),
9983
+ expiresAtBlock: zod.z.number().int().nonnegative(),
9984
+ blockEstimatedAt: zod.z.number().int().nonnegative().optional()
9985
+ }).passthrough()
9986
+ ]);
9987
+ /** Schema for a signed fee quote returned by the Quote API. */ zod.z.object({
9988
+ // The runtime YAML spec maps signedQuote to a looser `hex` (which allows
9989
+ // an empty `0x`); we keep the stricter non-empty form. Do not relax
9990
+ // without a reason.
9991
+ signedQuote: nonEmptyHexSchema,
9992
+ issuedAt: zod.z.number().int().nonnegative(),
9993
+ // The API returns a mode-specific timestamp or source-block deadline.
9994
+ expiry: expirySchema,
9995
+ feeTotalAmount: numericStringSchema,
9996
+ feeToken: evmAddressSchema,
9997
+ nonce: numericStringSchema,
9998
+ items: zod.z.array(feeQuoteItemSchema),
9999
+ metadata: metadataSchema.optional()
10000
+ }).passthrough();
10001
+ /** Validate input to {@link validateQuote}. */ zod.z.object({
10002
+ sourceDomain: zod.z.number().int().nonnegative(),
10003
+ abiSignature: zod.z.string().min(1),
10004
+ args: zod.z.array(zod.z.union([
10005
+ zod.z.string(),
10006
+ zod.z.array(zod.z.string())
10007
+ ])),
10008
+ isTestnet: zod.z.boolean(),
10009
+ baseUrl: httpsUrlSchema.optional(),
10010
+ config: apiPollingConfigSchema.optional()
10011
+ }).strict();
10012
+ const quoteExpiryStatusSchema = zod.z.discriminatedUnion('mode', [
10013
+ zod.z.object({
10014
+ mode: zod.z.literal('TIMESTAMP'),
10015
+ expired: zod.z.boolean(),
10016
+ secondsRemaining: zod.z.number().int().nonnegative(),
10017
+ expiresAt: zod.z.number().int().nonnegative()
10018
+ }).passthrough(),
10019
+ zod.z.object({
10020
+ mode: zod.z.literal('BLOCK_NUMBER'),
10021
+ expired: zod.z.boolean(),
10022
+ secondsRemaining: zod.z.number().int().nonnegative(),
10023
+ expiresAtBlock: zod.z.number().int().nonnegative(),
10024
+ blockEstimatedAt: zod.z.number().int().nonnegative().optional()
10025
+ }).passthrough()
10026
+ ]);
10027
+ const validateQuoteItemSchema = zod.z.object({
10028
+ type: zod.z.string().min(1),
10029
+ argsMatch: zod.z.boolean(),
10030
+ amount: numericStringSchema.optional(),
10031
+ args: zod.z.array(zod.z.string()).optional(),
10032
+ argsHash: bytes32Schema.optional(),
10033
+ computedArgsHash: bytes32Schema.optional()
10034
+ }).passthrough();
10035
+ /**
10036
+ * Schema for a response from the Quote API validation endpoint.
10037
+ *
10038
+ * The endpoint takes the source domain as a URL path parameter and does not
10039
+ * return it in the response body, so `sourceDomain` is intentionally not part
10040
+ * of this schema.
10041
+ */ zod.z.object({
10042
+ signedQuote: nonEmptyHexSchema,
10043
+ expiry: quoteExpiryStatusSchema,
10044
+ feeTotalAmount: numericStringSchema,
10045
+ feeToken: evmAddressSchema,
10046
+ nonce: numericStringSchema,
10047
+ claimable: zod.z.boolean(),
10048
+ // Preserve newly introduced server-side reasons as opaque strings rather
10049
+ // than rejecting the entire safety response before the SDK is updated.
10050
+ failedChecks: zod.z.array(zod.z.string().min(1)),
10051
+ items: zod.z.array(validateQuoteItemSchema)
10052
+ }).passthrough();
10053
+
9568
10054
  /** SDK name used in telemetry payloads. */ resolveKitSdkName(pkg$3.name);
9569
10055
 
9570
10056
  // Auto-register this kit for user agent tracking
9571
10057
  registerKit(`${pkg$3.name}/${pkg$3.version}`);
9572
10058
 
9573
10059
  var name$2 = "@circle-fin/swap-kit";
9574
- var version$2 = "1.5.1";
10060
+ var version$2 = "1.6.0";
9575
10061
  var pkg$2 = {
9576
10062
  name: name$2,
9577
10063
  version: version$2};
@@ -9585,7 +10071,7 @@ const optionalChainIdentifierField = chainIdentifierField.optional();
9585
10071
  * Catches obviously malformed addresses at parse time; chain-specific validation
9586
10072
  * is performed in buildServiceParams.
9587
10073
  */ const destinationAddressSchema = zod.z.union([
9588
- evmAddressSchema,
10074
+ evmAddressSchema$1,
9589
10075
  solanaAddressSchema
9590
10076
  ]);
9591
10077
  /**
@@ -9631,9 +10117,16 @@ const optionalChainIdentifierField = chainIdentifierField.optional();
9631
10117
  message: 'stopLimit must be greater than 0'
9632
10118
  }).optional(),
9633
10119
  customFee: serviceSwapCustomFeeSchema.optional(),
10120
+ apiKey: zod.z.string({
10121
+ invalid_type_error: 'apiKey must be a string'
10122
+ })// Tolerate '' so the `process.env.CIRCLE_API_KEY ?? ''` idiom falls back to
10123
+ // kitKey via resolveApiKey instead of being rejected here.
10124
+ .optional(),
9634
10125
  kitKey: zod.z.string({
9635
10126
  invalid_type_error: 'kitKey must be a string'
9636
- }).min(1, 'kitKey must be a non-empty string').optional(),
10127
+ })// Tolerate '' so an unset kit-key env var yields the permissionless path,
10128
+ // matching buildServiceParams (which already omits an empty credential).
10129
+ .optional(),
9637
10130
  provider: zod.z.string({
9638
10131
  invalid_type_error: 'provider must be a string'
9639
10132
  }).min(1, 'provider must be a non-empty string').optional(),
@@ -9806,6 +10299,41 @@ const optionalChainIdentifierField = chainIdentifierField.optional();
9806
10299
  *
9807
10300
  * @internal
9808
10301
  */ const MAX_RATE_ADDRESSES_PER_REQUEST = 100;
10302
+ /**
10303
+ * Environment prefixes carried by Circle platform API keys.
10304
+ *
10305
+ * A Circle API key is `<ENV>_API_KEY:<keyId>:<keySecret>`, where `<ENV>` is one
10306
+ * of these prefixes.
10307
+ *
10308
+ * @internal
10309
+ */ const API_KEY_ENV_PREFIXES = [
10310
+ 'TEST',
10311
+ 'LIVE',
10312
+ 'SAND',
10313
+ 'SANDBOX',
10314
+ 'SMOK',
10315
+ 'PROD',
10316
+ 'STAG',
10317
+ 'DEV'
10318
+ ];
10319
+ /**
10320
+ * Accepted credential formats for Stablecoin Service authentication.
10321
+ *
10322
+ * Matches a Circle platform API key (`<ENV>_API_KEY:<keyId>:<keySecret>`) and
10323
+ * the legacy kit key (`KIT_KEY:<keyId>:<keySecret>`). API keys are the
10324
+ * recommended credential; kit keys remain accepted as the legacy path.
10325
+ *
10326
+ * @remarks
10327
+ * This is a local pre-flight check, not the authority — the Stablecoin Service
10328
+ * validates the credential and answers 401 when it rejects one. The prefix list
10329
+ * is therefore deliberately permissive: a valid key carrying a prefix this SDK
10330
+ * has not been taught about should reach the service and be judged there rather
10331
+ * than be refused locally, since refusing locally is indistinguishable from an
10332
+ * outage to the caller. Kept as the single source of truth so the pattern is
10333
+ * not restated per call site.
10334
+ *
10335
+ * @internal
10336
+ */ const API_KEY_PATTERN = new RegExp(`^(?:KIT_KEY|(?:${API_KEY_ENV_PREFIXES.join('|')})_API_KEY)` + ':[a-zA-Z0-9._-]+:[a-zA-Z0-9._-]+$');
9809
10337
 
9810
10338
  /**
9811
10339
  * Zod schema for validating stop limits.
@@ -9874,13 +10402,14 @@ const optionalChainIdentifierField = chainIdentifierField.optional();
9874
10402
  /**
9875
10403
  * Zod schema for validating API keys.
9876
10404
  *
9877
- * Validates that the API key is a valid API key format.
10405
+ * Accepts a Circle platform API key (`<ENV>_API_KEY:<keyId>:<keySecret>`) and
10406
+ * the legacy kit key (`KIT_KEY:<keyId>:<keySecret>`).
9878
10407
  *
9879
10408
  * @example
9880
10409
  * ```typescript
9881
10410
  * import { apiKeySchema } from '@core/service-client'
9882
10411
  *
9883
- * const result = apiKeySchema.safeParse('KIT_KEY:e84d2546d4e321b2ff427dc988c89503:f84d2548d4e322b2ff427fc989c87503')
10412
+ * const result = apiKeySchema.safeParse('TEST_API_KEY:e84d2546d4e321b2ff427dc988c89503:f84d2548d4e322b2ff427fc989c87503')
9884
10413
  * if (!result.success) {
9885
10414
  * console.error('Invalid API key format:', result.error.issues)
9886
10415
  * }
@@ -9888,7 +10417,7 @@ const optionalChainIdentifierField = chainIdentifierField.optional();
9888
10417
  */ const apiKeySchema = zod.z.string({
9889
10418
  required_error: 'API key is required',
9890
10419
  invalid_type_error: 'Invalid API key format'
9891
- }).regex(/^KIT_KEY:[a-zA-Z0-9._-]+:[a-zA-Z0-9._-]+$/, 'Invalid API key format');
10420
+ }).regex(API_KEY_PATTERN, 'Invalid API key format');
9892
10421
  /**
9893
10422
  * Zod schema for platform fees configuration.
9894
10423
  *
@@ -10331,8 +10860,8 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
10331
10860
  * Validates that an API key is properly formatted for Circle Stablecoin Service.
10332
10861
  *
10333
10862
  * This function performs validation on API keys to ensure they conform to the
10334
- * expected format before making API requests. The key must follow the structure:
10335
- * `KIT_KEY:keyId:keySecret`
10863
+ * expected format before making API requests. The key must follow the structure
10864
+ * `<ENV>_API_KEY:keyId:keySecret`, or the legacy `KIT_KEY:keyId:keySecret`.
10336
10865
  *
10337
10866
  * @param apiKey - The API key to validate (can be any type for graceful handling).
10338
10867
  * @returns True if the API key is valid, false otherwise.
@@ -10340,7 +10869,8 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
10340
10869
  * @remarks
10341
10870
  * This function handles invalid inputs gracefully by returning false rather than
10342
10871
  * throwing errors. It validates:
10343
- * - The key starts with the `KIT_KEY:` prefix
10872
+ * - The key carries a recognized prefix — `<ENV>_API_KEY:` for a Circle platform
10873
+ * API key, or `KIT_KEY:` for the legacy kit key
10344
10874
  * - Contains exactly three colon-separated parts
10345
10875
  * - keyId and keySecret contain only valid characters (alphanumeric, `-`, `_`, `.`)
10346
10876
  * - keyId and keySecret are non-empty
@@ -10348,23 +10878,62 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
10348
10878
  *
10349
10879
  * Valid characters in keyId and keySecret: `a-z`, `A-Z`, `0-9`, `-`, `_`, `.`
10350
10880
  *
10881
+ * Format is checked locally only so an obviously malformed credential fails
10882
+ * before a request is made. The Stablecoin Service remains the authority on
10883
+ * whether a well-formed key is actually accepted.
10884
+ *
10351
10885
  * @example
10352
10886
  * ```typescript
10353
10887
  * import { isValidApiKey } from '@core/service-client'
10354
10888
  *
10355
10889
  * // Valid API key
10356
- * const isValid = isValidApiKey('KIT_KEY:e84d2546d4e321b2ff427dc988c89503:f84d2548d4e322b2ff427fc989c87503')
10890
+ * const isValid = isValidApiKey('TEST_API_KEY:e84d2546d4e321b2ff427dc988c89503:f84d2548d4e322b2ff427fc989c87503')
10357
10891
  * console.log(isValid) // true
10358
10892
  *
10893
+ * // Legacy kit keys remain valid
10894
+ * console.log(isValidApiKey('KIT_KEY:my-key-id:my-key-secret')) // true
10895
+ *
10359
10896
  * ```
10360
10897
  */ const isValidApiKey = (apiKey)=>{
10361
10898
  // Handle invalid input types
10362
10899
  if (typeof apiKey !== 'string') {
10363
10900
  return false;
10364
10901
  }
10365
- const apiKeyPattern = /^KIT_KEY:[a-zA-Z0-9._-]+:[a-zA-Z0-9._-]+$/;
10366
10902
  // Validate without trimming - any whitespace will cause validation to fail
10367
- return apiKeyPattern.test(apiKey);
10903
+ return API_KEY_PATTERN.test(apiKey);
10904
+ };
10905
+ /**
10906
+ * Resolve the credential to authenticate a Stablecoin Service request with.
10907
+ *
10908
+ * `apiKey` is the supported field; `kitKey` is the deprecated alias kept for
10909
+ * existing integrations. When both are supplied `apiKey` wins, so a caller
10910
+ * migrating field-by-field cannot be silently pinned to a stale credential.
10911
+ *
10912
+ * An empty-string value is treated as absent on either field. Without this, the
10913
+ * common `process.env.CIRCLE_API_KEY ?? ''` idiom (which yields `''` when the
10914
+ * variable is unset) would either shadow a working `kitKey` or, on a bare
10915
+ * `kitKey: ''`, reach downstream validation as an invalid credential instead of
10916
+ * falling through to the permissionless path.
10917
+ *
10918
+ * @param source - Object carrying either credential field, or neither.
10919
+ * @returns The credential to use, or `undefined` for the permissionless
10920
+ * (keyless) path.
10921
+ *
10922
+ * @example
10923
+ * ```typescript
10924
+ * import { resolveApiKey } from '@core/service-client'
10925
+ *
10926
+ * resolveApiKey({ apiKey: 'TEST_API_KEY:id:secret' }) // 'TEST_API_KEY:id:secret'
10927
+ * resolveApiKey({ kitKey: 'KIT_KEY:id:secret' }) // 'KIT_KEY:id:secret'
10928
+ * resolveApiKey({ apiKey: '', kitKey: 'KIT_KEY:id:secret' }) // 'KIT_KEY:id:secret'
10929
+ * resolveApiKey({ kitKey: '' }) // undefined
10930
+ * resolveApiKey({}) // undefined
10931
+ * ```
10932
+ */ const resolveApiKey = (source)=>{
10933
+ // Treat an empty-string value as absent on either field so the
10934
+ // `env ?? ''` idiom falls through to the next credential (or permissionless).
10935
+ const normalize = (value)=>value !== undefined && value !== '' ? value : undefined;
10936
+ return normalize(source.apiKey) ?? normalize(source.kitKey);
10368
10937
  };
10369
10938
 
10370
10939
  /**
@@ -11101,7 +11670,7 @@ const abiParameterSchema = zod.z.object({
11101
11670
  */ zod.z.object({
11102
11671
  type: zod.z.literal('evm'),
11103
11672
  abi: abiSchema,
11104
- address: evmAddressSchema,
11673
+ address: evmAddressSchema$1,
11105
11674
  functionName: zod.z.string({
11106
11675
  required_error: 'Function name is required',
11107
11676
  invalid_type_error: 'Function name must be a string'
@@ -11138,7 +11707,7 @@ const abiParameterSchema = zod.z.object({
11138
11707
  * }
11139
11708
  * ```
11140
11709
  */ zod.z.object({
11141
- address: evmAddressSchema,
11710
+ address: evmAddressSchema$1,
11142
11711
  value: zod.z.bigint({
11143
11712
  required_error: 'Value is required for native transfers',
11144
11713
  invalid_type_error: 'Value must be a bigint'
@@ -11306,7 +11875,7 @@ zod.z.object({
11306
11875
  signature: evmSignatureSchema,
11307
11876
  tokenInputs: zod.z.array(zod.z.object({
11308
11877
  permitType: zod.z.nativeEnum(PermitType),
11309
- token: evmAddressSchema,
11878
+ token: evmAddressSchema$1,
11310
11879
  amount: zod.z.bigint().refine((value)=>value >= 0n, {
11311
11880
  message: 'amount must be a non-negative bigint'
11312
11881
  }),
@@ -11726,7 +12295,7 @@ const optionalSwapChainIdentifierField = swapChainIdentifierField.optional();
11726
12295
  /**
11727
12296
  * Fee recipient address (required).
11728
12297
  * Must be a valid EVM address or Solana address.
11729
- */ recipientAddress: zod.z.string().refine((value)=>evmAddressSchema.safeParse(value).success || solanaAddressSchema.safeParse(value).success, {
12298
+ */ recipientAddress: zod.z.string().refine((value)=>evmAddressSchema$1.safeParse(value).success || solanaAddressSchema.safeParse(value).success, {
11730
12299
  message: 'recipientAddress must be a valid blockchain address: EVM (0x + 40 hex chars) or Solana (base58, 32-44 chars)'
11731
12300
  })
11732
12301
  }).strict();
@@ -11738,7 +12307,8 @@ const optionalSwapChainIdentifierField = swapChainIdentifierField.optional();
11738
12307
  * - slippageBps: Optional positive number for slippage tolerance
11739
12308
  * - stopLimit: Optional decimal string for minimum output
11740
12309
  * - customFee: Optional fee configuration
11741
- * - kitKey: Optional string identifier
12310
+ * - apiKey: Optional credential string
12311
+ * - kitKey: Optional credential string (deprecated alias for apiKey)
11742
12312
  */ const swapConfigSchema = zod.z.object({
11743
12313
  allowanceStrategy: allowanceStrategySchema.optional(),
11744
12314
  slippageBps: zod.z.number().int().min(0).optional(),
@@ -11748,11 +12318,12 @@ const optionalSwapChainIdentifierField = swapChainIdentifierField.optional();
11748
12318
  attributeName: 'stopLimit'
11749
12319
  })(zod.z.string())).optional(),
11750
12320
  customFee: swapCustomFeeSchema.optional(),
12321
+ apiKey: zod.z.string().optional(),
11751
12322
  kitKey: zod.z.string().optional()
11752
12323
  });
11753
12324
  const swapDestinationSchema = zod.z.object({
11754
12325
  chain: optionalSwapChainIdentifierField,
11755
- recipientAddress: zod.z.string().refine((value)=>evmAddressSchema.safeParse(value).success || solanaAddressSchema.safeParse(value).success, {
12326
+ recipientAddress: zod.z.string().refine((value)=>evmAddressSchema$1.safeParse(value).success || solanaAddressSchema.safeParse(value).success, {
11756
12327
  message: 'recipientAddress must be a valid blockchain address: EVM (0x + 40 hex chars) or Solana (base58, 32-44 chars)'
11757
12328
  }).optional()
11758
12329
  }).strict();
@@ -13185,7 +13756,7 @@ new Set(Object.values(Blockchain));
13185
13756
  registerKit(`${pkg$2.name}/${pkg$2.version}`);
13186
13757
 
13187
13758
  var name$1 = "@circle-fin/earn-kit";
13188
- var version$1 = "1.5.0";
13759
+ var version$1 = "1.6.0";
13189
13760
  var pkg$1 = {
13190
13761
  name: name$1,
13191
13762
  version: version$1};
@@ -13401,7 +13972,7 @@ function toSdkChain(chain) {
13401
13972
  *
13402
13973
  * @internal
13403
13974
  */ function assertHexAddress(field, value, message = `${field} must be a 0x-prefixed 20-byte hex address`) {
13404
- const result = evmAddressSchema.safeParse(value);
13975
+ const result = evmAddressSchema$1.safeParse(value);
13405
13976
  if (!result.success) {
13406
13977
  throw createValidationFailedError(field, value, message);
13407
13978
  }
@@ -13432,30 +14003,6 @@ function toSdkChain(chain) {
13432
14003
  return assertHexAddress('chain.kitContracts.adapter', adapterContractAddress, `Adapter contract for chain ${chain.name} must be a 0x-prefixed 20-byte hex address.`);
13433
14004
  }
13434
14005
 
13435
- /**
13436
- * Parse the raw `token.allowance` adapter response into a bigint.
13437
- *
13438
- * @internal
13439
- */ function parseAllowanceResponse(allowanceRaw) {
13440
- if (allowanceRaw === undefined || allowanceRaw === null) {
13441
- return 0n;
13442
- }
13443
- let allowance;
13444
- if (typeof allowanceRaw === 'bigint') {
13445
- allowance = allowanceRaw;
13446
- } else if (typeof allowanceRaw === 'string') {
13447
- try {
13448
- allowance = BigInt(allowanceRaw);
13449
- } catch {
13450
- allowance = undefined;
13451
- }
13452
- }
13453
- if (allowance === undefined || allowance < 0n) {
13454
- throw createValidationFailedError('token.allowance', allowanceRaw, 'token.allowance response must be a non-negative bigint-compatible string or bigint');
13455
- }
13456
- return allowance;
13457
- }
13458
-
13459
14006
  /**
13460
14007
  * Safety multiplier applied to locally estimated gas for earn transactions.
13461
14008
  *
@@ -13677,17 +14224,15 @@ const GAS_SAFETY_MULTIPLIER_DENOMINATOR = 10n;
13677
14224
  if (requiredAllowance <= 0n) {
13678
14225
  return undefined;
13679
14226
  }
13680
- const allowancePrepared = await adapter.prepareAction('token.allowance', {
13681
- tokenAddress,
13682
- delegate
13683
- }, {
13684
- chain,
13685
- address
13686
- });
13687
- // Each execute() is a fresh allowance read at `latest`, so the same prepared
13688
- // action serves both the pre-approval decision read and the post-approval
13689
- // propagation polls.
13690
- const readAllowance = async ()=>parseAllowanceResponse(await allowancePrepared.execute());
14227
+ // Each call is a fresh allowance read at `latest`, so the same function serves
14228
+ // both the pre-approval decision and post-approval propagation polls.
14229
+ const readAllowance = async ()=>readTokenAllowance(adapter, {
14230
+ tokenAddress,
14231
+ delegate
14232
+ }, {
14233
+ chain,
14234
+ address
14235
+ });
13691
14236
  const currentAllowance = await readAllowance();
13692
14237
  if (currentAllowance >= requiredAllowance) {
13693
14238
  return undefined;
@@ -14732,14 +15277,13 @@ function throwBatchFailure(result, executeReceipt, chain, actionKey, revertMessa
14732
15277
  // approveAllowanceIfNeeded guard and avoids an increaseAllowance underflow
14733
15278
  // (requiredAllowance - currentAllowance would be negative, which reverts as
14734
15279
  // an out-of-range uint256).
14735
- const allowancePrepared = await adapter.prepareAction('token.allowance', {
15280
+ const currentAllowance = await readTokenAllowance(adapter, {
14736
15281
  tokenAddress: approvalToken,
14737
15282
  delegate
14738
15283
  }, {
14739
15284
  chain,
14740
15285
  address
14741
15286
  });
14742
- const currentAllowance = parseAllowanceResponse(await allowancePrepared.execute());
14743
15287
  const approvalNeeded = currentAllowance < requiredAllowance;
14744
15288
  const executePrepared = await adapter.prepareAction(actionKey, {
14745
15289
  executeParams,
@@ -15076,7 +15620,7 @@ const EARN_OPERATIONS = new Set([
15076
15620
  // Store the original service params non-enumerably. `retry()` reads them by
15077
15621
  // direct property access (`trace.params`), but JSON.stringify, console.log,
15078
15622
  // and telemetry serializers skip non-enumerable properties — so a
15079
- // permissioned call's `config.kitKey` (a `KIT_KEY:<id>:<secret>` value) and
15623
+ // permissioned call's `config.apiKey` (a credential value) and
15080
15624
  // the in-memory adapter never leak through a logged error. defineProperty
15081
15625
  // also redefines any enumerable `params` an upstream trace may have carried.
15082
15626
  Object.defineProperty(trace, 'params', {
@@ -15147,7 +15691,7 @@ function isNonNegativeBigIntLike(value) {
15147
15691
  }
15148
15692
  }
15149
15693
  const hexSignatureSchema = evmSignatureSchema;
15150
- const hexAddressSchema = evmAddressSchema;
15694
+ const hexAddressSchema = evmAddressSchema$1;
15151
15695
  // '0x' prefix + 32 bytes * 2 hex chars.
15152
15696
  const BYTES32_HEX_LENGTH = 66;
15153
15697
  const bridgeFeeTokenSchema = hexAddressSchema;
@@ -16116,7 +16660,7 @@ const bridgeDepositPrepareReviewSchema = zod.z.object({
16116
16660
  }
16117
16661
 
16118
16662
  var name = "@circle-fin/provider-earn-service";
16119
- var version = "1.4.0";
16663
+ var version = "1.5.0";
16120
16664
  var pkg = {
16121
16665
  name: name,
16122
16666
  version: version};
@@ -16178,10 +16722,12 @@ var pkg = {
16178
16722
  *
16179
16723
  * @internal
16180
16724
  */ function buildConfig(serviceConfig) {
16181
- // The kit key is a server-only secret. Reject it in the browser so it cannot
16182
- // leak into a client bundle (no-op in Node.js). Keyless usage stays allowed.
16183
- if (serviceConfig?.kitKey !== undefined && isBrowserEnvironment()) {
16184
- throw createValidationFailedError('kitKey', '[redacted]', 'kitKey must not be provided in a browser environment — it is a server-only secret. Run EarnKit operations that use a kit key on your server, or omit kitKey to use the permissionless (keyless) client path');
16725
+ const apiKey = resolveApiKey(serviceConfig ?? {});
16726
+ // The credential is a server-only secret. Reject it in the browser so it
16727
+ // cannot leak into a client bundle (no-op in Node.js). Keyless usage stays
16728
+ // allowed.
16729
+ if (apiKey !== undefined && isBrowserEnvironment()) {
16730
+ throw createValidationFailedError('apiKey', '[redacted]', 'apiKey must not be provided in a browser environment — it is a server-only secret. Run EarnKit operations that use an API key on your server, or omit apiKey (and the legacy kitKey) to use the permissionless (keyless) client path');
16185
16731
  }
16186
16732
  const baseUrl = serviceConfig?.baseUrl ?? EARN_SERVICE_BASE_URL;
16187
16733
  // The API CORS policy does not allow this custom header. Keep the existing
@@ -16190,7 +16736,7 @@ var pkg = {
16190
16736
  const sdkVersionHeader = isNodeEnvironment() ? {
16191
16737
  [SDK_VERSION_HEADER]: resolveSdkVersionHeader()
16192
16738
  } : {};
16193
- if (serviceConfig?.kitKey === undefined) {
16739
+ if (apiKey === undefined) {
16194
16740
  return {
16195
16741
  pollingConfig: {
16196
16742
  ...DEFAULT_CONFIG,
@@ -16202,11 +16748,11 @@ var pkg = {
16202
16748
  baseUrl
16203
16749
  };
16204
16750
  }
16205
- if (!isValidApiKey(serviceConfig.kitKey)) {
16751
+ if (!isValidApiKey(apiKey)) {
16206
16752
  throw new KitError({
16207
16753
  ...InputError.VALIDATION_FAILED,
16208
16754
  recoverability: 'FATAL',
16209
- message: 'Invalid kitKey format. Expected KIT_KEY:<keyId>:<keySecret>.'
16755
+ message: 'Invalid apiKey format. Expected <ENV>_API_KEY:<keyId>:<keySecret> (for example TEST_API_KEY:...), or a legacy KIT_KEY:<keyId>:<keySecret>.'
16210
16756
  });
16211
16757
  }
16212
16758
  return {
@@ -16215,7 +16761,7 @@ var pkg = {
16215
16761
  headers: {
16216
16762
  ...DEFAULT_CONFIG.headers,
16217
16763
  ...sdkVersionHeader,
16218
- Authorization: `Bearer ${serviceConfig.kitKey}`
16764
+ Authorization: `Bearer ${apiKey}`
16219
16765
  }
16220
16766
  },
16221
16767
  baseUrl
@@ -17522,9 +18068,9 @@ function finishElapsedWait(lastStatus, lastError) {
17522
18068
  * // Permissionless mode
17523
18069
  * const provider = new EarnServiceProvider()
17524
18070
  *
17525
- * // Permissioned mode with Kit Key
18071
+ * // Permissioned mode with an API key
17526
18072
  * const provider = new EarnServiceProvider({
17527
- * kitKey: 'KIT_KEY:keyId:keySecret',
18073
+ * apiKey: 'TEST_API_KEY:keyId:keySecret',
17528
18074
  * })
17529
18075
  *
17530
18076
  * // Custom base URL for testing
@@ -18751,7 +19297,7 @@ function findProvider(context, chain, operation = 'earn') {
18751
19297
  * fast instead of round-tripping to the service.
18752
19298
  *
18753
19299
  * @internal
18754
- */ 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');
19300
+ */ 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');
18755
19301
  /**
18756
19302
  * Schema for the adapter context within earn operations.
18757
19303
  *
@@ -18783,19 +19329,39 @@ const sourceAdapterContextSchema = zod.z.object({
18783
19329
  /**
18784
19330
  * Schema for the EarnConfig options.
18785
19331
  *
18786
- * Validate the optional Kit Key field using the standard `apiKeySchema`
18787
- * format (`KIT_KEY:<keyId>:<keySecret>`). When omitted, the SDK
18788
- * operates in permissionless mode. `baseUrl` overrides the Earn Service
18789
- * endpoint (e.g. staging); `batchTransactions: false` opts out of atomic
18790
- * batched execution. Both are forwarded to the provider, so this `.strict()`
18791
- * schema must accept them or a valid config object is rejected.
19332
+ * Validate the *resolved* credential using the standard `apiKeySchema` format
19333
+ * (`<ENV>_API_KEY:<keyId>:<keySecret>`, or a legacy
19334
+ * `KIT_KEY:<keyId>:<keySecret>`). `apiKey` takes precedence over the deprecated
19335
+ * `kitKey`, so a malformed `kitKey` that is being ignored must not fail a config
19336
+ * that supplies a valid `apiKey` (and vice versa) only the credential that
19337
+ * would actually be sent is format-checked. When neither is supplied the SDK
19338
+ * operates in permissionless mode. `baseUrl` overrides the Earn Service endpoint
19339
+ * (e.g. staging); `batchTransactions: false` opts out of atomic batched
19340
+ * execution. All are forwarded to the provider, so this `.strict()` schema must
19341
+ * accept them or a valid config object is rejected.
18792
19342
  *
18793
19343
  * @internal
18794
19344
  */ const earnConfigSchema = zod.z.object({
18795
- kitKey: apiKeySchema.optional(),
19345
+ apiKey: zod.z.string().optional(),
19346
+ kitKey: zod.z.string().optional(),
18796
19347
  baseUrl: zod.z.string().optional(),
18797
19348
  batchTransactions: zod.z.boolean().optional()
18798
- }).strict();
19349
+ }).strict().superRefine((config, ctx)=>{
19350
+ const credential = resolveApiKey(config);
19351
+ if (credential === undefined) {
19352
+ return;
19353
+ }
19354
+ const result = apiKeySchema.safeParse(credential);
19355
+ if (!result.success) {
19356
+ ctx.addIssue({
19357
+ code: zod.z.ZodIssueCode.custom,
19358
+ path: [
19359
+ credential === config.apiKey ? 'apiKey' : 'kitKey'
19360
+ ],
19361
+ message: result.error.issues[0]?.message ?? 'Invalid API key format'
19362
+ });
19363
+ }
19364
+ });
18799
19365
  /**
18800
19366
  * Canonical decimal form: a leading digit with no leading zeros (a single
18801
19367
  * '0' is only allowed immediately before the decimal point). Rejects the
@@ -18867,7 +19433,7 @@ const sourceAdapterContextSchema = zod.z.object({
18867
19433
  * currently supports EVM vault addresses on Arc Testnet.
18868
19434
  *
18869
19435
  * @internal
18870
- */ const vaultAddressSchema = evmAddressSchema.refine(isValidEip55Checksum, 'address has an invalid EIP-55 checksum');
19436
+ */ const vaultAddressSchema = evmAddressSchema$1.refine(isValidEip55Checksum, 'address has an invalid EIP-55 checksum');
18871
19437
  /**
18872
19438
  * Validation schema for VaultQuery.
18873
19439
  *
@@ -19142,7 +19708,7 @@ const sameChainGetDepositQuoteParamsSchema = zod.z.object({
19142
19708
  const crossChainGetDepositQuoteParamsSchema = zod.z.object({
19143
19709
  from: sourceAdapterContextSchema,
19144
19710
  chain: earnBridgeDestinationChainIdentifierSchema,
19145
- address: evmAddressSchema,
19711
+ address: evmAddressSchema$1,
19146
19712
  vaultAddress: vaultAddressSchema,
19147
19713
  amount: amountSchema,
19148
19714
  transferSpeed: zod.z.enum([