@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/CHANGELOG.md +59 -0
- package/README.md +31 -12
- package/bridge.cjs +2214 -186
- package/bridge.d.cts +86 -17
- package/bridge.d.mts +86 -17
- package/bridge.d.ts +86 -17
- package/bridge.mjs +2216 -188
- package/chains.cjs +134 -0
- package/chains.d.cts +126 -1
- package/chains.d.mts +126 -1
- package/chains.d.ts +126 -1
- package/chains.mjs +133 -1
- package/context.d.cts +86 -17
- package/context.d.mts +86 -17
- package/context.d.ts +86 -17
- package/earn.cjs +467 -48
- package/earn.d.cts +86 -17
- package/earn.d.mts +86 -17
- package/earn.d.ts +86 -17
- package/earn.mjs +467 -48
- package/estimateBridge.cjs +2214 -186
- package/estimateBridge.d.cts +196 -18
- package/estimateBridge.d.mts +196 -18
- package/estimateBridge.d.ts +196 -18
- package/estimateBridge.mjs +2216 -188
- package/estimateSwap.cjs +571 -131
- package/estimateSwap.d.cts +86 -17
- package/estimateSwap.d.mts +86 -17
- package/estimateSwap.d.ts +86 -17
- package/estimateSwap.mjs +571 -131
- package/index.cjs +2101 -434
- package/index.d.cts +949 -147
- package/index.d.mts +949 -147
- package/index.d.ts +949 -147
- package/index.mjs +2103 -436
- package/package.json +6 -6
- package/swap.cjs +571 -131
- package/swap.d.cts +93 -18
- package/swap.d.mts +93 -18
- package/swap.d.ts +93 -18
- package/swap.mjs +571 -131
- package/unifiedBalance.cjs +384 -67
- package/unifiedBalance.d.cts +76 -2
- package/unifiedBalance.d.mts +76 -2
- package/unifiedBalance.d.ts +76 -2
- package/unifiedBalance.mjs +384 -67
package/unifiedBalance.cjs
CHANGED
|
@@ -2303,6 +2303,8 @@ class KitError extends Error {
|
|
|
2303
2303
|
Blockchain["Optimism_Sepolia"] = "Optimism_Sepolia";
|
|
2304
2304
|
Blockchain["Pharos"] = "Pharos";
|
|
2305
2305
|
Blockchain["Pharos_Testnet"] = "Pharos_Testnet";
|
|
2306
|
+
Blockchain["Plasma"] = "Plasma";
|
|
2307
|
+
Blockchain["Plasma_Testnet"] = "Plasma_Testnet";
|
|
2306
2308
|
Blockchain["Polkadot_Asset_Hub"] = "Polkadot_Asset_Hub";
|
|
2307
2309
|
Blockchain["Polkadot_Westmint"] = "Polkadot_Westmint";
|
|
2308
2310
|
Blockchain["Plume"] = "Plume";
|
|
@@ -2372,6 +2374,7 @@ var BridgeChain;
|
|
|
2372
2374
|
BridgeChain["Morph"] = "Morph";
|
|
2373
2375
|
BridgeChain["Optimism"] = "Optimism";
|
|
2374
2376
|
BridgeChain["Pharos"] = "Pharos";
|
|
2377
|
+
BridgeChain["Plasma"] = "Plasma";
|
|
2375
2378
|
BridgeChain["Plume"] = "Plume";
|
|
2376
2379
|
BridgeChain["Polygon"] = "Polygon";
|
|
2377
2380
|
BridgeChain["Sei"] = "Sei";
|
|
@@ -2398,6 +2401,7 @@ var BridgeChain;
|
|
|
2398
2401
|
BridgeChain["Morph_Testnet"] = "Morph_Testnet";
|
|
2399
2402
|
BridgeChain["Optimism_Sepolia"] = "Optimism_Sepolia";
|
|
2400
2403
|
BridgeChain["Pharos_Testnet"] = "Pharos_Testnet";
|
|
2404
|
+
BridgeChain["Plasma_Testnet"] = "Plasma_Testnet";
|
|
2401
2405
|
BridgeChain["Plume_Testnet"] = "Plume_Testnet";
|
|
2402
2406
|
BridgeChain["Polygon_Amoy_Testnet"] = "Polygon_Amoy_Testnet";
|
|
2403
2407
|
BridgeChain["Sei_Testnet"] = "Sei_Testnet";
|
|
@@ -2844,6 +2848,8 @@ var EarnChain;
|
|
|
2844
2848
|
* This program handles minting operations for Gateway transactions
|
|
2845
2849
|
* on Solana devnet.
|
|
2846
2850
|
*/ const GATEWAY_MINTER_SOLANA_DEVNET = 'GATEmKK2ECL1brEngQZWCgMWPbvrEYqsV6u29dAaHavr';
|
|
2851
|
+
/** TokenMessengerWithFees address shared by enabled EVM mainnet sources. */ const TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET = '0x71f54F818671cD0D7ea140Da213e5C8b5C92a408';
|
|
2852
|
+
/** TokenMessengerWithFees address shared by enabled EVM testnet sources. */ const TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET = '0x8745D906D67C346E5eb1aEEED38Eb87F34DF0C0A';
|
|
2847
2853
|
/**
|
|
2848
2854
|
* Circle's fee recipient address for EVM chains.
|
|
2849
2855
|
*
|
|
@@ -2891,6 +2897,7 @@ var EarnChain;
|
|
|
2891
2897
|
v2: {
|
|
2892
2898
|
type: 'split',
|
|
2893
2899
|
tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
|
|
2900
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
|
|
2894
2901
|
messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
|
|
2895
2902
|
confirmations: 1,
|
|
2896
2903
|
fastConfirmations: 1
|
|
@@ -2958,6 +2965,7 @@ var EarnChain;
|
|
|
2958
2965
|
v2: {
|
|
2959
2966
|
type: 'split',
|
|
2960
2967
|
tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
|
|
2968
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
|
|
2961
2969
|
messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
|
|
2962
2970
|
confirmations: 65,
|
|
2963
2971
|
fastConfirmations: 1
|
|
@@ -3022,6 +3030,7 @@ var EarnChain;
|
|
|
3022
3030
|
v2: {
|
|
3023
3031
|
type: 'split',
|
|
3024
3032
|
tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
|
|
3033
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
|
|
3025
3034
|
messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
|
|
3026
3035
|
confirmations: 65,
|
|
3027
3036
|
fastConfirmations: 1
|
|
@@ -3086,6 +3095,7 @@ var EarnChain;
|
|
|
3086
3095
|
v2: {
|
|
3087
3096
|
type: 'split',
|
|
3088
3097
|
tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
|
|
3098
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
|
|
3089
3099
|
messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
|
|
3090
3100
|
confirmations: 1,
|
|
3091
3101
|
fastConfirmations: 1
|
|
@@ -3147,6 +3157,7 @@ var EarnChain;
|
|
|
3147
3157
|
v2: {
|
|
3148
3158
|
type: 'split',
|
|
3149
3159
|
tokenMessenger: '0x8fe6b999dc680ccfdd5bf7eb0974218be2542daa',
|
|
3160
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
|
|
3150
3161
|
messageTransmitter: '0xe737e5cebeeba77efe34d4aa090756590b1ce275',
|
|
3151
3162
|
confirmations: 1,
|
|
3152
3163
|
fastConfirmations: 1
|
|
@@ -3214,6 +3225,7 @@ var EarnChain;
|
|
|
3214
3225
|
v2: {
|
|
3215
3226
|
type: 'split',
|
|
3216
3227
|
tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
|
|
3228
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
|
|
3217
3229
|
messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
|
|
3218
3230
|
confirmations: 65,
|
|
3219
3231
|
fastConfirmations: 1
|
|
@@ -3278,6 +3290,7 @@ var EarnChain;
|
|
|
3278
3290
|
v2: {
|
|
3279
3291
|
type: 'split',
|
|
3280
3292
|
tokenMessenger: '0x8fe6b999dc680ccfdd5bf7eb0974218be2542daa',
|
|
3293
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
|
|
3281
3294
|
messageTransmitter: '0xe737e5cebeeba77efe34d4aa090756590b1ce275',
|
|
3282
3295
|
confirmations: 65,
|
|
3283
3296
|
fastConfirmations: 1
|
|
@@ -3388,6 +3401,7 @@ var EarnChain;
|
|
|
3388
3401
|
v2: {
|
|
3389
3402
|
type: 'split',
|
|
3390
3403
|
tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
|
|
3404
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
|
|
3391
3405
|
messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
|
|
3392
3406
|
confirmations: 65,
|
|
3393
3407
|
fastConfirmations: 1
|
|
@@ -3432,6 +3446,7 @@ var EarnChain;
|
|
|
3432
3446
|
v2: {
|
|
3433
3447
|
type: 'split',
|
|
3434
3448
|
tokenMessenger: '0x8fe6b999dc680ccfdd5bf7eb0974218be2542daa',
|
|
3449
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
|
|
3435
3450
|
messageTransmitter: '0xe737e5cebeeba77efe34d4aa090756590b1ce275',
|
|
3436
3451
|
confirmations: 65,
|
|
3437
3452
|
fastConfirmations: 1
|
|
@@ -3663,6 +3678,7 @@ var EarnChain;
|
|
|
3663
3678
|
v2: {
|
|
3664
3679
|
type: 'split',
|
|
3665
3680
|
tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
|
|
3681
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
|
|
3666
3682
|
messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
|
|
3667
3683
|
confirmations: 65,
|
|
3668
3684
|
fastConfirmations: 2
|
|
@@ -3727,6 +3743,7 @@ var EarnChain;
|
|
|
3727
3743
|
v2: {
|
|
3728
3744
|
type: 'split',
|
|
3729
3745
|
tokenMessenger: '0x8fe6b999dc680ccfdd5bf7eb0974218be2542daa',
|
|
3746
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
|
|
3730
3747
|
messageTransmitter: '0xe737e5cebeeba77efe34d4aa090756590b1ce275',
|
|
3731
3748
|
confirmations: 65,
|
|
3732
3749
|
fastConfirmations: 2
|
|
@@ -3837,6 +3854,7 @@ var EarnChain;
|
|
|
3837
3854
|
v2: {
|
|
3838
3855
|
type: 'split',
|
|
3839
3856
|
tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
|
|
3857
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
|
|
3840
3858
|
messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
|
|
3841
3859
|
confirmations: 1,
|
|
3842
3860
|
fastConfirmations: 1
|
|
@@ -3896,6 +3914,7 @@ var EarnChain;
|
|
|
3896
3914
|
v2: {
|
|
3897
3915
|
type: 'split',
|
|
3898
3916
|
tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
|
|
3917
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
|
|
3899
3918
|
messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
|
|
3900
3919
|
confirmations: 1,
|
|
3901
3920
|
fastConfirmations: 1
|
|
@@ -4050,6 +4069,7 @@ var EarnChain;
|
|
|
4050
4069
|
v2: {
|
|
4051
4070
|
type: 'split',
|
|
4052
4071
|
tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
|
|
4072
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
|
|
4053
4073
|
messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
|
|
4054
4074
|
confirmations: 65,
|
|
4055
4075
|
fastConfirmations: 1
|
|
@@ -4097,6 +4117,7 @@ var EarnChain;
|
|
|
4097
4117
|
v2: {
|
|
4098
4118
|
type: 'split',
|
|
4099
4119
|
tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
|
|
4120
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
|
|
4100
4121
|
messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
|
|
4101
4122
|
confirmations: 65,
|
|
4102
4123
|
fastConfirmations: 1
|
|
@@ -4141,6 +4162,7 @@ var EarnChain;
|
|
|
4141
4162
|
v2: {
|
|
4142
4163
|
type: 'split',
|
|
4143
4164
|
tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
|
|
4165
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
|
|
4144
4166
|
messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
|
|
4145
4167
|
confirmations: 1,
|
|
4146
4168
|
fastConfirmations: 1
|
|
@@ -4186,6 +4208,7 @@ var EarnChain;
|
|
|
4186
4208
|
v2: {
|
|
4187
4209
|
type: 'split',
|
|
4188
4210
|
tokenMessenger: '0x8fe6b999dc680ccfdd5bf7eb0974218be2542daa',
|
|
4211
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
|
|
4189
4212
|
messageTransmitter: '0xe737e5cebeeba77efe34d4aa090756590b1ce275',
|
|
4190
4213
|
confirmations: 1,
|
|
4191
4214
|
fastConfirmations: 1
|
|
@@ -4232,6 +4255,7 @@ var EarnChain;
|
|
|
4232
4255
|
v2: {
|
|
4233
4256
|
type: 'split',
|
|
4234
4257
|
tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
|
|
4258
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
|
|
4235
4259
|
messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
|
|
4236
4260
|
confirmations: 1,
|
|
4237
4261
|
fastConfirmations: 1
|
|
@@ -4545,6 +4569,7 @@ var EarnChain;
|
|
|
4545
4569
|
v2: {
|
|
4546
4570
|
type: 'split',
|
|
4547
4571
|
tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
|
|
4572
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
|
|
4548
4573
|
messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
|
|
4549
4574
|
confirmations: 65,
|
|
4550
4575
|
fastConfirmations: 1
|
|
@@ -4609,6 +4634,7 @@ var EarnChain;
|
|
|
4609
4634
|
v2: {
|
|
4610
4635
|
type: 'split',
|
|
4611
4636
|
tokenMessenger: '0x8fe6b999dc680ccfdd5bf7eb0974218be2542daa',
|
|
4637
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
|
|
4612
4638
|
messageTransmitter: '0xe737e5cebeeba77efe34d4aa090756590b1ce275',
|
|
4613
4639
|
confirmations: 65,
|
|
4614
4640
|
fastConfirmations: 1
|
|
@@ -4729,6 +4755,98 @@ var EarnChain;
|
|
|
4729
4755
|
}
|
|
4730
4756
|
});
|
|
4731
4757
|
|
|
4758
|
+
/**
|
|
4759
|
+
* Plasma Mainnet chain definition
|
|
4760
|
+
* @remarks
|
|
4761
|
+
* This represents the official production network for the Plasma blockchain.
|
|
4762
|
+
* Plasma is an EVM-equivalent Layer 1 blockchain purpose-built for global
|
|
4763
|
+
* stablecoin payments, with deterministic BFT finality (PlasmaBFT/Fast-HotStuff).
|
|
4764
|
+
*/ const Plasma = defineChain({
|
|
4765
|
+
type: 'evm',
|
|
4766
|
+
chain: Blockchain.Plasma,
|
|
4767
|
+
name: 'Plasma',
|
|
4768
|
+
title: 'Plasma Mainnet',
|
|
4769
|
+
nativeCurrency: {
|
|
4770
|
+
name: 'Plasma',
|
|
4771
|
+
symbol: 'XPL',
|
|
4772
|
+
decimals: 18
|
|
4773
|
+
},
|
|
4774
|
+
chainId: 9745,
|
|
4775
|
+
isTestnet: false,
|
|
4776
|
+
explorerUrl: 'https://plasmascan.to/tx/{hash}',
|
|
4777
|
+
rpcEndpoints: [
|
|
4778
|
+
'https://rpc.plasma.to'
|
|
4779
|
+
],
|
|
4780
|
+
eurcAddress: '0x3EE196E78d4d4248b849B8E1C7F44C5457FAFD2C',
|
|
4781
|
+
usdcAddress: '0x2d661C89D812261039AF9764eceaAee884f5F67F',
|
|
4782
|
+
usdtAddress: null,
|
|
4783
|
+
cctp: {
|
|
4784
|
+
domain: 33,
|
|
4785
|
+
contracts: {
|
|
4786
|
+
v2: {
|
|
4787
|
+
type: 'split',
|
|
4788
|
+
tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
|
|
4789
|
+
messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
|
|
4790
|
+
confirmations: 3,
|
|
4791
|
+
fastConfirmations: 1
|
|
4792
|
+
}
|
|
4793
|
+
},
|
|
4794
|
+
forwarderSupported: {
|
|
4795
|
+
source: false,
|
|
4796
|
+
destination: false
|
|
4797
|
+
}
|
|
4798
|
+
},
|
|
4799
|
+
kitContracts: {
|
|
4800
|
+
bridge: BRIDGE_CONTRACT_EVM_MAINNET
|
|
4801
|
+
}
|
|
4802
|
+
});
|
|
4803
|
+
|
|
4804
|
+
/**
|
|
4805
|
+
* Plasma Testnet chain definition
|
|
4806
|
+
* @remarks
|
|
4807
|
+
* This represents the official test network for the Plasma blockchain.
|
|
4808
|
+
* Plasma is an EVM-equivalent Layer 1 blockchain purpose-built for global
|
|
4809
|
+
* stablecoin payments, with deterministic BFT finality (PlasmaBFT/Fast-HotStuff).
|
|
4810
|
+
*/ const PlasmaTestnet = defineChain({
|
|
4811
|
+
type: 'evm',
|
|
4812
|
+
chain: Blockchain.Plasma_Testnet,
|
|
4813
|
+
name: 'Plasma Testnet',
|
|
4814
|
+
title: 'Plasma Testnet',
|
|
4815
|
+
nativeCurrency: {
|
|
4816
|
+
name: 'Plasma',
|
|
4817
|
+
symbol: 'XPL',
|
|
4818
|
+
decimals: 18
|
|
4819
|
+
},
|
|
4820
|
+
chainId: 9746,
|
|
4821
|
+
isTestnet: true,
|
|
4822
|
+
explorerUrl: 'https://testnet.plasmascan.to/tx/{hash}',
|
|
4823
|
+
rpcEndpoints: [
|
|
4824
|
+
'https://testnet-rpc.plasma.to'
|
|
4825
|
+
],
|
|
4826
|
+
eurcAddress: '0x98AfA0F93Dd993B736399f9074eDcEBD1985A330',
|
|
4827
|
+
usdcAddress: '0xE67Fb267022cBA8064Dd388CC2FED724F3120D9D',
|
|
4828
|
+
usdtAddress: null,
|
|
4829
|
+
cctp: {
|
|
4830
|
+
domain: 33,
|
|
4831
|
+
contracts: {
|
|
4832
|
+
v2: {
|
|
4833
|
+
type: 'split',
|
|
4834
|
+
tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
|
|
4835
|
+
messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
|
|
4836
|
+
confirmations: 3,
|
|
4837
|
+
fastConfirmations: 1
|
|
4838
|
+
}
|
|
4839
|
+
},
|
|
4840
|
+
forwarderSupported: {
|
|
4841
|
+
source: false,
|
|
4842
|
+
destination: false
|
|
4843
|
+
}
|
|
4844
|
+
},
|
|
4845
|
+
kitContracts: {
|
|
4846
|
+
bridge: BRIDGE_CONTRACT_EVM_TESTNET
|
|
4847
|
+
}
|
|
4848
|
+
});
|
|
4849
|
+
|
|
4732
4850
|
/**
|
|
4733
4851
|
* Plume Mainnet chain definition
|
|
4734
4852
|
* @remarks
|
|
@@ -4760,6 +4878,7 @@ var EarnChain;
|
|
|
4760
4878
|
v2: {
|
|
4761
4879
|
type: 'split',
|
|
4762
4880
|
tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
|
|
4881
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
|
|
4763
4882
|
messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
|
|
4764
4883
|
confirmations: 65,
|
|
4765
4884
|
fastConfirmations: 1
|
|
@@ -4806,6 +4925,7 @@ var EarnChain;
|
|
|
4806
4925
|
v2: {
|
|
4807
4926
|
type: 'split',
|
|
4808
4927
|
tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
|
|
4928
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
|
|
4809
4929
|
messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
|
|
4810
4930
|
confirmations: 65,
|
|
4811
4931
|
fastConfirmations: 1
|
|
@@ -4907,6 +5027,7 @@ var EarnChain;
|
|
|
4907
5027
|
v2: {
|
|
4908
5028
|
type: 'split',
|
|
4909
5029
|
tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
|
|
5030
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
|
|
4910
5031
|
messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
|
|
4911
5032
|
confirmations: 33,
|
|
4912
5033
|
fastConfirmations: 13
|
|
@@ -4972,6 +5093,7 @@ var EarnChain;
|
|
|
4972
5093
|
v2: {
|
|
4973
5094
|
type: 'split',
|
|
4974
5095
|
tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
|
|
5096
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
|
|
4975
5097
|
messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
|
|
4976
5098
|
confirmations: 33,
|
|
4977
5099
|
fastConfirmations: 13
|
|
@@ -5031,6 +5153,7 @@ var EarnChain;
|
|
|
5031
5153
|
v2: {
|
|
5032
5154
|
type: 'split',
|
|
5033
5155
|
tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
|
|
5156
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
|
|
5034
5157
|
messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
|
|
5035
5158
|
confirmations: 1,
|
|
5036
5159
|
fastConfirmations: 1
|
|
@@ -5090,6 +5213,7 @@ var EarnChain;
|
|
|
5090
5213
|
v2: {
|
|
5091
5214
|
type: 'split',
|
|
5092
5215
|
tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
|
|
5216
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
|
|
5093
5217
|
messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
|
|
5094
5218
|
confirmations: 1,
|
|
5095
5219
|
fastConfirmations: 1
|
|
@@ -5147,6 +5271,7 @@ var EarnChain;
|
|
|
5147
5271
|
v2: {
|
|
5148
5272
|
type: 'split',
|
|
5149
5273
|
tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
|
|
5274
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
|
|
5150
5275
|
messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
|
|
5151
5276
|
confirmations: 1,
|
|
5152
5277
|
fastConfirmations: 1
|
|
@@ -5205,6 +5330,7 @@ var EarnChain;
|
|
|
5205
5330
|
v2: {
|
|
5206
5331
|
type: 'split',
|
|
5207
5332
|
tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
|
|
5333
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
|
|
5208
5334
|
messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
|
|
5209
5335
|
confirmations: 1,
|
|
5210
5336
|
fastConfirmations: 1
|
|
@@ -5520,6 +5646,7 @@ var EarnChain;
|
|
|
5520
5646
|
v2: {
|
|
5521
5647
|
type: 'split',
|
|
5522
5648
|
tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
|
|
5649
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
|
|
5523
5650
|
messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
|
|
5524
5651
|
confirmations: 65,
|
|
5525
5652
|
fastConfirmations: 1
|
|
@@ -5584,6 +5711,7 @@ var EarnChain;
|
|
|
5584
5711
|
v2: {
|
|
5585
5712
|
type: 'split',
|
|
5586
5713
|
tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
|
|
5714
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
|
|
5587
5715
|
messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
|
|
5588
5716
|
confirmations: 65,
|
|
5589
5717
|
fastConfirmations: 1
|
|
@@ -5641,6 +5769,7 @@ var EarnChain;
|
|
|
5641
5769
|
v2: {
|
|
5642
5770
|
type: 'split',
|
|
5643
5771
|
tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cF5d',
|
|
5772
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
|
|
5644
5773
|
messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
|
|
5645
5774
|
confirmations: 65,
|
|
5646
5775
|
fastConfirmations: 1
|
|
@@ -5700,6 +5829,7 @@ var EarnChain;
|
|
|
5700
5829
|
v2: {
|
|
5701
5830
|
type: 'split',
|
|
5702
5831
|
tokenMessenger: '0x8fe6b999dc680ccfdd5bf7eb0974218be2542daa',
|
|
5832
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
|
|
5703
5833
|
messageTransmitter: '0xe737e5cebeeba77efe34d4aa090756590b1ce275',
|
|
5704
5834
|
confirmations: 65,
|
|
5705
5835
|
fastConfirmations: 1
|
|
@@ -5760,6 +5890,7 @@ var EarnChain;
|
|
|
5760
5890
|
v2: {
|
|
5761
5891
|
type: 'split',
|
|
5762
5892
|
tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
|
|
5893
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
|
|
5763
5894
|
messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
|
|
5764
5895
|
confirmations: 3,
|
|
5765
5896
|
fastConfirmations: 3
|
|
@@ -5805,6 +5936,7 @@ var EarnChain;
|
|
|
5805
5936
|
v2: {
|
|
5806
5937
|
type: 'split',
|
|
5807
5938
|
tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
|
|
5939
|
+
tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
|
|
5808
5940
|
messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
|
|
5809
5941
|
confirmations: 3,
|
|
5810
5942
|
fastConfirmations: 1
|
|
@@ -6015,6 +6147,8 @@ var Chains = {
|
|
|
6015
6147
|
OptimismSepolia: OptimismSepolia,
|
|
6016
6148
|
Pharos: Pharos,
|
|
6017
6149
|
PharosTestnet: PharosTestnet,
|
|
6150
|
+
Plasma: Plasma,
|
|
6151
|
+
PlasmaTestnet: PlasmaTestnet,
|
|
6018
6152
|
Plume: Plume,
|
|
6019
6153
|
PlumeTestnet: PlumeTestnet,
|
|
6020
6154
|
PolkadotAssetHub: PolkadotAssetHub,
|
|
@@ -7980,6 +8114,7 @@ function parseOrThrow(value, schema, context) {
|
|
|
7980
8114
|
[Blockchain.Noble]: 'uusdc',
|
|
7981
8115
|
[Blockchain.Optimism]: '0x0b2c639c533813f4aa9d7837caf62653d097ff85',
|
|
7982
8116
|
[Blockchain.Pharos]: '0xC879C018dB60520F4355C26eD1a6D572cdAC1815',
|
|
8117
|
+
[Blockchain.Plasma]: '0x2d661C89D812261039AF9764eceaAee884f5F67F',
|
|
7983
8118
|
[Blockchain.Plume]: '0x222365EF19F7947e5484218551B56bb3965Aa7aF',
|
|
7984
8119
|
[Blockchain.Polkadot_Asset_Hub]: '1337',
|
|
7985
8120
|
[Blockchain.Polygon]: '0x3c499c542cef5e3811e1192ce70d8cc03d5c3359',
|
|
@@ -8016,6 +8151,7 @@ function parseOrThrow(value, schema, context) {
|
|
|
8016
8151
|
[Blockchain.Noble_Testnet]: 'uusdc',
|
|
8017
8152
|
[Blockchain.Optimism_Sepolia]: '0x5fd84259d66Cd46123540766Be93DFE6D43130D7',
|
|
8018
8153
|
[Blockchain.Pharos_Testnet]: '0xcfC8330f4BCAB529c625D12781b1C19466A9Fc8B',
|
|
8154
|
+
[Blockchain.Plasma_Testnet]: '0xE67Fb267022cBA8064Dd388CC2FED724F3120D9D',
|
|
8019
8155
|
[Blockchain.Plume_Testnet]: '0xcB5f30e335672893c7eb944B374c196392C19D18',
|
|
8020
8156
|
[Blockchain.Polkadot_Westmint]: '31337',
|
|
8021
8157
|
[Blockchain.Polygon_Amoy_Testnet]: '0x41e94eb019c0762f9bfcf9fb1e58725bfb0e7582',
|
|
@@ -8078,6 +8214,7 @@ function parseOrThrow(value, schema, context) {
|
|
|
8078
8214
|
[Blockchain.Base]: '0x60a3E35Cc302bFA44Cb288Bc5a4F316Fdb1adb42',
|
|
8079
8215
|
[Blockchain.Cronos]: '0xA6dE01a2d62C6B5f3525d768f34d276652C554c8',
|
|
8080
8216
|
[Blockchain.Ethereum]: '0x1aBaEA1f7C830bD89Acc67eC4af516284b1bC33c',
|
|
8217
|
+
[Blockchain.Plasma]: '0x3EE196E78d4d4248b849B8E1C7F44C5457FAFD2C',
|
|
8081
8218
|
[Blockchain.Solana]: 'HzwqbKZw8HxMN6bF2yFZNrht3c2iXXzpKcFu7uBEDKtr',
|
|
8082
8219
|
[Blockchain.World_Chain]: '0x1C60ba0A0eD1019e8Eb035E6daF4155A5cE2380B',
|
|
8083
8220
|
// =========================================================================
|
|
@@ -8086,7 +8223,8 @@ function parseOrThrow(value, schema, context) {
|
|
|
8086
8223
|
[Blockchain.Arc_Testnet]: '0x89B50855Aa3bE2F677cD6303Cec089B5F319D72a',
|
|
8087
8224
|
[Blockchain.Base_Sepolia]: '0x808456652fdb597867f38412077A9182bf77359F',
|
|
8088
8225
|
[Blockchain.Cronos_Testnet]: '0x31f7538adb53cF16350e6B0c89d03D91b7D12c46',
|
|
8089
|
-
[Blockchain.Ethereum_Sepolia]: '0x08210F9170F89Ab7658F0B5E3fF39b0E03C594D4'
|
|
8226
|
+
[Blockchain.Ethereum_Sepolia]: '0x08210F9170F89Ab7658F0B5E3fF39b0E03C594D4',
|
|
8227
|
+
[Blockchain.Plasma_Testnet]: '0x98AfA0F93Dd993B736399f9074eDcEBD1985A330'
|
|
8090
8228
|
}
|
|
8091
8229
|
};
|
|
8092
8230
|
|
|
@@ -8893,7 +9031,7 @@ function parseOrThrow(value, schema, context) {
|
|
|
8893
9031
|
}
|
|
8894
9032
|
|
|
8895
9033
|
var name = "@circle-fin/unified-balance-kit";
|
|
8896
|
-
var version = "1.
|
|
9034
|
+
var version = "1.5.0";
|
|
8897
9035
|
var pkg = {
|
|
8898
9036
|
name: name,
|
|
8899
9037
|
version: version};
|
|
@@ -12469,6 +12607,23 @@ async function signUnits(group, signingUnits) {
|
|
|
12469
12607
|
}
|
|
12470
12608
|
return signedSets;
|
|
12471
12609
|
}
|
|
12610
|
+
/**
|
|
12611
|
+
* Fail loudly if a signing group carries an intent it does not own.
|
|
12612
|
+
*
|
|
12613
|
+
* Every intent in a group is signed by `group.address`, so that signer must own
|
|
12614
|
+
* each intent's `spec.sourceSigner`. If distinct spend sources ever collapse
|
|
12615
|
+
* into one group again (DEVX-3638), this throws before signing instead of
|
|
12616
|
+
* silently producing a wrong-signer signature. specs are bytes32 and
|
|
12617
|
+
* `group.address` is a native address, so normalize both before comparing.
|
|
12618
|
+
*/ function assertGroupSignerOwnsIntents(group) {
|
|
12619
|
+
if (group.address == null || group.address === '') return;
|
|
12620
|
+
const groupSigner = convertAddress(group.address, 'bytes32').toLowerCase();
|
|
12621
|
+
for (const intent of group.intents){
|
|
12622
|
+
if (intent.spec.sourceSigner.toLowerCase() !== groupSigner) {
|
|
12623
|
+
throw createValidationFailedError$1('group.address', group.address, `Signing group for ${group.address} carries an intent whose ` + `sourceSigner is ${intent.spec.sourceSigner}; a group must be signed ` + 'by the wallet that owns every intent it carries. This indicates ' + 'distinct spend sources collapsed into a single signing group.');
|
|
12624
|
+
}
|
|
12625
|
+
}
|
|
12626
|
+
}
|
|
12472
12627
|
/**
|
|
12473
12628
|
* Sign an EVM adapter group.
|
|
12474
12629
|
*
|
|
@@ -12511,22 +12666,42 @@ async function signUnits(group, signingUnits) {
|
|
|
12511
12666
|
// Validate the collection before doing bytecode reads or asking a wallet
|
|
12512
12667
|
// to sign. evmSigningData owns the canonical BurnIntent validation.
|
|
12513
12668
|
validateGroupIntents(group.intents);
|
|
12669
|
+
// Guard against a wrong-signer collapse: the group's signer must own every
|
|
12670
|
+
// intent it carries.
|
|
12671
|
+
assertGroupSignerOwnsIntents(group);
|
|
12514
12672
|
const chainsByDomain = collectChainsByDomain(group);
|
|
12515
12673
|
const signerTypeByDomain = await classifySignerTypes(group, chainsByDomain);
|
|
12516
12674
|
const signingUnits = createSigningUnits(group, signerTypeByDomain);
|
|
12517
12675
|
return await signUnits(group, signingUnits);
|
|
12518
12676
|
}
|
|
12519
12677
|
|
|
12678
|
+
// One adapter instance can serve several signer addresses (e.g. a single
|
|
12679
|
+
// dev-controlled adapter used for multiple wallets), so the group map must be
|
|
12680
|
+
// keyed on `(adapter, sourceSigner)` rather than the adapter reference alone.
|
|
12681
|
+
// Keying on the adapter alone collapsed two same-chain sources into one group,
|
|
12682
|
+
// signing the second wallet's intent with the first wallet (DEVX-3638 /
|
|
12683
|
+
// DEVX-3194). A Map needs a primitive key, so give each adapter instance a
|
|
12684
|
+
// stable token and combine it with the (case-normalized) signer address.
|
|
12685
|
+
const adapterTokens = new WeakMap();
|
|
12686
|
+
let nextAdapterToken = 0;
|
|
12687
|
+
function groupKey(alloc) {
|
|
12688
|
+
let token = adapterTokens.get(alloc.adapter);
|
|
12689
|
+
if (token === undefined) {
|
|
12690
|
+
token = nextAdapterToken++;
|
|
12691
|
+
adapterTokens.set(alloc.adapter, token);
|
|
12692
|
+
}
|
|
12693
|
+
return `${String(token)}:${alloc.sourceSigner.toLowerCase()}`;
|
|
12694
|
+
}
|
|
12520
12695
|
/**
|
|
12521
12696
|
* Add an EVM intent into the batched EVM group map.
|
|
12522
12697
|
*
|
|
12523
|
-
* On EVM, all intents for the same adapter are batched into a
|
|
12524
|
-
* group. The signing step uses `chainsByDomain` to preserve EOA batching
|
|
12698
|
+
* On EVM, all intents for the same adapter **and signer** are batched into a
|
|
12699
|
+
* single group. The signing step uses `chainsByDomain` to preserve EOA batching
|
|
12525
12700
|
* while signing ERC-1271 intents separately on their source chains.
|
|
12526
12701
|
*
|
|
12527
12702
|
* @param intent - The burn intent to group.
|
|
12528
12703
|
* @param alloc - The allocation that resolved to this intent.
|
|
12529
|
-
* @param evmGroups - Mutable map of adapter → EVM group.
|
|
12704
|
+
* @param evmGroups - Mutable map of `(adapter, sourceSigner)` key → EVM group.
|
|
12530
12705
|
*
|
|
12531
12706
|
* @example
|
|
12532
12707
|
* ```typescript
|
|
@@ -12536,12 +12711,13 @@ async function signUnits(group, signingUnits) {
|
|
|
12536
12711
|
* groupEvmIntents(intent, alloc, groups)
|
|
12537
12712
|
* ```
|
|
12538
12713
|
*/ function groupEvmIntents(intent, alloc, evmGroups) {
|
|
12539
|
-
const
|
|
12714
|
+
const key = groupKey(alloc);
|
|
12715
|
+
const existing = evmGroups.get(key);
|
|
12540
12716
|
if (existing) {
|
|
12541
12717
|
existing.intents.push(intent);
|
|
12542
12718
|
existing.chainsByDomain.set(alloc.chain.gateway.domain, alloc.chain);
|
|
12543
12719
|
} else {
|
|
12544
|
-
evmGroups.set(
|
|
12720
|
+
evmGroups.set(key, {
|
|
12545
12721
|
adapter: alloc.adapter,
|
|
12546
12722
|
chain: alloc.chain,
|
|
12547
12723
|
intents: [
|
|
@@ -13570,6 +13746,8 @@ const gatewayInfoSchema = zod.z.object({
|
|
|
13570
13746
|
* Fetch Gateway info from the `/v1/info` endpoint.
|
|
13571
13747
|
*
|
|
13572
13748
|
* @param isTestnet - Whether to query the testnet or mainnet API.
|
|
13749
|
+
* @param config - Optional polling config overrides, including custom
|
|
13750
|
+
* `headers` forwarded with the request.
|
|
13573
13751
|
* @returns Parsed Gateway info including per-domain processed heights.
|
|
13574
13752
|
* @throws KitError on HTTP failure or invalid response.
|
|
13575
13753
|
*
|
|
@@ -13578,11 +13756,11 @@ const gatewayInfoSchema = zod.z.object({
|
|
|
13578
13756
|
* const info = await fetchGatewayInfo(true)
|
|
13579
13757
|
* console.log(info.domains.map(d => `${d.chain}: ${d.processedHeight}`))
|
|
13580
13758
|
* ```
|
|
13581
|
-
*/ async function fetchGatewayInfo(isTestnet) {
|
|
13759
|
+
*/ async function fetchGatewayInfo(isTestnet, config) {
|
|
13582
13760
|
const apiBaseUrl = getGatewayApiBaseUrl(isTestnet);
|
|
13583
13761
|
const url = `${apiBaseUrl}/v1/info`;
|
|
13584
13762
|
try {
|
|
13585
|
-
return await pollApiGet(url, assertGatewayInfoResponse);
|
|
13763
|
+
return await pollApiGet(url, assertGatewayInfoResponse, config);
|
|
13586
13764
|
} catch (error) {
|
|
13587
13765
|
if (error instanceof KitError) {
|
|
13588
13766
|
throw error;
|
|
@@ -13608,6 +13786,8 @@ const gatewayInfoSchema = zod.z.object({
|
|
|
13608
13786
|
*
|
|
13609
13787
|
* @param isTestnet - Whether to query the testnet or mainnet API.
|
|
13610
13788
|
* @param domain - The Gateway domain number (e.g. 0 = Ethereum, 6 = Base).
|
|
13789
|
+
* @param config - Optional polling config overrides, including custom
|
|
13790
|
+
* `headers` forwarded with the `/v1/info` request.
|
|
13611
13791
|
* @returns The processed height as a bigint.
|
|
13612
13792
|
* @throws KitError when the domain is not found in the response.
|
|
13613
13793
|
*
|
|
@@ -13616,10 +13796,10 @@ const gatewayInfoSchema = zod.z.object({
|
|
|
13616
13796
|
* const height = await getProcessedHeight(true, 6) // Base Sepolia
|
|
13617
13797
|
* console.log(`Gateway processed up to block ${height}`)
|
|
13618
13798
|
* ```
|
|
13619
|
-
*/ async function getProcessedHeight(isTestnet, domain) {
|
|
13799
|
+
*/ async function getProcessedHeight(isTestnet, domain, config) {
|
|
13620
13800
|
// No caching in v1 — /v1/info is cheap and delegate status checks
|
|
13621
13801
|
// are infrequent. Revisit if rate-limit or latency issues appear.
|
|
13622
|
-
const info = await fetchGatewayInfo(isTestnet);
|
|
13802
|
+
const info = await fetchGatewayInfo(isTestnet, config);
|
|
13623
13803
|
const entry = info.domains.find((d)=>d.domain === domain);
|
|
13624
13804
|
if (!entry) {
|
|
13625
13805
|
throw new KitError({
|
|
@@ -14085,12 +14265,22 @@ function throwNetworkMismatch(expected, actual) {
|
|
|
14085
14265
|
* @param allocations - Normalized allocations used to map domain → adapter/chain.
|
|
14086
14266
|
* @returns Array of groups, each with adapter, chain, and intents to sign.
|
|
14087
14267
|
*/ function groupIntentsByAdapter(intents, allocations) {
|
|
14268
|
+
// Keyed by `(adapter, sourceSigner)` (see groupEvmIntents), not by adapter
|
|
14269
|
+
// alone: two spend sources on the same chain — including two addresses behind
|
|
14270
|
+
// one shared adapter — must stay in separate signing groups.
|
|
14088
14271
|
const evmGroups = new Map();
|
|
14089
14272
|
const solanaGroups = [];
|
|
14090
14273
|
for (const intent of intents){
|
|
14091
|
-
|
|
14274
|
+
// Match each intent back to its source allocation by BOTH Gateway domain
|
|
14275
|
+
// and signer. Two spend sources on the same chain share a domain, so
|
|
14276
|
+
// matching on domain alone always returned the FIRST allocation — folding
|
|
14277
|
+
// the second wallet's intent into the first wallet's signing group so it
|
|
14278
|
+
// was signed by the wrong wallet (DEVX-3638). specs carry sourceSigner as
|
|
14279
|
+
// bytes32 and allocations carry native addresses, so normalize both.
|
|
14280
|
+
const intentSigner = intent.spec.sourceSigner.toLowerCase();
|
|
14281
|
+
const alloc = allocations.find((a)=>a.chain.gateway.domain === intent.spec.sourceDomain && convertAddress(a.sourceSigner, 'bytes32').toLowerCase() === intentSigner);
|
|
14092
14282
|
if (!alloc) {
|
|
14093
|
-
throw createValidationFailedError$1('intent.spec.sourceDomain', intent.spec.sourceDomain, `No allocation found for sourceDomain ${String(intent.spec.sourceDomain)}; ` + 'estimate response contains an intent that does not match any allocation');
|
|
14283
|
+
throw createValidationFailedError$1('intent.spec.sourceDomain', intent.spec.sourceDomain, `No allocation found for sourceDomain ${String(intent.spec.sourceDomain)} and sourceSigner ${String(intent.spec.sourceSigner)}; ` + 'estimate response contains an intent that does not match any allocation');
|
|
14094
14284
|
}
|
|
14095
14285
|
if (alloc.chain.type === 'solana') {
|
|
14096
14286
|
solanaGroups.push(groupSolanaIntents(intent, alloc));
|
|
@@ -17507,12 +17697,12 @@ const FORWARDER_POLL_TIMEOUT_MS = 300_000;
|
|
|
17507
17697
|
* exceeds the 5-minute timeout without reaching a terminal status.
|
|
17508
17698
|
* @throws KitError Propagated from {@link pollApiGet} if the HTTP
|
|
17509
17699
|
* request itself fails or returns a non-OK response.
|
|
17510
|
-
*/ async function pollForwarderCompletion(apiBaseUrl, transferId) {
|
|
17700
|
+
*/ async function pollForwarderCompletion(apiBaseUrl, transferId, requestConfig) {
|
|
17511
17701
|
const startTime = Date.now();
|
|
17512
17702
|
while(Date.now() - startTime < FORWARDER_POLL_TIMEOUT_MS){
|
|
17513
17703
|
let status;
|
|
17514
17704
|
try {
|
|
17515
|
-
status = await pollApiGet(`${apiBaseUrl}/v1/transfer/${transferId}`, assertGatewayTransferDetails);
|
|
17705
|
+
status = await pollApiGet(`${apiBaseUrl}/v1/transfer/${transferId}`, assertGatewayTransferDetails, requestConfig);
|
|
17516
17706
|
} catch (error) {
|
|
17517
17707
|
throwGatewayApiError(error);
|
|
17518
17708
|
}
|
|
@@ -17630,7 +17820,7 @@ const FORWARDER_POLL_TIMEOUT_MS = 300_000;
|
|
|
17630
17820
|
* @param params - Spend parameters (source(s) and token).
|
|
17631
17821
|
* @param destChain - Resolved destination chain (used for network type).
|
|
17632
17822
|
* @returns Confirmed balances tagged with their originating source index.
|
|
17633
|
-
*/ async function fetchChainBalances(params, destChain) {
|
|
17823
|
+
*/ async function fetchChainBalances(params, destChain, requestConfig) {
|
|
17634
17824
|
const rawSources = Array.isArray(params.from) ? params.from : [
|
|
17635
17825
|
params.from
|
|
17636
17826
|
];
|
|
@@ -17659,7 +17849,7 @@ const FORWARDER_POLL_TIMEOUT_MS = 300_000;
|
|
|
17659
17849
|
token: params.token,
|
|
17660
17850
|
sources: querySource,
|
|
17661
17851
|
networkType
|
|
17662
|
-
});
|
|
17852
|
+
}, requestConfig);
|
|
17663
17853
|
}));
|
|
17664
17854
|
const chainBalances = [];
|
|
17665
17855
|
for(let i = 0; i < balanceResults.length; i++){
|
|
@@ -17732,9 +17922,9 @@ const FORWARDER_POLL_TIMEOUT_MS = 300_000;
|
|
|
17732
17922
|
* @param recipientAddress - Resolved recipient address.
|
|
17733
17923
|
* @param useForwarder - Whether the Forwarding Service path is active.
|
|
17734
17924
|
* @returns Allocations, intents, and (auto-allocation only) confirmed balances.
|
|
17735
|
-
*/ async function resolveAllocationsAndIntents(params, destChain, recipientAddress, useForwarder) {
|
|
17925
|
+
*/ async function resolveAllocationsAndIntents(params, destChain, recipientAddress, useForwarder, requestConfig) {
|
|
17736
17926
|
if (params.amountIn) {
|
|
17737
|
-
const chainBalances = await fetchChainBalances(params, destChain);
|
|
17927
|
+
const chainBalances = await fetchChainBalances(params, destChain, requestConfig);
|
|
17738
17928
|
const { allocations, intents } = await buildAutoAllocatedFromBalances(params, destChain, recipientAddress, useForwarder, params.amountIn, chainBalances);
|
|
17739
17929
|
return {
|
|
17740
17930
|
allocations,
|
|
@@ -17757,11 +17947,11 @@ const FORWARDER_POLL_TIMEOUT_MS = 300_000;
|
|
|
17757
17947
|
* @param useForwarder - Whether the Forwarding Service path is active.
|
|
17758
17948
|
* @param allocations - Normalised allocations (forwarded to error handler).
|
|
17759
17949
|
* @returns Estimate entries and optional forwarding fee.
|
|
17760
|
-
*/ async function fetchEstimate(apiBaseUrl, estimateBody, useForwarder, allocations) {
|
|
17950
|
+
*/ async function fetchEstimate(apiBaseUrl, estimateBody, useForwarder, allocations, requestConfig) {
|
|
17761
17951
|
if (useForwarder) {
|
|
17762
17952
|
let fwdResponse;
|
|
17763
17953
|
try {
|
|
17764
|
-
fwdResponse = await pollApiPost(`${apiBaseUrl}/v1/estimate?enableForwarder=true`, estimateBody, assertGatewayForwarderEstimateResponse);
|
|
17954
|
+
fwdResponse = await pollApiPost(`${apiBaseUrl}/v1/estimate?enableForwarder=true`, estimateBody, assertGatewayForwarderEstimateResponse, requestConfig);
|
|
17765
17955
|
} catch (error) {
|
|
17766
17956
|
throwGatewayApiError(error, allocations);
|
|
17767
17957
|
}
|
|
@@ -17772,7 +17962,7 @@ const FORWARDER_POLL_TIMEOUT_MS = 300_000;
|
|
|
17772
17962
|
}
|
|
17773
17963
|
let entries;
|
|
17774
17964
|
try {
|
|
17775
|
-
entries = await pollApiPost(`${apiBaseUrl}/v1/estimate`, estimateBody, assertGatewayEstimateResponse);
|
|
17965
|
+
entries = await pollApiPost(`${apiBaseUrl}/v1/estimate`, estimateBody, assertGatewayEstimateResponse, requestConfig);
|
|
17776
17966
|
} catch (error) {
|
|
17777
17967
|
throwGatewayApiError(error, allocations);
|
|
17778
17968
|
}
|
|
@@ -17843,14 +18033,14 @@ const FORWARDER_POLL_TIMEOUT_MS = 300_000;
|
|
|
17843
18033
|
* @param destChain - Resolved destination chain with Gateway v1 config.
|
|
17844
18034
|
* @param useForwarder - Whether the Forwarding Service path is active.
|
|
17845
18035
|
* @returns Estimated intents (with real maxFee) and optional forwarding fee.
|
|
17846
|
-
*/ async function validateAndEstimate(allocations, intents, destChain, useForwarder) {
|
|
18036
|
+
*/ async function validateAndEstimate(allocations, intents, destChain, useForwarder, requestConfig) {
|
|
17847
18037
|
assertNetworkCompatibility(allocations, destChain);
|
|
17848
18038
|
if (useForwarder) {
|
|
17849
18039
|
assertForwarderRouteSupport(destChain, allocations);
|
|
17850
18040
|
}
|
|
17851
18041
|
const apiBaseUrl = getGatewayApiBaseUrl(destChain.isTestnet);
|
|
17852
18042
|
const estimateBody = buildEstimateRequestBody(intents);
|
|
17853
|
-
const { entries, forwardingFee } = await fetchEstimate(apiBaseUrl, estimateBody, useForwarder, allocations);
|
|
18043
|
+
const { entries, forwardingFee } = await fetchEstimate(apiBaseUrl, estimateBody, useForwarder, allocations, requestConfig);
|
|
17854
18044
|
const estimatedIntents = parseEstimateResponse(entries, intents);
|
|
17855
18045
|
return {
|
|
17856
18046
|
estimatedIntents,
|
|
@@ -17909,7 +18099,7 @@ const FORWARDER_POLL_TIMEOUT_MS = 300_000;
|
|
|
17909
18099
|
}
|
|
17910
18100
|
throw err;
|
|
17911
18101
|
}
|
|
17912
|
-
const { estimatedIntents, forwardingFee } = await validateAndEstimate(corrected.allocations, corrected.intents, opts.destChain, opts.useForwarder);
|
|
18102
|
+
const { estimatedIntents, forwardingFee } = await validateAndEstimate(corrected.allocations, corrected.intents, opts.destChain, opts.useForwarder, opts.requestConfig);
|
|
17913
18103
|
const stillOverdrawn = findOverdrawnChains(estimatedIntents, corrected.allocations, opts.chainBalances);
|
|
17914
18104
|
if (stillOverdrawn.length === 0) {
|
|
17915
18105
|
return {
|
|
@@ -17943,12 +18133,12 @@ const FORWARDER_POLL_TIMEOUT_MS = 300_000;
|
|
|
17943
18133
|
* @param recipientAddress - Resolved recipient address.
|
|
17944
18134
|
* @param useForwarder - Whether the Forwarding Service path is active.
|
|
17945
18135
|
* @returns Allocations, estimated intents, and optional forwarding fee.
|
|
17946
|
-
*/ async function resolveValidatedIntents(params, destChain, recipientAddress, useForwarder) {
|
|
18136
|
+
*/ async function resolveValidatedIntents(params, destChain, recipientAddress, useForwarder, requestConfig) {
|
|
17947
18137
|
if (useForwarder) {
|
|
17948
18138
|
assertForwarderRouteSupport(destChain);
|
|
17949
18139
|
}
|
|
17950
|
-
const { allocations, intents, chainBalances } = await resolveAllocationsAndIntents(params, destChain, recipientAddress, useForwarder);
|
|
17951
|
-
const { estimatedIntents, forwardingFee } = await validateAndEstimate(allocations, intents, destChain, useForwarder);
|
|
18140
|
+
const { allocations, intents, chainBalances } = await resolveAllocationsAndIntents(params, destChain, recipientAddress, useForwarder, requestConfig);
|
|
18141
|
+
const { estimatedIntents, forwardingFee } = await validateAndEstimate(allocations, intents, destChain, useForwarder, requestConfig);
|
|
17952
18142
|
if (params.amountIn && chainBalances) {
|
|
17953
18143
|
const overdrawn = findOverdrawnChains(estimatedIntents, allocations, chainBalances);
|
|
17954
18144
|
if (overdrawn.length > 0) {
|
|
@@ -17961,7 +18151,10 @@ const FORWARDER_POLL_TIMEOUT_MS = 300_000;
|
|
|
17961
18151
|
chainBalances,
|
|
17962
18152
|
estimatedIntents,
|
|
17963
18153
|
allocations,
|
|
17964
|
-
overdrawn
|
|
18154
|
+
overdrawn,
|
|
18155
|
+
...requestConfig ? {
|
|
18156
|
+
requestConfig
|
|
18157
|
+
} : {}
|
|
17965
18158
|
});
|
|
17966
18159
|
}
|
|
17967
18160
|
}
|
|
@@ -18005,10 +18198,10 @@ const FORWARDER_POLL_TIMEOUT_MS = 300_000;
|
|
|
18005
18198
|
attestationSignature: transferResponse.signature
|
|
18006
18199
|
};
|
|
18007
18200
|
}
|
|
18008
|
-
async function runSpendNormalPath(params, destChain, useForwarder, dispatcher, steps) {
|
|
18201
|
+
async function runSpendNormalPath(params, destChain, useForwarder, dispatcher, steps, requestConfig) {
|
|
18009
18202
|
const chainName = destChain.name;
|
|
18010
18203
|
const recipientAddress = await resolveRecipientAddress(params.to);
|
|
18011
|
-
const { allocations, estimatedIntents, forwardingFee: estimateFwdFee } = await resolveValidatedIntents(params, destChain, recipientAddress, useForwarder);
|
|
18204
|
+
const { allocations, estimatedIntents, forwardingFee: estimateFwdFee } = await resolveValidatedIntents(params, destChain, recipientAddress, useForwarder, requestConfig);
|
|
18012
18205
|
pushStep(steps, dispatcher, 'gateway.spend.step.buildBurnIntents', chainName, {
|
|
18013
18206
|
name: 'buildBurnIntents',
|
|
18014
18207
|
state: 'success',
|
|
@@ -18045,7 +18238,7 @@ async function runSpendNormalPath(params, destChain, useForwarder, dispatcher, s
|
|
|
18045
18238
|
const forwarderParam = useForwarder ? '?enableForwarder=true' : '';
|
|
18046
18239
|
let transferResponse;
|
|
18047
18240
|
try {
|
|
18048
|
-
transferResponse = await pollApiPost(`${transferApiBaseUrl}/v1/transfer${forwarderParam}`, transferBody, assertGatewayTransferResponse);
|
|
18241
|
+
transferResponse = await pollApiPost(`${transferApiBaseUrl}/v1/transfer${forwarderParam}`, transferBody, assertGatewayTransferResponse, requestConfig);
|
|
18049
18242
|
} catch (error) {
|
|
18050
18243
|
throwGatewayApiError(error, allocations);
|
|
18051
18244
|
}
|
|
@@ -18125,10 +18318,11 @@ function updateFeesWithActual(fees, completionStatus) {
|
|
|
18125
18318
|
amount: actual
|
|
18126
18319
|
} : f);
|
|
18127
18320
|
}
|
|
18128
|
-
async function resolveDestinationTxHash(
|
|
18321
|
+
async function resolveDestinationTxHash(opts) {
|
|
18322
|
+
const { params, destChain, forwarder, transferId, attestation, attestationSignature, fees, requestConfig } = opts;
|
|
18129
18323
|
if (forwarder && transferId) {
|
|
18130
18324
|
const apiBaseUrl = getGatewayApiBaseUrl(destChain.isTestnet);
|
|
18131
|
-
const completionStatus = await pollForwarderCompletion(apiBaseUrl, transferId);
|
|
18325
|
+
const completionStatus = await pollForwarderCompletion(apiBaseUrl, transferId, requestConfig);
|
|
18132
18326
|
if (!completionStatus.transactionHash) {
|
|
18133
18327
|
throw new KitError({
|
|
18134
18328
|
...OnchainError.TRANSACTION_REVERTED,
|
|
@@ -18211,9 +18405,20 @@ function buildSpendResult(recipientAddress, destChain, txHash, allocationResults
|
|
|
18211
18405
|
/**
|
|
18212
18406
|
* Execute the mint step, recording success/error as a spend step.
|
|
18213
18407
|
*/ async function executeMintStep(opts) {
|
|
18214
|
-
const { params, destChain, forwarder, transferId, attestation, attestationSignature, fees, steps, dispatcher } = opts;
|
|
18408
|
+
const { params, destChain, forwarder, transferId, attestation, attestationSignature, fees, steps, dispatcher, requestConfig } = opts;
|
|
18215
18409
|
try {
|
|
18216
|
-
const mintResult = await resolveDestinationTxHash(
|
|
18410
|
+
const mintResult = await resolveDestinationTxHash({
|
|
18411
|
+
params,
|
|
18412
|
+
destChain,
|
|
18413
|
+
forwarder,
|
|
18414
|
+
transferId,
|
|
18415
|
+
attestation,
|
|
18416
|
+
attestationSignature,
|
|
18417
|
+
fees,
|
|
18418
|
+
...requestConfig ? {
|
|
18419
|
+
requestConfig
|
|
18420
|
+
} : {}
|
|
18421
|
+
});
|
|
18217
18422
|
pushStep(steps, dispatcher, 'gateway.spend.step.mint', destChain.name, {
|
|
18218
18423
|
name: 'mint',
|
|
18219
18424
|
state: 'success',
|
|
@@ -18268,7 +18473,8 @@ function buildSpendResult(recipientAddress, destChain, txHash, allocationResults
|
|
|
18268
18473
|
assertSpendAddresses(params, destChain);
|
|
18269
18474
|
const forwarder = isForwarderEnabled(params.to);
|
|
18270
18475
|
const steps = [];
|
|
18271
|
-
const
|
|
18476
|
+
const requestConfig = options?.requestConfig;
|
|
18477
|
+
const context = params.config?.retry ? await resolveRetryContext(params) : await resolveNormalContext(params, destChain, forwarder, dispatcher, steps, requestConfig);
|
|
18272
18478
|
const fees = appendForwarderFee(context.fees, context.forwardingFee);
|
|
18273
18479
|
const mintResult = await executeMintStep({
|
|
18274
18480
|
params,
|
|
@@ -18279,7 +18485,10 @@ function buildSpendResult(recipientAddress, destChain, txHash, allocationResults
|
|
|
18279
18485
|
attestationSignature: context.attestationSignature,
|
|
18280
18486
|
fees,
|
|
18281
18487
|
steps,
|
|
18282
|
-
dispatcher
|
|
18488
|
+
dispatcher,
|
|
18489
|
+
...requestConfig ? {
|
|
18490
|
+
requestConfig
|
|
18491
|
+
} : {}
|
|
18283
18492
|
});
|
|
18284
18493
|
// A throwing `onBroadcast` must never strand the caller after a
|
|
18285
18494
|
// successful mint — the chain has moved. `safeInvokeCallback` swallows
|
|
@@ -18296,14 +18505,14 @@ function buildSpendResult(recipientAddress, destChain, txHash, allocationResults
|
|
|
18296
18505
|
/**
|
|
18297
18506
|
* Resolve the spend context via the normal (non-retry) path.
|
|
18298
18507
|
* Validates `from`, then delegates to `runSpendNormalPath`.
|
|
18299
|
-
*/ async function resolveNormalContext(params, destChain, forwarder, dispatcher, steps) {
|
|
18508
|
+
*/ async function resolveNormalContext(params, destChain, forwarder, dispatcher, steps, requestConfig) {
|
|
18300
18509
|
if (!params.from) {
|
|
18301
18510
|
throw createValidationFailedError$1('from', params.from, 'Source (from) is required when config.retry is not provided.');
|
|
18302
18511
|
}
|
|
18303
18512
|
return runSpendNormalPath({
|
|
18304
18513
|
...params,
|
|
18305
18514
|
from: params.from
|
|
18306
|
-
}, destChain, forwarder, dispatcher, steps);
|
|
18515
|
+
}, destChain, forwarder, dispatcher, steps, requestConfig);
|
|
18307
18516
|
}
|
|
18308
18517
|
/**
|
|
18309
18518
|
* Estimate fees for a Gateway spend without executing it.
|
|
@@ -18326,13 +18535,13 @@ function buildSpendResult(recipientAddress, destChain, txHash, allocationResults
|
|
|
18326
18535
|
* })
|
|
18327
18536
|
* fees.forEach((f) => console.log(f.type, f.amount, f.allocations))
|
|
18328
18537
|
* ```
|
|
18329
|
-
*/ async function estimateSpend$1(params) {
|
|
18538
|
+
*/ async function estimateSpend$1(params, requestConfig) {
|
|
18330
18539
|
const destChain = resolveChainIdentifier(params.to.chain);
|
|
18331
18540
|
assertGatewayV1(destChain);
|
|
18332
18541
|
assertSpendAddresses(params, destChain);
|
|
18333
18542
|
const forwarder = isForwarderEnabled(params.to);
|
|
18334
18543
|
const recipientAddress = await resolveRecipientAddress(params.to);
|
|
18335
|
-
const { allocations, estimatedIntents, forwardingFee } = await resolveValidatedIntents(params, destChain, recipientAddress, forwarder);
|
|
18544
|
+
const { allocations, estimatedIntents, forwardingFee } = await resolveValidatedIntents(params, destChain, recipientAddress, forwarder, requestConfig);
|
|
18336
18545
|
const fees = computeEstimateFees(estimatedIntents, allocations, params.config?.customFee);
|
|
18337
18546
|
if (forwardingFee) {
|
|
18338
18547
|
fees.push({
|
|
@@ -18456,6 +18665,9 @@ function assertNotSelfDelegation(chain, signerAddress, delegateAddress, action)
|
|
|
18456
18665
|
* the delegate is `'ready'` (finalized); otherwise it is `'pending'`.
|
|
18457
18666
|
*
|
|
18458
18667
|
* @param params - The adapter context (`from`), delegate address, and token.
|
|
18668
|
+
* @param requestConfig - Optional polling config overrides, including custom
|
|
18669
|
+
* `headers` forwarded with the `/v1/info` request used on the EVM finality
|
|
18670
|
+
* check.
|
|
18459
18671
|
* @returns Promise resolving to `'none'`, `'pending'`, or `'ready'`.
|
|
18460
18672
|
* @throws KitError if the chain is unsupported or `/v1/info` fails.
|
|
18461
18673
|
*
|
|
@@ -18475,7 +18687,7 @@ function assertNotSelfDelegation(chain, signerAddress, delegateAddress, action)
|
|
|
18475
18687
|
* const status = await getDelegateStatus(params)
|
|
18476
18688
|
* if (status === 'ready') { // safe to spend }
|
|
18477
18689
|
* ```
|
|
18478
|
-
*/ async function getDelegateStatus$1(params) {
|
|
18690
|
+
*/ async function getDelegateStatus$1(params, requestConfig) {
|
|
18479
18691
|
const { from, delegateAddress } = params;
|
|
18480
18692
|
const { adapter } = from;
|
|
18481
18693
|
const chain = resolveChainIdentifier(from.chain);
|
|
@@ -18515,7 +18727,7 @@ function assertNotSelfDelegation(chain, signerAddress, delegateAddress, action)
|
|
|
18515
18727
|
return String(finalizedResult).toLowerCase() === 'true' ? 'ready' : 'pending';
|
|
18516
18728
|
}
|
|
18517
18729
|
// EVM: use processedHeight from /v1/info
|
|
18518
|
-
const processedHeight = await getProcessedHeight(chain.isTestnet, chain.gateway.domain);
|
|
18730
|
+
const processedHeight = await getProcessedHeight(chain.isTestnet, chain.gateway.domain, requestConfig);
|
|
18519
18731
|
// If the RPC node lags Gateway's indexer view, the historical read at
|
|
18520
18732
|
// processedHeight may throw a block-range error. This is safe to treat
|
|
18521
18733
|
// as 'pending' because processedHeight comes from Gateway's /v1/info
|
|
@@ -18733,6 +18945,35 @@ function dispatchEvent(dispatcher, opName, stage, chain, data) {
|
|
|
18733
18945
|
dispatchEvent(dispatcher, opName, 'failed', chain, extractErrorInfo(error));
|
|
18734
18946
|
}
|
|
18735
18947
|
|
|
18948
|
+
// ---------------------------------------------------------------------------
|
|
18949
|
+
// Config validation
|
|
18950
|
+
// ---------------------------------------------------------------------------
|
|
18951
|
+
function isPlainObject(value) {
|
|
18952
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
18953
|
+
return false;
|
|
18954
|
+
}
|
|
18955
|
+
const prototype = Object.getPrototypeOf(value);
|
|
18956
|
+
return prototype === Object.prototype || prototype === null;
|
|
18957
|
+
}
|
|
18958
|
+
function assertHeadersConfig(headers) {
|
|
18959
|
+
if (headers === undefined) {
|
|
18960
|
+
return;
|
|
18961
|
+
}
|
|
18962
|
+
if (!isPlainObject(headers)) {
|
|
18963
|
+
throw createValidationFailedError$1('config.headers', headers, 'config.headers must be a plain object with string header values when provided');
|
|
18964
|
+
}
|
|
18965
|
+
for (const [name, value] of Object.entries(headers)){
|
|
18966
|
+
if (typeof value !== 'string') {
|
|
18967
|
+
throw createValidationFailedError$1(`config.headers.${name}`, value, 'header values must be strings');
|
|
18968
|
+
}
|
|
18969
|
+
}
|
|
18970
|
+
}
|
|
18971
|
+
function assertGatewayV1Config(config) {
|
|
18972
|
+
if (!isPlainObject(config)) {
|
|
18973
|
+
throw createValidationFailedError$1('config', config, 'config must be a plain object when provided');
|
|
18974
|
+
}
|
|
18975
|
+
assertHeadersConfig(config['headers']);
|
|
18976
|
+
}
|
|
18736
18977
|
// ---------------------------------------------------------------------------
|
|
18737
18978
|
// Factory
|
|
18738
18979
|
// ---------------------------------------------------------------------------
|
|
@@ -18742,7 +18983,12 @@ function dispatchEvent(dispatcher, opName, stage, chain, data) {
|
|
|
18742
18983
|
* Returns a plain object that implements {@link IGatewayProvider} by
|
|
18743
18984
|
* delegating to the standalone functions in `operations/`.
|
|
18744
18985
|
*
|
|
18986
|
+
* @param config - Optional provider configuration. Supply `headers` to
|
|
18987
|
+
* forward custom HTTP headers with every Gateway API request. See
|
|
18988
|
+
* {@link GatewayV1Config}.
|
|
18745
18989
|
* @returns An {@link IGatewayProvider} instance.
|
|
18990
|
+
* @throws Throws when `config` or `config.headers` is not a plain object, or a
|
|
18991
|
+
* header value is not a string.
|
|
18746
18992
|
*
|
|
18747
18993
|
* @example
|
|
18748
18994
|
* ```typescript
|
|
@@ -18751,7 +18997,23 @@ function dispatchEvent(dispatcher, opName, stage, chain, data) {
|
|
|
18751
18997
|
* const provider = createGatewayV1Provider()
|
|
18752
18998
|
* const chains = provider.getSupportedChains()
|
|
18753
18999
|
* ```
|
|
18754
|
-
|
|
19000
|
+
*
|
|
19001
|
+
* @example
|
|
19002
|
+
* ```typescript
|
|
19003
|
+
* // Forward a custom header on every Gateway API request.
|
|
19004
|
+
* const provider = createGatewayV1Provider({
|
|
19005
|
+
* headers: { 'X-Access-Key': process.env.GATEWAY_ACCESS_KEY! },
|
|
19006
|
+
* })
|
|
19007
|
+
* ```
|
|
19008
|
+
*/ function createGatewayV1Provider(config = {}) {
|
|
19009
|
+
assertGatewayV1Config(config);
|
|
19010
|
+
// Captured once and threaded to every Gateway API call the operations make,
|
|
19011
|
+
// so a configured header reaches balances, estimate, transfer, forwarder
|
|
19012
|
+
// status, and /v1/info alike. Left undefined when no headers are configured
|
|
19013
|
+
// so the operations keep their existing defaults untouched.
|
|
19014
|
+
const requestConfig = config.headers ? {
|
|
19015
|
+
headers: config.headers
|
|
19016
|
+
} : undefined;
|
|
18755
19017
|
/**
|
|
18756
19018
|
* Execute an operation with started/succeeded/failed event dispatch.
|
|
18757
19019
|
*/ async function withEvents(opName, chain, startedData, params, fn) {
|
|
@@ -18782,21 +19044,25 @@ function dispatchEvent(dispatcher, opName, stage, chain, data) {
|
|
|
18782
19044
|
}, params, depositFor$1),
|
|
18783
19045
|
spend: async (params, options)=>{
|
|
18784
19046
|
const destChainName = extractChainInfo(params.to.chain).name;
|
|
19047
|
+
const mergedOptions = requestConfig ? {
|
|
19048
|
+
...options,
|
|
19049
|
+
requestConfig
|
|
19050
|
+
} : options;
|
|
18785
19051
|
return withEvents('spend', destChainName, {
|
|
18786
19052
|
destinationChain: destChainName,
|
|
18787
19053
|
token: params.token ?? 'USDC'
|
|
18788
|
-
}, params, async (p)=>spend$1(p, provider.actionDispatcher,
|
|
19054
|
+
}, params, async (p)=>spend$1(p, provider.actionDispatcher, mergedOptions));
|
|
18789
19055
|
},
|
|
18790
19056
|
estimateSpend: async (params)=>{
|
|
18791
19057
|
const destChainName = extractChainInfo(params.to.chain).name;
|
|
18792
19058
|
return withEvents('estimateSpend', destChainName, {
|
|
18793
19059
|
destinationChain: destChainName,
|
|
18794
19060
|
token: params.token ?? 'USDC'
|
|
18795
|
-
}, params, estimateSpend$1);
|
|
19061
|
+
}, params, async (p)=>estimateSpend$1(p, requestConfig));
|
|
18796
19062
|
},
|
|
18797
19063
|
getBalances: async (params)=>withEvents('getBalances', 'aggregate', {
|
|
18798
19064
|
token: params.token ?? 'USDC'
|
|
18799
|
-
}, params, getBalances$1),
|
|
19065
|
+
}, params, async (p)=>getBalances$1(p, requestConfig)),
|
|
18800
19066
|
addDelegate: async (params)=>withEvents('addDelegate', extractChainInfo(params.from.chain).name, {
|
|
18801
19067
|
delegateAddress: params.delegateAddress
|
|
18802
19068
|
}, params, addDelegate$1),
|
|
@@ -18814,7 +19080,9 @@ function dispatchEvent(dispatcher, opName, stage, chain, data) {
|
|
|
18814
19080
|
// in withEvents. getSupportedChains is synchronous. getDelegateStatus is a
|
|
18815
19081
|
// lightweight read that consumers treat as a utility check, unlike
|
|
18816
19082
|
// getBalances which involves API polling and benefits from lifecycle events.
|
|
18817
|
-
getDelegateStatus
|
|
19083
|
+
// getDelegateStatus is wrapped to forward the provider's request config to
|
|
19084
|
+
// its /v1/info call; getSupportedChains makes no API call.
|
|
19085
|
+
getDelegateStatus: async (params)=>getDelegateStatus$1(params, requestConfig),
|
|
18818
19086
|
getSupportedChains: getSupportedChains$1
|
|
18819
19087
|
};
|
|
18820
19088
|
return provider;
|
|
@@ -18824,6 +19092,7 @@ function dispatchEvent(dispatcher, opName, stage, chain, data) {
|
|
|
18824
19092
|
* The default providers that will be used in addition to the providers
|
|
18825
19093
|
* provided to the createUnifiedBalanceKitContext factory function.
|
|
18826
19094
|
*
|
|
19095
|
+
* @param config - Optional configuration forwarded to the default provider.
|
|
18827
19096
|
* @returns A readonly tuple with one element: the default Gateway v1 provider
|
|
18828
19097
|
* instance created via {@link createGatewayV1Provider}.
|
|
18829
19098
|
* @internal
|
|
@@ -18835,8 +19104,10 @@ function dispatchEvent(dispatcher, opName, stage, chain, data) {
|
|
|
18835
19104
|
* const { providers } = createUnifiedBalanceKitContext()
|
|
18836
19105
|
* // providers[0] is the default Gateway v1 instance from getDefaultProviders()
|
|
18837
19106
|
* ```
|
|
18838
|
-
*/ const getDefaultProviders = ()=>[
|
|
18839
|
-
createGatewayV1Provider(
|
|
19107
|
+
*/ const getDefaultProviders = (config = {})=>[
|
|
19108
|
+
createGatewayV1Provider(config.headers ? {
|
|
19109
|
+
headers: config.headers
|
|
19110
|
+
} : {})
|
|
18840
19111
|
];
|
|
18841
19112
|
function createUnifiedBalanceKitContext(config = {}) {
|
|
18842
19113
|
// Runtime guard: `excludeDefaultProviders: true` with no `providers` is
|
|
@@ -18850,7 +19121,10 @@ function createUnifiedBalanceKitContext(config = {}) {
|
|
|
18850
19121
|
// Initialize default providers — either the canonical singleton tuple or
|
|
18851
19122
|
// an empty list when the caller has opted out. Typed loosely here; each
|
|
18852
19123
|
// public overload narrows the return type for callers.
|
|
18853
|
-
const
|
|
19124
|
+
const defaultProvidersConfig = config.headers ? {
|
|
19125
|
+
headers: config.headers
|
|
19126
|
+
} : {};
|
|
19127
|
+
const defaultProviders = config.excludeDefaultProviders === true ? [] : getDefaultProviders(defaultProvidersConfig);
|
|
18854
19128
|
const providers = [
|
|
18855
19129
|
...defaultProviders,
|
|
18856
19130
|
...config.providers ?? []
|
|
@@ -19541,29 +19815,65 @@ function sumAllocationsFromSources(sources) {
|
|
|
19541
19815
|
}
|
|
19542
19816
|
});
|
|
19543
19817
|
|
|
19818
|
+
function normalizeAddressIdentity(value) {
|
|
19819
|
+
if (typeof value !== 'string') return undefined;
|
|
19820
|
+
try {
|
|
19821
|
+
return convertAddress(value, 'bytes32').toLowerCase();
|
|
19822
|
+
} catch {
|
|
19823
|
+
// Address validation below owns the structured error for invalid input.
|
|
19824
|
+
return value;
|
|
19825
|
+
}
|
|
19826
|
+
}
|
|
19544
19827
|
/**
|
|
19545
|
-
* Reject `from` arrays
|
|
19546
|
-
*
|
|
19547
|
-
*
|
|
19828
|
+
* Reject `from` arrays that describe the same spend source more than once.
|
|
19829
|
+
*
|
|
19830
|
+
* One adapter instance may legitimately be reused across distinct Gateway
|
|
19831
|
+
* source accounts. When `sourceAccount` is omitted, the signer address
|
|
19832
|
+
* identifies the source. Must run on the raw input (before Zod parsing)
|
|
19833
|
+
* because `z.object()` creates new wrapper objects and adapter identity
|
|
19834
|
+
* (`===`) is lost.
|
|
19548
19835
|
*
|
|
19549
19836
|
* @internal
|
|
19550
|
-
*/ function
|
|
19837
|
+
*/ function assertNoDuplicateSpendSources(params) {
|
|
19551
19838
|
if (params == null || typeof params !== 'object') return;
|
|
19552
19839
|
const from = params['from'];
|
|
19553
19840
|
if (!Array.isArray(from) || from.length < 2) return;
|
|
19554
|
-
const seen = new
|
|
19841
|
+
const seen = new Map();
|
|
19555
19842
|
for (const source of from){
|
|
19556
19843
|
if (source == null || typeof source !== 'object') continue;
|
|
19557
|
-
const
|
|
19844
|
+
const record = source;
|
|
19845
|
+
const adapter = record['adapter'];
|
|
19558
19846
|
if (adapter == null) continue;
|
|
19559
|
-
|
|
19847
|
+
const sourceAccount = normalizeAddressIdentity(record['sourceAccount']) ?? normalizeAddressIdentity(record['address']);
|
|
19848
|
+
let sourceAccounts = seen.get(adapter);
|
|
19849
|
+
if (sourceAccounts == null) {
|
|
19850
|
+
sourceAccounts = new Set();
|
|
19851
|
+
seen.set(adapter, sourceAccounts);
|
|
19852
|
+
}
|
|
19853
|
+
if (sourceAccounts.has(sourceAccount)) {
|
|
19560
19854
|
throw new KitError({
|
|
19561
19855
|
...InputError.VALIDATION_FAILED,
|
|
19562
19856
|
recoverability: 'FATAL',
|
|
19563
|
-
message: 'Duplicate
|
|
19857
|
+
message: 'Duplicate spend source detected in from array. The same adapter ' + 'and Gateway source account are reused more than once.'
|
|
19564
19858
|
});
|
|
19565
19859
|
}
|
|
19566
|
-
|
|
19860
|
+
sourceAccounts.add(sourceAccount);
|
|
19861
|
+
}
|
|
19862
|
+
}
|
|
19863
|
+
function assertSourceAddressContexts(from) {
|
|
19864
|
+
const sources = Array.isArray(from) ? from : [
|
|
19865
|
+
from
|
|
19866
|
+
];
|
|
19867
|
+
for (const raw of sources){
|
|
19868
|
+
if (raw == null || typeof raw !== 'object') continue;
|
|
19869
|
+
const source = raw;
|
|
19870
|
+
const addressContext = source.adapter?.capabilities?.addressContext;
|
|
19871
|
+
if (addressContext === 'developer-controlled' && (typeof source.address !== 'string' || source.address === '')) {
|
|
19872
|
+
throw createValidationFailedError$1('address', source.address, 'Address is required for developer-controlled adapters.');
|
|
19873
|
+
}
|
|
19874
|
+
if (addressContext === 'user-controlled' && source.address !== undefined) {
|
|
19875
|
+
throw createValidationFailedError$1('address', source.address, 'Address should not be provided for user-controlled adapters. ' + 'The address is automatically resolved from the connected wallet.');
|
|
19876
|
+
}
|
|
19567
19877
|
}
|
|
19568
19878
|
}
|
|
19569
19879
|
/**
|
|
@@ -19577,14 +19887,17 @@ function sumAllocationsFromSources(sources) {
|
|
|
19577
19887
|
* @throws \{KitError\} When validation fails; error code is
|
|
19578
19888
|
* {@link InputError.VALIDATION_FAILED}.
|
|
19579
19889
|
*/ function assertSpendParams(params) {
|
|
19580
|
-
|
|
19890
|
+
assertNoDuplicateSpendSources(params);
|
|
19891
|
+
if (params != null && typeof params === 'object' && 'from' in params) {
|
|
19892
|
+
assertSourceAddressContexts(params['from']);
|
|
19893
|
+
}
|
|
19581
19894
|
const result = spendParamsSchema.safeParse(params);
|
|
19582
19895
|
if (!result.success) {
|
|
19583
19896
|
throw convertZodErrorToStructured(result.error, params);
|
|
19584
19897
|
}
|
|
19585
19898
|
const data = result.data;
|
|
19586
19899
|
// Validate recipientAddress against the destination chain
|
|
19587
|
-
if (data.to.recipientAddress) {
|
|
19900
|
+
if (data.to.recipientAddress !== undefined && data.to.recipientAddress !== '') {
|
|
19588
19901
|
const toChain = data.to.chain;
|
|
19589
19902
|
if (!isValidAddressForChain(data.to.recipientAddress, toChain)) {
|
|
19590
19903
|
const chainInfo = extractChainInfo(toChain);
|
|
@@ -19592,7 +19905,7 @@ function sumAllocationsFromSources(sources) {
|
|
|
19592
19905
|
}
|
|
19593
19906
|
}
|
|
19594
19907
|
// Validate sourceAccount against each source's allocation chain
|
|
19595
|
-
if (data.from) {
|
|
19908
|
+
if (data.from !== undefined) {
|
|
19596
19909
|
assertSourceAccountAddresses(data.from);
|
|
19597
19910
|
}
|
|
19598
19911
|
}
|
|
@@ -19607,11 +19920,15 @@ function assertSourceAccountAddresses(from) {
|
|
|
19607
19920
|
from
|
|
19608
19921
|
];
|
|
19609
19922
|
for (const raw of sources){
|
|
19610
|
-
if (
|
|
19923
|
+
if (raw === null || typeof raw !== 'object' || !('sourceAccount' in raw)) {
|
|
19924
|
+
continue;
|
|
19925
|
+
}
|
|
19611
19926
|
const source = raw;
|
|
19612
|
-
if (
|
|
19927
|
+
if (source.sourceAccount === undefined || source.sourceAccount === '') {
|
|
19928
|
+
continue;
|
|
19929
|
+
}
|
|
19613
19930
|
const sourceChain = getSourceChainFromAllocations(source.allocations);
|
|
19614
|
-
if (
|
|
19931
|
+
if (sourceChain === undefined) continue;
|
|
19615
19932
|
if (!isValidAddressForChain(source.sourceAccount, sourceChain)) {
|
|
19616
19933
|
const chainInfo = extractChainInfo(sourceChain);
|
|
19617
19934
|
throw createInvalidAddressError(source.sourceAccount, String(chainInfo.name), chainInfo.expectedAddressFormat);
|