@circle-fin/app-kit 1.12.1 → 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/estimateSwap.mjs CHANGED
@@ -2981,6 +2981,8 @@ class KitError extends Error {
2981
2981
  Blockchain["Optimism_Sepolia"] = "Optimism_Sepolia";
2982
2982
  Blockchain["Pharos"] = "Pharos";
2983
2983
  Blockchain["Pharos_Testnet"] = "Pharos_Testnet";
2984
+ Blockchain["Plasma"] = "Plasma";
2985
+ Blockchain["Plasma_Testnet"] = "Plasma_Testnet";
2984
2986
  Blockchain["Polkadot_Asset_Hub"] = "Polkadot_Asset_Hub";
2985
2987
  Blockchain["Polkadot_Westmint"] = "Polkadot_Westmint";
2986
2988
  Blockchain["Plume"] = "Plume";
@@ -3050,6 +3052,7 @@ var BridgeChain;
3050
3052
  BridgeChain["Morph"] = "Morph";
3051
3053
  BridgeChain["Optimism"] = "Optimism";
3052
3054
  BridgeChain["Pharos"] = "Pharos";
3055
+ BridgeChain["Plasma"] = "Plasma";
3053
3056
  BridgeChain["Plume"] = "Plume";
3054
3057
  BridgeChain["Polygon"] = "Polygon";
3055
3058
  BridgeChain["Sei"] = "Sei";
@@ -3076,6 +3079,7 @@ var BridgeChain;
3076
3079
  BridgeChain["Morph_Testnet"] = "Morph_Testnet";
3077
3080
  BridgeChain["Optimism_Sepolia"] = "Optimism_Sepolia";
3078
3081
  BridgeChain["Pharos_Testnet"] = "Pharos_Testnet";
3082
+ BridgeChain["Plasma_Testnet"] = "Plasma_Testnet";
3079
3083
  BridgeChain["Plume_Testnet"] = "Plume_Testnet";
3080
3084
  BridgeChain["Polygon_Amoy_Testnet"] = "Polygon_Amoy_Testnet";
3081
3085
  BridgeChain["Sei_Testnet"] = "Sei_Testnet";
@@ -3533,6 +3537,8 @@ var EarnChain;
3533
3537
  * This program handles minting operations for Gateway transactions
3534
3538
  * on Solana devnet.
3535
3539
  */ const GATEWAY_MINTER_SOLANA_DEVNET = 'GATEmKK2ECL1brEngQZWCgMWPbvrEYqsV6u29dAaHavr';
3540
+ /** TokenMessengerWithFees address shared by enabled EVM mainnet sources. */ const TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET = '0x71f54F818671cD0D7ea140Da213e5C8b5C92a408';
3541
+ /** TokenMessengerWithFees address shared by enabled EVM testnet sources. */ const TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET = '0x8745D906D67C346E5eb1aEEED38Eb87F34DF0C0A';
3536
3542
 
3537
3543
  /**
3538
3544
  * Arc Testnet chain definition
@@ -3570,6 +3576,7 @@ var EarnChain;
3570
3576
  v2: {
3571
3577
  type: 'split',
3572
3578
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
3579
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
3573
3580
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
3574
3581
  confirmations: 1,
3575
3582
  fastConfirmations: 1
@@ -3637,6 +3644,7 @@ var EarnChain;
3637
3644
  v2: {
3638
3645
  type: 'split',
3639
3646
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
3647
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
3640
3648
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
3641
3649
  confirmations: 65,
3642
3650
  fastConfirmations: 1
@@ -3701,6 +3709,7 @@ var EarnChain;
3701
3709
  v2: {
3702
3710
  type: 'split',
3703
3711
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
3712
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
3704
3713
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
3705
3714
  confirmations: 65,
3706
3715
  fastConfirmations: 1
@@ -3765,6 +3774,7 @@ var EarnChain;
3765
3774
  v2: {
3766
3775
  type: 'split',
3767
3776
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
3777
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
3768
3778
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
3769
3779
  confirmations: 1,
3770
3780
  fastConfirmations: 1
@@ -3826,6 +3836,7 @@ var EarnChain;
3826
3836
  v2: {
3827
3837
  type: 'split',
3828
3838
  tokenMessenger: '0x8fe6b999dc680ccfdd5bf7eb0974218be2542daa',
3839
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
3829
3840
  messageTransmitter: '0xe737e5cebeeba77efe34d4aa090756590b1ce275',
3830
3841
  confirmations: 1,
3831
3842
  fastConfirmations: 1
@@ -3893,6 +3904,7 @@ var EarnChain;
3893
3904
  v2: {
3894
3905
  type: 'split',
3895
3906
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
3907
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
3896
3908
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
3897
3909
  confirmations: 65,
3898
3910
  fastConfirmations: 1
@@ -3957,6 +3969,7 @@ var EarnChain;
3957
3969
  v2: {
3958
3970
  type: 'split',
3959
3971
  tokenMessenger: '0x8fe6b999dc680ccfdd5bf7eb0974218be2542daa',
3972
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
3960
3973
  messageTransmitter: '0xe737e5cebeeba77efe34d4aa090756590b1ce275',
3961
3974
  confirmations: 65,
3962
3975
  fastConfirmations: 1
@@ -4067,6 +4080,7 @@ var EarnChain;
4067
4080
  v2: {
4068
4081
  type: 'split',
4069
4082
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
4083
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
4070
4084
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
4071
4085
  confirmations: 65,
4072
4086
  fastConfirmations: 1
@@ -4111,6 +4125,7 @@ var EarnChain;
4111
4125
  v2: {
4112
4126
  type: 'split',
4113
4127
  tokenMessenger: '0x8fe6b999dc680ccfdd5bf7eb0974218be2542daa',
4128
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
4114
4129
  messageTransmitter: '0xe737e5cebeeba77efe34d4aa090756590b1ce275',
4115
4130
  confirmations: 65,
4116
4131
  fastConfirmations: 1
@@ -4342,6 +4357,7 @@ var EarnChain;
4342
4357
  v2: {
4343
4358
  type: 'split',
4344
4359
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
4360
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
4345
4361
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
4346
4362
  confirmations: 65,
4347
4363
  fastConfirmations: 2
@@ -4406,6 +4422,7 @@ var EarnChain;
4406
4422
  v2: {
4407
4423
  type: 'split',
4408
4424
  tokenMessenger: '0x8fe6b999dc680ccfdd5bf7eb0974218be2542daa',
4425
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
4409
4426
  messageTransmitter: '0xe737e5cebeeba77efe34d4aa090756590b1ce275',
4410
4427
  confirmations: 65,
4411
4428
  fastConfirmations: 2
@@ -4516,6 +4533,7 @@ var EarnChain;
4516
4533
  v2: {
4517
4534
  type: 'split',
4518
4535
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
4536
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
4519
4537
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
4520
4538
  confirmations: 1,
4521
4539
  fastConfirmations: 1
@@ -4575,6 +4593,7 @@ var EarnChain;
4575
4593
  v2: {
4576
4594
  type: 'split',
4577
4595
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
4596
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
4578
4597
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
4579
4598
  confirmations: 1,
4580
4599
  fastConfirmations: 1
@@ -4729,6 +4748,7 @@ var EarnChain;
4729
4748
  v2: {
4730
4749
  type: 'split',
4731
4750
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
4751
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
4732
4752
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
4733
4753
  confirmations: 65,
4734
4754
  fastConfirmations: 1
@@ -4776,6 +4796,7 @@ var EarnChain;
4776
4796
  v2: {
4777
4797
  type: 'split',
4778
4798
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
4799
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
4779
4800
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
4780
4801
  confirmations: 65,
4781
4802
  fastConfirmations: 1
@@ -4820,6 +4841,7 @@ var EarnChain;
4820
4841
  v2: {
4821
4842
  type: 'split',
4822
4843
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
4844
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
4823
4845
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
4824
4846
  confirmations: 1,
4825
4847
  fastConfirmations: 1
@@ -4865,6 +4887,7 @@ var EarnChain;
4865
4887
  v2: {
4866
4888
  type: 'split',
4867
4889
  tokenMessenger: '0x8fe6b999dc680ccfdd5bf7eb0974218be2542daa',
4890
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
4868
4891
  messageTransmitter: '0xe737e5cebeeba77efe34d4aa090756590b1ce275',
4869
4892
  confirmations: 1,
4870
4893
  fastConfirmations: 1
@@ -4911,6 +4934,7 @@ var EarnChain;
4911
4934
  v2: {
4912
4935
  type: 'split',
4913
4936
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
4937
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
4914
4938
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
4915
4939
  confirmations: 1,
4916
4940
  fastConfirmations: 1
@@ -5224,6 +5248,7 @@ var EarnChain;
5224
5248
  v2: {
5225
5249
  type: 'split',
5226
5250
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
5251
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
5227
5252
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
5228
5253
  confirmations: 65,
5229
5254
  fastConfirmations: 1
@@ -5288,6 +5313,7 @@ var EarnChain;
5288
5313
  v2: {
5289
5314
  type: 'split',
5290
5315
  tokenMessenger: '0x8fe6b999dc680ccfdd5bf7eb0974218be2542daa',
5316
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
5291
5317
  messageTransmitter: '0xe737e5cebeeba77efe34d4aa090756590b1ce275',
5292
5318
  confirmations: 65,
5293
5319
  fastConfirmations: 1
@@ -5408,6 +5434,98 @@ var EarnChain;
5408
5434
  }
5409
5435
  });
5410
5436
 
5437
+ /**
5438
+ * Plasma Mainnet chain definition
5439
+ * @remarks
5440
+ * This represents the official production network for the Plasma blockchain.
5441
+ * Plasma is an EVM-equivalent Layer 1 blockchain purpose-built for global
5442
+ * stablecoin payments, with deterministic BFT finality (PlasmaBFT/Fast-HotStuff).
5443
+ */ const Plasma = defineChain({
5444
+ type: 'evm',
5445
+ chain: Blockchain.Plasma,
5446
+ name: 'Plasma',
5447
+ title: 'Plasma Mainnet',
5448
+ nativeCurrency: {
5449
+ name: 'Plasma',
5450
+ symbol: 'XPL',
5451
+ decimals: 18
5452
+ },
5453
+ chainId: 9745,
5454
+ isTestnet: false,
5455
+ explorerUrl: 'https://plasmascan.to/tx/{hash}',
5456
+ rpcEndpoints: [
5457
+ 'https://rpc.plasma.to'
5458
+ ],
5459
+ eurcAddress: '0x3EE196E78d4d4248b849B8E1C7F44C5457FAFD2C',
5460
+ usdcAddress: '0x2d661C89D812261039AF9764eceaAee884f5F67F',
5461
+ usdtAddress: null,
5462
+ cctp: {
5463
+ domain: 33,
5464
+ contracts: {
5465
+ v2: {
5466
+ type: 'split',
5467
+ tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
5468
+ messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
5469
+ confirmations: 3,
5470
+ fastConfirmations: 1
5471
+ }
5472
+ },
5473
+ forwarderSupported: {
5474
+ source: false,
5475
+ destination: false
5476
+ }
5477
+ },
5478
+ kitContracts: {
5479
+ bridge: BRIDGE_CONTRACT_EVM_MAINNET
5480
+ }
5481
+ });
5482
+
5483
+ /**
5484
+ * Plasma Testnet chain definition
5485
+ * @remarks
5486
+ * This represents the official test network for the Plasma blockchain.
5487
+ * Plasma is an EVM-equivalent Layer 1 blockchain purpose-built for global
5488
+ * stablecoin payments, with deterministic BFT finality (PlasmaBFT/Fast-HotStuff).
5489
+ */ const PlasmaTestnet = defineChain({
5490
+ type: 'evm',
5491
+ chain: Blockchain.Plasma_Testnet,
5492
+ name: 'Plasma Testnet',
5493
+ title: 'Plasma Testnet',
5494
+ nativeCurrency: {
5495
+ name: 'Plasma',
5496
+ symbol: 'XPL',
5497
+ decimals: 18
5498
+ },
5499
+ chainId: 9746,
5500
+ isTestnet: true,
5501
+ explorerUrl: 'https://testnet.plasmascan.to/tx/{hash}',
5502
+ rpcEndpoints: [
5503
+ 'https://testnet-rpc.plasma.to'
5504
+ ],
5505
+ eurcAddress: '0x98AfA0F93Dd993B736399f9074eDcEBD1985A330',
5506
+ usdcAddress: '0xE67Fb267022cBA8064Dd388CC2FED724F3120D9D',
5507
+ usdtAddress: null,
5508
+ cctp: {
5509
+ domain: 33,
5510
+ contracts: {
5511
+ v2: {
5512
+ type: 'split',
5513
+ tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
5514
+ messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
5515
+ confirmations: 3,
5516
+ fastConfirmations: 1
5517
+ }
5518
+ },
5519
+ forwarderSupported: {
5520
+ source: false,
5521
+ destination: false
5522
+ }
5523
+ },
5524
+ kitContracts: {
5525
+ bridge: BRIDGE_CONTRACT_EVM_TESTNET
5526
+ }
5527
+ });
5528
+
5411
5529
  /**
5412
5530
  * Plume Mainnet chain definition
5413
5531
  * @remarks
@@ -5439,6 +5557,7 @@ var EarnChain;
5439
5557
  v2: {
5440
5558
  type: 'split',
5441
5559
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
5560
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
5442
5561
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
5443
5562
  confirmations: 65,
5444
5563
  fastConfirmations: 1
@@ -5485,6 +5604,7 @@ var EarnChain;
5485
5604
  v2: {
5486
5605
  type: 'split',
5487
5606
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
5607
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
5488
5608
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
5489
5609
  confirmations: 65,
5490
5610
  fastConfirmations: 1
@@ -5586,6 +5706,7 @@ var EarnChain;
5586
5706
  v2: {
5587
5707
  type: 'split',
5588
5708
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
5709
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
5589
5710
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
5590
5711
  confirmations: 33,
5591
5712
  fastConfirmations: 13
@@ -5651,6 +5772,7 @@ var EarnChain;
5651
5772
  v2: {
5652
5773
  type: 'split',
5653
5774
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
5775
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
5654
5776
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
5655
5777
  confirmations: 33,
5656
5778
  fastConfirmations: 13
@@ -5710,6 +5832,7 @@ var EarnChain;
5710
5832
  v2: {
5711
5833
  type: 'split',
5712
5834
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
5835
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
5713
5836
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
5714
5837
  confirmations: 1,
5715
5838
  fastConfirmations: 1
@@ -5769,6 +5892,7 @@ var EarnChain;
5769
5892
  v2: {
5770
5893
  type: 'split',
5771
5894
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
5895
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
5772
5896
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
5773
5897
  confirmations: 1,
5774
5898
  fastConfirmations: 1
@@ -5826,6 +5950,7 @@ var EarnChain;
5826
5950
  v2: {
5827
5951
  type: 'split',
5828
5952
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
5953
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
5829
5954
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
5830
5955
  confirmations: 1,
5831
5956
  fastConfirmations: 1
@@ -5884,6 +6009,7 @@ var EarnChain;
5884
6009
  v2: {
5885
6010
  type: 'split',
5886
6011
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
6012
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
5887
6013
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
5888
6014
  confirmations: 1,
5889
6015
  fastConfirmations: 1
@@ -6199,6 +6325,7 @@ var EarnChain;
6199
6325
  v2: {
6200
6326
  type: 'split',
6201
6327
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
6328
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
6202
6329
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
6203
6330
  confirmations: 65,
6204
6331
  fastConfirmations: 1
@@ -6263,6 +6390,7 @@ var EarnChain;
6263
6390
  v2: {
6264
6391
  type: 'split',
6265
6392
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
6393
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
6266
6394
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
6267
6395
  confirmations: 65,
6268
6396
  fastConfirmations: 1
@@ -6320,6 +6448,7 @@ var EarnChain;
6320
6448
  v2: {
6321
6449
  type: 'split',
6322
6450
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cF5d',
6451
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
6323
6452
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
6324
6453
  confirmations: 65,
6325
6454
  fastConfirmations: 1
@@ -6379,6 +6508,7 @@ var EarnChain;
6379
6508
  v2: {
6380
6509
  type: 'split',
6381
6510
  tokenMessenger: '0x8fe6b999dc680ccfdd5bf7eb0974218be2542daa',
6511
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
6382
6512
  messageTransmitter: '0xe737e5cebeeba77efe34d4aa090756590b1ce275',
6383
6513
  confirmations: 65,
6384
6514
  fastConfirmations: 1
@@ -6439,6 +6569,7 @@ var EarnChain;
6439
6569
  v2: {
6440
6570
  type: 'split',
6441
6571
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
6572
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
6442
6573
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
6443
6574
  confirmations: 3,
6444
6575
  fastConfirmations: 3
@@ -6484,6 +6615,7 @@ var EarnChain;
6484
6615
  v2: {
6485
6616
  type: 'split',
6486
6617
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
6618
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
6487
6619
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
6488
6620
  confirmations: 3,
6489
6621
  fastConfirmations: 1
@@ -6694,6 +6826,8 @@ var Chains = /*#__PURE__*/Object.freeze({
6694
6826
  OptimismSepolia: OptimismSepolia,
6695
6827
  Pharos: Pharos,
6696
6828
  PharosTestnet: PharosTestnet,
6829
+ Plasma: Plasma,
6830
+ PlasmaTestnet: PlasmaTestnet,
6697
6831
  Plume: Plume,
6698
6832
  PlumeTestnet: PlumeTestnet,
6699
6833
  PolkadotAssetHub: PolkadotAssetHub,
@@ -8735,6 +8869,7 @@ const swapTokenEnumSchema = z.enum([
8735
8869
  [Blockchain.Noble]: 'uusdc',
8736
8870
  [Blockchain.Optimism]: '0x0b2c639c533813f4aa9d7837caf62653d097ff85',
8737
8871
  [Blockchain.Pharos]: '0xC879C018dB60520F4355C26eD1a6D572cdAC1815',
8872
+ [Blockchain.Plasma]: '0x2d661C89D812261039AF9764eceaAee884f5F67F',
8738
8873
  [Blockchain.Plume]: '0x222365EF19F7947e5484218551B56bb3965Aa7aF',
8739
8874
  [Blockchain.Polkadot_Asset_Hub]: '1337',
8740
8875
  [Blockchain.Polygon]: '0x3c499c542cef5e3811e1192ce70d8cc03d5c3359',
@@ -8771,6 +8906,7 @@ const swapTokenEnumSchema = z.enum([
8771
8906
  [Blockchain.Noble_Testnet]: 'uusdc',
8772
8907
  [Blockchain.Optimism_Sepolia]: '0x5fd84259d66Cd46123540766Be93DFE6D43130D7',
8773
8908
  [Blockchain.Pharos_Testnet]: '0xcfC8330f4BCAB529c625D12781b1C19466A9Fc8B',
8909
+ [Blockchain.Plasma_Testnet]: '0xE67Fb267022cBA8064Dd388CC2FED724F3120D9D',
8774
8910
  [Blockchain.Plume_Testnet]: '0xcB5f30e335672893c7eb944B374c196392C19D18',
8775
8911
  [Blockchain.Polkadot_Westmint]: '31337',
8776
8912
  [Blockchain.Polygon_Amoy_Testnet]: '0x41e94eb019c0762f9bfcf9fb1e58725bfb0e7582',
@@ -8833,6 +8969,7 @@ const swapTokenEnumSchema = z.enum([
8833
8969
  [Blockchain.Base]: '0x60a3E35Cc302bFA44Cb288Bc5a4F316Fdb1adb42',
8834
8970
  [Blockchain.Cronos]: '0xA6dE01a2d62C6B5f3525d768f34d276652C554c8',
8835
8971
  [Blockchain.Ethereum]: '0x1aBaEA1f7C830bD89Acc67eC4af516284b1bC33c',
8972
+ [Blockchain.Plasma]: '0x3EE196E78d4d4248b849B8E1C7F44C5457FAFD2C',
8836
8973
  [Blockchain.Solana]: 'HzwqbKZw8HxMN6bF2yFZNrht3c2iXXzpKcFu7uBEDKtr',
8837
8974
  [Blockchain.World_Chain]: '0x1C60ba0A0eD1019e8Eb035E6daF4155A5cE2380B',
8838
8975
  // =========================================================================
@@ -8841,7 +8978,8 @@ const swapTokenEnumSchema = z.enum([
8841
8978
  [Blockchain.Arc_Testnet]: '0x89B50855Aa3bE2F677cD6303Cec089B5F319D72a',
8842
8979
  [Blockchain.Base_Sepolia]: '0x808456652fdb597867f38412077A9182bf77359F',
8843
8980
  [Blockchain.Cronos_Testnet]: '0x31f7538adb53cF16350e6B0c89d03D91b7D12c46',
8844
- [Blockchain.Ethereum_Sepolia]: '0x08210F9170F89Ab7658F0B5E3fF39b0E03C594D4'
8981
+ [Blockchain.Ethereum_Sepolia]: '0x08210F9170F89Ab7658F0B5E3fF39b0E03C594D4',
8982
+ [Blockchain.Plasma_Testnet]: '0x98AfA0F93Dd993B736399f9074eDcEBD1985A330'
8845
8983
  }
8846
8984
  };
8847
8985
 
@@ -10070,7 +10208,7 @@ const swapTokenEnumSchema = z.enum([
10070
10208
  }
10071
10209
 
10072
10210
  var name$2 = "@circle-fin/bridge-kit";
10073
- var version$2 = "1.13.0";
10211
+ var version$2 = "1.14.0";
10074
10212
  var pkg$2 = {
10075
10213
  name: name$2,
10076
10214
  version: version$2};
@@ -10424,7 +10562,7 @@ const READ_ACTION_KEY_SET = new Set(READ_ACTION_KEYS);
10424
10562
  * const result = evmAddressSchema.safeParse(validAddress)
10425
10563
  * console.log(result.success) // true
10426
10564
  * ```
10427
- */ const evmAddressSchema = hexStringSchema.refine((value)=>value.length === 42, 'EVM address must be exactly 42 characters long (0x + 40 hex characters)').transform((value)=>value);
10565
+ */ const evmAddressSchema$1 = hexStringSchema.refine((value)=>value.length === 42, 'EVM address must be exactly 42 characters long (0x + 40 hex characters)').transform((value)=>value);
10428
10566
  /**
10429
10567
  * Schema for validating transaction hashes.
10430
10568
  *
@@ -10961,6 +11099,10 @@ var TransferSpeed;
10961
11099
  token: z.literal('USDC').optional(),
10962
11100
  config: z.object({
10963
11101
  transferSpeed: z.nativeEnum(TransferSpeed).optional(),
11102
+ feePayment: z.enum([
11103
+ 'source',
11104
+ 'destination'
11105
+ ]).optional(),
10964
11106
  maxFee: z.string().min(1, 'Required').pipe(createDecimalStringValidator({
10965
11107
  allowZero: true,
10966
11108
  regexMessage: MAX_FEE_FORMAT_ERROR_MESSAGE,
@@ -10968,7 +11110,8 @@ var TransferSpeed;
10968
11110
  maxDecimals: 6
10969
11111
  })(z.string())).optional(),
10970
11112
  customFee: customFeeSchema.optional()
10971
- }).optional()
11113
+ }).optional(),
11114
+ quote: z.string().regex(/^0x([a-fA-F0-9]{2})+$/, 'must be non-empty 0x hex').optional()
10972
11115
  });
10973
11116
 
10974
11117
  /**
@@ -11146,13 +11289,182 @@ var TransferSpeed;
11146
11289
  * @internal
11147
11290
  */ Object.values(Chains).filter((chain)=>isCCTPV2Supported(chain));
11148
11291
 
11292
+ /** Decimal string in token minor units, constrained to be strictly positive. */ const positiveAmountSchema = z.string().regex(/^\d+$/, 'must be a non-negative integer string')// Re-check the digit shape here: zod still runs this refinement when the
11293
+ // regex check above fails ("dirty"), so guard BigInt() against throwing on a
11294
+ // non-numeric value before comparing.
11295
+ .refine((value)=>/^\d+$/.test(value) && BigInt(value) > 0n, 'must be greater than zero');
11296
+ /**
11297
+ * A 20-byte EVM address in `0x` hex.
11298
+ *
11299
+ * The MVP prepaid-`FORWARD` `burn/usdc` path targets EVM contracts
11300
+ * (`TokenMessengerWithFees` / `GenericExecutor`), so `feeToken` and
11301
+ * `destinationCaller` are constrained to EVM addresses by design. This is an
11302
+ * intentional scope limit, not a permanent one: it can be widened to other
11303
+ * address formats as the fee service expands to more chains.
11304
+ */ const evmAddressSchema = z.string().regex(/^0x[a-fA-F0-9]{40}$/, 'must be a 20-byte 0x address');
11305
+ /** Even-length `0x` hex (the empty `0x` is allowed). */ const hexSchema = z.string().regex(/^0x([a-fA-F0-9]{2})*$/, 'must be even-length 0x hex');
11306
+ /** Non-empty, even-length `0x` hex. */ const nonEmptyHexSchema = z.string().regex(/^0x([a-fA-F0-9]{2})+$/, 'must be non-empty 0x hex');
11307
+ /** A 32-byte `0x` hex hash. */ const bytes32Schema = z.string().regex(/^0x[a-fA-F0-9]{64}$/, 'must be a 32-byte 0x hash');
11308
+ /** Decimal string in minor units, allowing zero. */ const numericStringSchema = z.string().regex(/^\d+$/, 'must be a non-negative integer string');
11309
+ /** An `https:` URL, used for the optional base-URL override. */ const httpsUrlSchema = z.string().refine((value)=>{
11310
+ try {
11311
+ return new URL(value).protocol === 'https:';
11312
+ } catch {
11313
+ return false;
11314
+ }
11315
+ }, 'must be an https URL');
11316
+ const forwardParamsSchema = z.object({
11317
+ hookData: hexSchema.optional(),
11318
+ destinationCaller: evmAddressSchema.optional()
11319
+ }).strict();
11320
+ const forwardRequestSchema = z.object({
11321
+ type: z.literal('FORWARD'),
11322
+ params: forwardParamsSchema.optional()
11323
+ }).strict();
11324
+ const preFinalityRequestSchema = z.object({
11325
+ type: z.literal('PRE_FINALITY')
11326
+ }).strict();
11327
+ /** A single quote request item (`FORWARD` or `PRE_FINALITY`). */ const feeQuoteRequestSchema = z.discriminatedUnion('type', [
11328
+ forwardRequestSchema,
11329
+ preFinalityRequestSchema
11330
+ ]);
11331
+ /** A non-empty list of quote request items with unique types. */ const feeQuoteRequestsSchema = 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');
11332
+ /**
11333
+ * A structured `Partial<ApiPollingConfig>` polling override.
11334
+ *
11335
+ * Validates the field types callers actually set, so a plain-JS caller passing
11336
+ * `{ timeout: 'soon' }` is rejected at the boundary rather than failing opaquely
11337
+ * inside the transport. Unknown keys pass through so a future `ApiPollingConfig`
11338
+ * field is forwarded rather than silently dropped.
11339
+ */ const apiPollingConfigSchema = z.object({
11340
+ timeout: z.number().int().positive().optional(),
11341
+ maxRetries: z.number().int().nonnegative().optional(),
11342
+ retryDelay: z.number().int().nonnegative().optional(),
11343
+ backoff: z.enum([
11344
+ 'fixed',
11345
+ 'exponential'
11346
+ ]).optional(),
11347
+ maxRetryDelayMs: z.number().int().positive().optional(),
11348
+ headers: z.record(z.string()).optional()
11349
+ }).passthrough();
11350
+ /**
11351
+ * The validatable input for {@link fetchFeeQuote}.
11352
+ *
11353
+ * This is the single source of truth for input validation, including the CCTP
11354
+ * domains and the `isTestnet` environment flag. Validating `isTestnet` at
11355
+ * runtime matters because a plain-JS caller who omits it would otherwise leave
11356
+ * it `undefined`, which is falsy and silently selects the production base URL.
11357
+ * (`buildFeeQuoteUrl` independently re-validates the domains for standalone
11358
+ * callers.)
11359
+ */ z.object({
11360
+ sourceDomain: z.number().int().nonnegative(),
11361
+ destinationDomain: z.number().int().nonnegative(),
11362
+ amount: positiveAmountSchema,
11363
+ feeToken: evmAddressSchema.optional(),
11364
+ requests: feeQuoteRequestsSchema,
11365
+ isTestnet: z.boolean(),
11366
+ baseUrl: httpsUrlSchema.optional(),
11367
+ config: apiPollingConfigSchema.optional()
11368
+ }).strict();
11369
+ const feeQuoteItemSchema = z.object({
11370
+ type: z.string().min(1),
11371
+ amount: numericStringSchema,
11372
+ args: z.array(z.string()),
11373
+ argsHash: bytes32Schema
11374
+ }).passthrough();
11375
+ const exchangeRatesSchema = z.object({
11376
+ feeTokenUsd: z.string(),
11377
+ destinationTokenUsd: z.string()
11378
+ }).passthrough();
11379
+ const metadataSchema = z.object({
11380
+ destinationGasPrice: z.string().optional(),
11381
+ exchangeRates: exchangeRatesSchema.optional()
11382
+ }).passthrough();
11383
+ /** The `expiry` object the Quote API nests the quote TTL under. */ const expirySchema = z.discriminatedUnion('mode', [
11384
+ z.object({
11385
+ mode: z.literal('TIMESTAMP'),
11386
+ expiresAt: z.number().int().nonnegative()
11387
+ }).passthrough(),
11388
+ z.object({
11389
+ mode: z.literal('BLOCK_NUMBER'),
11390
+ expiresAtBlock: z.number().int().nonnegative(),
11391
+ blockEstimatedAt: z.number().int().nonnegative().optional()
11392
+ }).passthrough()
11393
+ ]);
11394
+ /** Schema for a signed fee quote returned by the Quote API. */ z.object({
11395
+ // The runtime YAML spec maps signedQuote to a looser `hex` (which allows
11396
+ // an empty `0x`); we keep the stricter non-empty form. Do not relax
11397
+ // without a reason.
11398
+ signedQuote: nonEmptyHexSchema,
11399
+ issuedAt: z.number().int().nonnegative(),
11400
+ // The API returns a mode-specific timestamp or source-block deadline.
11401
+ expiry: expirySchema,
11402
+ feeTotalAmount: numericStringSchema,
11403
+ feeToken: evmAddressSchema,
11404
+ nonce: numericStringSchema,
11405
+ items: z.array(feeQuoteItemSchema),
11406
+ metadata: metadataSchema.optional()
11407
+ }).passthrough();
11408
+ /** Validate input to {@link validateQuote}. */ z.object({
11409
+ sourceDomain: z.number().int().nonnegative(),
11410
+ abiSignature: z.string().min(1),
11411
+ args: z.array(z.union([
11412
+ z.string(),
11413
+ z.array(z.string())
11414
+ ])),
11415
+ isTestnet: z.boolean(),
11416
+ baseUrl: httpsUrlSchema.optional(),
11417
+ config: apiPollingConfigSchema.optional()
11418
+ }).strict();
11419
+ const quoteExpiryStatusSchema = z.discriminatedUnion('mode', [
11420
+ z.object({
11421
+ mode: z.literal('TIMESTAMP'),
11422
+ expired: z.boolean(),
11423
+ secondsRemaining: z.number().int().nonnegative(),
11424
+ expiresAt: z.number().int().nonnegative()
11425
+ }).passthrough(),
11426
+ z.object({
11427
+ mode: z.literal('BLOCK_NUMBER'),
11428
+ expired: z.boolean(),
11429
+ secondsRemaining: z.number().int().nonnegative(),
11430
+ expiresAtBlock: z.number().int().nonnegative(),
11431
+ blockEstimatedAt: z.number().int().nonnegative().optional()
11432
+ }).passthrough()
11433
+ ]);
11434
+ const validateQuoteItemSchema = z.object({
11435
+ type: z.string().min(1),
11436
+ argsMatch: z.boolean(),
11437
+ amount: numericStringSchema.optional(),
11438
+ args: z.array(z.string()).optional(),
11439
+ argsHash: bytes32Schema.optional(),
11440
+ computedArgsHash: bytes32Schema.optional()
11441
+ }).passthrough();
11442
+ /**
11443
+ * Schema for a response from the Quote API validation endpoint.
11444
+ *
11445
+ * The endpoint takes the source domain as a URL path parameter and does not
11446
+ * return it in the response body, so `sourceDomain` is intentionally not part
11447
+ * of this schema.
11448
+ */ z.object({
11449
+ signedQuote: nonEmptyHexSchema,
11450
+ expiry: quoteExpiryStatusSchema,
11451
+ feeTotalAmount: numericStringSchema,
11452
+ feeToken: evmAddressSchema,
11453
+ nonce: numericStringSchema,
11454
+ claimable: z.boolean(),
11455
+ // Preserve newly introduced server-side reasons as opaque strings rather
11456
+ // than rejecting the entire safety response before the SDK is updated.
11457
+ failedChecks: z.array(z.string().min(1)),
11458
+ items: z.array(validateQuoteItemSchema)
11459
+ }).passthrough();
11460
+
11149
11461
  /** SDK name used in telemetry payloads. */ resolveKitSdkName(pkg$2.name);
11150
11462
 
11151
11463
  // Auto-register this kit for user agent tracking
11152
11464
  registerKit(`${pkg$2.name}/${pkg$2.version}`);
11153
11465
 
11154
11466
  var name$1 = "@circle-fin/swap-kit";
11155
- var version$1 = "1.5.2";
11467
+ var version$1 = "1.6.0";
11156
11468
  var pkg$1 = {
11157
11469
  name: name$1,
11158
11470
  version: version$1};
@@ -11166,7 +11478,7 @@ const optionalChainIdentifierField = chainIdentifierField.optional();
11166
11478
  * Catches obviously malformed addresses at parse time; chain-specific validation
11167
11479
  * is performed in buildServiceParams.
11168
11480
  */ const destinationAddressSchema = z.union([
11169
- evmAddressSchema,
11481
+ evmAddressSchema$1,
11170
11482
  solanaAddressSchema
11171
11483
  ]);
11172
11484
  /**
@@ -11212,9 +11524,16 @@ const optionalChainIdentifierField = chainIdentifierField.optional();
11212
11524
  message: 'stopLimit must be greater than 0'
11213
11525
  }).optional(),
11214
11526
  customFee: serviceSwapCustomFeeSchema.optional(),
11527
+ apiKey: z.string({
11528
+ invalid_type_error: 'apiKey must be a string'
11529
+ })// Tolerate '' so the `process.env.CIRCLE_API_KEY ?? ''` idiom falls back to
11530
+ // kitKey via resolveApiKey instead of being rejected here.
11531
+ .optional(),
11215
11532
  kitKey: z.string({
11216
11533
  invalid_type_error: 'kitKey must be a string'
11217
- }).min(1, 'kitKey must be a non-empty string').optional(),
11534
+ })// Tolerate '' so an unset kit-key env var yields the permissionless path,
11535
+ // matching buildServiceParams (which already omits an empty credential).
11536
+ .optional(),
11218
11537
  provider: z.string({
11219
11538
  invalid_type_error: 'provider must be a string'
11220
11539
  }).min(1, 'provider must be a non-empty string').optional(),
@@ -11379,23 +11698,49 @@ const optionalChainIdentifierField = chainIdentifierField.optional();
11379
11698
  fees: z.array(serviceSwapFeeSchema).optional()
11380
11699
  }).passthrough();
11381
11700
 
11382
- /** Placeholder used wherever a kit key is scrubbed from logs, traces, or errors. */ const REDACTED_KIT_KEY = '[redacted]';
11701
+ /** Placeholder used wherever a credential is scrubbed from logs, traces, or errors. */ const REDACTED_CREDENTIAL = '[redacted]';
11702
+ /**
11703
+ * Config fields that carry a Stablecoin Service credential.
11704
+ *
11705
+ * `apiKey` is the supported field; `kitKey` is the deprecated alias. Redaction
11706
+ * and credential resolution both read this list so a newly added field is
11707
+ * scrubbed everywhere it needs to be.
11708
+ */ const CREDENTIAL_CONFIG_FIELDS = [
11709
+ 'apiKey',
11710
+ 'kitKey'
11711
+ ];
11383
11712
 
11713
+ /**
11714
+ * Replaces any credential field present on a config with a redaction marker.
11715
+ *
11716
+ * Covers `apiKey` and the deprecated `kitKey`, so adding a credential field
11717
+ * without extending this list cannot silently leak it into a trace. Returns the
11718
+ * config unchanged when it carries no credential.
11719
+ */ const redactCredentialFields = (config)=>{
11720
+ const present = CREDENTIAL_CONFIG_FIELDS.filter((field)=>field in config);
11721
+ if (present.length === 0) {
11722
+ return config;
11723
+ }
11724
+ return present.reduce((acc, field)=>({
11725
+ ...acc,
11726
+ [field]: REDACTED_CREDENTIAL
11727
+ }), {
11728
+ ...config
11729
+ });
11730
+ };
11384
11731
  /**
11385
11732
  * Builds a redacted projection of swap params that is safe to embed in error
11386
11733
  * traces (which may be logged downstream). Allow-lists only non-sensitive
11387
11734
  * fields and drops `from` entirely — `from.adapter` can carry signer/private-key
11388
- * material for signer-backed (viem/ethers) flows — and redacts `config.kitKey`.
11735
+ * material for signer-backed (viem/ethers) flows — and redacts every credential
11736
+ * field on `config`.
11389
11737
  */ const redactSwapParamsForTrace = (params)=>{
11390
11738
  if (typeof params !== 'object' || params === null) {
11391
11739
  return params;
11392
11740
  }
11393
11741
  const record = params;
11394
11742
  const config = record['config'];
11395
- const redactedConfig = typeof config === 'object' && config !== null && 'kitKey' in config ? {
11396
- ...config,
11397
- kitKey: REDACTED_KIT_KEY
11398
- } : config;
11743
+ const redactedConfig = typeof config === 'object' && config !== null ? redactCredentialFields(config) : config;
11399
11744
  return {
11400
11745
  tokenIn: record['tokenIn'],
11401
11746
  tokenOut: record['tokenOut'],
@@ -11479,6 +11824,41 @@ const optionalChainIdentifierField = chainIdentifierField.optional();
11479
11824
  *
11480
11825
  * @internal
11481
11826
  */ const MAX_RATE_ADDRESSES_PER_REQUEST = 100;
11827
+ /**
11828
+ * Environment prefixes carried by Circle platform API keys.
11829
+ *
11830
+ * A Circle API key is `<ENV>_API_KEY:<keyId>:<keySecret>`, where `<ENV>` is one
11831
+ * of these prefixes.
11832
+ *
11833
+ * @internal
11834
+ */ const API_KEY_ENV_PREFIXES = [
11835
+ 'TEST',
11836
+ 'LIVE',
11837
+ 'SAND',
11838
+ 'SANDBOX',
11839
+ 'SMOK',
11840
+ 'PROD',
11841
+ 'STAG',
11842
+ 'DEV'
11843
+ ];
11844
+ /**
11845
+ * Accepted credential formats for Stablecoin Service authentication.
11846
+ *
11847
+ * Matches a Circle platform API key (`<ENV>_API_KEY:<keyId>:<keySecret>`) and
11848
+ * the legacy kit key (`KIT_KEY:<keyId>:<keySecret>`). API keys are the
11849
+ * recommended credential; kit keys remain accepted as the legacy path.
11850
+ *
11851
+ * @remarks
11852
+ * This is a local pre-flight check, not the authority — the Stablecoin Service
11853
+ * validates the credential and answers 401 when it rejects one. The prefix list
11854
+ * is therefore deliberately permissive: a valid key carrying a prefix this SDK
11855
+ * has not been taught about should reach the service and be judged there rather
11856
+ * than be refused locally, since refusing locally is indistinguishable from an
11857
+ * outage to the caller. Kept as the single source of truth so the pattern is
11858
+ * not restated per call site.
11859
+ *
11860
+ * @internal
11861
+ */ const API_KEY_PATTERN = new RegExp(`^(?:KIT_KEY|(?:${API_KEY_ENV_PREFIXES.join('|')})_API_KEY)` + ':[a-zA-Z0-9._-]+:[a-zA-Z0-9._-]+$');
11482
11862
 
11483
11863
  /**
11484
11864
  * Zod schema for validating stop limits.
@@ -11547,13 +11927,14 @@ const optionalChainIdentifierField = chainIdentifierField.optional();
11547
11927
  /**
11548
11928
  * Zod schema for validating API keys.
11549
11929
  *
11550
- * Validates that the API key is a valid API key format.
11930
+ * Accepts a Circle platform API key (`<ENV>_API_KEY:<keyId>:<keySecret>`) and
11931
+ * the legacy kit key (`KIT_KEY:<keyId>:<keySecret>`).
11551
11932
  *
11552
11933
  * @example
11553
11934
  * ```typescript
11554
11935
  * import { apiKeySchema } from '@core/service-client'
11555
11936
  *
11556
- * const result = apiKeySchema.safeParse('KIT_KEY:e84d2546d4e321b2ff427dc988c89503:f84d2548d4e322b2ff427fc989c87503')
11937
+ * const result = apiKeySchema.safeParse('TEST_API_KEY:e84d2546d4e321b2ff427dc988c89503:f84d2548d4e322b2ff427fc989c87503')
11557
11938
  * if (!result.success) {
11558
11939
  * console.error('Invalid API key format:', result.error.issues)
11559
11940
  * }
@@ -11561,7 +11942,7 @@ const optionalChainIdentifierField = chainIdentifierField.optional();
11561
11942
  */ const apiKeySchema = z.string({
11562
11943
  required_error: 'API key is required',
11563
11944
  invalid_type_error: 'Invalid API key format'
11564
- }).regex(/^KIT_KEY:[a-zA-Z0-9._-]+:[a-zA-Z0-9._-]+$/, 'Invalid API key format');
11945
+ }).regex(API_KEY_PATTERN, 'Invalid API key format');
11565
11946
  /**
11566
11947
  * Zod schema for platform fees configuration.
11567
11948
  *
@@ -12082,21 +12463,55 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
12082
12463
  * ```
12083
12464
  */ const isGetTokenRatesResponse = (obj)=>getTokenRatesResponseSchema.safeParse(obj).success;
12084
12465
  /**
12085
- * Assert that a Stablecoin Service kit key is not being supplied from a browser.
12466
+ * Resolve the credential to authenticate a Stablecoin Service request with.
12467
+ *
12468
+ * `apiKey` is the supported field; `kitKey` is the deprecated alias kept for
12469
+ * existing integrations. When both are supplied `apiKey` wins, so a caller
12470
+ * migrating field-by-field cannot be silently pinned to a stale credential.
12471
+ *
12472
+ * An empty-string value is treated as absent on either field. Without this, the
12473
+ * common `process.env.CIRCLE_API_KEY ?? ''` idiom (which yields `''` when the
12474
+ * variable is unset) would either shadow a working `kitKey` or, on a bare
12475
+ * `kitKey: ''`, reach downstream validation as an invalid credential instead of
12476
+ * falling through to the permissionless path.
12477
+ *
12478
+ * @param source - Object carrying either credential field, or neither.
12479
+ * @returns The credential to use, or `undefined` for the permissionless
12480
+ * (keyless) path.
12481
+ *
12482
+ * @example
12483
+ * ```typescript
12484
+ * import { resolveApiKey } from '@core/service-client'
12485
+ *
12486
+ * resolveApiKey({ apiKey: 'TEST_API_KEY:id:secret' }) // 'TEST_API_KEY:id:secret'
12487
+ * resolveApiKey({ kitKey: 'KIT_KEY:id:secret' }) // 'KIT_KEY:id:secret'
12488
+ * resolveApiKey({ apiKey: '', kitKey: 'KIT_KEY:id:secret' }) // 'KIT_KEY:id:secret'
12489
+ * resolveApiKey({ kitKey: '' }) // undefined
12490
+ * resolveApiKey({}) // undefined
12491
+ * ```
12492
+ */ const resolveApiKey = (source)=>{
12493
+ // Treat an empty-string value as absent on either field so the
12494
+ // `env ?? ''` idiom falls through to the next credential (or permissionless).
12495
+ const normalize = (value)=>value !== undefined && value !== '' ? value : undefined;
12496
+ return normalize(source.apiKey) ?? normalize(source.kitKey);
12497
+ };
12498
+ /**
12499
+ * Assert that a Stablecoin Service credential is not supplied from a browser.
12086
12500
  *
12087
- * The kit key (`KIT_KEY:<id>:<secret>`) is a server-only secret. Every
12088
- * Stablecoin Service request that attaches an `Authorization: Bearer` header
12089
- * funnels through this package, so calling this guard before that header is
12090
- * built prevents the secret from being sent from and thus bundled into — a
12091
- * client application. In Node.js the check is a no-op, preserving the
12092
- * legitimate "hold the kit key on the server, forward the prepared transaction
12093
- * to the client" flow. When no kit key is supplied the permissionless (keyless)
12094
- * client path remains fully allowed.
12501
+ * An API key (`<ENV>_API_KEY:<id>:<secret>`) and a legacy kit key
12502
+ * (`KIT_KEY:<id>:<secret>`) are both server-only secrets. Every Stablecoin
12503
+ * Service request that attaches an `Authorization: Bearer` header funnels
12504
+ * through this package, so calling this guard before that header is built
12505
+ * prevents the secret from being sent from and thus bundled into — a client
12506
+ * application. In Node.js the check is a no-op, preserving the legitimate "hold
12507
+ * the credential on the server, forward the prepared transaction to the client"
12508
+ * flow. When no credential is supplied the permissionless (keyless) client path
12509
+ * remains fully allowed.
12095
12510
  *
12096
- * @param apiKey - The inline kit key for the request, or `undefined` when none
12097
- * was supplied (permissionless mode).
12511
+ * @param apiKey - The inline credential for the request, or `undefined` when
12512
+ * none was supplied (permissionless mode).
12098
12513
  * @returns Nothing.
12099
- * @throws KitError with VALIDATION_FAILED when a kit key is supplied while
12514
+ * @throws KitError with VALIDATION_FAILED when a credential is supplied while
12100
12515
  * running in a browser environment. The secret value is never echoed.
12101
12516
  *
12102
12517
  * @example
@@ -12104,10 +12519,10 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
12104
12519
  * import { assertBrowserSafeApiKey } from '@core/service-client'
12105
12520
  *
12106
12521
  * // Server (Node.js): no-op, request proceeds with the Authorization header.
12107
- * assertBrowserSafeApiKey('KIT_KEY:my-id:my-secret')
12522
+ * assertBrowserSafeApiKey('TEST_API_KEY:my-id:my-secret')
12108
12523
  *
12109
12524
  * // Browser: throws to stop the secret from leaking into the client bundle.
12110
- * assertBrowserSafeApiKey('KIT_KEY:my-id:my-secret')
12525
+ * assertBrowserSafeApiKey('TEST_API_KEY:my-id:my-secret')
12111
12526
  *
12112
12527
  * // Browser, permissionless: allowed.
12113
12528
  * assertBrowserSafeApiKey(undefined)
@@ -12117,7 +12532,7 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
12117
12532
  return;
12118
12533
  }
12119
12534
  if (isBrowserEnvironment()) {
12120
- 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');
12535
+ 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');
12121
12536
  }
12122
12537
  };
12123
12538
 
@@ -12129,7 +12544,8 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
12129
12544
  *
12130
12545
  * @remarks
12131
12546
  * - Input validation leverages Zod schemas to surface actionable KitErrors.
12132
- * - API key format must match `KIT_KEY:<keyId>:<keySecret>`
12547
+ * - API key format must match `<ENV>_API_KEY:<keyId>:<keySecret>`, or the
12548
+ * legacy `KIT_KEY:<keyId>:<keySecret>`
12133
12549
  *
12134
12550
  * @param params - The create transaction request parameters with API key.
12135
12551
  * @returns A promise that resolves to a typed {@link CreateSwapResponse}.
@@ -12158,7 +12574,7 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
12158
12574
  * recipientAddress: '0x050928e1f9086b20539c767c96909663ff7fbdf2',
12159
12575
  * },
12160
12576
  * },
12161
- * apiKey: 'KIT_KEY:example-key:example-secret',
12577
+ * apiKey: 'TEST_API_KEY:example-key:example-secret',
12162
12578
  * })
12163
12579
  *
12164
12580
  * console.log(`Transaction target: ${transaction.transaction.target}`)
@@ -12177,13 +12593,13 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
12177
12593
  const url = new URL('/v1/stablecoinKits/swap', STABLECOIN_SERVICE_BASE_URL).toString();
12178
12594
  // Remove the API key from the request body
12179
12595
  const { apiKey, ...requestBody } = validatedParams;
12180
- // Never let a server-only kit key leave a browser (no-op in Node.js).
12596
+ // Never let a server-only credential leave a browser (no-op in Node.js).
12181
12597
  assertBrowserSafeApiKey(apiKey);
12182
12598
  const effectiveConfig = {
12183
12599
  ...DEFAULT_CONFIG,
12184
12600
  headers: {
12185
12601
  ...DEFAULT_CONFIG.headers,
12186
- // Permissionless mode: no Authorization header when the kit key is absent.
12602
+ // Permissionless mode: no Authorization header when the credential is absent.
12187
12603
  ...apiKey !== undefined && {
12188
12604
  Authorization: `Bearer ${apiKey}`
12189
12605
  }
@@ -12333,7 +12749,7 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
12333
12749
  }
12334
12750
  // Use validated data
12335
12751
  const validatedParams = result.data;
12336
- // Never let a server-only kit key leave a browser (no-op in Node.js).
12752
+ // Never let a server-only credential leave a browser (no-op in Node.js).
12337
12753
  assertBrowserSafeApiKey(validatedParams.apiKey);
12338
12754
  // Build the API URL
12339
12755
  const url = buildQuoteUrl(validatedParams);
@@ -12342,7 +12758,7 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
12342
12758
  ...DEFAULT_CONFIG,
12343
12759
  headers: {
12344
12760
  ...DEFAULT_CONFIG.headers,
12345
- // Permissionless mode: no Authorization header when the kit key is absent.
12761
+ // Permissionless mode: no Authorization header when the credential is absent.
12346
12762
  ...validatedParams.apiKey !== undefined && {
12347
12763
  Authorization: `Bearer ${validatedParams.apiKey}`
12348
12764
  }
@@ -12407,14 +12823,14 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
12407
12823
  toChain: result.data.toChain
12408
12824
  }
12409
12825
  };
12410
- // Never let a server-only kit key leave a browser (no-op in Node.js).
12826
+ // Never let a server-only credential leave a browser (no-op in Node.js).
12411
12827
  assertBrowserSafeApiKey(validatedParams.apiKey);
12412
12828
  const url = buildSwapStatusUrl(validatedParams);
12413
12829
  const effectiveConfig = {
12414
12830
  ...DEFAULT_CONFIG,
12415
12831
  headers: {
12416
12832
  ...DEFAULT_CONFIG.headers,
12417
- // Permissionless mode: no Authorization header when the kit key is absent.
12833
+ // Permissionless mode: no Authorization header when the credential is absent.
12418
12834
  ...validatedParams.apiKey !== undefined && {
12419
12835
  Authorization: `Bearer ${validatedParams.apiKey}`
12420
12836
  }
@@ -12440,7 +12856,7 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
12440
12856
  * const url = buildTokenRatesUrl({
12441
12857
  * chain: 'Ethereum',
12442
12858
  * addresses: ['0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'],
12443
- * apiKey: 'KIT_KEY:key:secret',
12859
+ * apiKey: 'TEST_API_KEY:key:secret',
12444
12860
  * })
12445
12861
  * // => 'https://api.circle.com/v1/stablecoinKits/rates?chain=Ethereum&addresses=...'
12446
12862
  * ```
@@ -12513,14 +12929,14 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
12513
12929
  addresses: result.data.addresses
12514
12930
  }
12515
12931
  };
12516
- // Never let a server-only kit key leave a browser (no-op in Node.js).
12932
+ // Never let a server-only credential leave a browser (no-op in Node.js).
12517
12933
  assertBrowserSafeApiKey(validatedParams.apiKey);
12518
12934
  const url = buildTokenRatesUrl(validatedParams);
12519
12935
  const effectiveConfig = {
12520
12936
  ...DEFAULT_CONFIG,
12521
12937
  headers: {
12522
12938
  ...DEFAULT_CONFIG.headers,
12523
- // Permissionless mode: no Authorization header when the kit key is absent.
12939
+ // Permissionless mode: no Authorization header when the credential is absent.
12524
12940
  ...validatedParams.apiKey !== undefined && {
12525
12941
  Authorization: `Bearer ${validatedParams.apiKey}`
12526
12942
  }
@@ -12958,7 +13374,7 @@ const abiParameterSchema = z.object({
12958
13374
  */ z.object({
12959
13375
  type: z.literal('evm'),
12960
13376
  abi: abiSchema,
12961
- address: evmAddressSchema,
13377
+ address: evmAddressSchema$1,
12962
13378
  functionName: z.string({
12963
13379
  required_error: 'Function name is required',
12964
13380
  invalid_type_error: 'Function name must be a string'
@@ -12995,7 +13411,7 @@ const abiParameterSchema = z.object({
12995
13411
  * }
12996
13412
  * ```
12997
13413
  */ z.object({
12998
- address: evmAddressSchema,
13414
+ address: evmAddressSchema$1,
12999
13415
  value: z.bigint({
13000
13416
  required_error: 'Value is required for native transfers',
13001
13417
  invalid_type_error: 'Value must be a bigint'
@@ -13527,7 +13943,7 @@ z.object({
13527
13943
  signature: evmSignatureSchema,
13528
13944
  tokenInputs: z.array(z.object({
13529
13945
  permitType: z.nativeEnum(PermitType),
13530
- token: evmAddressSchema,
13946
+ token: evmAddressSchema$1,
13531
13947
  amount: z.bigint().refine((value)=>value >= 0n, {
13532
13948
  message: 'amount must be a non-negative bigint'
13533
13949
  }),
@@ -13788,7 +14204,7 @@ enc.encode('used_transfer_spec_hash');
13788
14204
  });
13789
14205
 
13790
14206
  /**
13791
- * Assert that the kit key is valid for swap operations.
14207
+ * Assert that the credential is valid for swap operations.
13792
14208
  *
13793
14209
  * @remarks
13794
14210
  * This validation is called when swap operations are executed, not at construction time.
@@ -13796,34 +14212,35 @@ enc.encode('used_transfer_spec_hash');
13796
14212
  * at usage time rather than construction time.
13797
14213
  *
13798
14214
  * Validates:
13799
- * - Kit key matches the required format (KIT_KEY:id:secret) when provided.
13800
- * An absent or empty kit key is permitted (permissionless mode) — the swap
13801
- * service now treats the key as optional.
14215
+ * - The credential matches an accepted format when provided — a Circle API key
14216
+ * (`<ENV>_API_KEY:id:secret`) or a legacy kit key (`KIT_KEY:id:secret`).
14217
+ * An absent or empty credential is permitted (permissionless mode) — the swap
14218
+ * service treats the credential as optional.
13802
14219
  *
13803
- * @param kitKey - The inline kit key from the swap operation config (optional)
13804
- * @throws KitError with VALIDATION_FAILED if a kit key is provided but does not
13805
- * match the KIT_KEY:<keyId>:<keySecret> format
14220
+ * @param apiKey - The inline credential from the swap operation config (optional)
14221
+ * @throws KitError with VALIDATION_FAILED if a credential is provided but does
14222
+ * not match an accepted format
13806
14223
  *
13807
14224
  * @example
13808
14225
  * ```typescript
13809
- * import { assertKitKey } from './assertKitKey'
14226
+ * import { assertApiKey } from './assertApiKey'
13810
14227
  *
13811
- * const kitKey = 'KIT_KEY:9d1bd085-bad2-4a2b-ae67-5814b85167c9:secretvalue'
14228
+ * const apiKey = 'TEST_API_KEY:9d1bd085-bad2-4a2b-ae67-5814b85167c9:secretvalue'
13812
14229
  *
13813
- * // Validate kit key before use
13814
- * assertKitKey(kitKey)
14230
+ * // Validate the credential before use
14231
+ * assertApiKey(apiKey)
13815
14232
  * ```
13816
- */ function assertKitKey(kitKey) {
13817
- // Permissionless mode: the swap service treats the kit key as optional, so an
13818
- // absent (or empty) key is valid. Only validate the format when a key is
14233
+ */ function assertApiKey(apiKey) {
14234
+ // Permissionless mode: the swap service treats the credential as optional, so
14235
+ // an absent (or empty) value is valid. Only validate the format when one is
13819
14236
  // actually provided.
13820
- if (!kitKey) {
14237
+ if (!apiKey) {
13821
14238
  return;
13822
14239
  }
13823
- const apiKeyResult = apiKeySchema.safeParse(kitKey);
14240
+ const apiKeyResult = apiKeySchema.safeParse(apiKey);
13824
14241
  if (!apiKeyResult.success) {
13825
14242
  const errors = apiKeyResult.error.issues.map((issue)=>issue.message).join(', ');
13826
- 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`);
14243
+ 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`);
13827
14244
  }
13828
14245
  }
13829
14246
 
@@ -14015,7 +14432,7 @@ const TOKEN_REGISTRY$3 = createTokenRegistry();
14015
14432
  }
14016
14433
  // Validate recipient address format matches the chain type
14017
14434
  if (chain.type === 'evm') {
14018
- const result = evmAddressSchema.safeParse(recipientAddress);
14435
+ const result = evmAddressSchema$1.safeParse(recipientAddress);
14019
14436
  if (!result.success) {
14020
14437
  throw createInvalidAddressError(recipientAddress, chain.name, '0x-prefixed 42-character hex string (0x + 40 hex characters)');
14021
14438
  }
@@ -14077,7 +14494,7 @@ function resolveFeePayoutChain(tokenIn, tokenOut, sourceChain, destinationChain)
14077
14494
  * to: '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
14078
14495
  * config: {
14079
14496
  * slippageBps: 300,
14080
- * kitKey: 'KIT_KEY:...:...' // Required inline kit key
14497
+ * apiKey: 'TEST_API_KEY:...:...' // Inline credential (optional)
14081
14498
  * }
14082
14499
  * }
14083
14500
  *
@@ -14115,18 +14532,17 @@ function resolveFeePayoutChain(tokenIn, tokenOut, sourceChain, destinationChain)
14115
14532
  validateResolvedAddress(resolvedTokenInAddress, chain);
14116
14533
  validateResolvedAddress(resolvedTokenOutAddress, destinationChain);
14117
14534
  validateResolvedAddress(to, destinationChain);
14118
- const kitKey = config?.kitKey;
14119
- // Validate the kit key format when one is provided (permissionless otherwise).
14120
- assertKitKey(kitKey);
14535
+ const apiKey = resolveApiKey(config ?? {});
14536
+ // Validate the credential format when one is provided (permissionless
14537
+ // otherwise).
14538
+ assertApiKey(apiKey);
14121
14539
  // Validate custom fee configuration if present
14122
14540
  const customFee = config?.customFee;
14123
14541
  if (customFee !== undefined) {
14124
14542
  const feePayoutChain = resolveFeePayoutChain(tokenIn, tokenOut, chain, destinationChain);
14125
14543
  validateCustomFeeConfig(customFee, feePayoutChain);
14126
14544
  }
14127
- // Build CreateSwapParams for service client
14128
- // Use object spread to conditionally include optional properties
14129
- // Note: Service client expects 'apiKey' field, so we map kitKey → apiKey
14545
+ // Build CreateSwapParams for service client, spreading optional properties.
14130
14546
  const chainName = chain.chain // The API expects the Blockchain enum value format like "World_Chain"
14131
14547
  ;
14132
14548
  const destinationChainName = destinationChain.chain;
@@ -14161,9 +14577,9 @@ function resolveFeePayoutChain(tokenIn, tokenOut, sourceChain, destinationChain)
14161
14577
  }
14162
14578
  }
14163
14579
  },
14164
- // Map kitKey → apiKey for the service client; omitted in permissionless mode.
14165
- ...kitKey ? {
14166
- apiKey: kitKey
14580
+ // Omitted in permissionless mode.
14581
+ ...apiKey ? {
14582
+ apiKey
14167
14583
  } : {}
14168
14584
  };
14169
14585
  }
@@ -16067,9 +16483,9 @@ async function fetchSameChainStatusSnapshot({ isCrossChainSwap, txHash, chain, a
16067
16483
  * ```typescript
16068
16484
  * import { StablecoinServiceSwapProvider } from '@circle-fin/provider-stablecoin-service-swap'
16069
16485
  *
16070
- * // Create provider with developer fee (1 USDC)
16486
+ * // Create provider with developer fee (1 USDC).
16487
+ * // Credentials are supplied per operation via `config.apiKey`, not here.
16071
16488
  * const provider = new StablecoinServiceSwapProvider({
16072
- * kitKey: process.env.STABLECOIN_KIT_API_KEY,
16073
16489
  * customFee: {
16074
16490
  * amount: '1000000', // 1 USDC in base units (6 decimals)
16075
16491
  * recipientAddress: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0'
@@ -16731,9 +17147,7 @@ async function fetchSameChainStatusSnapshot({ isCrossChainSwap, txHash, chain, a
16731
17147
  * import { createAdapterFromPrivateKey } from '@circle-fin/adapter-viem-v2'
16732
17148
  * import { Ethereum } from '@core/chains'
16733
17149
  *
16734
- * const provider = new StablecoinServiceSwapProvider({
16735
- * kitKey: process.env.STABLECOIN_KIT_API_KEY
16736
- * })
17150
+ * const provider = new StablecoinServiceSwapProvider()
16737
17151
  *
16738
17152
  * const adapter = createAdapterFromPrivateKey({
16739
17153
  * privateKey: process.env.PRIVATE_KEY
@@ -17227,7 +17641,7 @@ const optionalSwapChainIdentifierField = swapChainIdentifierField.optional();
17227
17641
  /**
17228
17642
  * Fee recipient address (required).
17229
17643
  * Must be a valid EVM address or Solana address.
17230
- */ recipientAddress: z.string().refine((value)=>evmAddressSchema.safeParse(value).success || solanaAddressSchema.safeParse(value).success, {
17644
+ */ recipientAddress: z.string().refine((value)=>evmAddressSchema$1.safeParse(value).success || solanaAddressSchema.safeParse(value).success, {
17231
17645
  message: 'recipientAddress must be a valid blockchain address: EVM (0x + 40 hex chars) or Solana (base58, 32-44 chars)'
17232
17646
  })
17233
17647
  }).strict();
@@ -17239,7 +17653,8 @@ const optionalSwapChainIdentifierField = swapChainIdentifierField.optional();
17239
17653
  * - slippageBps: Optional positive number for slippage tolerance
17240
17654
  * - stopLimit: Optional decimal string for minimum output
17241
17655
  * - customFee: Optional fee configuration
17242
- * - kitKey: Optional string identifier
17656
+ * - apiKey: Optional credential string
17657
+ * - kitKey: Optional credential string (deprecated alias for apiKey)
17243
17658
  */ const swapConfigSchema = z.object({
17244
17659
  allowanceStrategy: allowanceStrategySchema.optional(),
17245
17660
  slippageBps: z.number().int().min(0).optional(),
@@ -17249,11 +17664,12 @@ const optionalSwapChainIdentifierField = swapChainIdentifierField.optional();
17249
17664
  attributeName: 'stopLimit'
17250
17665
  })(z.string())).optional(),
17251
17666
  customFee: swapCustomFeeSchema.optional(),
17667
+ apiKey: z.string().optional(),
17252
17668
  kitKey: z.string().optional()
17253
17669
  });
17254
17670
  const swapDestinationSchema = z.object({
17255
17671
  chain: optionalSwapChainIdentifierField,
17256
- recipientAddress: z.string().refine((value)=>evmAddressSchema.safeParse(value).success || solanaAddressSchema.safeParse(value).success, {
17672
+ recipientAddress: z.string().refine((value)=>evmAddressSchema$1.safeParse(value).success || solanaAddressSchema.safeParse(value).success, {
17257
17673
  message: 'recipientAddress must be a valid blockchain address: EVM (0x + 40 hex chars) or Solana (base58, 32-44 chars)'
17258
17674
  }).optional()
17259
17675
  }).strict();
@@ -19360,7 +19776,8 @@ const transformAmount = (value, direction, decimals)=>formatUnits(value, decimal
19360
19776
  /**
19361
19777
  * Helper to format the config section of a swap result, transforming fee amounts.
19362
19778
  *
19363
- * Strips sensitive fields like kitKey from the config before returning.
19779
+ * Strips the credential fields (`apiKey` and the deprecated `kitKey`) from the
19780
+ * config before returning, so a result is safe to log or serialize.
19364
19781
  *
19365
19782
  * @param config - The swap config from the provider.
19366
19783
  * @param outputTokenTransform - The amount transformer for output-token-denominated values (fees and amountOut).
@@ -19369,11 +19786,11 @@ const transformAmount = (value, direction, decimals)=>formatUnits(value, decimal
19369
19786
  if (!config) {
19370
19787
  return undefined;
19371
19788
  }
19372
- // Remove kitKey from the config
19373
- const cloneConfig = {
19374
- ...config
19375
- };
19376
- delete cloneConfig.kitKey;
19789
+ // Rebuild the config without any credential field. Filtering entries rather
19790
+ // than deleting them avoids reading the deprecated `kitKey` property
19791
+ // directly, and keeps the credential list in one place.
19792
+ const credentialFields = CREDENTIAL_CONFIG_FIELDS;
19793
+ const cloneConfig = Object.fromEntries(Object.entries(config).filter(([key])=>!credentialFields.includes(key)));
19377
19794
  if (Object.keys(cloneConfig).length === 0) {
19378
19795
  return undefined;
19379
19796
  }
@@ -19574,9 +19991,9 @@ const transformAmount = (value, direction, decimals)=>formatUnits(value, decimal
19574
19991
  try {
19575
19992
  // Step 1: Build quote params directly (no need for buildServiceParams)
19576
19993
  // Use chain.chain (Blockchain enum value like "World_Chain") not chain.name
19577
- // The kit key is optional (permissionless mode); when absent the quote is
19578
- // fetched without an Authorization header.
19579
- const kitKey = params.config?.kitKey;
19994
+ // The credential is optional (permissionless mode); when absent the quote
19995
+ // is fetched without an Authorization header.
19996
+ const apiKey = resolveApiKey(params.config ?? {});
19580
19997
  // Resolve token aliases to addresses for the quote API
19581
19998
  // The quote endpoint requires resolved addresses, not aliases like 'USDC'
19582
19999
  const chain = params.from.chain;
@@ -19601,8 +20018,8 @@ const transformAmount = (value, direction, decimals)=>formatUnits(value, decimal
19601
20018
  ...params.config?.slippageBps !== undefined && {
19602
20019
  slippageBps: params.config.slippageBps
19603
20020
  },
19604
- ...kitKey ? {
19605
- apiKey: kitKey
20021
+ ...apiKey ? {
20022
+ apiKey
19606
20023
  } : {}
19607
20024
  };
19608
20025
  // Step 2: Get quote from service
@@ -20006,7 +20423,7 @@ const sleep$1 = async (ms)=>new Promise((resolve)=>setTimeout(resolve, ms));
20006
20423
  * the service returns `receivingTokenDecimals`. When decimals are missing
20007
20424
  * the field is omitted entirely (never raw base units).
20008
20425
  *
20009
- * @param params - `txHash`, `chainIn`, optional `chainOut`, and `kitKey`.
20426
+ * @param params - `txHash`, `chainIn`, optional `chainOut`, and `apiKey`.
20010
20427
  * @returns A single snapshot of the swap's status.
20011
20428
  * @throws \{KitError\} If `chainIn` or `chainOut` is malformed.
20012
20429
  *
@@ -20022,7 +20439,7 @@ const sleep$1 = async (ms)=>new Promise((resolve)=>setTimeout(resolve, ms));
20022
20439
  * txHash: result.txHash,
20023
20440
  * chainIn: result.chainIn,
20024
20441
  * chainOut: result.chainOut,
20025
- * kitKey: process.env.KIT_KEY ?? '',
20442
+ * apiKey: process.env.CIRCLE_API_KEY,
20026
20443
  * })
20027
20444
  * while (status.progress.status === 'PENDING') {
20028
20445
  * await new Promise((r) => setTimeout(r, 3_000))
@@ -20030,7 +20447,7 @@ const sleep$1 = async (ms)=>new Promise((resolve)=>setTimeout(resolve, ms));
20030
20447
  * txHash: result.txHash,
20031
20448
  * chainIn: result.chainIn,
20032
20449
  * chainOut: result.chainOut,
20033
- * kitKey: process.env.KIT_KEY ?? '',
20450
+ * apiKey: process.env.CIRCLE_API_KEY,
20034
20451
  * })
20035
20452
  * }
20036
20453
  *
@@ -20048,14 +20465,15 @@ const sleep$1 = async (ms)=>new Promise((resolve)=>setTimeout(resolve, ms));
20048
20465
  const chainIn = normalizeChain(params.chainIn, 'chainIn');
20049
20466
  const chainOut = params.chainOut === undefined ? undefined : normalizeChain(params.chainOut, 'chainOut');
20050
20467
  const isCrossChain = chainOut !== undefined && chainOut !== chainIn;
20468
+ const apiKey = resolveApiKey(params);
20051
20469
  const request = {
20052
20470
  txHash: params.txHash,
20053
20471
  chain: chainIn,
20054
20472
  ...isCrossChain && {
20055
20473
  toChain: chainOut
20056
20474
  },
20057
- ...params.kitKey ? {
20058
- apiKey: params.kitKey
20475
+ ...apiKey ? {
20476
+ apiKey
20059
20477
  } : {}
20060
20478
  };
20061
20479
  let raw = await getSwapStatus$1(request);
@@ -20134,9 +20552,9 @@ const isResultShape = (params)=>'result' in params;
20134
20552
  *
20135
20553
  * Two parameter shapes are accepted:
20136
20554
  *
20137
- * - Pass the {@link SwapResult} directly: `{ result, kitKey, ... }`.
20555
+ * - Pass the {@link SwapResult} directly: `{ result, apiKey, ... }`.
20138
20556
  * Cleanest when chaining off `kit.swap()`.
20139
- * - Pass discrete fields: `{ txHash, chainIn, chainOut?, kitKey, ... }`.
20557
+ * - Pass discrete fields: `{ txHash, chainIn, chainOut?, apiKey, ... }`.
20140
20558
  * Useful for resuming an in-flight swap from a persisted record.
20141
20559
  *
20142
20560
  * @param params - Wait configuration. See {@link WaitForSwapParams}.
@@ -20156,7 +20574,7 @@ const isResultShape = (params)=>'result' in params;
20156
20574
  *
20157
20575
  * const final = await waitForSwap({
20158
20576
  * result,
20159
- * kitKey: process.env.KIT_KEY ?? '',
20577
+ * apiKey: process.env.CIRCLE_API_KEY,
20160
20578
  * onProgress: (snapshot) => {
20161
20579
  * console.log(snapshot.progress.substatus ?? snapshot.progress.status)
20162
20580
  * },
@@ -20174,7 +20592,7 @@ const isResultShape = (params)=>'result' in params;
20174
20592
  * txHash: '0x…',
20175
20593
  * chainIn: 'Ethereum',
20176
20594
  * chainOut: 'Base',
20177
- * kitKey: process.env.KIT_KEY ?? '',
20595
+ * apiKey: process.env.CIRCLE_API_KEY,
20178
20596
  * })
20179
20597
  * ```
20180
20598
  */ async function waitForSwap(params) {
@@ -20190,14 +20608,15 @@ const isResultShape = (params)=>'result' in params;
20190
20608
  const chainOut = isResultShape(params) ? params.result.chainOut : params.chainOut;
20191
20609
  // Delegate parameter validation (txHash, chainIn, chainOut) to
20192
20610
  // getSwapStatus so the same rules apply to both helpers.
20611
+ const apiKey = resolveApiKey(params);
20193
20612
  const statusParams = {
20194
20613
  txHash,
20195
20614
  chainIn,
20196
20615
  ...chainOut !== undefined && {
20197
20616
  chainOut
20198
20617
  },
20199
- ...params.kitKey ? {
20200
- kitKey: params.kitKey
20618
+ ...apiKey ? {
20619
+ apiKey
20201
20620
  } : {}
20202
20621
  };
20203
20622
  const deadline = Date.now() + timeoutMs;
@@ -20321,7 +20740,7 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
20321
20740
  *
20322
20741
  * @param context - SwapKit context (provides the `TokenRegistry` used for
20323
20742
  * symbol resolution).
20324
- * @param params - `chain`, optional `tokens`, and `kitKey`.
20743
+ * @param params - `chain`, optional `tokens`, and `apiKey`.
20325
20744
  * @returns A nested map of `[chain][address] → { priceUSD, fetchedAt }`.
20326
20745
  * @throws \{KitError\} If `chain` cannot be resolved, `tokens` exceeds 100
20327
20746
  * entries, or any entry is neither a registered symbol nor a
@@ -20336,7 +20755,7 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
20336
20755
  * const { rates } = await getTokenRates(context, {
20337
20756
  * chain: Blockchain.Ethereum,
20338
20757
  * tokens: ['USDC', 'EURC', 'NATIVE'],
20339
- * kitKey: process.env.KIT_KEY ?? '',
20758
+ * apiKey: process.env.CIRCLE_API_KEY,
20340
20759
  * })
20341
20760
  *
20342
20761
  * const usdc = rates['Ethereum']?.['0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48']
@@ -20357,10 +20776,11 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
20357
20776
  // valid Blockchain enum string, so `getChainByEnum` is guaranteed to resolve.
20358
20777
  const chainDef = getChainByEnum(chain);
20359
20778
  const resolvedAddresses = params.tokens?.map((entry, index)=>resolveTokenEntry(entry, index, chain, chainDef, context));
20779
+ const apiKey = resolveApiKey(params);
20360
20780
  return getTokenRates$1({
20361
20781
  chain,
20362
- ...params.kitKey ? {
20363
- apiKey: params.kitKey
20782
+ ...apiKey ? {
20783
+ apiKey
20364
20784
  } : {},
20365
20785
  ...resolvedAddresses !== undefined && {
20366
20786
  addresses: resolvedAddresses
@@ -20991,7 +21411,7 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
20991
21411
  * is formatted as a human-readable decimal string; when decimals are
20992
21412
  * missing the field is omitted entirely (never raw base units).
20993
21413
  *
20994
- * @param params - `txHash`, `chainIn`, optional `chainOut`, and `kitKey`.
21414
+ * @param params - `txHash`, `chainIn`, optional `chainOut`, and `apiKey`.
20995
21415
  * @returns A snapshot of the swap's status at the time of the call.
20996
21416
  * @throws \{KitError\} If `chainIn` or `chainOut` is malformed.
20997
21417
  *
@@ -21004,7 +21424,7 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
21004
21424
  * txHash: result.txHash,
21005
21425
  * chainIn: result.chainIn,
21006
21426
  * chainOut: result.chainOut,
21007
- * kitKey: process.env.KIT_KEY ?? '',
21427
+ * apiKey: process.env.CIRCLE_API_KEY,
21008
21428
  * })
21009
21429
  * console.log(status.progress.status, status.progress.substatus)
21010
21430
  * ```
@@ -21016,7 +21436,7 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
21016
21436
  * txHash: result.txHash,
21017
21437
  * chainIn: result.chainIn,
21018
21438
  * chainOut: result.chainOut,
21019
- * kitKey: process.env.KIT_KEY ?? '',
21439
+ * apiKey: process.env.CIRCLE_API_KEY,
21020
21440
  * })
21021
21441
  * while (status.progress.status === 'PENDING') {
21022
21442
  * await new Promise((r) => setTimeout(r, 3_000))
@@ -21024,7 +21444,7 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
21024
21444
  * txHash: result.txHash,
21025
21445
  * chainIn: result.chainIn,
21026
21446
  * chainOut: result.chainOut,
21027
- * kitKey: process.env.KIT_KEY ?? '',
21447
+ * apiKey: process.env.CIRCLE_API_KEY,
21028
21448
  * })
21029
21449
  * }
21030
21450
  *
@@ -21055,7 +21475,7 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
21055
21475
  * 5xx, etc.) surface unchanged so the caller can decide whether to
21056
21476
  * retry the whole wait. The wait itself only emits a timeout error.
21057
21477
  *
21058
- * @param params - Wait configuration including identifiers, kit key,
21478
+ * @param params - Wait configuration including identifiers, API key,
21059
21479
  * optional `timeoutMs`, and an optional `onProgress`
21060
21480
  * callback fired on every successful poll.
21061
21481
  * @returns The first terminal {@link SwapStatusResult} observed.
@@ -21074,7 +21494,7 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
21074
21494
  *
21075
21495
  * const final = await kit.waitForSwap({
21076
21496
  * result,
21077
- * kitKey: process.env.KIT_KEY ?? '',
21497
+ * apiKey: process.env.CIRCLE_API_KEY,
21078
21498
  * onProgress: (snap) => console.log(snap.progress.substatus ?? snap.progress.status),
21079
21499
  * })
21080
21500
  *
@@ -21092,7 +21512,7 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
21092
21512
  * txHash: persisted.txHash,
21093
21513
  * chainIn: persisted.chainIn,
21094
21514
  * chainOut: persisted.chainOut,
21095
- * kitKey: process.env.KIT_KEY ?? '',
21515
+ * apiKey: process.env.CIRCLE_API_KEY,
21096
21516
  * })
21097
21517
  * ```
21098
21518
  */ async waitForSwap(params) {
@@ -21126,7 +21546,7 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
21126
21546
  * not cache a rate for the native asset on that chain, the response simply
21127
21547
  * omits the address.
21128
21548
  *
21129
- * @param params - `chain`, optional `tokens`, and `kitKey`.
21549
+ * @param params - `chain`, optional `tokens`, and `apiKey`.
21130
21550
  * @returns A nested map of `[chain][address] → { priceUSD, fetchedAt }`.
21131
21551
  * @throws \{KitError\} If `chain` is malformed, `tokens` exceeds 100
21132
21552
  * entries, or any entry is neither a registered symbol nor a
@@ -21138,7 +21558,7 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
21138
21558
  * const { rates } = await kit.getTokenRates({
21139
21559
  * chain: 'Ethereum',
21140
21560
  * tokens: ['USDC', 'EURC', 'NATIVE'],
21141
- * kitKey: process.env.KIT_KEY ?? '',
21561
+ * apiKey: process.env.CIRCLE_API_KEY,
21142
21562
  * })
21143
21563
  *
21144
21564
  * const usdc = rates['Ethereum']?.['0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48']
@@ -21152,7 +21572,7 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
21152
21572
  * chain: 'Ethereum',
21153
21573
  * // 'USDC' (registry symbol) + raw USDT address
21154
21574
  * tokens: ['USDC', '0xdAC17F958D2ee523a2206206994597C13D831ec7'],
21155
- * kitKey: process.env.KIT_KEY ?? '',
21575
+ * apiKey: process.env.CIRCLE_API_KEY,
21156
21576
  * })
21157
21577
  * ```
21158
21578
  *
@@ -21161,7 +21581,7 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
21161
21581
  * ```typescript
21162
21582
  * const { rates } = await kit.getTokenRates({
21163
21583
  * chain: 'Base',
21164
- * kitKey: process.env.KIT_KEY ?? '',
21584
+ * apiKey: process.env.CIRCLE_API_KEY,
21165
21585
  * })
21166
21586
  * ```
21167
21587
  */ async getTokenRates(params) {
@@ -21416,7 +21836,7 @@ registerKit(`${pkg$1.name}/${pkg$1.version}`);
21416
21836
  };
21417
21837
 
21418
21838
  var name = "@circle-fin/earn-kit";
21419
- var version = "1.5.1";
21839
+ var version = "1.6.0";
21420
21840
  var pkg = {
21421
21841
  name: name,
21422
21842
  version: version};
@@ -21488,7 +21908,7 @@ function isNonNegativeBigIntLike(value) {
21488
21908
  }
21489
21909
  }
21490
21910
  const hexSignatureSchema = evmSignatureSchema;
21491
- const hexAddressSchema = evmAddressSchema;
21911
+ const hexAddressSchema = evmAddressSchema$1;
21492
21912
  // '0x' prefix + 32 bytes * 2 hex chars.
21493
21913
  const BYTES32_HEX_LENGTH = 66;
21494
21914
  const bridgeFeeTokenSchema = hexAddressSchema;
@@ -22393,7 +22813,7 @@ createTokenRegistry();
22393
22813
  * fast instead of round-tripping to the service.
22394
22814
  *
22395
22815
  * @internal
22396
- */ 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');
22816
+ */ 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');
22397
22817
  /**
22398
22818
  * Schema for the adapter context within earn operations.
22399
22819
  *
@@ -22425,19 +22845,39 @@ const sourceAdapterContextSchema = z.object({
22425
22845
  /**
22426
22846
  * Schema for the EarnConfig options.
22427
22847
  *
22428
- * Validate the optional Kit Key field using the standard `apiKeySchema`
22429
- * format (`KIT_KEY:<keyId>:<keySecret>`). When omitted, the SDK
22430
- * operates in permissionless mode. `baseUrl` overrides the Earn Service
22431
- * endpoint (e.g. staging); `batchTransactions: false` opts out of atomic
22432
- * batched execution. Both are forwarded to the provider, so this `.strict()`
22433
- * schema must accept them or a valid config object is rejected.
22848
+ * Validate the *resolved* credential using the standard `apiKeySchema` format
22849
+ * (`<ENV>_API_KEY:<keyId>:<keySecret>`, or a legacy
22850
+ * `KIT_KEY:<keyId>:<keySecret>`). `apiKey` takes precedence over the deprecated
22851
+ * `kitKey`, so a malformed `kitKey` that is being ignored must not fail a config
22852
+ * that supplies a valid `apiKey` (and vice versa) only the credential that
22853
+ * would actually be sent is format-checked. When neither is supplied the SDK
22854
+ * operates in permissionless mode. `baseUrl` overrides the Earn Service endpoint
22855
+ * (e.g. staging); `batchTransactions: false` opts out of atomic batched
22856
+ * execution. All are forwarded to the provider, so this `.strict()` schema must
22857
+ * accept them or a valid config object is rejected.
22434
22858
  *
22435
22859
  * @internal
22436
22860
  */ const earnConfigSchema = z.object({
22437
- kitKey: apiKeySchema.optional(),
22861
+ apiKey: z.string().optional(),
22862
+ kitKey: z.string().optional(),
22438
22863
  baseUrl: z.string().optional(),
22439
22864
  batchTransactions: z.boolean().optional()
22440
- }).strict();
22865
+ }).strict().superRefine((config, ctx)=>{
22866
+ const credential = resolveApiKey(config);
22867
+ if (credential === undefined) {
22868
+ return;
22869
+ }
22870
+ const result = apiKeySchema.safeParse(credential);
22871
+ if (!result.success) {
22872
+ ctx.addIssue({
22873
+ code: z.ZodIssueCode.custom,
22874
+ path: [
22875
+ credential === config.apiKey ? 'apiKey' : 'kitKey'
22876
+ ],
22877
+ message: result.error.issues[0]?.message ?? 'Invalid API key format'
22878
+ });
22879
+ }
22880
+ });
22441
22881
  /**
22442
22882
  * Canonical decimal form: a leading digit with no leading zeros (a single
22443
22883
  * '0' is only allowed immediately before the decimal point). Rejects the
@@ -22509,7 +22949,7 @@ const sourceAdapterContextSchema = z.object({
22509
22949
  * currently supports EVM vault addresses on Arc Testnet.
22510
22950
  *
22511
22951
  * @internal
22512
- */ const vaultAddressSchema = evmAddressSchema.refine(isValidEip55Checksum, 'address has an invalid EIP-55 checksum');
22952
+ */ const vaultAddressSchema = evmAddressSchema$1.refine(isValidEip55Checksum, 'address has an invalid EIP-55 checksum');
22513
22953
  /**
22514
22954
  * Validation schema for VaultQuery.
22515
22955
  *
@@ -22784,7 +23224,7 @@ const sameChainGetDepositQuoteParamsSchema = z.object({
22784
23224
  const crossChainGetDepositQuoteParamsSchema = z.object({
22785
23225
  from: sourceAdapterContextSchema,
22786
23226
  chain: earnBridgeDestinationChainIdentifierSchema,
22787
- address: evmAddressSchema,
23227
+ address: evmAddressSchema$1,
22788
23228
  vaultAddress: vaultAddressSchema,
22789
23229
  amount: amountSchema,
22790
23230
  transferSpeed: z.enum([