@circle-fin/app-kit 1.4.1 → 1.5.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 +19 -0
- package/README.md +3 -3
- package/chains.cjs +198 -2
- package/chains.d.ts +6 -2
- package/chains.mjs +198 -2
- package/index.cjs +1040 -221
- package/index.d.ts +326 -2
- package/index.mjs +1040 -221
- package/package.json +5 -5
package/index.cjs
CHANGED
|
@@ -3405,6 +3405,8 @@ exports.Blockchain = void 0;
|
|
|
3405
3405
|
Blockchain["Hedera_Testnet"] = "Hedera_Testnet";
|
|
3406
3406
|
Blockchain["HyperEVM"] = "HyperEVM";
|
|
3407
3407
|
Blockchain["HyperEVM_Testnet"] = "HyperEVM_Testnet";
|
|
3408
|
+
Blockchain["Injective"] = "Injective";
|
|
3409
|
+
Blockchain["Injective_Testnet"] = "Injective_Testnet";
|
|
3408
3410
|
Blockchain["Ink"] = "Ink";
|
|
3409
3411
|
Blockchain["Ink_Testnet"] = "Ink_Testnet";
|
|
3410
3412
|
Blockchain["Linea"] = "Linea";
|
|
@@ -3419,6 +3421,8 @@ exports.Blockchain = void 0;
|
|
|
3419
3421
|
Blockchain["Noble_Testnet"] = "Noble_Testnet";
|
|
3420
3422
|
Blockchain["Optimism"] = "Optimism";
|
|
3421
3423
|
Blockchain["Optimism_Sepolia"] = "Optimism_Sepolia";
|
|
3424
|
+
Blockchain["Pharos"] = "Pharos";
|
|
3425
|
+
Blockchain["Pharos_Testnet"] = "Pharos_Testnet";
|
|
3422
3426
|
Blockchain["Polkadot_Asset_Hub"] = "Polkadot_Asset_Hub";
|
|
3423
3427
|
Blockchain["Polkadot_Westmint"] = "Polkadot_Westmint";
|
|
3424
3428
|
Blockchain["Plume"] = "Plume";
|
|
@@ -3622,11 +3626,13 @@ exports.BridgeChain = void 0;
|
|
|
3622
3626
|
BridgeChain["Edge"] = "Edge";
|
|
3623
3627
|
BridgeChain["Ethereum"] = "Ethereum";
|
|
3624
3628
|
BridgeChain["HyperEVM"] = "HyperEVM";
|
|
3629
|
+
BridgeChain["Injective"] = "Injective";
|
|
3625
3630
|
BridgeChain["Ink"] = "Ink";
|
|
3626
3631
|
BridgeChain["Linea"] = "Linea";
|
|
3627
3632
|
BridgeChain["Monad"] = "Monad";
|
|
3628
3633
|
BridgeChain["Morph"] = "Morph";
|
|
3629
3634
|
BridgeChain["Optimism"] = "Optimism";
|
|
3635
|
+
BridgeChain["Pharos"] = "Pharos";
|
|
3630
3636
|
BridgeChain["Plume"] = "Plume";
|
|
3631
3637
|
BridgeChain["Polygon"] = "Polygon";
|
|
3632
3638
|
BridgeChain["Sei"] = "Sei";
|
|
@@ -3644,11 +3650,13 @@ exports.BridgeChain = void 0;
|
|
|
3644
3650
|
BridgeChain["Edge_Testnet"] = "Edge_Testnet";
|
|
3645
3651
|
BridgeChain["Ethereum_Sepolia"] = "Ethereum_Sepolia";
|
|
3646
3652
|
BridgeChain["HyperEVM_Testnet"] = "HyperEVM_Testnet";
|
|
3653
|
+
BridgeChain["Injective_Testnet"] = "Injective_Testnet";
|
|
3647
3654
|
BridgeChain["Ink_Testnet"] = "Ink_Testnet";
|
|
3648
3655
|
BridgeChain["Linea_Sepolia"] = "Linea_Sepolia";
|
|
3649
3656
|
BridgeChain["Monad_Testnet"] = "Monad_Testnet";
|
|
3650
3657
|
BridgeChain["Morph_Testnet"] = "Morph_Testnet";
|
|
3651
3658
|
BridgeChain["Optimism_Sepolia"] = "Optimism_Sepolia";
|
|
3659
|
+
BridgeChain["Pharos_Testnet"] = "Pharos_Testnet";
|
|
3652
3660
|
BridgeChain["Plume_Testnet"] = "Plume_Testnet";
|
|
3653
3661
|
BridgeChain["Polygon_Amoy_Testnet"] = "Polygon_Amoy_Testnet";
|
|
3654
3662
|
BridgeChain["Sei_Testnet"] = "Sei_Testnet";
|
|
@@ -3994,6 +4002,12 @@ const SWAP_TOKEN_REGISTRY = {
|
|
|
3994
4002
|
category: 'wrapped',
|
|
3995
4003
|
description: 'Wrapped Polygon',
|
|
3996
4004
|
},
|
|
4005
|
+
CIRBTC: {
|
|
4006
|
+
symbol: 'CIRBTC',
|
|
4007
|
+
decimals: 8,
|
|
4008
|
+
category: 'wrapped',
|
|
4009
|
+
description: 'Circle Bitcoin',
|
|
4010
|
+
},
|
|
3997
4011
|
};
|
|
3998
4012
|
/**
|
|
3999
4013
|
* Special NATIVE token constant for swap operations.
|
|
@@ -5081,6 +5095,98 @@ const HyperEVMTestnet = defineChain({
|
|
|
5081
5095
|
},
|
|
5082
5096
|
});
|
|
5083
5097
|
|
|
5098
|
+
/**
|
|
5099
|
+
* Injective Mainnet chain definition
|
|
5100
|
+
* @remarks
|
|
5101
|
+
* This represents the official production network for the Injective blockchain.
|
|
5102
|
+
* Injective is a high-performance, interoperable Layer-1 blockchain built for
|
|
5103
|
+
* finance, with an EVM execution layer on top of a Cosmos SDK base and
|
|
5104
|
+
* sub-second block finality.
|
|
5105
|
+
*/
|
|
5106
|
+
const Injective = defineChain({
|
|
5107
|
+
type: 'evm',
|
|
5108
|
+
chain: exports.Blockchain.Injective,
|
|
5109
|
+
name: 'Injective',
|
|
5110
|
+
title: 'Injective Mainnet',
|
|
5111
|
+
nativeCurrency: {
|
|
5112
|
+
name: 'Injective',
|
|
5113
|
+
symbol: 'INJ',
|
|
5114
|
+
decimals: 18,
|
|
5115
|
+
},
|
|
5116
|
+
chainId: 1776,
|
|
5117
|
+
isTestnet: false,
|
|
5118
|
+
explorerUrl: 'https://injscan.com/transaction/{hash}',
|
|
5119
|
+
rpcEndpoints: ['https://sentry.evm-rpc.injective.network'],
|
|
5120
|
+
eurcAddress: null,
|
|
5121
|
+
usdcAddress: '0xa00C59fF5a080D2b954d0c75e46E22a0c371235a',
|
|
5122
|
+
usdtAddress: null,
|
|
5123
|
+
cctp: {
|
|
5124
|
+
domain: 29,
|
|
5125
|
+
contracts: {
|
|
5126
|
+
v2: {
|
|
5127
|
+
type: 'split',
|
|
5128
|
+
tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
|
|
5129
|
+
messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
|
|
5130
|
+
confirmations: 1,
|
|
5131
|
+
fastConfirmations: 1,
|
|
5132
|
+
},
|
|
5133
|
+
},
|
|
5134
|
+
forwarderSupported: {
|
|
5135
|
+
source: false,
|
|
5136
|
+
destination: false,
|
|
5137
|
+
},
|
|
5138
|
+
},
|
|
5139
|
+
kitContracts: {
|
|
5140
|
+
bridge: BRIDGE_CONTRACT_EVM_MAINNET,
|
|
5141
|
+
},
|
|
5142
|
+
});
|
|
5143
|
+
|
|
5144
|
+
/**
|
|
5145
|
+
* Injective Testnet chain definition
|
|
5146
|
+
* @remarks
|
|
5147
|
+
* This represents the official test network for the Injective blockchain.
|
|
5148
|
+
* Injective is a high-performance, interoperable Layer-1 blockchain built for
|
|
5149
|
+
* finance, with an EVM execution layer on top of a Cosmos SDK base and
|
|
5150
|
+
* sub-second block finality.
|
|
5151
|
+
*/
|
|
5152
|
+
const InjectiveTestnet = defineChain({
|
|
5153
|
+
type: 'evm',
|
|
5154
|
+
chain: exports.Blockchain.Injective_Testnet,
|
|
5155
|
+
name: 'Injective Testnet',
|
|
5156
|
+
title: 'Injective Testnet',
|
|
5157
|
+
nativeCurrency: {
|
|
5158
|
+
name: 'Injective',
|
|
5159
|
+
symbol: 'INJ',
|
|
5160
|
+
decimals: 18,
|
|
5161
|
+
},
|
|
5162
|
+
chainId: 1439,
|
|
5163
|
+
isTestnet: true,
|
|
5164
|
+
explorerUrl: 'https://testnet.explorer.injective.network/transaction/{hash}',
|
|
5165
|
+
rpcEndpoints: ['https://k8s.testnet.json-rpc.injective.network'],
|
|
5166
|
+
eurcAddress: null,
|
|
5167
|
+
usdcAddress: '0x0C382e685bbeeFE5d3d9C29e29E341fEE8E84C5d',
|
|
5168
|
+
usdtAddress: null,
|
|
5169
|
+
cctp: {
|
|
5170
|
+
domain: 29,
|
|
5171
|
+
contracts: {
|
|
5172
|
+
v2: {
|
|
5173
|
+
type: 'split',
|
|
5174
|
+
tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
|
|
5175
|
+
messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
|
|
5176
|
+
confirmations: 1,
|
|
5177
|
+
fastConfirmations: 1,
|
|
5178
|
+
},
|
|
5179
|
+
},
|
|
5180
|
+
forwarderSupported: {
|
|
5181
|
+
source: false,
|
|
5182
|
+
destination: false,
|
|
5183
|
+
},
|
|
5184
|
+
},
|
|
5185
|
+
kitContracts: {
|
|
5186
|
+
bridge: BRIDGE_CONTRACT_EVM_TESTNET,
|
|
5187
|
+
},
|
|
5188
|
+
});
|
|
5189
|
+
|
|
5084
5190
|
/**
|
|
5085
5191
|
* Ink Mainnet chain definition
|
|
5086
5192
|
* @remarks
|
|
@@ -5690,6 +5796,96 @@ const OptimismSepolia = defineChain({
|
|
|
5690
5796
|
},
|
|
5691
5797
|
});
|
|
5692
5798
|
|
|
5799
|
+
/**
|
|
5800
|
+
* Pharos Mainnet chain definition
|
|
5801
|
+
* @remarks
|
|
5802
|
+
* This represents the official production network for the Pharos blockchain.
|
|
5803
|
+
* Pharos is a modular, full-stack parallel Layer 1 blockchain with
|
|
5804
|
+
* sub-second finality and EVM compatibility.
|
|
5805
|
+
*/
|
|
5806
|
+
const Pharos = defineChain({
|
|
5807
|
+
type: 'evm',
|
|
5808
|
+
chain: exports.Blockchain.Pharos,
|
|
5809
|
+
name: 'Pharos',
|
|
5810
|
+
title: 'Pharos Mainnet',
|
|
5811
|
+
nativeCurrency: {
|
|
5812
|
+
name: 'Pharos',
|
|
5813
|
+
symbol: 'PHAROS',
|
|
5814
|
+
decimals: 18,
|
|
5815
|
+
},
|
|
5816
|
+
chainId: 1672,
|
|
5817
|
+
isTestnet: false,
|
|
5818
|
+
explorerUrl: 'https://pharos.socialscan.io/tx/{hash}',
|
|
5819
|
+
rpcEndpoints: ['https://rpc.pharos.xyz'],
|
|
5820
|
+
eurcAddress: null,
|
|
5821
|
+
usdcAddress: '0xC879C018dB60520F4355C26eD1a6D572cdAC1815',
|
|
5822
|
+
usdtAddress: null,
|
|
5823
|
+
cctp: {
|
|
5824
|
+
domain: 31,
|
|
5825
|
+
contracts: {
|
|
5826
|
+
v2: {
|
|
5827
|
+
type: 'split',
|
|
5828
|
+
tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
|
|
5829
|
+
messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
|
|
5830
|
+
confirmations: 1,
|
|
5831
|
+
fastConfirmations: 1,
|
|
5832
|
+
},
|
|
5833
|
+
},
|
|
5834
|
+
forwarderSupported: {
|
|
5835
|
+
source: false,
|
|
5836
|
+
destination: false,
|
|
5837
|
+
},
|
|
5838
|
+
},
|
|
5839
|
+
kitContracts: {
|
|
5840
|
+
bridge: BRIDGE_CONTRACT_EVM_MAINNET,
|
|
5841
|
+
},
|
|
5842
|
+
});
|
|
5843
|
+
|
|
5844
|
+
/**
|
|
5845
|
+
* Pharos Atlantic Testnet chain definition
|
|
5846
|
+
* @remarks
|
|
5847
|
+
* This represents the official test network for the Pharos blockchain.
|
|
5848
|
+
* Pharos is a modular, full-stack parallel Layer 1 blockchain with
|
|
5849
|
+
* sub-second finality and EVM compatibility.
|
|
5850
|
+
*/
|
|
5851
|
+
const PharosTestnet = defineChain({
|
|
5852
|
+
type: 'evm',
|
|
5853
|
+
chain: exports.Blockchain.Pharos_Testnet,
|
|
5854
|
+
name: 'Pharos Atlantic',
|
|
5855
|
+
title: 'Pharos Atlantic Testnet',
|
|
5856
|
+
nativeCurrency: {
|
|
5857
|
+
name: 'Pharos',
|
|
5858
|
+
symbol: 'PHAROS',
|
|
5859
|
+
decimals: 18,
|
|
5860
|
+
},
|
|
5861
|
+
chainId: 688689,
|
|
5862
|
+
isTestnet: true,
|
|
5863
|
+
explorerUrl: 'https://atlantic.pharosscan.xyz/tx/{hash}',
|
|
5864
|
+
rpcEndpoints: ['https://atlantic.dplabs-internal.com'],
|
|
5865
|
+
eurcAddress: null,
|
|
5866
|
+
usdcAddress: '0xcfC8330f4BCAB529c625D12781b1C19466A9Fc8B',
|
|
5867
|
+
usdtAddress: null,
|
|
5868
|
+
cctp: {
|
|
5869
|
+
domain: 31,
|
|
5870
|
+
contracts: {
|
|
5871
|
+
v2: {
|
|
5872
|
+
type: 'split',
|
|
5873
|
+
tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
|
|
5874
|
+
messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
|
|
5875
|
+
confirmations: 1,
|
|
5876
|
+
fastConfirmations: 1,
|
|
5877
|
+
},
|
|
5878
|
+
},
|
|
5879
|
+
forwarderSupported: {
|
|
5880
|
+
source: false,
|
|
5881
|
+
destination: false,
|
|
5882
|
+
},
|
|
5883
|
+
},
|
|
5884
|
+
kitContracts: {
|
|
5885
|
+
bridge: BRIDGE_CONTRACT_EVM_TESTNET,
|
|
5886
|
+
},
|
|
5887
|
+
});
|
|
5888
|
+
|
|
5693
5889
|
/**
|
|
5694
5890
|
* Plume Mainnet chain definition
|
|
5695
5891
|
* @remarks
|
|
@@ -5972,7 +6168,7 @@ const Sei = defineChain({
|
|
|
5972
6168
|
},
|
|
5973
6169
|
chainId: 1329,
|
|
5974
6170
|
isTestnet: false,
|
|
5975
|
-
explorerUrl: 'https://
|
|
6171
|
+
explorerUrl: 'https://seiscan.io/tx/{hash}',
|
|
5976
6172
|
rpcEndpoints: ['https://evm-rpc.sei-apis.com'],
|
|
5977
6173
|
eurcAddress: null,
|
|
5978
6174
|
usdcAddress: '0xe15fC38F6D8c56aF07bbCBe3BAf5708A2Bf42392',
|
|
@@ -6030,7 +6226,7 @@ const SeiTestnet = defineChain({
|
|
|
6030
6226
|
},
|
|
6031
6227
|
chainId: 1328,
|
|
6032
6228
|
isTestnet: true,
|
|
6033
|
-
explorerUrl: 'https://
|
|
6229
|
+
explorerUrl: 'https://testnet.seiscan.io/tx/{hash}',
|
|
6034
6230
|
rpcEndpoints: ['https://evm-rpc-testnet.sei-apis.com'],
|
|
6035
6231
|
eurcAddress: null,
|
|
6036
6232
|
usdcAddress: '0x4fCF1784B31630811181f670Aea7A7bEF803eaED',
|
|
@@ -6833,6 +7029,8 @@ var Chains = {
|
|
|
6833
7029
|
HederaTestnet: HederaTestnet,
|
|
6834
7030
|
HyperEVM: HyperEVM,
|
|
6835
7031
|
HyperEVMTestnet: HyperEVMTestnet,
|
|
7032
|
+
Injective: Injective,
|
|
7033
|
+
InjectiveTestnet: InjectiveTestnet,
|
|
6836
7034
|
Ink: Ink,
|
|
6837
7035
|
InkTestnet: InkTestnet,
|
|
6838
7036
|
Linea: Linea,
|
|
@@ -6847,6 +7045,8 @@ var Chains = {
|
|
|
6847
7045
|
NobleTestnet: NobleTestnet,
|
|
6848
7046
|
Optimism: Optimism,
|
|
6849
7047
|
OptimismSepolia: OptimismSepolia,
|
|
7048
|
+
Pharos: Pharos,
|
|
7049
|
+
PharosTestnet: PharosTestnet,
|
|
6850
7050
|
Plume: Plume,
|
|
6851
7051
|
PlumeTestnet: PlumeTestnet,
|
|
6852
7052
|
PolkadotAssetHub: PolkadotAssetHub,
|
|
@@ -7452,6 +7652,44 @@ function resolveChainIdentifier(chainIdentifier) {
|
|
|
7452
7652
|
throw new Error(`Invalid chain identifier type: ${typeof chainIdentifier}. Expected ChainDefinition object, Blockchain enum, or string literal.`);
|
|
7453
7653
|
}
|
|
7454
7654
|
|
|
7655
|
+
/**
|
|
7656
|
+
* Resolve a chain identifier to a plain chain-name string.
|
|
7657
|
+
*
|
|
7658
|
+
* Accept a string literal (`'Ethereum'`), a `ChainDefinition`-like
|
|
7659
|
+
* object (`{ chain: 'Ethereum' }`), or `null`/`undefined` and return
|
|
7660
|
+
* the chain name as a string. Return `undefined` when the value
|
|
7661
|
+
* cannot be resolved.
|
|
7662
|
+
*
|
|
7663
|
+
* @remarks
|
|
7664
|
+
* Unlike `resolveChainIdentifier` (which returns a full `ChainDefinition`
|
|
7665
|
+
* and throws on invalid input), this helper is intentionally lenient and
|
|
7666
|
+
* never throws — it is safe to call in error-handling and telemetry paths.
|
|
7667
|
+
*
|
|
7668
|
+
* @param value - A string, chain-definition object, or nullish value.
|
|
7669
|
+
* @returns The chain name string, or `undefined`.
|
|
7670
|
+
*
|
|
7671
|
+
* @example
|
|
7672
|
+
* ```typescript
|
|
7673
|
+
* import { resolveChainName } from '@core/chains'
|
|
7674
|
+
*
|
|
7675
|
+
* resolveChainName('Ethereum') // 'Ethereum'
|
|
7676
|
+
* resolveChainName({ chain: 'Ethereum' }) // 'Ethereum'
|
|
7677
|
+
* resolveChainName(undefined) // undefined
|
|
7678
|
+
* ```
|
|
7679
|
+
*/
|
|
7680
|
+
function resolveChainName(value) {
|
|
7681
|
+
if (value == null)
|
|
7682
|
+
return undefined;
|
|
7683
|
+
if (typeof value === 'string')
|
|
7684
|
+
return value;
|
|
7685
|
+
if (typeof value === 'object' &&
|
|
7686
|
+
'chain' in value &&
|
|
7687
|
+
typeof value.chain === 'string') {
|
|
7688
|
+
return value.chain;
|
|
7689
|
+
}
|
|
7690
|
+
return undefined;
|
|
7691
|
+
}
|
|
7692
|
+
|
|
7455
7693
|
/**
|
|
7456
7694
|
* @packageDocumentation
|
|
7457
7695
|
* @module SwapTokenUtils
|
|
@@ -9108,6 +9346,7 @@ const USDC = {
|
|
|
9108
9346
|
[exports.Blockchain.Ethereum]: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
|
|
9109
9347
|
[exports.Blockchain.Hedera]: '0.0.456858',
|
|
9110
9348
|
[exports.Blockchain.HyperEVM]: '0xb88339CB7199b77E23DB6E890353E22632Ba630f',
|
|
9349
|
+
[exports.Blockchain.Injective]: '0xa00C59fF5a080D2b954d0c75e46E22a0c371235a',
|
|
9111
9350
|
[exports.Blockchain.Ink]: '0x2D270e6886d130D724215A266106e6832161EAEd',
|
|
9112
9351
|
[exports.Blockchain.Linea]: '0x176211869ca2b568f2a7d4ee941e073a821ee1ff',
|
|
9113
9352
|
[exports.Blockchain.Monad]: '0x754704Bc059F8C67012fEd69BC8A327a5aafb603',
|
|
@@ -9115,6 +9354,7 @@ const USDC = {
|
|
|
9115
9354
|
[exports.Blockchain.NEAR]: '17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1',
|
|
9116
9355
|
[exports.Blockchain.Noble]: 'uusdc',
|
|
9117
9356
|
[exports.Blockchain.Optimism]: '0x0b2c639c533813f4aa9d7837caf62653d097ff85',
|
|
9357
|
+
[exports.Blockchain.Pharos]: '0xC879C018dB60520F4355C26eD1a6D572cdAC1815',
|
|
9118
9358
|
[exports.Blockchain.Plume]: '0x222365EF19F7947e5484218551B56bb3965Aa7aF',
|
|
9119
9359
|
[exports.Blockchain.Polkadot_Asset_Hub]: '1337',
|
|
9120
9360
|
[exports.Blockchain.Polygon]: '0x3c499c542cef5e3811e1192ce70d8cc03d5c3359',
|
|
@@ -9139,6 +9379,7 @@ const USDC = {
|
|
|
9139
9379
|
[exports.Blockchain.Ethereum_Sepolia]: '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238',
|
|
9140
9380
|
[exports.Blockchain.Hedera_Testnet]: '0.0.429274',
|
|
9141
9381
|
[exports.Blockchain.HyperEVM_Testnet]: '0x2B3370eE501B4a559b57D449569354196457D8Ab',
|
|
9382
|
+
[exports.Blockchain.Injective_Testnet]: '0x0C382e685bbeeFE5d3d9C29e29E341fEE8E84C5d',
|
|
9142
9383
|
[exports.Blockchain.Ink_Testnet]: '0xFabab97dCE620294D2B0b0e46C68964e326300Ac',
|
|
9143
9384
|
[exports.Blockchain.Linea_Sepolia]: '0xfece4462d57bd51a6a552365a011b95f0e16d9b7',
|
|
9144
9385
|
[exports.Blockchain.Monad_Testnet]: '0x534b2f3A21130d7a60830c2Df862319e593943A3',
|
|
@@ -9146,6 +9387,7 @@ const USDC = {
|
|
|
9146
9387
|
[exports.Blockchain.NEAR_Testnet]: '3e2210e1184b45b64c8a434c0a7e7b23cc04ea7eb7a6c3c32520d03d4afcb8af',
|
|
9147
9388
|
[exports.Blockchain.Noble_Testnet]: 'uusdc',
|
|
9148
9389
|
[exports.Blockchain.Optimism_Sepolia]: '0x5fd84259d66Cd46123540766Be93DFE6D43130D7',
|
|
9390
|
+
[exports.Blockchain.Pharos_Testnet]: '0xcfC8330f4BCAB529c625D12781b1C19466A9Fc8B',
|
|
9149
9391
|
[exports.Blockchain.Plume_Testnet]: '0xcB5f30e335672893c7eb944B374c196392C19D18',
|
|
9150
9392
|
[exports.Blockchain.Polkadot_Westmint]: '31337',
|
|
9151
9393
|
[exports.Blockchain.Polygon_Amoy_Testnet]: '0x41e94eb019c0762f9bfcf9fb1e58725bfb0e7582',
|
|
@@ -9426,6 +9668,32 @@ const MON = {
|
|
|
9426
9668
|
},
|
|
9427
9669
|
};
|
|
9428
9670
|
|
|
9671
|
+
/**
|
|
9672
|
+
* cirBTC (Circle Bitcoin) token definition with addresses and metadata.
|
|
9673
|
+
*
|
|
9674
|
+
* @remarks
|
|
9675
|
+
* Built-in cirBTC definition for the TokenRegistry. Currently deployed
|
|
9676
|
+
* on Arc Testnet.
|
|
9677
|
+
*
|
|
9678
|
+
* @example
|
|
9679
|
+
* ```typescript
|
|
9680
|
+
* import { CIRBTC } from '@core/tokens'
|
|
9681
|
+
* import { Blockchain } from '@core/chains'
|
|
9682
|
+
*
|
|
9683
|
+
* console.log(CIRBTC.symbol) // 'cirBTC'
|
|
9684
|
+
* console.log(CIRBTC.decimals) // 8
|
|
9685
|
+
* console.log(CIRBTC.locators[Blockchain.Arc_Testnet])
|
|
9686
|
+
* // '0xf0C4a4CE82A5746AbAAd9425360Ab04fbBA432BF'
|
|
9687
|
+
* ```
|
|
9688
|
+
*/
|
|
9689
|
+
const CIRBTC = {
|
|
9690
|
+
symbol: 'cirBTC',
|
|
9691
|
+
decimals: 8,
|
|
9692
|
+
locators: {
|
|
9693
|
+
[exports.Blockchain.Arc_Testnet]: '0xf0C4a4CE82A5746AbAAd9425360Ab04fbBA432BF',
|
|
9694
|
+
},
|
|
9695
|
+
};
|
|
9696
|
+
|
|
9429
9697
|
// Re-export for consumers
|
|
9430
9698
|
/**
|
|
9431
9699
|
* All default token definitions.
|
|
@@ -9434,7 +9702,7 @@ const MON = {
|
|
|
9434
9702
|
* These tokens are automatically included in the TokenRegistry when created
|
|
9435
9703
|
* without explicit defaults. Extensions can override these definitions.
|
|
9436
9704
|
* Includes USDC, USDT, EURC, DAI, USDE, PYUSD, WETH, WBTC, WSOL, WAVAX,
|
|
9437
|
-
* WPOL, ETH, POL, PLUME, and
|
|
9705
|
+
* WPOL, ETH, POL, PLUME, MON, and cirBTC.
|
|
9438
9706
|
*
|
|
9439
9707
|
* @example
|
|
9440
9708
|
* ```typescript
|
|
@@ -9465,6 +9733,7 @@ const DEFAULT_TOKENS = [
|
|
|
9465
9733
|
POL,
|
|
9466
9734
|
PLUME,
|
|
9467
9735
|
MON,
|
|
9736
|
+
CIRBTC,
|
|
9468
9737
|
];
|
|
9469
9738
|
/**
|
|
9470
9739
|
* Uppercased token symbols approved for swap fee collection.
|
|
@@ -10212,8 +10481,325 @@ async function retryAsync(fn, options) {
|
|
|
10212
10481
|
throw new Error('retryAsync: unreachable');
|
|
10213
10482
|
}
|
|
10214
10483
|
|
|
10484
|
+
/**
|
|
10485
|
+
* Default telemetry endpoint.
|
|
10486
|
+
*
|
|
10487
|
+
* Override via the `STABLECOIN_KITS_TELEMETRY_URL` environment variable
|
|
10488
|
+
* (e.g. for staging or local development).
|
|
10489
|
+
*
|
|
10490
|
+
* @internal
|
|
10491
|
+
*/
|
|
10492
|
+
const DEFAULT_LOGS_URL = 'https://api.circle.com/v1/stablecoinKits/logs';
|
|
10493
|
+
/**
|
|
10494
|
+
* Resolve the telemetry endpoint URL.
|
|
10495
|
+
*
|
|
10496
|
+
* @internal
|
|
10497
|
+
*/
|
|
10498
|
+
function getLogsUrl() {
|
|
10499
|
+
if (isNodeEnvironment() &&
|
|
10500
|
+
typeof process.env['STABLECOIN_KITS_TELEMETRY_URL'] === 'string' &&
|
|
10501
|
+
process.env['STABLECOIN_KITS_TELEMETRY_URL'].length > 0) {
|
|
10502
|
+
return process.env['STABLECOIN_KITS_TELEMETRY_URL'];
|
|
10503
|
+
}
|
|
10504
|
+
return DEFAULT_LOGS_URL;
|
|
10505
|
+
}
|
|
10506
|
+
/**
|
|
10507
|
+
* Send a telemetry event to the proxy service.
|
|
10508
|
+
*
|
|
10509
|
+
* @remarks
|
|
10510
|
+
* Fire-and-forget: the returned promise is intentionally not awaited
|
|
10511
|
+
* by the caller. A fetch failure (network error, non-2xx, timeout)
|
|
10512
|
+
* is silently swallowed so telemetry never blocks or fails user
|
|
10513
|
+
* operations.
|
|
10514
|
+
*
|
|
10515
|
+
* @param payload - The structured log payload matching the server schema.
|
|
10516
|
+
*
|
|
10517
|
+
* @example
|
|
10518
|
+
* ```typescript
|
|
10519
|
+
* import { emitAnalyticsLog } from '@core/utils'
|
|
10520
|
+
*
|
|
10521
|
+
* // Fire-and-forget — do not await
|
|
10522
|
+
* void emitAnalyticsLog(payload)
|
|
10523
|
+
* ```
|
|
10524
|
+
*/
|
|
10525
|
+
async function emitAnalyticsLog(payload) {
|
|
10526
|
+
try {
|
|
10527
|
+
const isNode = isNodeEnvironment();
|
|
10528
|
+
const userAgent = getUserAgent();
|
|
10529
|
+
await fetch(getLogsUrl(), {
|
|
10530
|
+
method: 'POST',
|
|
10531
|
+
headers: {
|
|
10532
|
+
'Content-Type': 'application/json',
|
|
10533
|
+
// Browser restricts setting User-Agent; use X-User-Agent instead.
|
|
10534
|
+
...(isNode
|
|
10535
|
+
? { 'User-Agent': userAgent }
|
|
10536
|
+
: { 'X-User-Agent': userAgent }),
|
|
10537
|
+
},
|
|
10538
|
+
body: JSON.stringify(payload),
|
|
10539
|
+
signal: AbortSignal.timeout(5_000),
|
|
10540
|
+
});
|
|
10541
|
+
}
|
|
10542
|
+
catch {
|
|
10543
|
+
// Silently swallow — telemetry must never break user operations.
|
|
10544
|
+
}
|
|
10545
|
+
}
|
|
10546
|
+
|
|
10547
|
+
/**
|
|
10548
|
+
* Build the `clientContext` object for telemetry payloads.
|
|
10549
|
+
*
|
|
10550
|
+
* @remarks
|
|
10551
|
+
* Use the exported `getRuntime()` and `isNodeEnvironment()` from
|
|
10552
|
+
* `@core/utils` to detect the runtime environment. The returned
|
|
10553
|
+
* string is parsed into the structured `ClientContext` fields
|
|
10554
|
+
* expected by the server schema.
|
|
10555
|
+
*
|
|
10556
|
+
* @returns A {@link ClientContext} with platform, OS, and runtime name
|
|
10557
|
+
* populated from the current environment.
|
|
10558
|
+
*
|
|
10559
|
+
* @example
|
|
10560
|
+
* ```typescript
|
|
10561
|
+
* import { buildClientContext } from '@core/utils'
|
|
10562
|
+
*
|
|
10563
|
+
* const ctx = buildClientContext()
|
|
10564
|
+
* // Node: { platform: 'node', os: 'darwin', runtimeName: null }
|
|
10565
|
+
* // Browser: { platform: 'browser', os: null, runtimeName: 'chrome' }
|
|
10566
|
+
* ```
|
|
10567
|
+
*/
|
|
10568
|
+
function buildClientContext() {
|
|
10569
|
+
const runtime = getRuntime();
|
|
10570
|
+
if (runtime.startsWith('browser/')) {
|
|
10571
|
+
return {
|
|
10572
|
+
platform: 'browser',
|
|
10573
|
+
os: null,
|
|
10574
|
+
runtimeName: runtime.slice('browser/'.length).toLowerCase(),
|
|
10575
|
+
};
|
|
10576
|
+
}
|
|
10577
|
+
if (runtime.startsWith('node/')) {
|
|
10578
|
+
return {
|
|
10579
|
+
platform: 'node',
|
|
10580
|
+
os: isNodeEnvironment() ? process.platform : null,
|
|
10581
|
+
runtimeName: null,
|
|
10582
|
+
};
|
|
10583
|
+
}
|
|
10584
|
+
return {
|
|
10585
|
+
platform: 'node',
|
|
10586
|
+
os: null,
|
|
10587
|
+
runtimeName: null,
|
|
10588
|
+
};
|
|
10589
|
+
}
|
|
10590
|
+
|
|
10591
|
+
/**
|
|
10592
|
+
* Extract structured error details from an unknown error value.
|
|
10593
|
+
*
|
|
10594
|
+
* @remarks
|
|
10595
|
+
* Handle three cases:
|
|
10596
|
+
* - `KitError` — extract `code` and `name`.
|
|
10597
|
+
* - `Error` — extract `name`.
|
|
10598
|
+
* - Anything else — return empty details.
|
|
10599
|
+
*
|
|
10600
|
+
* Only structured, bounded fields (`errorCode`, `errorType`) are
|
|
10601
|
+
* included. Free-text fields (`message`, `stack`) are intentionally
|
|
10602
|
+
* omitted to avoid leaking secrets or PII through vendor telemetry.
|
|
10603
|
+
*
|
|
10604
|
+
* @param error - The thrown value to extract details from.
|
|
10605
|
+
* @returns A {@link ErrorDetails} object suitable for telemetry payloads.
|
|
10606
|
+
*
|
|
10607
|
+
* @example
|
|
10608
|
+
* ```typescript
|
|
10609
|
+
* import { extractErrorDetails } from '@core/utils'
|
|
10610
|
+
*
|
|
10611
|
+
* try {
|
|
10612
|
+
* await riskyOperation()
|
|
10613
|
+
* } catch (error) {
|
|
10614
|
+
* const details = extractErrorDetails(error)
|
|
10615
|
+
* // { errorCode: '1001', errorType: 'INPUT_NETWORK_MISMATCH' }
|
|
10616
|
+
* }
|
|
10617
|
+
* ```
|
|
10618
|
+
*/
|
|
10619
|
+
function extractErrorDetails(error) {
|
|
10620
|
+
if (error instanceof KitError) {
|
|
10621
|
+
return {
|
|
10622
|
+
errorCode: String(error.code),
|
|
10623
|
+
errorType: error.name,
|
|
10624
|
+
};
|
|
10625
|
+
}
|
|
10626
|
+
if (error instanceof Error) {
|
|
10627
|
+
return {
|
|
10628
|
+
errorType: error.name,
|
|
10629
|
+
};
|
|
10630
|
+
}
|
|
10631
|
+
return {};
|
|
10632
|
+
}
|
|
10633
|
+
|
|
10634
|
+
/**
|
|
10635
|
+
* Register event handlers on an action dispatcher that emit analytics
|
|
10636
|
+
* telemetry for the configured events.
|
|
10637
|
+
*
|
|
10638
|
+
* @remarks
|
|
10639
|
+
* Subscribe to each action name in `actionEventMap`, call `mapEventToPayload`
|
|
10640
|
+
* for each event, and fire-and-forget `emitAnalyticsLog` if a non-null
|
|
10641
|
+
* payload is returned. All errors are silently swallowed so telemetry
|
|
10642
|
+
* never blocks or fails user operations.
|
|
10643
|
+
*
|
|
10644
|
+
* @param dispatcher - The `Actionable` instance from the kit.
|
|
10645
|
+
* @param sdkName - SDK package name (e.g. `'unified-balance-kit'`).
|
|
10646
|
+
* @param sdkVersion - SDK version string (e.g. `'1.0.0'`).
|
|
10647
|
+
* @param actionEventMap - Map of action names to subscribe to.
|
|
10648
|
+
* @param mapEventToPayload - Function that maps an action name and payload
|
|
10649
|
+
* to a {@link ClientLogPayload}, or `null` to skip logging.
|
|
10650
|
+
*
|
|
10651
|
+
* @example
|
|
10652
|
+
* ```typescript
|
|
10653
|
+
* import { registerTelemetryHandler } from '@core/utils'
|
|
10654
|
+
*
|
|
10655
|
+
* registerTelemetryHandler(
|
|
10656
|
+
* dispatcher,
|
|
10657
|
+
* 'unified-balance-kit',
|
|
10658
|
+
* '1.0.0',
|
|
10659
|
+
* VERB_EVENT_MAP,
|
|
10660
|
+
* mapSucceededEventToLog,
|
|
10661
|
+
* )
|
|
10662
|
+
* ```
|
|
10663
|
+
*/
|
|
10664
|
+
function registerTelemetryHandler$1(dispatcher, sdkName, sdkVersion, actionEventMap, mapEventToPayload) {
|
|
10665
|
+
for (const actionName of Object.keys(actionEventMap)) {
|
|
10666
|
+
dispatcher.on(actionName, (payload) => {
|
|
10667
|
+
try {
|
|
10668
|
+
const log = mapEventToPayload(actionName, payload, sdkName, sdkVersion);
|
|
10669
|
+
if (log) {
|
|
10670
|
+
// Fire-and-forget — intentionally not awaited.
|
|
10671
|
+
void emitAnalyticsLog(log);
|
|
10672
|
+
}
|
|
10673
|
+
}
|
|
10674
|
+
catch {
|
|
10675
|
+
// Silently swallow — telemetry must never break user operations.
|
|
10676
|
+
}
|
|
10677
|
+
});
|
|
10678
|
+
}
|
|
10679
|
+
}
|
|
10680
|
+
|
|
10681
|
+
/**
|
|
10682
|
+
* Strip the `@circle-fin/` scope from a kit package name to produce the
|
|
10683
|
+
* short SDK name used in telemetry payloads.
|
|
10684
|
+
*
|
|
10685
|
+
* @param pkgName - The full npm package name (e.g. `@circle-fin/bridge-kit`).
|
|
10686
|
+
* @returns The unscoped kit name (e.g. `bridge-kit`).
|
|
10687
|
+
*
|
|
10688
|
+
* @example
|
|
10689
|
+
* ```typescript
|
|
10690
|
+
* import pkg from '../../package.json'
|
|
10691
|
+
* import { resolveKitSdkName } from '@core/utils'
|
|
10692
|
+
*
|
|
10693
|
+
* const SDK_NAME = resolveKitSdkName(pkg.name) // 'bridge-kit'
|
|
10694
|
+
* ```
|
|
10695
|
+
*/
|
|
10696
|
+
function resolveKitSdkName(pkgName) {
|
|
10697
|
+
return pkgName.replace('@circle-fin/', '');
|
|
10698
|
+
}
|
|
10699
|
+
|
|
10700
|
+
/**
|
|
10701
|
+
* Build a telemetry payload from common fields.
|
|
10702
|
+
*
|
|
10703
|
+
* @internal
|
|
10704
|
+
*/
|
|
10705
|
+
function buildPayload$1(config, eventType, errorDetails, context) {
|
|
10706
|
+
return {
|
|
10707
|
+
sdkName: config.sdkName,
|
|
10708
|
+
sdkVersion: config.sdkVersion,
|
|
10709
|
+
eventType,
|
|
10710
|
+
timestamp: new Date().toISOString(),
|
|
10711
|
+
errorDetails,
|
|
10712
|
+
clientContext: buildClientContext(),
|
|
10713
|
+
...(context?.sourceChain != null && {
|
|
10714
|
+
sourceChain: context.sourceChain,
|
|
10715
|
+
}),
|
|
10716
|
+
...(context?.destinationChain != null && {
|
|
10717
|
+
destinationChain: context.destinationChain,
|
|
10718
|
+
}),
|
|
10719
|
+
...(context?.tokenIn != null && { tokenIn: context.tokenIn }),
|
|
10720
|
+
...(context?.tokenOut != null && { tokenOut: context.tokenOut }),
|
|
10721
|
+
};
|
|
10722
|
+
}
|
|
10723
|
+
/**
|
|
10724
|
+
* Wrap an async operation with error telemetry.
|
|
10725
|
+
*
|
|
10726
|
+
* Execute `fn` and, if it throws, emit an error telemetry payload
|
|
10727
|
+
* before re-throwing. No-ops when `config.disabled` is `true`.
|
|
10728
|
+
*
|
|
10729
|
+
* @param fn - The async operation to execute.
|
|
10730
|
+
* @param eventType - The telemetry event type for this operation.
|
|
10731
|
+
* @param config - Per-kit SDK identity and disabled flag.
|
|
10732
|
+
* @param context - Optional chain/token context.
|
|
10733
|
+
* @returns The result of the operation.
|
|
10734
|
+
* @throws Re-throws any error after emitting telemetry.
|
|
10735
|
+
*
|
|
10736
|
+
* @example
|
|
10737
|
+
* ```typescript
|
|
10738
|
+
* import { withErrorTelemetry } from '@core/utils'
|
|
10739
|
+
*
|
|
10740
|
+
* const result = await withErrorTelemetry(
|
|
10741
|
+
* () => provider.bridge(params),
|
|
10742
|
+
* 'bridge_bridge',
|
|
10743
|
+
* { sdkName: 'bridge-kit', sdkVersion: '1.0.0', disabled: false },
|
|
10744
|
+
* { sourceChain: 'Ethereum', destinationChain: 'Base', tokenIn: 'USDC' },
|
|
10745
|
+
* )
|
|
10746
|
+
* ```
|
|
10747
|
+
*/
|
|
10748
|
+
async function withErrorTelemetry(fn, eventType, config, context) {
|
|
10749
|
+
try {
|
|
10750
|
+
return await fn();
|
|
10751
|
+
}
|
|
10752
|
+
catch (error) {
|
|
10753
|
+
if (!config.disabled) {
|
|
10754
|
+
void emitAnalyticsLog(buildPayload$1(config, eventType, extractErrorDetails(error), context));
|
|
10755
|
+
}
|
|
10756
|
+
throw error;
|
|
10757
|
+
}
|
|
10758
|
+
}
|
|
10759
|
+
/**
|
|
10760
|
+
* Emit error telemetry for a result-reported step error.
|
|
10761
|
+
*
|
|
10762
|
+
* Handle the case where a provider reports a step failure inside a
|
|
10763
|
+
* result object (e.g. `BridgeResult.state === 'error'`) rather than
|
|
10764
|
+
* throwing. The caller extracts the failed step as a simple
|
|
10765
|
+
* {@link FailedStepInfo} — this function handles sanitization,
|
|
10766
|
+
* step-to-event mapping, and emission.
|
|
10767
|
+
*
|
|
10768
|
+
* No-ops when `config.disabled` is `true`.
|
|
10769
|
+
*
|
|
10770
|
+
* @param failedStep - The failed step info, or undefined if none found.
|
|
10771
|
+
* @param stepEventMap - Ordered mapping from step names to event types.
|
|
10772
|
+
* @param fallbackEventType - Event type when step is not in the map.
|
|
10773
|
+
* @param config - Per-kit SDK identity and disabled flag.
|
|
10774
|
+
* @param context - Optional chain/token context.
|
|
10775
|
+
*
|
|
10776
|
+
* @example
|
|
10777
|
+
* ```typescript
|
|
10778
|
+
* import { emitResultStepErrorTelemetry } from '@core/utils'
|
|
10779
|
+
*
|
|
10780
|
+
* const failedStep = result.steps.find((s) => s.state === 'error')
|
|
10781
|
+
* emitResultStepErrorTelemetry(
|
|
10782
|
+
* failedStep,
|
|
10783
|
+
* BRIDGE_STEP_EVENT_MAP,
|
|
10784
|
+
* 'bridge_bridge',
|
|
10785
|
+
* { sdkName: 'bridge-kit', sdkVersion: '1.0.0', disabled: false },
|
|
10786
|
+
* { sourceChain: 'Ethereum', tokenIn: 'USDC' },
|
|
10787
|
+
* )
|
|
10788
|
+
* ```
|
|
10789
|
+
*/
|
|
10790
|
+
function emitResultStepErrorTelemetry(failedStep, stepEventMap, fallbackEventType, config, context) {
|
|
10791
|
+
if (config.disabled) {
|
|
10792
|
+
return;
|
|
10793
|
+
}
|
|
10794
|
+
const stepEntry = stepEventMap.find(([name]) => name === failedStep?.name);
|
|
10795
|
+
const errorDetails = {
|
|
10796
|
+
...(failedStep?.name != null && { errorType: failedStep.name }),
|
|
10797
|
+
};
|
|
10798
|
+
void emitAnalyticsLog(buildPayload$1(config, stepEntry?.[1] ?? fallbackEventType, errorDetails, context));
|
|
10799
|
+
}
|
|
10800
|
+
|
|
10215
10801
|
var name$2 = "@circle-fin/bridge-kit";
|
|
10216
|
-
var version$3 = "1.
|
|
10802
|
+
var version$3 = "1.10.0";
|
|
10217
10803
|
var pkg$3 = {
|
|
10218
10804
|
name: name$2,
|
|
10219
10805
|
version: version$3};
|
|
@@ -13178,18 +13764,16 @@ const buildIrisUrl = (sourceDomainId, transactionHash, isTestnet) => {
|
|
|
13178
13764
|
};
|
|
13179
13765
|
/**
|
|
13180
13766
|
* Fetches attestation data from the IRIS API with retry and timeout handling.
|
|
13181
|
-
* Since fetching starts after a confirmed burn transaction, we attempt up to 10 retries.
|
|
13182
|
-
* Implements a conservative delay between requests to respect the API rate
|
|
13183
|
-
* limit of 35 requests per second. To avoid rate limiting when multiple processes are
|
|
13184
|
-
* running concurrently, we enforce a 200ms delay between retries.
|
|
13185
13767
|
*
|
|
13186
|
-
*
|
|
13187
|
-
*
|
|
13768
|
+
* Polls the IRIS API until a complete attestation is available. The default
|
|
13769
|
+
* window is sized for slow source chains where finality may take many
|
|
13770
|
+
* confirmations.
|
|
13188
13771
|
*
|
|
13189
|
-
*
|
|
13190
|
-
* - Per
|
|
13191
|
-
* - Retry
|
|
13192
|
-
* -
|
|
13772
|
+
* Defaults (see `DEFAULT_CONFIG`):
|
|
13773
|
+
* - Per-attempt timeout: 2 000 ms (each HTTP request aborts after 2 s)
|
|
13774
|
+
* - Retry delay: 2 000 ms between attempts
|
|
13775
|
+
* - Max retries: 600 (30 × 20)
|
|
13776
|
+
* - Total worst-case polling window: 600 × (2 000 ms + 2 000 ms) ≈ 40 minutes
|
|
13193
13777
|
*
|
|
13194
13778
|
* @param sourceDomainId - The CCTP domain ID.
|
|
13195
13779
|
* @param transactionHash - The transaction hash to fetch attestation for.
|
|
@@ -14344,11 +14928,18 @@ async function executePreparedChainRequest({ name, request, adapter, chain, conf
|
|
|
14344
14928
|
step.explorerUrl = buildExplorerUrl(chain, txHash);
|
|
14345
14929
|
if (outcome.errorMessage) {
|
|
14346
14930
|
step.errorMessage = outcome.errorMessage;
|
|
14931
|
+
// Transaction was mined but reverted on-chain.
|
|
14932
|
+
step.errorCategory = 'chain_revert';
|
|
14347
14933
|
}
|
|
14348
14934
|
}
|
|
14349
14935
|
catch (err) {
|
|
14350
14936
|
step.state = 'error';
|
|
14351
14937
|
step.error = err;
|
|
14938
|
+
// Sequential path does not yet attempt fine-grained classification of
|
|
14939
|
+
// pre-submission errors (user_rejected, capability errors, etc.). Mark
|
|
14940
|
+
// as `unknown` so consumers can at least detect the category is
|
|
14941
|
+
// populated uniformly across batched and sequential flows.
|
|
14942
|
+
step.errorCategory = 'unknown';
|
|
14352
14943
|
// Optionally parse for common blockchain error formats
|
|
14353
14944
|
if (err instanceof Error) {
|
|
14354
14945
|
step.errorMessage = err.message;
|
|
@@ -15014,16 +15605,70 @@ async function executeBatchedApproveAndBurn(params, provider) {
|
|
|
15014
15605
|
const batchResult = await adapter.batchExecute([approveCallData, burnCallData], chain);
|
|
15015
15606
|
const approveReceipt = batchResult.receipts[0];
|
|
15016
15607
|
const burnReceipt = batchResult.receipts[1];
|
|
15017
|
-
const approveStep = await buildBatchedStep('approve', approveReceipt, batchResult.batchId, adapter, chain);
|
|
15018
|
-
const burnStep = await buildBatchedStep('burn', burnReceipt, batchResult.batchId, adapter, chain);
|
|
15608
|
+
const approveStep = await buildBatchedStep('approve', approveReceipt, batchResult.batchId, adapter, chain, batchResult.statusCode, batchResult.error);
|
|
15609
|
+
const burnStep = await buildBatchedStep('burn', burnReceipt, batchResult.batchId, adapter, chain, batchResult.statusCode, batchResult.error);
|
|
15019
15610
|
if (burnStep.state !== 'error' && !burnStep.txHash) {
|
|
15020
15611
|
burnStep.state = 'error';
|
|
15021
15612
|
burnStep.errorMessage =
|
|
15022
15613
|
'Batched burn step completed but no transaction hash was returned.';
|
|
15614
|
+
burnStep.errorCategory = 'unknown';
|
|
15023
15615
|
}
|
|
15024
15616
|
const context = { burnTxHash: burnStep.txHash ?? '' };
|
|
15025
15617
|
return { approveStep, burnStep, context };
|
|
15026
15618
|
}
|
|
15619
|
+
/**
|
|
15620
|
+
* Derive a {@link BridgeStepErrorCategory} for a missing receipt.
|
|
15621
|
+
*
|
|
15622
|
+
* Combines the EIP-5792 `statusCode` (when present) with the underlying
|
|
15623
|
+
* polling error (when set) to produce the most specific category available.
|
|
15624
|
+
* Falls back to `'unknown'` when neither signal is conclusive.
|
|
15625
|
+
*
|
|
15626
|
+
* @param statusCode - The terminal `statusCode` from `wallet_getCallsStatus`, if any.
|
|
15627
|
+
* @param batchError - The polling error from `batchExecute`, if any.
|
|
15628
|
+
* @returns The derived error category for a missing-receipt step.
|
|
15629
|
+
*
|
|
15630
|
+
* @internal
|
|
15631
|
+
*/
|
|
15632
|
+
function categorizeMissingReceipt(statusCode, batchError) {
|
|
15633
|
+
if (statusCode === 400)
|
|
15634
|
+
return 'failed_offchain';
|
|
15635
|
+
if (statusCode === 500)
|
|
15636
|
+
return 'reverted_onchain';
|
|
15637
|
+
if (statusCode === 600)
|
|
15638
|
+
return 'partial_reverted';
|
|
15639
|
+
if (batchError instanceof KitError &&
|
|
15640
|
+
batchError.code === NetworkError.TIMEOUT.code) {
|
|
15641
|
+
return 'polling_timeout';
|
|
15642
|
+
}
|
|
15643
|
+
return 'unknown';
|
|
15644
|
+
}
|
|
15645
|
+
/**
|
|
15646
|
+
* Derive a {@link BridgeStepErrorCategory} for a receipt that was returned
|
|
15647
|
+
* but whose per-call `status` is not `'success'`.
|
|
15648
|
+
*
|
|
15649
|
+
* A numeric EIP-5792 `statusCode` of 500 or 600 tells us the whole batch
|
|
15650
|
+
* reverted on-chain (completely or partially); otherwise the receipt
|
|
15651
|
+
* itself signalled a revert without a distinguishing code, so classify
|
|
15652
|
+
* as a plain on-chain revert.
|
|
15653
|
+
*
|
|
15654
|
+
* @param statusCode - The terminal `statusCode` from `wallet_getCallsStatus`, if any.
|
|
15655
|
+
* @returns The derived error category for a failed-receipt step.
|
|
15656
|
+
*
|
|
15657
|
+
* @internal
|
|
15658
|
+
*/
|
|
15659
|
+
function categorizeFailedReceipt(statusCode) {
|
|
15660
|
+
// Mirror categorizeMissingReceipt: if the wallet's terminal status is
|
|
15661
|
+
// 400 ("batch not included onchain"), that judgement is authoritative
|
|
15662
|
+
// even when a non-success receipt is attached. Without this, a wrapped
|
|
15663
|
+
// 400 receipt would fall through to `chain_revert` and mislead UX.
|
|
15664
|
+
if (statusCode === 400)
|
|
15665
|
+
return 'failed_offchain';
|
|
15666
|
+
if (statusCode === 600)
|
|
15667
|
+
return 'partial_reverted';
|
|
15668
|
+
if (statusCode === 500)
|
|
15669
|
+
return 'reverted_onchain';
|
|
15670
|
+
return 'chain_revert';
|
|
15671
|
+
}
|
|
15027
15672
|
/**
|
|
15028
15673
|
* Build a {@link BridgeStep} from a single receipt within a batch.
|
|
15029
15674
|
*
|
|
@@ -15038,11 +15683,17 @@ async function executeBatchedApproveAndBurn(params, provider) {
|
|
|
15038
15683
|
* @param batchId - Wallet-assigned batch identifier.
|
|
15039
15684
|
* @param adapter - The batch-capable adapter (used for confirmation).
|
|
15040
15685
|
* @param chain - The EVM chain the batch was executed on.
|
|
15686
|
+
* @param statusCode - Optional EIP-5792 `statusCode` for the batch.
|
|
15687
|
+
* Used to classify the step's error category when the receipt is
|
|
15688
|
+
* missing or failed.
|
|
15689
|
+
* @param batchError - Optional polling error from `batchExecute`.
|
|
15690
|
+
* Preserved on the step so callers can inspect underlying timeouts
|
|
15691
|
+
* or RPC failures.
|
|
15041
15692
|
* @returns A fully-populated bridge step with state, tx hash and explorer URL.
|
|
15042
15693
|
*
|
|
15043
15694
|
* @internal
|
|
15044
15695
|
*/
|
|
15045
|
-
async function buildBatchedStep(name, receipt, batchId, adapter, chain) {
|
|
15696
|
+
async function buildBatchedStep(name, receipt, batchId, adapter, chain, statusCode, batchError) {
|
|
15046
15697
|
const step = {
|
|
15047
15698
|
name,
|
|
15048
15699
|
state: 'pending',
|
|
@@ -15052,6 +15703,10 @@ async function buildBatchedStep(name, receipt, batchId, adapter, chain) {
|
|
|
15052
15703
|
if (!receipt) {
|
|
15053
15704
|
step.state = 'error';
|
|
15054
15705
|
step.errorMessage = `No receipt returned for ${name} in batch ${batchId}.`;
|
|
15706
|
+
step.errorCategory = categorizeMissingReceipt(statusCode, batchError);
|
|
15707
|
+
if (batchError !== undefined) {
|
|
15708
|
+
step.error = batchError;
|
|
15709
|
+
}
|
|
15055
15710
|
return step;
|
|
15056
15711
|
}
|
|
15057
15712
|
step.txHash = receipt.txHash;
|
|
@@ -15061,11 +15716,13 @@ async function buildBatchedStep(name, receipt, batchId, adapter, chain) {
|
|
|
15061
15716
|
if (receipt.status !== 'success') {
|
|
15062
15717
|
step.state = 'error';
|
|
15063
15718
|
step.errorMessage = `${name} call failed within batch ${batchId}.`;
|
|
15719
|
+
step.errorCategory = categorizeFailedReceipt(statusCode);
|
|
15064
15720
|
return step;
|
|
15065
15721
|
}
|
|
15066
15722
|
if (!receipt.txHash) {
|
|
15067
15723
|
step.state = 'error';
|
|
15068
15724
|
step.errorMessage = `${name} succeeded in batch but returned an empty transaction hash.`;
|
|
15725
|
+
step.errorCategory = 'unknown';
|
|
15069
15726
|
return step;
|
|
15070
15727
|
}
|
|
15071
15728
|
try {
|
|
@@ -15080,6 +15737,7 @@ async function buildBatchedStep(name, receipt, batchId, adapter, chain) {
|
|
|
15080
15737
|
step.data = transaction;
|
|
15081
15738
|
if (outcome.errorMessage) {
|
|
15082
15739
|
step.errorMessage = outcome.errorMessage;
|
|
15740
|
+
step.errorCategory = 'chain_revert';
|
|
15083
15741
|
}
|
|
15084
15742
|
}
|
|
15085
15743
|
catch (err) {
|
|
@@ -15087,11 +15745,12 @@ async function buildBatchedStep(name, receipt, batchId, adapter, chain) {
|
|
|
15087
15745
|
step.error = err;
|
|
15088
15746
|
step.errorMessage =
|
|
15089
15747
|
err instanceof Error ? err.message : 'Unknown error during confirmation.';
|
|
15748
|
+
step.errorCategory = 'unknown';
|
|
15090
15749
|
}
|
|
15091
15750
|
return step;
|
|
15092
15751
|
}
|
|
15093
15752
|
|
|
15094
|
-
var version$2 = "1.
|
|
15753
|
+
var version$2 = "1.8.0";
|
|
15095
15754
|
var pkg$2 = {
|
|
15096
15755
|
version: version$2};
|
|
15097
15756
|
|
|
@@ -15167,6 +15826,7 @@ async function executeBatchedPath(params, provider, result, invocation) {
|
|
|
15167
15826
|
errorMessage: error_ instanceof Error
|
|
15168
15827
|
? error_.message
|
|
15169
15828
|
: 'Batched approve + burn failed.',
|
|
15829
|
+
errorCategory: classifyPreSubmissionError(error_),
|
|
15170
15830
|
});
|
|
15171
15831
|
return undefined;
|
|
15172
15832
|
}
|
|
@@ -15181,6 +15841,89 @@ function ensureStepErrorMessage(name, step) {
|
|
|
15181
15841
|
step.errorMessage = `${name} step failed: ${getErrorMessage(step.error)}`;
|
|
15182
15842
|
}
|
|
15183
15843
|
}
|
|
15844
|
+
/**
|
|
15845
|
+
* Coerce a raw JSON-RPC `code` to a number.
|
|
15846
|
+
*
|
|
15847
|
+
* Some wallet SDKs serialize the JSON-RPC `code` as a string ("4001")
|
|
15848
|
+
* after round-tripping through JSON; accept both shapes so strict `===`
|
|
15849
|
+
* comparisons downstream still classify 5720/5730/5740 correctly — those
|
|
15850
|
+
* codes have no message-pattern fallback.
|
|
15851
|
+
*
|
|
15852
|
+
* @param rawCode - The raw `code` extracted from the error object.
|
|
15853
|
+
* @returns The numeric code, or `undefined` if the value cannot be parsed.
|
|
15854
|
+
*
|
|
15855
|
+
* @internal
|
|
15856
|
+
*/
|
|
15857
|
+
function coerceRpcCode(rawCode) {
|
|
15858
|
+
if (typeof rawCode === 'number') {
|
|
15859
|
+
return rawCode;
|
|
15860
|
+
}
|
|
15861
|
+
if (typeof rawCode === 'string') {
|
|
15862
|
+
return Number.parseInt(rawCode, 10);
|
|
15863
|
+
}
|
|
15864
|
+
return undefined;
|
|
15865
|
+
}
|
|
15866
|
+
/**
|
|
15867
|
+
* Classify a pre-submission error thrown during `wallet_sendCalls`.
|
|
15868
|
+
*
|
|
15869
|
+
* Inspect the error's JSON-RPC `code` (falling back to message pattern
|
|
15870
|
+
* matching for wrapper errors like viem's `ChainMismatchError`) and map
|
|
15871
|
+
* it to a {@link BridgeStepErrorCategory}. This lets downstream consumers
|
|
15872
|
+
* distinguish user rejections, wallet capability gaps, and unknown
|
|
15873
|
+
* failures without parsing error messages.
|
|
15874
|
+
*
|
|
15875
|
+
* @remarks
|
|
15876
|
+
* Does NOT alter control flow — the SDK continues to surface a
|
|
15877
|
+
* `state: 'error'` step. Auto-fallback to sequential execution is
|
|
15878
|
+
* intentionally out of scope for this helper.
|
|
15879
|
+
*
|
|
15880
|
+
* @param err - The error thrown by `wallet_sendCalls`.
|
|
15881
|
+
* @returns The derived error category, or `'unknown'` if no match.
|
|
15882
|
+
*
|
|
15883
|
+
* @internal
|
|
15884
|
+
*/
|
|
15885
|
+
function classifyPreSubmissionError(err) {
|
|
15886
|
+
// Cross-realm-safe duck typing: `instanceof Error` returns false for
|
|
15887
|
+
// errors thrown in a different JavaScript realm (e.g., a wallet
|
|
15888
|
+
// provider running inside an iframe, which is common with WalletConnect
|
|
15889
|
+
// and the Coinbase Wallet SDK).
|
|
15890
|
+
if (typeof err !== 'object' || err === null || !('message' in err)) {
|
|
15891
|
+
return 'unknown';
|
|
15892
|
+
}
|
|
15893
|
+
const code = coerceRpcCode(err.code);
|
|
15894
|
+
const message = String(err.message);
|
|
15895
|
+
// Numeric JSON-RPC codes are authoritative; check them before falling
|
|
15896
|
+
// back to message-pattern matching. Order matters: an error carrying
|
|
15897
|
+
// `code === 5750` with a message like "user rejected the upgrade"
|
|
15898
|
+
// is a capability problem, not a plain user rejection.
|
|
15899
|
+
if (code === 4001) {
|
|
15900
|
+
return 'user_rejected';
|
|
15901
|
+
}
|
|
15902
|
+
if (code === 5700 || code === 5710 || code === 5750) {
|
|
15903
|
+
return 'atomic_unsupported';
|
|
15904
|
+
}
|
|
15905
|
+
if (code === 5720) {
|
|
15906
|
+
return 'duplicate_batch_id';
|
|
15907
|
+
}
|
|
15908
|
+
if (code === 5730) {
|
|
15909
|
+
return 'unknown_bundle';
|
|
15910
|
+
}
|
|
15911
|
+
if (code === 5740) {
|
|
15912
|
+
return 'batch_too_large';
|
|
15913
|
+
}
|
|
15914
|
+
// Fall back to message patterns when no specific code is available —
|
|
15915
|
+
// viem (and other wrapper layers) sometimes strip the numeric code
|
|
15916
|
+
// while preserving the original wallet message in `Details:`.
|
|
15917
|
+
if (/EIP-7702 not supported/i.test(message) ||
|
|
15918
|
+
/does not support the requested chain/i.test(message) ||
|
|
15919
|
+
/rejected the upgrade/i.test(message)) {
|
|
15920
|
+
return 'atomic_unsupported';
|
|
15921
|
+
}
|
|
15922
|
+
if (/user rejected/i.test(message)) {
|
|
15923
|
+
return 'user_rejected';
|
|
15924
|
+
}
|
|
15925
|
+
return 'unknown';
|
|
15926
|
+
}
|
|
15184
15927
|
/**
|
|
15185
15928
|
* Execute a cross-chain USDC bridge using the CCTP v2 protocol.
|
|
15186
15929
|
*
|
|
@@ -16673,6 +17416,35 @@ const formatBridgeResult = (result, formatDirection) => {
|
|
|
16673
17416
|
};
|
|
16674
17417
|
};
|
|
16675
17418
|
|
|
17419
|
+
/**
|
|
17420
|
+
* Telemetry event type identifiers for bridge-kit operations.
|
|
17421
|
+
*
|
|
17422
|
+
* @internal
|
|
17423
|
+
*/
|
|
17424
|
+
const BRIDGE_EVENT_TYPES = {
|
|
17425
|
+
BRIDGE: 'bridge_bridge',
|
|
17426
|
+
RETRY: 'bridge_retry',
|
|
17427
|
+
ESTIMATE: 'bridge_estimate',
|
|
17428
|
+
};
|
|
17429
|
+
/**
|
|
17430
|
+
* Ordered mapping from provider step event names to telemetry event types.
|
|
17431
|
+
*
|
|
17432
|
+
* @remarks
|
|
17433
|
+
* The order matches the CCTP v2 bridge execution sequence. During
|
|
17434
|
+
* `bridge()`, completed step events are counted so the failing step
|
|
17435
|
+
* can be identified by its index.
|
|
17436
|
+
*
|
|
17437
|
+
* @internal
|
|
17438
|
+
*/
|
|
17439
|
+
const BRIDGE_STEP_EVENT_MAP = [
|
|
17440
|
+
['approve', 'bridge_approve'],
|
|
17441
|
+
['burn', 'bridge_burn'],
|
|
17442
|
+
['fetchAttestation', 'bridge_fetch_attestation'],
|
|
17443
|
+
['mint', 'bridge_mint'],
|
|
17444
|
+
];
|
|
17445
|
+
|
|
17446
|
+
/** SDK name used in telemetry payloads. */
|
|
17447
|
+
const SDK_NAME$2 = resolveKitSdkName(pkg$3.name);
|
|
16676
17448
|
/**
|
|
16677
17449
|
* BridgeKit caller component for retry and estimate operations.
|
|
16678
17450
|
*/
|
|
@@ -16756,6 +17528,10 @@ class BridgeKit {
|
|
|
16756
17528
|
* A custom fee policy for the kit.
|
|
16757
17529
|
*/
|
|
16758
17530
|
customFeePolicy;
|
|
17531
|
+
/** Whether error telemetry is disabled. */
|
|
17532
|
+
disableErrorReporting;
|
|
17533
|
+
/** Per-kit telemetry identity for shared helpers. */
|
|
17534
|
+
telemetryConfig;
|
|
16759
17535
|
/**
|
|
16760
17536
|
* Create a new BridgeKit instance.
|
|
16761
17537
|
*
|
|
@@ -16773,6 +17549,12 @@ class BridgeKit {
|
|
|
16773
17549
|
const defaultProviders = getDefaultProviders$2();
|
|
16774
17550
|
this.providers = [...defaultProviders, ...(config.providers ?? [])];
|
|
16775
17551
|
this.actionDispatcher = new Actionable();
|
|
17552
|
+
this.disableErrorReporting = config.disableErrorReporting === true;
|
|
17553
|
+
this.telemetryConfig = {
|
|
17554
|
+
sdkName: SDK_NAME$2,
|
|
17555
|
+
sdkVersion: pkg$3.version,
|
|
17556
|
+
disabled: this.disableErrorReporting,
|
|
17557
|
+
};
|
|
16776
17558
|
for (const provider of this.providers) {
|
|
16777
17559
|
provider.registerDispatcher(this.actionDispatcher);
|
|
16778
17560
|
}
|
|
@@ -16846,19 +17628,36 @@ class BridgeKit {
|
|
|
16846
17628
|
* ```
|
|
16847
17629
|
*/
|
|
16848
17630
|
async bridge(params) {
|
|
16849
|
-
|
|
16850
|
-
|
|
16851
|
-
|
|
16852
|
-
|
|
16853
|
-
|
|
16854
|
-
|
|
16855
|
-
|
|
16856
|
-
|
|
16857
|
-
|
|
16858
|
-
|
|
16859
|
-
|
|
16860
|
-
|
|
16861
|
-
|
|
17631
|
+
return withErrorTelemetry(async () => {
|
|
17632
|
+
// First validate the parameters
|
|
17633
|
+
assertBridgeParams(params, bridgeParamsWithChainIdentifierSchema);
|
|
17634
|
+
// Then resolve chain definitions (includes adapter chain support validation)
|
|
17635
|
+
const resolvedParams = await resolveBridgeParams(params);
|
|
17636
|
+
// Validate network compatibility
|
|
17637
|
+
this.validateNetworkCompatibility(resolvedParams);
|
|
17638
|
+
// Merge the custom fee config into the resolved params
|
|
17639
|
+
const finalResolvedParams = await this.mergeCustomFeeConfig(resolvedParams);
|
|
17640
|
+
// Find a provider that supports this route
|
|
17641
|
+
const provider = this.findProviderForRoute(finalResolvedParams);
|
|
17642
|
+
// Execute the transfer using the provider
|
|
17643
|
+
// Format the bridge result into human-readable string values for the user
|
|
17644
|
+
const result = formatBridgeResult(await provider.bridge(finalResolvedParams), 'to-human-readable');
|
|
17645
|
+
// Emit error telemetry when the provider returns an error state
|
|
17646
|
+
// (provider records step failures in the result instead of throwing).
|
|
17647
|
+
if (result.state === 'error') {
|
|
17648
|
+
const failedStep = result.steps.find((s) => s.state === 'error');
|
|
17649
|
+
emitResultStepErrorTelemetry(failedStep, BRIDGE_STEP_EVENT_MAP, BRIDGE_EVENT_TYPES.BRIDGE, this.telemetryConfig, {
|
|
17650
|
+
sourceChain: resolveChainName(params.from.chain),
|
|
17651
|
+
destinationChain: resolveChainName(params.to.chain),
|
|
17652
|
+
tokenIn: params.token,
|
|
17653
|
+
});
|
|
17654
|
+
}
|
|
17655
|
+
return result;
|
|
17656
|
+
}, BRIDGE_EVENT_TYPES.BRIDGE, this.telemetryConfig, {
|
|
17657
|
+
sourceChain: resolveChainName(params.from.chain),
|
|
17658
|
+
destinationChain: resolveChainName(params.to.chain),
|
|
17659
|
+
tokenIn: params.token,
|
|
17660
|
+
});
|
|
16862
17661
|
}
|
|
16863
17662
|
/**
|
|
16864
17663
|
* Retry a failed or incomplete cross-chain USDC bridge operation.
|
|
@@ -16930,17 +17729,33 @@ class BridgeKit {
|
|
|
16930
17729
|
* ```
|
|
16931
17730
|
*/
|
|
16932
17731
|
async retry(result, context, invocationMeta) {
|
|
16933
|
-
|
|
16934
|
-
|
|
16935
|
-
|
|
16936
|
-
|
|
16937
|
-
|
|
16938
|
-
|
|
16939
|
-
|
|
16940
|
-
|
|
16941
|
-
|
|
16942
|
-
|
|
16943
|
-
|
|
17732
|
+
return withErrorTelemetry(async () => {
|
|
17733
|
+
const provider = this.providers.find((p) => p.name === result.provider);
|
|
17734
|
+
if (!provider) {
|
|
17735
|
+
throw new Error(`Provider ${result.provider} not found`);
|
|
17736
|
+
}
|
|
17737
|
+
// Merge BridgeKit caller into invocation metadata for retry operation
|
|
17738
|
+
const mergedMeta = mergeRetryInvocationMeta(invocationMeta);
|
|
17739
|
+
// Format the bridge result into bigint string values for internal use
|
|
17740
|
+
const formattedBridgeResultInternal = formatBridgeResult(result, 'to-internal');
|
|
17741
|
+
// Execute the retry using the provider
|
|
17742
|
+
// Format the bridge result into human-readable string values for the user
|
|
17743
|
+
const retryResult = formatBridgeResult(await provider.retry(formattedBridgeResultInternal, context, mergedMeta), 'to-human-readable');
|
|
17744
|
+
// Emit error telemetry when the provider returns an error state.
|
|
17745
|
+
if (retryResult.state === 'error') {
|
|
17746
|
+
const failedStep = retryResult.steps.find((s) => s.state === 'error');
|
|
17747
|
+
emitResultStepErrorTelemetry(failedStep, BRIDGE_STEP_EVENT_MAP, BRIDGE_EVENT_TYPES.RETRY, this.telemetryConfig, {
|
|
17748
|
+
sourceChain: result.source.chain.chain,
|
|
17749
|
+
destinationChain: result.destination.chain.chain,
|
|
17750
|
+
tokenIn: result.token,
|
|
17751
|
+
});
|
|
17752
|
+
}
|
|
17753
|
+
return retryResult;
|
|
17754
|
+
}, BRIDGE_EVENT_TYPES.RETRY, this.telemetryConfig, {
|
|
17755
|
+
sourceChain: result.source.chain.chain,
|
|
17756
|
+
destinationChain: result.destination.chain.chain,
|
|
17757
|
+
tokenIn: result.token,
|
|
17758
|
+
});
|
|
16944
17759
|
}
|
|
16945
17760
|
/**
|
|
16946
17761
|
* Estimate the cost and fees for a cross-chain USDC bridge operation.
|
|
@@ -16979,18 +17794,24 @@ class BridgeKit {
|
|
|
16979
17794
|
* ```
|
|
16980
17795
|
*/
|
|
16981
17796
|
async estimate(params) {
|
|
16982
|
-
|
|
16983
|
-
|
|
16984
|
-
|
|
16985
|
-
|
|
16986
|
-
|
|
16987
|
-
|
|
16988
|
-
|
|
16989
|
-
|
|
16990
|
-
|
|
16991
|
-
|
|
16992
|
-
|
|
16993
|
-
|
|
17797
|
+
return withErrorTelemetry(async () => {
|
|
17798
|
+
// First validate the parameters
|
|
17799
|
+
assertBridgeParams(params, bridgeParamsWithChainIdentifierSchema);
|
|
17800
|
+
// Then resolve chain definitions (includes adapter chain support validation)
|
|
17801
|
+
const resolvedParams = await resolveBridgeParams(params);
|
|
17802
|
+
// Validate network compatibility
|
|
17803
|
+
this.validateNetworkCompatibility(resolvedParams);
|
|
17804
|
+
// Merge the custom fee config into the resolved params
|
|
17805
|
+
const finalResolvedParams = await this.mergeCustomFeeConfig(resolvedParams);
|
|
17806
|
+
// Find a provider that supports this route
|
|
17807
|
+
const provider = this.findProviderForRoute(finalResolvedParams);
|
|
17808
|
+
// Estimate the transfer using the provider and format amounts to human-readable strings
|
|
17809
|
+
return formatBridgeResult(await provider.estimate(finalResolvedParams), 'to-human-readable');
|
|
17810
|
+
}, BRIDGE_EVENT_TYPES.ESTIMATE, this.telemetryConfig, {
|
|
17811
|
+
sourceChain: resolveChainName(params.from.chain),
|
|
17812
|
+
destinationChain: resolveChainName(params.to.chain),
|
|
17813
|
+
tokenIn: params.token,
|
|
17814
|
+
});
|
|
16994
17815
|
}
|
|
16995
17816
|
/**
|
|
16996
17817
|
* Get all chains supported by any provider in the kit, with optional filtering.
|
|
@@ -17307,7 +18128,11 @@ const createBridgeKit = (context) => {
|
|
|
17307
18128
|
const getFee = context.getFee?.bind(context);
|
|
17308
18129
|
const getFeeRecipient = context.getFeeRecipient?.bind(context);
|
|
17309
18130
|
const hasBoth = typeof getFee === 'function' && typeof getFeeRecipient === 'function';
|
|
17310
|
-
const kit = new BridgeKit(
|
|
18131
|
+
const kit = new BridgeKit({
|
|
18132
|
+
...(context.disableErrorReporting != null && {
|
|
18133
|
+
disableErrorReporting: context.disableErrorReporting,
|
|
18134
|
+
}),
|
|
18135
|
+
});
|
|
17311
18136
|
if (hasBoth) {
|
|
17312
18137
|
kit.setCustomFeePolicy({
|
|
17313
18138
|
calculateFee: async (params) => {
|
|
@@ -17324,7 +18149,7 @@ const createBridgeKit = (context) => {
|
|
|
17324
18149
|
};
|
|
17325
18150
|
|
|
17326
18151
|
var name$1 = "@circle-fin/swap-kit";
|
|
17327
|
-
var version$1 = "1.
|
|
18152
|
+
var version$1 = "1.2.0";
|
|
17328
18153
|
var pkg$1 = {
|
|
17329
18154
|
name: name$1,
|
|
17330
18155
|
version: version$1};
|
|
@@ -27785,6 +28610,18 @@ function createSwapKitContext(config = {}) {
|
|
|
27785
28610
|
return context;
|
|
27786
28611
|
}
|
|
27787
28612
|
|
|
28613
|
+
/**
|
|
28614
|
+
* Telemetry event type identifiers for swap-kit operations.
|
|
28615
|
+
*
|
|
28616
|
+
* @internal
|
|
28617
|
+
*/
|
|
28618
|
+
const SWAP_EVENT_TYPES = {
|
|
28619
|
+
SWAP: 'swap_swap',
|
|
28620
|
+
ESTIMATE: 'swap_estimate',
|
|
28621
|
+
};
|
|
28622
|
+
|
|
28623
|
+
/** SDK name used in telemetry payloads. */
|
|
28624
|
+
const SDK_NAME$1 = resolveKitSdkName(pkg$1.name);
|
|
27788
28625
|
/**
|
|
27789
28626
|
* A high-level class-based interface for single-chain token swap operations.
|
|
27790
28627
|
*
|
|
@@ -27856,6 +28693,10 @@ function createSwapKitContext(config = {}) {
|
|
|
27856
28693
|
*/
|
|
27857
28694
|
class SwapKit {
|
|
27858
28695
|
context;
|
|
28696
|
+
/** Whether error telemetry is disabled. */
|
|
28697
|
+
disableErrorReporting;
|
|
28698
|
+
/** Per-kit telemetry identity for shared helpers. */
|
|
28699
|
+
telemetryConfig;
|
|
27859
28700
|
/**
|
|
27860
28701
|
* Create a new SwapKit instance.
|
|
27861
28702
|
*
|
|
@@ -27904,6 +28745,12 @@ class SwapKit {
|
|
|
27904
28745
|
*/
|
|
27905
28746
|
constructor(config = {}) {
|
|
27906
28747
|
this.context = createSwapKitContext(config);
|
|
28748
|
+
this.disableErrorReporting = config.disableErrorReporting === true;
|
|
28749
|
+
this.telemetryConfig = {
|
|
28750
|
+
sdkName: SDK_NAME$1,
|
|
28751
|
+
sdkVersion: pkg$1.version,
|
|
28752
|
+
disabled: this.disableErrorReporting,
|
|
28753
|
+
};
|
|
27907
28754
|
}
|
|
27908
28755
|
/**
|
|
27909
28756
|
* Estimate the output amount and fees for a swap operation.
|
|
@@ -27945,7 +28792,11 @@ class SwapKit {
|
|
|
27945
28792
|
* ```
|
|
27946
28793
|
*/
|
|
27947
28794
|
async estimate(params) {
|
|
27948
|
-
return estimate(this.context, params)
|
|
28795
|
+
return withErrorTelemetry(async () => estimate(this.context, params), SWAP_EVENT_TYPES.ESTIMATE, this.telemetryConfig, {
|
|
28796
|
+
sourceChain: resolveChainName(params.from.chain),
|
|
28797
|
+
tokenIn: params.tokenIn,
|
|
28798
|
+
tokenOut: params.tokenOut,
|
|
28799
|
+
});
|
|
27949
28800
|
}
|
|
27950
28801
|
/**
|
|
27951
28802
|
* Execute a token swap operation on a single chain.
|
|
@@ -28001,7 +28852,11 @@ class SwapKit {
|
|
|
28001
28852
|
* ```
|
|
28002
28853
|
*/
|
|
28003
28854
|
async swap(params) {
|
|
28004
|
-
return swap$1(this.context, params)
|
|
28855
|
+
return withErrorTelemetry(async () => swap$1(this.context, params), SWAP_EVENT_TYPES.SWAP, this.telemetryConfig, {
|
|
28856
|
+
sourceChain: resolveChainName(params.from.chain),
|
|
28857
|
+
tokenIn: params.tokenIn,
|
|
28858
|
+
tokenOut: params.tokenOut,
|
|
28859
|
+
});
|
|
28005
28860
|
}
|
|
28006
28861
|
/**
|
|
28007
28862
|
* Get all chains supported by the configured swap providers.
|
|
@@ -28194,7 +29049,11 @@ const createSwapKit = (context) => {
|
|
|
28194
29049
|
const getFee = context.getFee?.bind(context);
|
|
28195
29050
|
const getFeeRecipient = context.getFeeRecipient?.bind(context);
|
|
28196
29051
|
const hasBoth = typeof getFee === 'function' && typeof getFeeRecipient === 'function';
|
|
28197
|
-
const kit = new SwapKit(
|
|
29052
|
+
const kit = new SwapKit({
|
|
29053
|
+
...(context.disableErrorReporting != null && {
|
|
29054
|
+
disableErrorReporting: context.disableErrorReporting,
|
|
29055
|
+
}),
|
|
29056
|
+
});
|
|
28198
29057
|
if (hasBoth) {
|
|
28199
29058
|
kit.setCustomFeePolicy({
|
|
28200
29059
|
computeFee: async (params) => {
|
|
@@ -28698,7 +29557,7 @@ const prepareSend = async (params) => {
|
|
|
28698
29557
|
const fromContext = params.from;
|
|
28699
29558
|
const fromAdapter = fromContext.adapter;
|
|
28700
29559
|
const fromChain = resolveChainIdentifier(fromContext.chain);
|
|
28701
|
-
const fromAddress = await fromAdapter.getAddress(fromChain);
|
|
29560
|
+
const fromAddress = fromContext.address ?? (await fromAdapter.getAddress(fromChain));
|
|
28702
29561
|
// resolve input parameters
|
|
28703
29562
|
const token = params.token ?? 'USDC';
|
|
28704
29563
|
// Validate token and determine if it's an alias or custom address
|
|
@@ -29143,121 +30002,11 @@ const getSupportedChains$2 = (context, operationType, unifiedBalance) => {
|
|
|
29143
30002
|
};
|
|
29144
30003
|
|
|
29145
30004
|
var name = "@circle-fin/unified-balance-kit";
|
|
29146
|
-
var version = "1.0
|
|
30005
|
+
var version = "1.1.0";
|
|
29147
30006
|
var pkg = {
|
|
29148
30007
|
name: name,
|
|
29149
30008
|
version: version};
|
|
29150
30009
|
|
|
29151
|
-
/**
|
|
29152
|
-
* Default telemetry endpoint.
|
|
29153
|
-
*
|
|
29154
|
-
* Override via the `STABLECOIN_KITS_TELEMETRY_URL` environment variable
|
|
29155
|
-
* (e.g. for staging or local development).
|
|
29156
|
-
*
|
|
29157
|
-
* @internal
|
|
29158
|
-
*/
|
|
29159
|
-
const DEFAULT_LOGS_URL = 'https://api.circle.com/v1/stablecoinKits/logs';
|
|
29160
|
-
/**
|
|
29161
|
-
* Resolve the telemetry endpoint URL.
|
|
29162
|
-
*
|
|
29163
|
-
* @internal
|
|
29164
|
-
*/
|
|
29165
|
-
function getLogsUrl() {
|
|
29166
|
-
if (isNodeEnvironment() &&
|
|
29167
|
-
typeof process.env['STABLECOIN_KITS_TELEMETRY_URL'] === 'string' &&
|
|
29168
|
-
process.env['STABLECOIN_KITS_TELEMETRY_URL'].length > 0) {
|
|
29169
|
-
return process.env['STABLECOIN_KITS_TELEMETRY_URL'];
|
|
29170
|
-
}
|
|
29171
|
-
return DEFAULT_LOGS_URL;
|
|
29172
|
-
}
|
|
29173
|
-
/**
|
|
29174
|
-
* Send a telemetry event to the proxy service.
|
|
29175
|
-
*
|
|
29176
|
-
* @remarks
|
|
29177
|
-
* Fire-and-forget: the returned promise is intentionally not awaited
|
|
29178
|
-
* by the caller. A fetch failure (network error, non-2xx, timeout)
|
|
29179
|
-
* is silently swallowed so telemetry never blocks or fails user
|
|
29180
|
-
* operations.
|
|
29181
|
-
*
|
|
29182
|
-
* @param payload - The structured log payload matching the server schema.
|
|
29183
|
-
*
|
|
29184
|
-
* @example
|
|
29185
|
-
* ```typescript
|
|
29186
|
-
* import { emitAnalyticsLog } from './emitLog'
|
|
29187
|
-
*
|
|
29188
|
-
* // Fire-and-forget — do not await
|
|
29189
|
-
* emitAnalyticsLog(payload).catch(() => {})
|
|
29190
|
-
* ```
|
|
29191
|
-
*
|
|
29192
|
-
* @internal
|
|
29193
|
-
*/
|
|
29194
|
-
async function emitAnalyticsLog(payload) {
|
|
29195
|
-
try {
|
|
29196
|
-
const isNode = isNodeEnvironment();
|
|
29197
|
-
const userAgent = getUserAgent();
|
|
29198
|
-
await fetch(getLogsUrl(), {
|
|
29199
|
-
method: 'POST',
|
|
29200
|
-
headers: {
|
|
29201
|
-
'Content-Type': 'application/json',
|
|
29202
|
-
// Browser restricts setting User-Agent; use X-User-Agent instead.
|
|
29203
|
-
...(isNode
|
|
29204
|
-
? { 'User-Agent': userAgent }
|
|
29205
|
-
: { 'X-User-Agent': userAgent }),
|
|
29206
|
-
},
|
|
29207
|
-
body: JSON.stringify(payload),
|
|
29208
|
-
signal: AbortSignal.timeout(5_000),
|
|
29209
|
-
});
|
|
29210
|
-
}
|
|
29211
|
-
catch {
|
|
29212
|
-
// Silently swallow — telemetry must never break user operations.
|
|
29213
|
-
}
|
|
29214
|
-
}
|
|
29215
|
-
|
|
29216
|
-
/**
|
|
29217
|
-
* Build the `clientContext` object for telemetry payloads.
|
|
29218
|
-
*
|
|
29219
|
-
* @remarks
|
|
29220
|
-
* Uses the exported `getRuntime()` and `isNodeEnvironment()` from
|
|
29221
|
-
* `@core/utils` to detect the runtime environment (per Dominik's
|
|
29222
|
-
* feedback to reuse existing infrastructure). The returned string
|
|
29223
|
-
* is parsed into the structured `ClientContext` fields expected by
|
|
29224
|
-
* the server schema.
|
|
29225
|
-
*
|
|
29226
|
-
* @returns A {@link ClientContext} with platform, OS, and runtime name
|
|
29227
|
-
* populated from the current environment.
|
|
29228
|
-
*
|
|
29229
|
-
* @example
|
|
29230
|
-
* ```typescript
|
|
29231
|
-
* import { buildClientContext } from './clientContext'
|
|
29232
|
-
*
|
|
29233
|
-
* const ctx = buildClientContext()
|
|
29234
|
-
* // Node: { platform: 'node', os: 'darwin', runtimeName: null }
|
|
29235
|
-
* // Browser: { platform: 'browser', os: null, runtimeName: 'chrome' }
|
|
29236
|
-
* ```
|
|
29237
|
-
*/
|
|
29238
|
-
function buildClientContext() {
|
|
29239
|
-
const runtime = getRuntime();
|
|
29240
|
-
if (runtime.startsWith('browser/')) {
|
|
29241
|
-
return {
|
|
29242
|
-
platform: 'browser',
|
|
29243
|
-
os: null,
|
|
29244
|
-
runtimeName: runtime.slice('browser/'.length).toLowerCase(),
|
|
29245
|
-
};
|
|
29246
|
-
}
|
|
29247
|
-
if (runtime.startsWith('node/')) {
|
|
29248
|
-
return {
|
|
29249
|
-
platform: 'node',
|
|
29250
|
-
os: isNodeEnvironment() ? process.platform : null,
|
|
29251
|
-
runtimeName: null,
|
|
29252
|
-
};
|
|
29253
|
-
}
|
|
29254
|
-
return {
|
|
29255
|
-
platform: 'node',
|
|
29256
|
-
os: null,
|
|
29257
|
-
runtimeName: null,
|
|
29258
|
-
};
|
|
29259
|
-
}
|
|
29260
|
-
|
|
29261
30010
|
/**
|
|
29262
30011
|
* Event type identifiers accepted by the server-side logs endpoint.
|
|
29263
30012
|
*
|
|
@@ -29270,6 +30019,11 @@ const EVENT_TYPES = {
|
|
|
29270
30019
|
DEPOSIT_FOR: 'unified_balance_deposit_for',
|
|
29271
30020
|
SPEND: 'unified_balance_spend',
|
|
29272
30021
|
SPEND_FORWARDER: 'unified_balance_spend_forwarder',
|
|
30022
|
+
ESTIMATE_SPEND: 'unified_balance_estimate_spend',
|
|
30023
|
+
GET_BALANCES: 'unified_balance_get_balances',
|
|
30024
|
+
ADD_DELEGATE: 'unified_balance_add_delegate',
|
|
30025
|
+
REMOVE_DELEGATE: 'unified_balance_remove_delegate',
|
|
30026
|
+
GET_DELEGATE_STATUS: 'unified_balance_get_delegate_status',
|
|
29273
30027
|
INITIATE_REMOVE_FUND: 'unified_balance_initiate_remove_fund',
|
|
29274
30028
|
REMOVE_FUND: 'unified_balance_remove_fund',
|
|
29275
30029
|
};
|
|
@@ -29307,33 +30061,29 @@ function extractSingleChainResult(data) {
|
|
|
29307
30061
|
txHash: data.txHash,
|
|
29308
30062
|
};
|
|
29309
30063
|
}
|
|
29310
|
-
/**
|
|
29311
|
-
* Resolve a chain identifier that may be a string or a
|
|
29312
|
-
* `ChainDefinition` object to a plain string.
|
|
29313
|
-
*
|
|
29314
|
-
* @internal
|
|
29315
|
-
*/
|
|
29316
|
-
function resolveChainString(chain) {
|
|
29317
|
-
if (typeof chain === 'string')
|
|
29318
|
-
return chain;
|
|
29319
|
-
return chain.chain;
|
|
29320
|
-
}
|
|
29321
30064
|
/**
|
|
29322
30065
|
* Extract log-relevant fields from a spend result.
|
|
29323
30066
|
*
|
|
30067
|
+
* @remarks
|
|
30068
|
+
* Collects all source chains from allocations and joins them with
|
|
30069
|
+
* commas so multi-chain spends are fully represented.
|
|
30070
|
+
*
|
|
29324
30071
|
* @internal
|
|
29325
30072
|
*/
|
|
29326
30073
|
function extractSpend(data) {
|
|
29327
|
-
const
|
|
29328
|
-
|
|
29329
|
-
|
|
29330
|
-
|
|
30074
|
+
const allocs = data.allocations ?? [];
|
|
30075
|
+
const chains = [];
|
|
30076
|
+
for (const alloc of allocs) {
|
|
30077
|
+
const name = resolveChainName(alloc.chain);
|
|
30078
|
+
if (name != null) {
|
|
30079
|
+
chains.push(name);
|
|
30080
|
+
}
|
|
29331
30081
|
}
|
|
29332
|
-
const
|
|
30082
|
+
const sourceChain = chains.length > 0 ? chains.join(',') : undefined;
|
|
29333
30083
|
return {
|
|
29334
|
-
...(
|
|
30084
|
+
...(sourceChain != null && { sourceChain }),
|
|
29335
30085
|
destinationChain: data.destinationChain,
|
|
29336
|
-
...(
|
|
30086
|
+
...(allocs.length > 0 && { tokenIn: 'USDC' }),
|
|
29337
30087
|
txHash: data.txHash,
|
|
29338
30088
|
};
|
|
29339
30089
|
}
|
|
@@ -29432,10 +30182,9 @@ function mapSucceededEventToLog(actionName, payload, sdkName, sdkVersion) {
|
|
|
29432
30182
|
* telemetry for successful verb operations.
|
|
29433
30183
|
*
|
|
29434
30184
|
* @remarks
|
|
29435
|
-
*
|
|
29436
|
-
*
|
|
29437
|
-
*
|
|
29438
|
-
* subscribed to.
|
|
30185
|
+
* Registers a handler for each verb's `.succeeded` event using the
|
|
30186
|
+
* shared `registerTelemetryHandler` from `@core/utils`. Non-verb and
|
|
30187
|
+
* non-succeeded events are not subscribed to.
|
|
29439
30188
|
*
|
|
29440
30189
|
* The HTTP POST is fire-and-forget — telemetry never blocks or fails
|
|
29441
30190
|
* user operations.
|
|
@@ -29455,20 +30204,7 @@ function mapSucceededEventToLog(actionName, payload, sdkName, sdkVersion) {
|
|
|
29455
30204
|
* @internal
|
|
29456
30205
|
*/
|
|
29457
30206
|
function registerTelemetryHandler(dispatcher, sdkName, sdkVersion) {
|
|
29458
|
-
|
|
29459
|
-
dispatcher.on(actionName, (payload) => {
|
|
29460
|
-
try {
|
|
29461
|
-
const log = mapSucceededEventToLog(actionName, payload, sdkName, sdkVersion);
|
|
29462
|
-
if (log) {
|
|
29463
|
-
// Fire-and-forget — intentionally not awaited.
|
|
29464
|
-
void emitAnalyticsLog(log);
|
|
29465
|
-
}
|
|
29466
|
-
}
|
|
29467
|
-
catch {
|
|
29468
|
-
// Silently swallow — telemetry must never break user operations.
|
|
29469
|
-
}
|
|
29470
|
-
});
|
|
29471
|
-
}
|
|
30207
|
+
registerTelemetryHandler$1(dispatcher, sdkName, sdkVersion, VERB_EVENT_MAP, mapSucceededEventToLog);
|
|
29472
30208
|
}
|
|
29473
30209
|
|
|
29474
30210
|
/**
|
|
@@ -35498,6 +36234,8 @@ function getSupportedChains(context, token, options) {
|
|
|
35498
36234
|
return Object.values(Object.fromEntries(filtered.map((chain) => [chain.chain, chain])));
|
|
35499
36235
|
}
|
|
35500
36236
|
|
|
36237
|
+
/** SDK name used in telemetry payloads. */
|
|
36238
|
+
const SDK_NAME = resolveKitSdkName(pkg.name);
|
|
35501
36239
|
/**
|
|
35502
36240
|
* A high-level class-based interface for cross-chain USDC deposits,
|
|
35503
36241
|
* spending, balance queries, delegation management, and withdrawals.
|
|
@@ -35545,6 +36283,10 @@ class UnifiedBalanceKit {
|
|
|
35545
36283
|
* The action dispatcher for the kit.
|
|
35546
36284
|
*/
|
|
35547
36285
|
actionDispatcher;
|
|
36286
|
+
/** Whether error telemetry is disabled. */
|
|
36287
|
+
disableErrorReporting;
|
|
36288
|
+
/** Per-kit telemetry identity for shared helpers. */
|
|
36289
|
+
telemetryConfig;
|
|
35548
36290
|
/**
|
|
35549
36291
|
* Create a new UnifiedBalanceKit instance.
|
|
35550
36292
|
*
|
|
@@ -35557,14 +36299,49 @@ class UnifiedBalanceKit {
|
|
|
35557
36299
|
constructor(config = {}) {
|
|
35558
36300
|
this.context = createUnifiedBalanceKitContext(config);
|
|
35559
36301
|
this.actionDispatcher = new Actionable();
|
|
36302
|
+
this.disableErrorReporting = config.disableErrorReporting === true;
|
|
36303
|
+
this.telemetryConfig = {
|
|
36304
|
+
sdkName: SDK_NAME,
|
|
36305
|
+
sdkVersion: pkg.version,
|
|
36306
|
+
disabled: this.disableErrorReporting,
|
|
36307
|
+
};
|
|
35560
36308
|
for (const provider of this.context.providers) {
|
|
35561
36309
|
provider.registerDispatcher(this.actionDispatcher);
|
|
35562
36310
|
}
|
|
35563
36311
|
if (!config.disableAnalytics) {
|
|
35564
|
-
|
|
35565
|
-
registerTelemetryHandler(this.actionDispatcher, sdkName, pkg.version);
|
|
36312
|
+
registerTelemetryHandler(this.actionDispatcher, SDK_NAME, pkg.version);
|
|
35566
36313
|
}
|
|
35567
36314
|
}
|
|
36315
|
+
/**
|
|
36316
|
+
* Extract comma-separated source chain names from spend params.
|
|
36317
|
+
*
|
|
36318
|
+
* @internal
|
|
36319
|
+
*/
|
|
36320
|
+
static extractSpendSourceChains(params) {
|
|
36321
|
+
if (params == null || typeof params !== 'object' || !('from' in params)) {
|
|
36322
|
+
return undefined;
|
|
36323
|
+
}
|
|
36324
|
+
const fromVal = params.from;
|
|
36325
|
+
const sources = Array.isArray(fromVal) ? fromVal : [fromVal];
|
|
36326
|
+
const chains = [];
|
|
36327
|
+
for (const src of sources) {
|
|
36328
|
+
const allocs = src?.allocations;
|
|
36329
|
+
let allocArr;
|
|
36330
|
+
if (allocs == null) {
|
|
36331
|
+
allocArr = [];
|
|
36332
|
+
}
|
|
36333
|
+
else {
|
|
36334
|
+
allocArr = Array.isArray(allocs) ? allocs : [allocs];
|
|
36335
|
+
}
|
|
36336
|
+
for (const alloc of allocArr) {
|
|
36337
|
+
const name = resolveChainName(alloc.chain);
|
|
36338
|
+
if (name != null) {
|
|
36339
|
+
chains.push(name);
|
|
36340
|
+
}
|
|
36341
|
+
}
|
|
36342
|
+
}
|
|
36343
|
+
return chains.length > 0 ? chains.join(',') : undefined;
|
|
36344
|
+
}
|
|
35568
36345
|
// implementation just forwards to the bus
|
|
35569
36346
|
on(actionOrWildcard, handler) {
|
|
35570
36347
|
this.actionDispatcher.on(actionOrWildcard, handler);
|
|
@@ -35587,7 +36364,10 @@ class UnifiedBalanceKit {
|
|
|
35587
36364
|
* @see UnifiedBalanceKit.depositFor to deposit into another account.
|
|
35588
36365
|
*/
|
|
35589
36366
|
async deposit(params) {
|
|
35590
|
-
return deposit(this.context, params)
|
|
36367
|
+
return withErrorTelemetry(async () => deposit(this.context, params), EVENT_TYPES.DEPOSIT, this.telemetryConfig, {
|
|
36368
|
+
sourceChain: resolveChainName(params.from?.chain),
|
|
36369
|
+
tokenIn: params.token ?? 'USDC',
|
|
36370
|
+
});
|
|
35591
36371
|
}
|
|
35592
36372
|
/**
|
|
35593
36373
|
* Deposit USDC into another account (not the caller's).
|
|
@@ -35599,7 +36379,10 @@ class UnifiedBalanceKit {
|
|
|
35599
36379
|
* @see UnifiedBalanceKit.deposit to deposit into your own account.
|
|
35600
36380
|
*/
|
|
35601
36381
|
async depositFor(params) {
|
|
35602
|
-
return depositFor(this.context, params)
|
|
36382
|
+
return withErrorTelemetry(async () => depositFor(this.context, params), EVENT_TYPES.DEPOSIT_FOR, this.telemetryConfig, {
|
|
36383
|
+
sourceChain: resolveChainName(params.from?.chain),
|
|
36384
|
+
tokenIn: params.token ?? 'USDC',
|
|
36385
|
+
});
|
|
35603
36386
|
}
|
|
35604
36387
|
/**
|
|
35605
36388
|
* Spend (mint) USDC on a destination chain by pulling funds from one
|
|
@@ -35612,7 +36395,17 @@ class UnifiedBalanceKit {
|
|
|
35612
36395
|
* @see UnifiedBalanceKit.estimateSpend to preview fees before spending.
|
|
35613
36396
|
*/
|
|
35614
36397
|
async spend(params) {
|
|
35615
|
-
|
|
36398
|
+
const destChain = 'to' in params
|
|
36399
|
+
? resolveChainName(params.to.chain)
|
|
36400
|
+
: undefined;
|
|
36401
|
+
const tokenIn = 'token' in params
|
|
36402
|
+
? (params.token ?? 'USDC')
|
|
36403
|
+
: 'USDC';
|
|
36404
|
+
return withErrorTelemetry(async () => spend(this.context, params), EVENT_TYPES.SPEND, this.telemetryConfig, {
|
|
36405
|
+
sourceChain: UnifiedBalanceKit.extractSpendSourceChains(params),
|
|
36406
|
+
...(destChain != null && { destinationChain: destChain }),
|
|
36407
|
+
tokenIn,
|
|
36408
|
+
});
|
|
35616
36409
|
}
|
|
35617
36410
|
/**
|
|
35618
36411
|
* Estimate the fees for a spend operation without executing it.
|
|
@@ -35622,7 +36415,17 @@ class UnifiedBalanceKit {
|
|
|
35622
36415
|
* @returns Promise resolving to the fee estimate.
|
|
35623
36416
|
*/
|
|
35624
36417
|
async estimateSpend(params) {
|
|
35625
|
-
|
|
36418
|
+
const destChain = 'to' in params
|
|
36419
|
+
? resolveChainName(params.to.chain)
|
|
36420
|
+
: undefined;
|
|
36421
|
+
const sourceChain = UnifiedBalanceKit.extractSpendSourceChains(params);
|
|
36422
|
+
return withErrorTelemetry(async () => estimateSpend(this.context, params), EVENT_TYPES.ESTIMATE_SPEND, this.telemetryConfig, {
|
|
36423
|
+
...(sourceChain != null && { sourceChain }),
|
|
36424
|
+
...(destChain != null && { destinationChain: destChain }),
|
|
36425
|
+
tokenIn: 'token' in params
|
|
36426
|
+
? (params.token ?? 'USDC')
|
|
36427
|
+
: 'USDC',
|
|
36428
|
+
});
|
|
35626
36429
|
}
|
|
35627
36430
|
/**
|
|
35628
36431
|
* Fetch aggregated and per-chain balances for one or more accounts.
|
|
@@ -35631,7 +36434,7 @@ class UnifiedBalanceKit {
|
|
|
35631
36434
|
* @returns Promise resolving to the aggregated balance result.
|
|
35632
36435
|
*/
|
|
35633
36436
|
async getBalances(params) {
|
|
35634
|
-
return getBalances(this.context, params);
|
|
36437
|
+
return withErrorTelemetry(async () => getBalances(this.context, params), EVENT_TYPES.GET_BALANCES, this.telemetryConfig);
|
|
35635
36438
|
}
|
|
35636
36439
|
/**
|
|
35637
36440
|
* Grant spending rights to another address on the owner's account.
|
|
@@ -35646,7 +36449,7 @@ class UnifiedBalanceKit {
|
|
|
35646
36449
|
* @see UnifiedBalanceKit.getDelegateStatus to check delegate status.
|
|
35647
36450
|
*/
|
|
35648
36451
|
async addDelegate(params) {
|
|
35649
|
-
return addDelegate(this.context, params);
|
|
36452
|
+
return withErrorTelemetry(async () => addDelegate(this.context, params), EVENT_TYPES.ADD_DELEGATE, this.telemetryConfig, { sourceChain: resolveChainName(params.from?.chain) });
|
|
35650
36453
|
}
|
|
35651
36454
|
/**
|
|
35652
36455
|
* Revoke spending rights from a delegate on the owner's account.
|
|
@@ -35661,7 +36464,7 @@ class UnifiedBalanceKit {
|
|
|
35661
36464
|
* @see UnifiedBalanceKit.getDelegateStatus to check delegate status.
|
|
35662
36465
|
*/
|
|
35663
36466
|
async removeDelegate(params) {
|
|
35664
|
-
return removeDelegate(this.context, params);
|
|
36467
|
+
return withErrorTelemetry(async () => removeDelegate(this.context, params), EVENT_TYPES.REMOVE_DELEGATE, this.telemetryConfig, { sourceChain: resolveChainName(params.from?.chain) });
|
|
35665
36468
|
}
|
|
35666
36469
|
/**
|
|
35667
36470
|
* Kick off a delayed fund removal from an account.
|
|
@@ -35673,7 +36476,10 @@ class UnifiedBalanceKit {
|
|
|
35673
36476
|
* @see UnifiedBalanceKit.removeFund to complete the fund removal.
|
|
35674
36477
|
*/
|
|
35675
36478
|
async initiateRemoveFund(params) {
|
|
35676
|
-
return initiateRemoveFund(this.context, params)
|
|
36479
|
+
return withErrorTelemetry(async () => initiateRemoveFund(this.context, params), EVENT_TYPES.INITIATE_REMOVE_FUND, this.telemetryConfig, {
|
|
36480
|
+
sourceChain: resolveChainName(params.from?.chain),
|
|
36481
|
+
tokenIn: params.token ?? 'USDC',
|
|
36482
|
+
});
|
|
35677
36483
|
}
|
|
35678
36484
|
/**
|
|
35679
36485
|
* Complete a fund removal once the activation period has passed.
|
|
@@ -35685,7 +36491,10 @@ class UnifiedBalanceKit {
|
|
|
35685
36491
|
* @see UnifiedBalanceKit.initiateRemoveFund to start the process.
|
|
35686
36492
|
*/
|
|
35687
36493
|
async removeFund(params) {
|
|
35688
|
-
return removeFund(this.context, params)
|
|
36494
|
+
return withErrorTelemetry(async () => removeFund(this.context, params), EVENT_TYPES.REMOVE_FUND, this.telemetryConfig, {
|
|
36495
|
+
sourceChain: resolveChainName(params.from?.chain),
|
|
36496
|
+
tokenIn: params.token ?? 'USDC',
|
|
36497
|
+
});
|
|
35689
36498
|
}
|
|
35690
36499
|
/**
|
|
35691
36500
|
* Check the finality-aware delegate status of an address.
|
|
@@ -35713,7 +36522,7 @@ class UnifiedBalanceKit {
|
|
|
35713
36522
|
* ```
|
|
35714
36523
|
*/
|
|
35715
36524
|
async getDelegateStatus(params) {
|
|
35716
|
-
return getDelegateStatus(this.context, params);
|
|
36525
|
+
return withErrorTelemetry(async () => getDelegateStatus(this.context, params), EVENT_TYPES.GET_DELEGATE_STATUS, this.telemetryConfig, { sourceChain: resolveChainName(params.from?.chain) });
|
|
35717
36526
|
}
|
|
35718
36527
|
/**
|
|
35719
36528
|
* Get all chains supported by the kit.
|
|
@@ -36203,8 +37012,18 @@ class AppKit {
|
|
|
36203
37012
|
* ```
|
|
36204
37013
|
*/
|
|
36205
37014
|
constructor(config = {}) {
|
|
36206
|
-
this.context = createContext(
|
|
36207
|
-
|
|
37015
|
+
this.context = createContext({
|
|
37016
|
+
...config,
|
|
37017
|
+
...(config.disableErrorReporting != null && {
|
|
37018
|
+
disableErrorReporting: config.disableErrorReporting,
|
|
37019
|
+
}),
|
|
37020
|
+
});
|
|
37021
|
+
this.unifiedBalance = new AppKitUnifiedBalance({
|
|
37022
|
+
...config.unifiedBalance,
|
|
37023
|
+
...(config.disableErrorReporting != null && {
|
|
37024
|
+
disableErrorReporting: config.disableErrorReporting,
|
|
37025
|
+
}),
|
|
37026
|
+
});
|
|
36208
37027
|
}
|
|
36209
37028
|
/**
|
|
36210
37029
|
* Execute a cross-chain USDC bridge transfer.
|