@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.mjs
CHANGED
|
@@ -3398,6 +3398,8 @@ var Blockchain;
|
|
|
3398
3398
|
Blockchain["Hedera_Testnet"] = "Hedera_Testnet";
|
|
3399
3399
|
Blockchain["HyperEVM"] = "HyperEVM";
|
|
3400
3400
|
Blockchain["HyperEVM_Testnet"] = "HyperEVM_Testnet";
|
|
3401
|
+
Blockchain["Injective"] = "Injective";
|
|
3402
|
+
Blockchain["Injective_Testnet"] = "Injective_Testnet";
|
|
3401
3403
|
Blockchain["Ink"] = "Ink";
|
|
3402
3404
|
Blockchain["Ink_Testnet"] = "Ink_Testnet";
|
|
3403
3405
|
Blockchain["Linea"] = "Linea";
|
|
@@ -3412,6 +3414,8 @@ var Blockchain;
|
|
|
3412
3414
|
Blockchain["Noble_Testnet"] = "Noble_Testnet";
|
|
3413
3415
|
Blockchain["Optimism"] = "Optimism";
|
|
3414
3416
|
Blockchain["Optimism_Sepolia"] = "Optimism_Sepolia";
|
|
3417
|
+
Blockchain["Pharos"] = "Pharos";
|
|
3418
|
+
Blockchain["Pharos_Testnet"] = "Pharos_Testnet";
|
|
3415
3419
|
Blockchain["Polkadot_Asset_Hub"] = "Polkadot_Asset_Hub";
|
|
3416
3420
|
Blockchain["Polkadot_Westmint"] = "Polkadot_Westmint";
|
|
3417
3421
|
Blockchain["Plume"] = "Plume";
|
|
@@ -3615,11 +3619,13 @@ var BridgeChain;
|
|
|
3615
3619
|
BridgeChain["Edge"] = "Edge";
|
|
3616
3620
|
BridgeChain["Ethereum"] = "Ethereum";
|
|
3617
3621
|
BridgeChain["HyperEVM"] = "HyperEVM";
|
|
3622
|
+
BridgeChain["Injective"] = "Injective";
|
|
3618
3623
|
BridgeChain["Ink"] = "Ink";
|
|
3619
3624
|
BridgeChain["Linea"] = "Linea";
|
|
3620
3625
|
BridgeChain["Monad"] = "Monad";
|
|
3621
3626
|
BridgeChain["Morph"] = "Morph";
|
|
3622
3627
|
BridgeChain["Optimism"] = "Optimism";
|
|
3628
|
+
BridgeChain["Pharos"] = "Pharos";
|
|
3623
3629
|
BridgeChain["Plume"] = "Plume";
|
|
3624
3630
|
BridgeChain["Polygon"] = "Polygon";
|
|
3625
3631
|
BridgeChain["Sei"] = "Sei";
|
|
@@ -3637,11 +3643,13 @@ var BridgeChain;
|
|
|
3637
3643
|
BridgeChain["Edge_Testnet"] = "Edge_Testnet";
|
|
3638
3644
|
BridgeChain["Ethereum_Sepolia"] = "Ethereum_Sepolia";
|
|
3639
3645
|
BridgeChain["HyperEVM_Testnet"] = "HyperEVM_Testnet";
|
|
3646
|
+
BridgeChain["Injective_Testnet"] = "Injective_Testnet";
|
|
3640
3647
|
BridgeChain["Ink_Testnet"] = "Ink_Testnet";
|
|
3641
3648
|
BridgeChain["Linea_Sepolia"] = "Linea_Sepolia";
|
|
3642
3649
|
BridgeChain["Monad_Testnet"] = "Monad_Testnet";
|
|
3643
3650
|
BridgeChain["Morph_Testnet"] = "Morph_Testnet";
|
|
3644
3651
|
BridgeChain["Optimism_Sepolia"] = "Optimism_Sepolia";
|
|
3652
|
+
BridgeChain["Pharos_Testnet"] = "Pharos_Testnet";
|
|
3645
3653
|
BridgeChain["Plume_Testnet"] = "Plume_Testnet";
|
|
3646
3654
|
BridgeChain["Polygon_Amoy_Testnet"] = "Polygon_Amoy_Testnet";
|
|
3647
3655
|
BridgeChain["Sei_Testnet"] = "Sei_Testnet";
|
|
@@ -3987,6 +3995,12 @@ const SWAP_TOKEN_REGISTRY = {
|
|
|
3987
3995
|
category: 'wrapped',
|
|
3988
3996
|
description: 'Wrapped Polygon',
|
|
3989
3997
|
},
|
|
3998
|
+
CIRBTC: {
|
|
3999
|
+
symbol: 'CIRBTC',
|
|
4000
|
+
decimals: 8,
|
|
4001
|
+
category: 'wrapped',
|
|
4002
|
+
description: 'Circle Bitcoin',
|
|
4003
|
+
},
|
|
3990
4004
|
};
|
|
3991
4005
|
/**
|
|
3992
4006
|
* Special NATIVE token constant for swap operations.
|
|
@@ -5074,6 +5088,98 @@ const HyperEVMTestnet = defineChain({
|
|
|
5074
5088
|
},
|
|
5075
5089
|
});
|
|
5076
5090
|
|
|
5091
|
+
/**
|
|
5092
|
+
* Injective Mainnet chain definition
|
|
5093
|
+
* @remarks
|
|
5094
|
+
* This represents the official production network for the Injective blockchain.
|
|
5095
|
+
* Injective is a high-performance, interoperable Layer-1 blockchain built for
|
|
5096
|
+
* finance, with an EVM execution layer on top of a Cosmos SDK base and
|
|
5097
|
+
* sub-second block finality.
|
|
5098
|
+
*/
|
|
5099
|
+
const Injective = defineChain({
|
|
5100
|
+
type: 'evm',
|
|
5101
|
+
chain: Blockchain.Injective,
|
|
5102
|
+
name: 'Injective',
|
|
5103
|
+
title: 'Injective Mainnet',
|
|
5104
|
+
nativeCurrency: {
|
|
5105
|
+
name: 'Injective',
|
|
5106
|
+
symbol: 'INJ',
|
|
5107
|
+
decimals: 18,
|
|
5108
|
+
},
|
|
5109
|
+
chainId: 1776,
|
|
5110
|
+
isTestnet: false,
|
|
5111
|
+
explorerUrl: 'https://injscan.com/transaction/{hash}',
|
|
5112
|
+
rpcEndpoints: ['https://sentry.evm-rpc.injective.network'],
|
|
5113
|
+
eurcAddress: null,
|
|
5114
|
+
usdcAddress: '0xa00C59fF5a080D2b954d0c75e46E22a0c371235a',
|
|
5115
|
+
usdtAddress: null,
|
|
5116
|
+
cctp: {
|
|
5117
|
+
domain: 29,
|
|
5118
|
+
contracts: {
|
|
5119
|
+
v2: {
|
|
5120
|
+
type: 'split',
|
|
5121
|
+
tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
|
|
5122
|
+
messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
|
|
5123
|
+
confirmations: 1,
|
|
5124
|
+
fastConfirmations: 1,
|
|
5125
|
+
},
|
|
5126
|
+
},
|
|
5127
|
+
forwarderSupported: {
|
|
5128
|
+
source: false,
|
|
5129
|
+
destination: false,
|
|
5130
|
+
},
|
|
5131
|
+
},
|
|
5132
|
+
kitContracts: {
|
|
5133
|
+
bridge: BRIDGE_CONTRACT_EVM_MAINNET,
|
|
5134
|
+
},
|
|
5135
|
+
});
|
|
5136
|
+
|
|
5137
|
+
/**
|
|
5138
|
+
* Injective Testnet chain definition
|
|
5139
|
+
* @remarks
|
|
5140
|
+
* This represents the official test network for the Injective blockchain.
|
|
5141
|
+
* Injective is a high-performance, interoperable Layer-1 blockchain built for
|
|
5142
|
+
* finance, with an EVM execution layer on top of a Cosmos SDK base and
|
|
5143
|
+
* sub-second block finality.
|
|
5144
|
+
*/
|
|
5145
|
+
const InjectiveTestnet = defineChain({
|
|
5146
|
+
type: 'evm',
|
|
5147
|
+
chain: Blockchain.Injective_Testnet,
|
|
5148
|
+
name: 'Injective Testnet',
|
|
5149
|
+
title: 'Injective Testnet',
|
|
5150
|
+
nativeCurrency: {
|
|
5151
|
+
name: 'Injective',
|
|
5152
|
+
symbol: 'INJ',
|
|
5153
|
+
decimals: 18,
|
|
5154
|
+
},
|
|
5155
|
+
chainId: 1439,
|
|
5156
|
+
isTestnet: true,
|
|
5157
|
+
explorerUrl: 'https://testnet.explorer.injective.network/transaction/{hash}',
|
|
5158
|
+
rpcEndpoints: ['https://k8s.testnet.json-rpc.injective.network'],
|
|
5159
|
+
eurcAddress: null,
|
|
5160
|
+
usdcAddress: '0x0C382e685bbeeFE5d3d9C29e29E341fEE8E84C5d',
|
|
5161
|
+
usdtAddress: null,
|
|
5162
|
+
cctp: {
|
|
5163
|
+
domain: 29,
|
|
5164
|
+
contracts: {
|
|
5165
|
+
v2: {
|
|
5166
|
+
type: 'split',
|
|
5167
|
+
tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
|
|
5168
|
+
messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
|
|
5169
|
+
confirmations: 1,
|
|
5170
|
+
fastConfirmations: 1,
|
|
5171
|
+
},
|
|
5172
|
+
},
|
|
5173
|
+
forwarderSupported: {
|
|
5174
|
+
source: false,
|
|
5175
|
+
destination: false,
|
|
5176
|
+
},
|
|
5177
|
+
},
|
|
5178
|
+
kitContracts: {
|
|
5179
|
+
bridge: BRIDGE_CONTRACT_EVM_TESTNET,
|
|
5180
|
+
},
|
|
5181
|
+
});
|
|
5182
|
+
|
|
5077
5183
|
/**
|
|
5078
5184
|
* Ink Mainnet chain definition
|
|
5079
5185
|
* @remarks
|
|
@@ -5683,6 +5789,96 @@ const OptimismSepolia = defineChain({
|
|
|
5683
5789
|
},
|
|
5684
5790
|
});
|
|
5685
5791
|
|
|
5792
|
+
/**
|
|
5793
|
+
* Pharos Mainnet chain definition
|
|
5794
|
+
* @remarks
|
|
5795
|
+
* This represents the official production network for the Pharos blockchain.
|
|
5796
|
+
* Pharos is a modular, full-stack parallel Layer 1 blockchain with
|
|
5797
|
+
* sub-second finality and EVM compatibility.
|
|
5798
|
+
*/
|
|
5799
|
+
const Pharos = defineChain({
|
|
5800
|
+
type: 'evm',
|
|
5801
|
+
chain: Blockchain.Pharos,
|
|
5802
|
+
name: 'Pharos',
|
|
5803
|
+
title: 'Pharos Mainnet',
|
|
5804
|
+
nativeCurrency: {
|
|
5805
|
+
name: 'Pharos',
|
|
5806
|
+
symbol: 'PHAROS',
|
|
5807
|
+
decimals: 18,
|
|
5808
|
+
},
|
|
5809
|
+
chainId: 1672,
|
|
5810
|
+
isTestnet: false,
|
|
5811
|
+
explorerUrl: 'https://pharos.socialscan.io/tx/{hash}',
|
|
5812
|
+
rpcEndpoints: ['https://rpc.pharos.xyz'],
|
|
5813
|
+
eurcAddress: null,
|
|
5814
|
+
usdcAddress: '0xC879C018dB60520F4355C26eD1a6D572cdAC1815',
|
|
5815
|
+
usdtAddress: null,
|
|
5816
|
+
cctp: {
|
|
5817
|
+
domain: 31,
|
|
5818
|
+
contracts: {
|
|
5819
|
+
v2: {
|
|
5820
|
+
type: 'split',
|
|
5821
|
+
tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
|
|
5822
|
+
messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
|
|
5823
|
+
confirmations: 1,
|
|
5824
|
+
fastConfirmations: 1,
|
|
5825
|
+
},
|
|
5826
|
+
},
|
|
5827
|
+
forwarderSupported: {
|
|
5828
|
+
source: false,
|
|
5829
|
+
destination: false,
|
|
5830
|
+
},
|
|
5831
|
+
},
|
|
5832
|
+
kitContracts: {
|
|
5833
|
+
bridge: BRIDGE_CONTRACT_EVM_MAINNET,
|
|
5834
|
+
},
|
|
5835
|
+
});
|
|
5836
|
+
|
|
5837
|
+
/**
|
|
5838
|
+
* Pharos Atlantic Testnet chain definition
|
|
5839
|
+
* @remarks
|
|
5840
|
+
* This represents the official test network for the Pharos blockchain.
|
|
5841
|
+
* Pharos is a modular, full-stack parallel Layer 1 blockchain with
|
|
5842
|
+
* sub-second finality and EVM compatibility.
|
|
5843
|
+
*/
|
|
5844
|
+
const PharosTestnet = defineChain({
|
|
5845
|
+
type: 'evm',
|
|
5846
|
+
chain: Blockchain.Pharos_Testnet,
|
|
5847
|
+
name: 'Pharos Atlantic',
|
|
5848
|
+
title: 'Pharos Atlantic Testnet',
|
|
5849
|
+
nativeCurrency: {
|
|
5850
|
+
name: 'Pharos',
|
|
5851
|
+
symbol: 'PHAROS',
|
|
5852
|
+
decimals: 18,
|
|
5853
|
+
},
|
|
5854
|
+
chainId: 688689,
|
|
5855
|
+
isTestnet: true,
|
|
5856
|
+
explorerUrl: 'https://atlantic.pharosscan.xyz/tx/{hash}',
|
|
5857
|
+
rpcEndpoints: ['https://atlantic.dplabs-internal.com'],
|
|
5858
|
+
eurcAddress: null,
|
|
5859
|
+
usdcAddress: '0xcfC8330f4BCAB529c625D12781b1C19466A9Fc8B',
|
|
5860
|
+
usdtAddress: null,
|
|
5861
|
+
cctp: {
|
|
5862
|
+
domain: 31,
|
|
5863
|
+
contracts: {
|
|
5864
|
+
v2: {
|
|
5865
|
+
type: 'split',
|
|
5866
|
+
tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
|
|
5867
|
+
messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
|
|
5868
|
+
confirmations: 1,
|
|
5869
|
+
fastConfirmations: 1,
|
|
5870
|
+
},
|
|
5871
|
+
},
|
|
5872
|
+
forwarderSupported: {
|
|
5873
|
+
source: false,
|
|
5874
|
+
destination: false,
|
|
5875
|
+
},
|
|
5876
|
+
},
|
|
5877
|
+
kitContracts: {
|
|
5878
|
+
bridge: BRIDGE_CONTRACT_EVM_TESTNET,
|
|
5879
|
+
},
|
|
5880
|
+
});
|
|
5881
|
+
|
|
5686
5882
|
/**
|
|
5687
5883
|
* Plume Mainnet chain definition
|
|
5688
5884
|
* @remarks
|
|
@@ -5965,7 +6161,7 @@ const Sei = defineChain({
|
|
|
5965
6161
|
},
|
|
5966
6162
|
chainId: 1329,
|
|
5967
6163
|
isTestnet: false,
|
|
5968
|
-
explorerUrl: 'https://
|
|
6164
|
+
explorerUrl: 'https://seiscan.io/tx/{hash}',
|
|
5969
6165
|
rpcEndpoints: ['https://evm-rpc.sei-apis.com'],
|
|
5970
6166
|
eurcAddress: null,
|
|
5971
6167
|
usdcAddress: '0xe15fC38F6D8c56aF07bbCBe3BAf5708A2Bf42392',
|
|
@@ -6023,7 +6219,7 @@ const SeiTestnet = defineChain({
|
|
|
6023
6219
|
},
|
|
6024
6220
|
chainId: 1328,
|
|
6025
6221
|
isTestnet: true,
|
|
6026
|
-
explorerUrl: 'https://
|
|
6222
|
+
explorerUrl: 'https://testnet.seiscan.io/tx/{hash}',
|
|
6027
6223
|
rpcEndpoints: ['https://evm-rpc-testnet.sei-apis.com'],
|
|
6028
6224
|
eurcAddress: null,
|
|
6029
6225
|
usdcAddress: '0x4fCF1784B31630811181f670Aea7A7bEF803eaED',
|
|
@@ -6826,6 +7022,8 @@ var Chains = /*#__PURE__*/Object.freeze({
|
|
|
6826
7022
|
HederaTestnet: HederaTestnet,
|
|
6827
7023
|
HyperEVM: HyperEVM,
|
|
6828
7024
|
HyperEVMTestnet: HyperEVMTestnet,
|
|
7025
|
+
Injective: Injective,
|
|
7026
|
+
InjectiveTestnet: InjectiveTestnet,
|
|
6829
7027
|
Ink: Ink,
|
|
6830
7028
|
InkTestnet: InkTestnet,
|
|
6831
7029
|
Linea: Linea,
|
|
@@ -6840,6 +7038,8 @@ var Chains = /*#__PURE__*/Object.freeze({
|
|
|
6840
7038
|
NobleTestnet: NobleTestnet,
|
|
6841
7039
|
Optimism: Optimism,
|
|
6842
7040
|
OptimismSepolia: OptimismSepolia,
|
|
7041
|
+
Pharos: Pharos,
|
|
7042
|
+
PharosTestnet: PharosTestnet,
|
|
6843
7043
|
Plume: Plume,
|
|
6844
7044
|
PlumeTestnet: PlumeTestnet,
|
|
6845
7045
|
PolkadotAssetHub: PolkadotAssetHub,
|
|
@@ -7445,6 +7645,44 @@ function resolveChainIdentifier(chainIdentifier) {
|
|
|
7445
7645
|
throw new Error(`Invalid chain identifier type: ${typeof chainIdentifier}. Expected ChainDefinition object, Blockchain enum, or string literal.`);
|
|
7446
7646
|
}
|
|
7447
7647
|
|
|
7648
|
+
/**
|
|
7649
|
+
* Resolve a chain identifier to a plain chain-name string.
|
|
7650
|
+
*
|
|
7651
|
+
* Accept a string literal (`'Ethereum'`), a `ChainDefinition`-like
|
|
7652
|
+
* object (`{ chain: 'Ethereum' }`), or `null`/`undefined` and return
|
|
7653
|
+
* the chain name as a string. Return `undefined` when the value
|
|
7654
|
+
* cannot be resolved.
|
|
7655
|
+
*
|
|
7656
|
+
* @remarks
|
|
7657
|
+
* Unlike `resolveChainIdentifier` (which returns a full `ChainDefinition`
|
|
7658
|
+
* and throws on invalid input), this helper is intentionally lenient and
|
|
7659
|
+
* never throws — it is safe to call in error-handling and telemetry paths.
|
|
7660
|
+
*
|
|
7661
|
+
* @param value - A string, chain-definition object, or nullish value.
|
|
7662
|
+
* @returns The chain name string, or `undefined`.
|
|
7663
|
+
*
|
|
7664
|
+
* @example
|
|
7665
|
+
* ```typescript
|
|
7666
|
+
* import { resolveChainName } from '@core/chains'
|
|
7667
|
+
*
|
|
7668
|
+
* resolveChainName('Ethereum') // 'Ethereum'
|
|
7669
|
+
* resolveChainName({ chain: 'Ethereum' }) // 'Ethereum'
|
|
7670
|
+
* resolveChainName(undefined) // undefined
|
|
7671
|
+
* ```
|
|
7672
|
+
*/
|
|
7673
|
+
function resolveChainName(value) {
|
|
7674
|
+
if (value == null)
|
|
7675
|
+
return undefined;
|
|
7676
|
+
if (typeof value === 'string')
|
|
7677
|
+
return value;
|
|
7678
|
+
if (typeof value === 'object' &&
|
|
7679
|
+
'chain' in value &&
|
|
7680
|
+
typeof value.chain === 'string') {
|
|
7681
|
+
return value.chain;
|
|
7682
|
+
}
|
|
7683
|
+
return undefined;
|
|
7684
|
+
}
|
|
7685
|
+
|
|
7448
7686
|
/**
|
|
7449
7687
|
* @packageDocumentation
|
|
7450
7688
|
* @module SwapTokenUtils
|
|
@@ -9101,6 +9339,7 @@ const USDC = {
|
|
|
9101
9339
|
[Blockchain.Ethereum]: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
|
|
9102
9340
|
[Blockchain.Hedera]: '0.0.456858',
|
|
9103
9341
|
[Blockchain.HyperEVM]: '0xb88339CB7199b77E23DB6E890353E22632Ba630f',
|
|
9342
|
+
[Blockchain.Injective]: '0xa00C59fF5a080D2b954d0c75e46E22a0c371235a',
|
|
9104
9343
|
[Blockchain.Ink]: '0x2D270e6886d130D724215A266106e6832161EAEd',
|
|
9105
9344
|
[Blockchain.Linea]: '0x176211869ca2b568f2a7d4ee941e073a821ee1ff',
|
|
9106
9345
|
[Blockchain.Monad]: '0x754704Bc059F8C67012fEd69BC8A327a5aafb603',
|
|
@@ -9108,6 +9347,7 @@ const USDC = {
|
|
|
9108
9347
|
[Blockchain.NEAR]: '17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1',
|
|
9109
9348
|
[Blockchain.Noble]: 'uusdc',
|
|
9110
9349
|
[Blockchain.Optimism]: '0x0b2c639c533813f4aa9d7837caf62653d097ff85',
|
|
9350
|
+
[Blockchain.Pharos]: '0xC879C018dB60520F4355C26eD1a6D572cdAC1815',
|
|
9111
9351
|
[Blockchain.Plume]: '0x222365EF19F7947e5484218551B56bb3965Aa7aF',
|
|
9112
9352
|
[Blockchain.Polkadot_Asset_Hub]: '1337',
|
|
9113
9353
|
[Blockchain.Polygon]: '0x3c499c542cef5e3811e1192ce70d8cc03d5c3359',
|
|
@@ -9132,6 +9372,7 @@ const USDC = {
|
|
|
9132
9372
|
[Blockchain.Ethereum_Sepolia]: '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238',
|
|
9133
9373
|
[Blockchain.Hedera_Testnet]: '0.0.429274',
|
|
9134
9374
|
[Blockchain.HyperEVM_Testnet]: '0x2B3370eE501B4a559b57D449569354196457D8Ab',
|
|
9375
|
+
[Blockchain.Injective_Testnet]: '0x0C382e685bbeeFE5d3d9C29e29E341fEE8E84C5d',
|
|
9135
9376
|
[Blockchain.Ink_Testnet]: '0xFabab97dCE620294D2B0b0e46C68964e326300Ac',
|
|
9136
9377
|
[Blockchain.Linea_Sepolia]: '0xfece4462d57bd51a6a552365a011b95f0e16d9b7',
|
|
9137
9378
|
[Blockchain.Monad_Testnet]: '0x534b2f3A21130d7a60830c2Df862319e593943A3',
|
|
@@ -9139,6 +9380,7 @@ const USDC = {
|
|
|
9139
9380
|
[Blockchain.NEAR_Testnet]: '3e2210e1184b45b64c8a434c0a7e7b23cc04ea7eb7a6c3c32520d03d4afcb8af',
|
|
9140
9381
|
[Blockchain.Noble_Testnet]: 'uusdc',
|
|
9141
9382
|
[Blockchain.Optimism_Sepolia]: '0x5fd84259d66Cd46123540766Be93DFE6D43130D7',
|
|
9383
|
+
[Blockchain.Pharos_Testnet]: '0xcfC8330f4BCAB529c625D12781b1C19466A9Fc8B',
|
|
9142
9384
|
[Blockchain.Plume_Testnet]: '0xcB5f30e335672893c7eb944B374c196392C19D18',
|
|
9143
9385
|
[Blockchain.Polkadot_Westmint]: '31337',
|
|
9144
9386
|
[Blockchain.Polygon_Amoy_Testnet]: '0x41e94eb019c0762f9bfcf9fb1e58725bfb0e7582',
|
|
@@ -9419,6 +9661,32 @@ const MON = {
|
|
|
9419
9661
|
},
|
|
9420
9662
|
};
|
|
9421
9663
|
|
|
9664
|
+
/**
|
|
9665
|
+
* cirBTC (Circle Bitcoin) token definition with addresses and metadata.
|
|
9666
|
+
*
|
|
9667
|
+
* @remarks
|
|
9668
|
+
* Built-in cirBTC definition for the TokenRegistry. Currently deployed
|
|
9669
|
+
* on Arc Testnet.
|
|
9670
|
+
*
|
|
9671
|
+
* @example
|
|
9672
|
+
* ```typescript
|
|
9673
|
+
* import { CIRBTC } from '@core/tokens'
|
|
9674
|
+
* import { Blockchain } from '@core/chains'
|
|
9675
|
+
*
|
|
9676
|
+
* console.log(CIRBTC.symbol) // 'cirBTC'
|
|
9677
|
+
* console.log(CIRBTC.decimals) // 8
|
|
9678
|
+
* console.log(CIRBTC.locators[Blockchain.Arc_Testnet])
|
|
9679
|
+
* // '0xf0C4a4CE82A5746AbAAd9425360Ab04fbBA432BF'
|
|
9680
|
+
* ```
|
|
9681
|
+
*/
|
|
9682
|
+
const CIRBTC = {
|
|
9683
|
+
symbol: 'cirBTC',
|
|
9684
|
+
decimals: 8,
|
|
9685
|
+
locators: {
|
|
9686
|
+
[Blockchain.Arc_Testnet]: '0xf0C4a4CE82A5746AbAAd9425360Ab04fbBA432BF',
|
|
9687
|
+
},
|
|
9688
|
+
};
|
|
9689
|
+
|
|
9422
9690
|
// Re-export for consumers
|
|
9423
9691
|
/**
|
|
9424
9692
|
* All default token definitions.
|
|
@@ -9427,7 +9695,7 @@ const MON = {
|
|
|
9427
9695
|
* These tokens are automatically included in the TokenRegistry when created
|
|
9428
9696
|
* without explicit defaults. Extensions can override these definitions.
|
|
9429
9697
|
* Includes USDC, USDT, EURC, DAI, USDE, PYUSD, WETH, WBTC, WSOL, WAVAX,
|
|
9430
|
-
* WPOL, ETH, POL, PLUME, and
|
|
9698
|
+
* WPOL, ETH, POL, PLUME, MON, and cirBTC.
|
|
9431
9699
|
*
|
|
9432
9700
|
* @example
|
|
9433
9701
|
* ```typescript
|
|
@@ -9458,6 +9726,7 @@ const DEFAULT_TOKENS = [
|
|
|
9458
9726
|
POL,
|
|
9459
9727
|
PLUME,
|
|
9460
9728
|
MON,
|
|
9729
|
+
CIRBTC,
|
|
9461
9730
|
];
|
|
9462
9731
|
/**
|
|
9463
9732
|
* Uppercased token symbols approved for swap fee collection.
|
|
@@ -10205,8 +10474,325 @@ async function retryAsync(fn, options) {
|
|
|
10205
10474
|
throw new Error('retryAsync: unreachable');
|
|
10206
10475
|
}
|
|
10207
10476
|
|
|
10477
|
+
/**
|
|
10478
|
+
* Default telemetry endpoint.
|
|
10479
|
+
*
|
|
10480
|
+
* Override via the `STABLECOIN_KITS_TELEMETRY_URL` environment variable
|
|
10481
|
+
* (e.g. for staging or local development).
|
|
10482
|
+
*
|
|
10483
|
+
* @internal
|
|
10484
|
+
*/
|
|
10485
|
+
const DEFAULT_LOGS_URL = 'https://api.circle.com/v1/stablecoinKits/logs';
|
|
10486
|
+
/**
|
|
10487
|
+
* Resolve the telemetry endpoint URL.
|
|
10488
|
+
*
|
|
10489
|
+
* @internal
|
|
10490
|
+
*/
|
|
10491
|
+
function getLogsUrl() {
|
|
10492
|
+
if (isNodeEnvironment() &&
|
|
10493
|
+
typeof process.env['STABLECOIN_KITS_TELEMETRY_URL'] === 'string' &&
|
|
10494
|
+
process.env['STABLECOIN_KITS_TELEMETRY_URL'].length > 0) {
|
|
10495
|
+
return process.env['STABLECOIN_KITS_TELEMETRY_URL'];
|
|
10496
|
+
}
|
|
10497
|
+
return DEFAULT_LOGS_URL;
|
|
10498
|
+
}
|
|
10499
|
+
/**
|
|
10500
|
+
* Send a telemetry event to the proxy service.
|
|
10501
|
+
*
|
|
10502
|
+
* @remarks
|
|
10503
|
+
* Fire-and-forget: the returned promise is intentionally not awaited
|
|
10504
|
+
* by the caller. A fetch failure (network error, non-2xx, timeout)
|
|
10505
|
+
* is silently swallowed so telemetry never blocks or fails user
|
|
10506
|
+
* operations.
|
|
10507
|
+
*
|
|
10508
|
+
* @param payload - The structured log payload matching the server schema.
|
|
10509
|
+
*
|
|
10510
|
+
* @example
|
|
10511
|
+
* ```typescript
|
|
10512
|
+
* import { emitAnalyticsLog } from '@core/utils'
|
|
10513
|
+
*
|
|
10514
|
+
* // Fire-and-forget — do not await
|
|
10515
|
+
* void emitAnalyticsLog(payload)
|
|
10516
|
+
* ```
|
|
10517
|
+
*/
|
|
10518
|
+
async function emitAnalyticsLog(payload) {
|
|
10519
|
+
try {
|
|
10520
|
+
const isNode = isNodeEnvironment();
|
|
10521
|
+
const userAgent = getUserAgent();
|
|
10522
|
+
await fetch(getLogsUrl(), {
|
|
10523
|
+
method: 'POST',
|
|
10524
|
+
headers: {
|
|
10525
|
+
'Content-Type': 'application/json',
|
|
10526
|
+
// Browser restricts setting User-Agent; use X-User-Agent instead.
|
|
10527
|
+
...(isNode
|
|
10528
|
+
? { 'User-Agent': userAgent }
|
|
10529
|
+
: { 'X-User-Agent': userAgent }),
|
|
10530
|
+
},
|
|
10531
|
+
body: JSON.stringify(payload),
|
|
10532
|
+
signal: AbortSignal.timeout(5_000),
|
|
10533
|
+
});
|
|
10534
|
+
}
|
|
10535
|
+
catch {
|
|
10536
|
+
// Silently swallow — telemetry must never break user operations.
|
|
10537
|
+
}
|
|
10538
|
+
}
|
|
10539
|
+
|
|
10540
|
+
/**
|
|
10541
|
+
* Build the `clientContext` object for telemetry payloads.
|
|
10542
|
+
*
|
|
10543
|
+
* @remarks
|
|
10544
|
+
* Use the exported `getRuntime()` and `isNodeEnvironment()` from
|
|
10545
|
+
* `@core/utils` to detect the runtime environment. The returned
|
|
10546
|
+
* string is parsed into the structured `ClientContext` fields
|
|
10547
|
+
* expected by the server schema.
|
|
10548
|
+
*
|
|
10549
|
+
* @returns A {@link ClientContext} with platform, OS, and runtime name
|
|
10550
|
+
* populated from the current environment.
|
|
10551
|
+
*
|
|
10552
|
+
* @example
|
|
10553
|
+
* ```typescript
|
|
10554
|
+
* import { buildClientContext } from '@core/utils'
|
|
10555
|
+
*
|
|
10556
|
+
* const ctx = buildClientContext()
|
|
10557
|
+
* // Node: { platform: 'node', os: 'darwin', runtimeName: null }
|
|
10558
|
+
* // Browser: { platform: 'browser', os: null, runtimeName: 'chrome' }
|
|
10559
|
+
* ```
|
|
10560
|
+
*/
|
|
10561
|
+
function buildClientContext() {
|
|
10562
|
+
const runtime = getRuntime();
|
|
10563
|
+
if (runtime.startsWith('browser/')) {
|
|
10564
|
+
return {
|
|
10565
|
+
platform: 'browser',
|
|
10566
|
+
os: null,
|
|
10567
|
+
runtimeName: runtime.slice('browser/'.length).toLowerCase(),
|
|
10568
|
+
};
|
|
10569
|
+
}
|
|
10570
|
+
if (runtime.startsWith('node/')) {
|
|
10571
|
+
return {
|
|
10572
|
+
platform: 'node',
|
|
10573
|
+
os: isNodeEnvironment() ? process.platform : null,
|
|
10574
|
+
runtimeName: null,
|
|
10575
|
+
};
|
|
10576
|
+
}
|
|
10577
|
+
return {
|
|
10578
|
+
platform: 'node',
|
|
10579
|
+
os: null,
|
|
10580
|
+
runtimeName: null,
|
|
10581
|
+
};
|
|
10582
|
+
}
|
|
10583
|
+
|
|
10584
|
+
/**
|
|
10585
|
+
* Extract structured error details from an unknown error value.
|
|
10586
|
+
*
|
|
10587
|
+
* @remarks
|
|
10588
|
+
* Handle three cases:
|
|
10589
|
+
* - `KitError` — extract `code` and `name`.
|
|
10590
|
+
* - `Error` — extract `name`.
|
|
10591
|
+
* - Anything else — return empty details.
|
|
10592
|
+
*
|
|
10593
|
+
* Only structured, bounded fields (`errorCode`, `errorType`) are
|
|
10594
|
+
* included. Free-text fields (`message`, `stack`) are intentionally
|
|
10595
|
+
* omitted to avoid leaking secrets or PII through vendor telemetry.
|
|
10596
|
+
*
|
|
10597
|
+
* @param error - The thrown value to extract details from.
|
|
10598
|
+
* @returns A {@link ErrorDetails} object suitable for telemetry payloads.
|
|
10599
|
+
*
|
|
10600
|
+
* @example
|
|
10601
|
+
* ```typescript
|
|
10602
|
+
* import { extractErrorDetails } from '@core/utils'
|
|
10603
|
+
*
|
|
10604
|
+
* try {
|
|
10605
|
+
* await riskyOperation()
|
|
10606
|
+
* } catch (error) {
|
|
10607
|
+
* const details = extractErrorDetails(error)
|
|
10608
|
+
* // { errorCode: '1001', errorType: 'INPUT_NETWORK_MISMATCH' }
|
|
10609
|
+
* }
|
|
10610
|
+
* ```
|
|
10611
|
+
*/
|
|
10612
|
+
function extractErrorDetails(error) {
|
|
10613
|
+
if (error instanceof KitError) {
|
|
10614
|
+
return {
|
|
10615
|
+
errorCode: String(error.code),
|
|
10616
|
+
errorType: error.name,
|
|
10617
|
+
};
|
|
10618
|
+
}
|
|
10619
|
+
if (error instanceof Error) {
|
|
10620
|
+
return {
|
|
10621
|
+
errorType: error.name,
|
|
10622
|
+
};
|
|
10623
|
+
}
|
|
10624
|
+
return {};
|
|
10625
|
+
}
|
|
10626
|
+
|
|
10627
|
+
/**
|
|
10628
|
+
* Register event handlers on an action dispatcher that emit analytics
|
|
10629
|
+
* telemetry for the configured events.
|
|
10630
|
+
*
|
|
10631
|
+
* @remarks
|
|
10632
|
+
* Subscribe to each action name in `actionEventMap`, call `mapEventToPayload`
|
|
10633
|
+
* for each event, and fire-and-forget `emitAnalyticsLog` if a non-null
|
|
10634
|
+
* payload is returned. All errors are silently swallowed so telemetry
|
|
10635
|
+
* never blocks or fails user operations.
|
|
10636
|
+
*
|
|
10637
|
+
* @param dispatcher - The `Actionable` instance from the kit.
|
|
10638
|
+
* @param sdkName - SDK package name (e.g. `'unified-balance-kit'`).
|
|
10639
|
+
* @param sdkVersion - SDK version string (e.g. `'1.0.0'`).
|
|
10640
|
+
* @param actionEventMap - Map of action names to subscribe to.
|
|
10641
|
+
* @param mapEventToPayload - Function that maps an action name and payload
|
|
10642
|
+
* to a {@link ClientLogPayload}, or `null` to skip logging.
|
|
10643
|
+
*
|
|
10644
|
+
* @example
|
|
10645
|
+
* ```typescript
|
|
10646
|
+
* import { registerTelemetryHandler } from '@core/utils'
|
|
10647
|
+
*
|
|
10648
|
+
* registerTelemetryHandler(
|
|
10649
|
+
* dispatcher,
|
|
10650
|
+
* 'unified-balance-kit',
|
|
10651
|
+
* '1.0.0',
|
|
10652
|
+
* VERB_EVENT_MAP,
|
|
10653
|
+
* mapSucceededEventToLog,
|
|
10654
|
+
* )
|
|
10655
|
+
* ```
|
|
10656
|
+
*/
|
|
10657
|
+
function registerTelemetryHandler$1(dispatcher, sdkName, sdkVersion, actionEventMap, mapEventToPayload) {
|
|
10658
|
+
for (const actionName of Object.keys(actionEventMap)) {
|
|
10659
|
+
dispatcher.on(actionName, (payload) => {
|
|
10660
|
+
try {
|
|
10661
|
+
const log = mapEventToPayload(actionName, payload, sdkName, sdkVersion);
|
|
10662
|
+
if (log) {
|
|
10663
|
+
// Fire-and-forget — intentionally not awaited.
|
|
10664
|
+
void emitAnalyticsLog(log);
|
|
10665
|
+
}
|
|
10666
|
+
}
|
|
10667
|
+
catch {
|
|
10668
|
+
// Silently swallow — telemetry must never break user operations.
|
|
10669
|
+
}
|
|
10670
|
+
});
|
|
10671
|
+
}
|
|
10672
|
+
}
|
|
10673
|
+
|
|
10674
|
+
/**
|
|
10675
|
+
* Strip the `@circle-fin/` scope from a kit package name to produce the
|
|
10676
|
+
* short SDK name used in telemetry payloads.
|
|
10677
|
+
*
|
|
10678
|
+
* @param pkgName - The full npm package name (e.g. `@circle-fin/bridge-kit`).
|
|
10679
|
+
* @returns The unscoped kit name (e.g. `bridge-kit`).
|
|
10680
|
+
*
|
|
10681
|
+
* @example
|
|
10682
|
+
* ```typescript
|
|
10683
|
+
* import pkg from '../../package.json'
|
|
10684
|
+
* import { resolveKitSdkName } from '@core/utils'
|
|
10685
|
+
*
|
|
10686
|
+
* const SDK_NAME = resolveKitSdkName(pkg.name) // 'bridge-kit'
|
|
10687
|
+
* ```
|
|
10688
|
+
*/
|
|
10689
|
+
function resolveKitSdkName(pkgName) {
|
|
10690
|
+
return pkgName.replace('@circle-fin/', '');
|
|
10691
|
+
}
|
|
10692
|
+
|
|
10693
|
+
/**
|
|
10694
|
+
* Build a telemetry payload from common fields.
|
|
10695
|
+
*
|
|
10696
|
+
* @internal
|
|
10697
|
+
*/
|
|
10698
|
+
function buildPayload$1(config, eventType, errorDetails, context) {
|
|
10699
|
+
return {
|
|
10700
|
+
sdkName: config.sdkName,
|
|
10701
|
+
sdkVersion: config.sdkVersion,
|
|
10702
|
+
eventType,
|
|
10703
|
+
timestamp: new Date().toISOString(),
|
|
10704
|
+
errorDetails,
|
|
10705
|
+
clientContext: buildClientContext(),
|
|
10706
|
+
...(context?.sourceChain != null && {
|
|
10707
|
+
sourceChain: context.sourceChain,
|
|
10708
|
+
}),
|
|
10709
|
+
...(context?.destinationChain != null && {
|
|
10710
|
+
destinationChain: context.destinationChain,
|
|
10711
|
+
}),
|
|
10712
|
+
...(context?.tokenIn != null && { tokenIn: context.tokenIn }),
|
|
10713
|
+
...(context?.tokenOut != null && { tokenOut: context.tokenOut }),
|
|
10714
|
+
};
|
|
10715
|
+
}
|
|
10716
|
+
/**
|
|
10717
|
+
* Wrap an async operation with error telemetry.
|
|
10718
|
+
*
|
|
10719
|
+
* Execute `fn` and, if it throws, emit an error telemetry payload
|
|
10720
|
+
* before re-throwing. No-ops when `config.disabled` is `true`.
|
|
10721
|
+
*
|
|
10722
|
+
* @param fn - The async operation to execute.
|
|
10723
|
+
* @param eventType - The telemetry event type for this operation.
|
|
10724
|
+
* @param config - Per-kit SDK identity and disabled flag.
|
|
10725
|
+
* @param context - Optional chain/token context.
|
|
10726
|
+
* @returns The result of the operation.
|
|
10727
|
+
* @throws Re-throws any error after emitting telemetry.
|
|
10728
|
+
*
|
|
10729
|
+
* @example
|
|
10730
|
+
* ```typescript
|
|
10731
|
+
* import { withErrorTelemetry } from '@core/utils'
|
|
10732
|
+
*
|
|
10733
|
+
* const result = await withErrorTelemetry(
|
|
10734
|
+
* () => provider.bridge(params),
|
|
10735
|
+
* 'bridge_bridge',
|
|
10736
|
+
* { sdkName: 'bridge-kit', sdkVersion: '1.0.0', disabled: false },
|
|
10737
|
+
* { sourceChain: 'Ethereum', destinationChain: 'Base', tokenIn: 'USDC' },
|
|
10738
|
+
* )
|
|
10739
|
+
* ```
|
|
10740
|
+
*/
|
|
10741
|
+
async function withErrorTelemetry(fn, eventType, config, context) {
|
|
10742
|
+
try {
|
|
10743
|
+
return await fn();
|
|
10744
|
+
}
|
|
10745
|
+
catch (error) {
|
|
10746
|
+
if (!config.disabled) {
|
|
10747
|
+
void emitAnalyticsLog(buildPayload$1(config, eventType, extractErrorDetails(error), context));
|
|
10748
|
+
}
|
|
10749
|
+
throw error;
|
|
10750
|
+
}
|
|
10751
|
+
}
|
|
10752
|
+
/**
|
|
10753
|
+
* Emit error telemetry for a result-reported step error.
|
|
10754
|
+
*
|
|
10755
|
+
* Handle the case where a provider reports a step failure inside a
|
|
10756
|
+
* result object (e.g. `BridgeResult.state === 'error'`) rather than
|
|
10757
|
+
* throwing. The caller extracts the failed step as a simple
|
|
10758
|
+
* {@link FailedStepInfo} — this function handles sanitization,
|
|
10759
|
+
* step-to-event mapping, and emission.
|
|
10760
|
+
*
|
|
10761
|
+
* No-ops when `config.disabled` is `true`.
|
|
10762
|
+
*
|
|
10763
|
+
* @param failedStep - The failed step info, or undefined if none found.
|
|
10764
|
+
* @param stepEventMap - Ordered mapping from step names to event types.
|
|
10765
|
+
* @param fallbackEventType - Event type when step is not in the map.
|
|
10766
|
+
* @param config - Per-kit SDK identity and disabled flag.
|
|
10767
|
+
* @param context - Optional chain/token context.
|
|
10768
|
+
*
|
|
10769
|
+
* @example
|
|
10770
|
+
* ```typescript
|
|
10771
|
+
* import { emitResultStepErrorTelemetry } from '@core/utils'
|
|
10772
|
+
*
|
|
10773
|
+
* const failedStep = result.steps.find((s) => s.state === 'error')
|
|
10774
|
+
* emitResultStepErrorTelemetry(
|
|
10775
|
+
* failedStep,
|
|
10776
|
+
* BRIDGE_STEP_EVENT_MAP,
|
|
10777
|
+
* 'bridge_bridge',
|
|
10778
|
+
* { sdkName: 'bridge-kit', sdkVersion: '1.0.0', disabled: false },
|
|
10779
|
+
* { sourceChain: 'Ethereum', tokenIn: 'USDC' },
|
|
10780
|
+
* )
|
|
10781
|
+
* ```
|
|
10782
|
+
*/
|
|
10783
|
+
function emitResultStepErrorTelemetry(failedStep, stepEventMap, fallbackEventType, config, context) {
|
|
10784
|
+
if (config.disabled) {
|
|
10785
|
+
return;
|
|
10786
|
+
}
|
|
10787
|
+
const stepEntry = stepEventMap.find(([name]) => name === failedStep?.name);
|
|
10788
|
+
const errorDetails = {
|
|
10789
|
+
...(failedStep?.name != null && { errorType: failedStep.name }),
|
|
10790
|
+
};
|
|
10791
|
+
void emitAnalyticsLog(buildPayload$1(config, stepEntry?.[1] ?? fallbackEventType, errorDetails, context));
|
|
10792
|
+
}
|
|
10793
|
+
|
|
10208
10794
|
var name$2 = "@circle-fin/bridge-kit";
|
|
10209
|
-
var version$3 = "1.
|
|
10795
|
+
var version$3 = "1.10.0";
|
|
10210
10796
|
var pkg$3 = {
|
|
10211
10797
|
name: name$2,
|
|
10212
10798
|
version: version$3};
|
|
@@ -13171,18 +13757,16 @@ const buildIrisUrl = (sourceDomainId, transactionHash, isTestnet) => {
|
|
|
13171
13757
|
};
|
|
13172
13758
|
/**
|
|
13173
13759
|
* Fetches attestation data from the IRIS API with retry and timeout handling.
|
|
13174
|
-
* Since fetching starts after a confirmed burn transaction, we attempt up to 10 retries.
|
|
13175
|
-
* Implements a conservative delay between requests to respect the API rate
|
|
13176
|
-
* limit of 35 requests per second. To avoid rate limiting when multiple processes are
|
|
13177
|
-
* running concurrently, we enforce a 200ms delay between retries.
|
|
13178
13760
|
*
|
|
13179
|
-
*
|
|
13180
|
-
*
|
|
13761
|
+
* Polls the IRIS API until a complete attestation is available. The default
|
|
13762
|
+
* window is sized for slow source chains where finality may take many
|
|
13763
|
+
* confirmations.
|
|
13181
13764
|
*
|
|
13182
|
-
*
|
|
13183
|
-
* - Per
|
|
13184
|
-
* - Retry
|
|
13185
|
-
* -
|
|
13765
|
+
* Defaults (see `DEFAULT_CONFIG`):
|
|
13766
|
+
* - Per-attempt timeout: 2 000 ms (each HTTP request aborts after 2 s)
|
|
13767
|
+
* - Retry delay: 2 000 ms between attempts
|
|
13768
|
+
* - Max retries: 600 (30 × 20)
|
|
13769
|
+
* - Total worst-case polling window: 600 × (2 000 ms + 2 000 ms) ≈ 40 minutes
|
|
13186
13770
|
*
|
|
13187
13771
|
* @param sourceDomainId - The CCTP domain ID.
|
|
13188
13772
|
* @param transactionHash - The transaction hash to fetch attestation for.
|
|
@@ -14337,11 +14921,18 @@ async function executePreparedChainRequest({ name, request, adapter, chain, conf
|
|
|
14337
14921
|
step.explorerUrl = buildExplorerUrl(chain, txHash);
|
|
14338
14922
|
if (outcome.errorMessage) {
|
|
14339
14923
|
step.errorMessage = outcome.errorMessage;
|
|
14924
|
+
// Transaction was mined but reverted on-chain.
|
|
14925
|
+
step.errorCategory = 'chain_revert';
|
|
14340
14926
|
}
|
|
14341
14927
|
}
|
|
14342
14928
|
catch (err) {
|
|
14343
14929
|
step.state = 'error';
|
|
14344
14930
|
step.error = err;
|
|
14931
|
+
// Sequential path does not yet attempt fine-grained classification of
|
|
14932
|
+
// pre-submission errors (user_rejected, capability errors, etc.). Mark
|
|
14933
|
+
// as `unknown` so consumers can at least detect the category is
|
|
14934
|
+
// populated uniformly across batched and sequential flows.
|
|
14935
|
+
step.errorCategory = 'unknown';
|
|
14345
14936
|
// Optionally parse for common blockchain error formats
|
|
14346
14937
|
if (err instanceof Error) {
|
|
14347
14938
|
step.errorMessage = err.message;
|
|
@@ -15007,16 +15598,70 @@ async function executeBatchedApproveAndBurn(params, provider) {
|
|
|
15007
15598
|
const batchResult = await adapter.batchExecute([approveCallData, burnCallData], chain);
|
|
15008
15599
|
const approveReceipt = batchResult.receipts[0];
|
|
15009
15600
|
const burnReceipt = batchResult.receipts[1];
|
|
15010
|
-
const approveStep = await buildBatchedStep('approve', approveReceipt, batchResult.batchId, adapter, chain);
|
|
15011
|
-
const burnStep = await buildBatchedStep('burn', burnReceipt, batchResult.batchId, adapter, chain);
|
|
15601
|
+
const approveStep = await buildBatchedStep('approve', approveReceipt, batchResult.batchId, adapter, chain, batchResult.statusCode, batchResult.error);
|
|
15602
|
+
const burnStep = await buildBatchedStep('burn', burnReceipt, batchResult.batchId, adapter, chain, batchResult.statusCode, batchResult.error);
|
|
15012
15603
|
if (burnStep.state !== 'error' && !burnStep.txHash) {
|
|
15013
15604
|
burnStep.state = 'error';
|
|
15014
15605
|
burnStep.errorMessage =
|
|
15015
15606
|
'Batched burn step completed but no transaction hash was returned.';
|
|
15607
|
+
burnStep.errorCategory = 'unknown';
|
|
15016
15608
|
}
|
|
15017
15609
|
const context = { burnTxHash: burnStep.txHash ?? '' };
|
|
15018
15610
|
return { approveStep, burnStep, context };
|
|
15019
15611
|
}
|
|
15612
|
+
/**
|
|
15613
|
+
* Derive a {@link BridgeStepErrorCategory} for a missing receipt.
|
|
15614
|
+
*
|
|
15615
|
+
* Combines the EIP-5792 `statusCode` (when present) with the underlying
|
|
15616
|
+
* polling error (when set) to produce the most specific category available.
|
|
15617
|
+
* Falls back to `'unknown'` when neither signal is conclusive.
|
|
15618
|
+
*
|
|
15619
|
+
* @param statusCode - The terminal `statusCode` from `wallet_getCallsStatus`, if any.
|
|
15620
|
+
* @param batchError - The polling error from `batchExecute`, if any.
|
|
15621
|
+
* @returns The derived error category for a missing-receipt step.
|
|
15622
|
+
*
|
|
15623
|
+
* @internal
|
|
15624
|
+
*/
|
|
15625
|
+
function categorizeMissingReceipt(statusCode, batchError) {
|
|
15626
|
+
if (statusCode === 400)
|
|
15627
|
+
return 'failed_offchain';
|
|
15628
|
+
if (statusCode === 500)
|
|
15629
|
+
return 'reverted_onchain';
|
|
15630
|
+
if (statusCode === 600)
|
|
15631
|
+
return 'partial_reverted';
|
|
15632
|
+
if (batchError instanceof KitError &&
|
|
15633
|
+
batchError.code === NetworkError.TIMEOUT.code) {
|
|
15634
|
+
return 'polling_timeout';
|
|
15635
|
+
}
|
|
15636
|
+
return 'unknown';
|
|
15637
|
+
}
|
|
15638
|
+
/**
|
|
15639
|
+
* Derive a {@link BridgeStepErrorCategory} for a receipt that was returned
|
|
15640
|
+
* but whose per-call `status` is not `'success'`.
|
|
15641
|
+
*
|
|
15642
|
+
* A numeric EIP-5792 `statusCode` of 500 or 600 tells us the whole batch
|
|
15643
|
+
* reverted on-chain (completely or partially); otherwise the receipt
|
|
15644
|
+
* itself signalled a revert without a distinguishing code, so classify
|
|
15645
|
+
* as a plain on-chain revert.
|
|
15646
|
+
*
|
|
15647
|
+
* @param statusCode - The terminal `statusCode` from `wallet_getCallsStatus`, if any.
|
|
15648
|
+
* @returns The derived error category for a failed-receipt step.
|
|
15649
|
+
*
|
|
15650
|
+
* @internal
|
|
15651
|
+
*/
|
|
15652
|
+
function categorizeFailedReceipt(statusCode) {
|
|
15653
|
+
// Mirror categorizeMissingReceipt: if the wallet's terminal status is
|
|
15654
|
+
// 400 ("batch not included onchain"), that judgement is authoritative
|
|
15655
|
+
// even when a non-success receipt is attached. Without this, a wrapped
|
|
15656
|
+
// 400 receipt would fall through to `chain_revert` and mislead UX.
|
|
15657
|
+
if (statusCode === 400)
|
|
15658
|
+
return 'failed_offchain';
|
|
15659
|
+
if (statusCode === 600)
|
|
15660
|
+
return 'partial_reverted';
|
|
15661
|
+
if (statusCode === 500)
|
|
15662
|
+
return 'reverted_onchain';
|
|
15663
|
+
return 'chain_revert';
|
|
15664
|
+
}
|
|
15020
15665
|
/**
|
|
15021
15666
|
* Build a {@link BridgeStep} from a single receipt within a batch.
|
|
15022
15667
|
*
|
|
@@ -15031,11 +15676,17 @@ async function executeBatchedApproveAndBurn(params, provider) {
|
|
|
15031
15676
|
* @param batchId - Wallet-assigned batch identifier.
|
|
15032
15677
|
* @param adapter - The batch-capable adapter (used for confirmation).
|
|
15033
15678
|
* @param chain - The EVM chain the batch was executed on.
|
|
15679
|
+
* @param statusCode - Optional EIP-5792 `statusCode` for the batch.
|
|
15680
|
+
* Used to classify the step's error category when the receipt is
|
|
15681
|
+
* missing or failed.
|
|
15682
|
+
* @param batchError - Optional polling error from `batchExecute`.
|
|
15683
|
+
* Preserved on the step so callers can inspect underlying timeouts
|
|
15684
|
+
* or RPC failures.
|
|
15034
15685
|
* @returns A fully-populated bridge step with state, tx hash and explorer URL.
|
|
15035
15686
|
*
|
|
15036
15687
|
* @internal
|
|
15037
15688
|
*/
|
|
15038
|
-
async function buildBatchedStep(name, receipt, batchId, adapter, chain) {
|
|
15689
|
+
async function buildBatchedStep(name, receipt, batchId, adapter, chain, statusCode, batchError) {
|
|
15039
15690
|
const step = {
|
|
15040
15691
|
name,
|
|
15041
15692
|
state: 'pending',
|
|
@@ -15045,6 +15696,10 @@ async function buildBatchedStep(name, receipt, batchId, adapter, chain) {
|
|
|
15045
15696
|
if (!receipt) {
|
|
15046
15697
|
step.state = 'error';
|
|
15047
15698
|
step.errorMessage = `No receipt returned for ${name} in batch ${batchId}.`;
|
|
15699
|
+
step.errorCategory = categorizeMissingReceipt(statusCode, batchError);
|
|
15700
|
+
if (batchError !== undefined) {
|
|
15701
|
+
step.error = batchError;
|
|
15702
|
+
}
|
|
15048
15703
|
return step;
|
|
15049
15704
|
}
|
|
15050
15705
|
step.txHash = receipt.txHash;
|
|
@@ -15054,11 +15709,13 @@ async function buildBatchedStep(name, receipt, batchId, adapter, chain) {
|
|
|
15054
15709
|
if (receipt.status !== 'success') {
|
|
15055
15710
|
step.state = 'error';
|
|
15056
15711
|
step.errorMessage = `${name} call failed within batch ${batchId}.`;
|
|
15712
|
+
step.errorCategory = categorizeFailedReceipt(statusCode);
|
|
15057
15713
|
return step;
|
|
15058
15714
|
}
|
|
15059
15715
|
if (!receipt.txHash) {
|
|
15060
15716
|
step.state = 'error';
|
|
15061
15717
|
step.errorMessage = `${name} succeeded in batch but returned an empty transaction hash.`;
|
|
15718
|
+
step.errorCategory = 'unknown';
|
|
15062
15719
|
return step;
|
|
15063
15720
|
}
|
|
15064
15721
|
try {
|
|
@@ -15073,6 +15730,7 @@ async function buildBatchedStep(name, receipt, batchId, adapter, chain) {
|
|
|
15073
15730
|
step.data = transaction;
|
|
15074
15731
|
if (outcome.errorMessage) {
|
|
15075
15732
|
step.errorMessage = outcome.errorMessage;
|
|
15733
|
+
step.errorCategory = 'chain_revert';
|
|
15076
15734
|
}
|
|
15077
15735
|
}
|
|
15078
15736
|
catch (err) {
|
|
@@ -15080,11 +15738,12 @@ async function buildBatchedStep(name, receipt, batchId, adapter, chain) {
|
|
|
15080
15738
|
step.error = err;
|
|
15081
15739
|
step.errorMessage =
|
|
15082
15740
|
err instanceof Error ? err.message : 'Unknown error during confirmation.';
|
|
15741
|
+
step.errorCategory = 'unknown';
|
|
15083
15742
|
}
|
|
15084
15743
|
return step;
|
|
15085
15744
|
}
|
|
15086
15745
|
|
|
15087
|
-
var version$2 = "1.
|
|
15746
|
+
var version$2 = "1.8.0";
|
|
15088
15747
|
var pkg$2 = {
|
|
15089
15748
|
version: version$2};
|
|
15090
15749
|
|
|
@@ -15160,6 +15819,7 @@ async function executeBatchedPath(params, provider, result, invocation) {
|
|
|
15160
15819
|
errorMessage: error_ instanceof Error
|
|
15161
15820
|
? error_.message
|
|
15162
15821
|
: 'Batched approve + burn failed.',
|
|
15822
|
+
errorCategory: classifyPreSubmissionError(error_),
|
|
15163
15823
|
});
|
|
15164
15824
|
return undefined;
|
|
15165
15825
|
}
|
|
@@ -15174,6 +15834,89 @@ function ensureStepErrorMessage(name, step) {
|
|
|
15174
15834
|
step.errorMessage = `${name} step failed: ${getErrorMessage(step.error)}`;
|
|
15175
15835
|
}
|
|
15176
15836
|
}
|
|
15837
|
+
/**
|
|
15838
|
+
* Coerce a raw JSON-RPC `code` to a number.
|
|
15839
|
+
*
|
|
15840
|
+
* Some wallet SDKs serialize the JSON-RPC `code` as a string ("4001")
|
|
15841
|
+
* after round-tripping through JSON; accept both shapes so strict `===`
|
|
15842
|
+
* comparisons downstream still classify 5720/5730/5740 correctly — those
|
|
15843
|
+
* codes have no message-pattern fallback.
|
|
15844
|
+
*
|
|
15845
|
+
* @param rawCode - The raw `code` extracted from the error object.
|
|
15846
|
+
* @returns The numeric code, or `undefined` if the value cannot be parsed.
|
|
15847
|
+
*
|
|
15848
|
+
* @internal
|
|
15849
|
+
*/
|
|
15850
|
+
function coerceRpcCode(rawCode) {
|
|
15851
|
+
if (typeof rawCode === 'number') {
|
|
15852
|
+
return rawCode;
|
|
15853
|
+
}
|
|
15854
|
+
if (typeof rawCode === 'string') {
|
|
15855
|
+
return Number.parseInt(rawCode, 10);
|
|
15856
|
+
}
|
|
15857
|
+
return undefined;
|
|
15858
|
+
}
|
|
15859
|
+
/**
|
|
15860
|
+
* Classify a pre-submission error thrown during `wallet_sendCalls`.
|
|
15861
|
+
*
|
|
15862
|
+
* Inspect the error's JSON-RPC `code` (falling back to message pattern
|
|
15863
|
+
* matching for wrapper errors like viem's `ChainMismatchError`) and map
|
|
15864
|
+
* it to a {@link BridgeStepErrorCategory}. This lets downstream consumers
|
|
15865
|
+
* distinguish user rejections, wallet capability gaps, and unknown
|
|
15866
|
+
* failures without parsing error messages.
|
|
15867
|
+
*
|
|
15868
|
+
* @remarks
|
|
15869
|
+
* Does NOT alter control flow — the SDK continues to surface a
|
|
15870
|
+
* `state: 'error'` step. Auto-fallback to sequential execution is
|
|
15871
|
+
* intentionally out of scope for this helper.
|
|
15872
|
+
*
|
|
15873
|
+
* @param err - The error thrown by `wallet_sendCalls`.
|
|
15874
|
+
* @returns The derived error category, or `'unknown'` if no match.
|
|
15875
|
+
*
|
|
15876
|
+
* @internal
|
|
15877
|
+
*/
|
|
15878
|
+
function classifyPreSubmissionError(err) {
|
|
15879
|
+
// Cross-realm-safe duck typing: `instanceof Error` returns false for
|
|
15880
|
+
// errors thrown in a different JavaScript realm (e.g., a wallet
|
|
15881
|
+
// provider running inside an iframe, which is common with WalletConnect
|
|
15882
|
+
// and the Coinbase Wallet SDK).
|
|
15883
|
+
if (typeof err !== 'object' || err === null || !('message' in err)) {
|
|
15884
|
+
return 'unknown';
|
|
15885
|
+
}
|
|
15886
|
+
const code = coerceRpcCode(err.code);
|
|
15887
|
+
const message = String(err.message);
|
|
15888
|
+
// Numeric JSON-RPC codes are authoritative; check them before falling
|
|
15889
|
+
// back to message-pattern matching. Order matters: an error carrying
|
|
15890
|
+
// `code === 5750` with a message like "user rejected the upgrade"
|
|
15891
|
+
// is a capability problem, not a plain user rejection.
|
|
15892
|
+
if (code === 4001) {
|
|
15893
|
+
return 'user_rejected';
|
|
15894
|
+
}
|
|
15895
|
+
if (code === 5700 || code === 5710 || code === 5750) {
|
|
15896
|
+
return 'atomic_unsupported';
|
|
15897
|
+
}
|
|
15898
|
+
if (code === 5720) {
|
|
15899
|
+
return 'duplicate_batch_id';
|
|
15900
|
+
}
|
|
15901
|
+
if (code === 5730) {
|
|
15902
|
+
return 'unknown_bundle';
|
|
15903
|
+
}
|
|
15904
|
+
if (code === 5740) {
|
|
15905
|
+
return 'batch_too_large';
|
|
15906
|
+
}
|
|
15907
|
+
// Fall back to message patterns when no specific code is available —
|
|
15908
|
+
// viem (and other wrapper layers) sometimes strip the numeric code
|
|
15909
|
+
// while preserving the original wallet message in `Details:`.
|
|
15910
|
+
if (/EIP-7702 not supported/i.test(message) ||
|
|
15911
|
+
/does not support the requested chain/i.test(message) ||
|
|
15912
|
+
/rejected the upgrade/i.test(message)) {
|
|
15913
|
+
return 'atomic_unsupported';
|
|
15914
|
+
}
|
|
15915
|
+
if (/user rejected/i.test(message)) {
|
|
15916
|
+
return 'user_rejected';
|
|
15917
|
+
}
|
|
15918
|
+
return 'unknown';
|
|
15919
|
+
}
|
|
15177
15920
|
/**
|
|
15178
15921
|
* Execute a cross-chain USDC bridge using the CCTP v2 protocol.
|
|
15179
15922
|
*
|
|
@@ -16666,6 +17409,35 @@ const formatBridgeResult = (result, formatDirection) => {
|
|
|
16666
17409
|
};
|
|
16667
17410
|
};
|
|
16668
17411
|
|
|
17412
|
+
/**
|
|
17413
|
+
* Telemetry event type identifiers for bridge-kit operations.
|
|
17414
|
+
*
|
|
17415
|
+
* @internal
|
|
17416
|
+
*/
|
|
17417
|
+
const BRIDGE_EVENT_TYPES = {
|
|
17418
|
+
BRIDGE: 'bridge_bridge',
|
|
17419
|
+
RETRY: 'bridge_retry',
|
|
17420
|
+
ESTIMATE: 'bridge_estimate',
|
|
17421
|
+
};
|
|
17422
|
+
/**
|
|
17423
|
+
* Ordered mapping from provider step event names to telemetry event types.
|
|
17424
|
+
*
|
|
17425
|
+
* @remarks
|
|
17426
|
+
* The order matches the CCTP v2 bridge execution sequence. During
|
|
17427
|
+
* `bridge()`, completed step events are counted so the failing step
|
|
17428
|
+
* can be identified by its index.
|
|
17429
|
+
*
|
|
17430
|
+
* @internal
|
|
17431
|
+
*/
|
|
17432
|
+
const BRIDGE_STEP_EVENT_MAP = [
|
|
17433
|
+
['approve', 'bridge_approve'],
|
|
17434
|
+
['burn', 'bridge_burn'],
|
|
17435
|
+
['fetchAttestation', 'bridge_fetch_attestation'],
|
|
17436
|
+
['mint', 'bridge_mint'],
|
|
17437
|
+
];
|
|
17438
|
+
|
|
17439
|
+
/** SDK name used in telemetry payloads. */
|
|
17440
|
+
const SDK_NAME$2 = resolveKitSdkName(pkg$3.name);
|
|
16669
17441
|
/**
|
|
16670
17442
|
* BridgeKit caller component for retry and estimate operations.
|
|
16671
17443
|
*/
|
|
@@ -16749,6 +17521,10 @@ class BridgeKit {
|
|
|
16749
17521
|
* A custom fee policy for the kit.
|
|
16750
17522
|
*/
|
|
16751
17523
|
customFeePolicy;
|
|
17524
|
+
/** Whether error telemetry is disabled. */
|
|
17525
|
+
disableErrorReporting;
|
|
17526
|
+
/** Per-kit telemetry identity for shared helpers. */
|
|
17527
|
+
telemetryConfig;
|
|
16752
17528
|
/**
|
|
16753
17529
|
* Create a new BridgeKit instance.
|
|
16754
17530
|
*
|
|
@@ -16766,6 +17542,12 @@ class BridgeKit {
|
|
|
16766
17542
|
const defaultProviders = getDefaultProviders$2();
|
|
16767
17543
|
this.providers = [...defaultProviders, ...(config.providers ?? [])];
|
|
16768
17544
|
this.actionDispatcher = new Actionable();
|
|
17545
|
+
this.disableErrorReporting = config.disableErrorReporting === true;
|
|
17546
|
+
this.telemetryConfig = {
|
|
17547
|
+
sdkName: SDK_NAME$2,
|
|
17548
|
+
sdkVersion: pkg$3.version,
|
|
17549
|
+
disabled: this.disableErrorReporting,
|
|
17550
|
+
};
|
|
16769
17551
|
for (const provider of this.providers) {
|
|
16770
17552
|
provider.registerDispatcher(this.actionDispatcher);
|
|
16771
17553
|
}
|
|
@@ -16839,19 +17621,36 @@ class BridgeKit {
|
|
|
16839
17621
|
* ```
|
|
16840
17622
|
*/
|
|
16841
17623
|
async bridge(params) {
|
|
16842
|
-
|
|
16843
|
-
|
|
16844
|
-
|
|
16845
|
-
|
|
16846
|
-
|
|
16847
|
-
|
|
16848
|
-
|
|
16849
|
-
|
|
16850
|
-
|
|
16851
|
-
|
|
16852
|
-
|
|
16853
|
-
|
|
16854
|
-
|
|
17624
|
+
return withErrorTelemetry(async () => {
|
|
17625
|
+
// First validate the parameters
|
|
17626
|
+
assertBridgeParams(params, bridgeParamsWithChainIdentifierSchema);
|
|
17627
|
+
// Then resolve chain definitions (includes adapter chain support validation)
|
|
17628
|
+
const resolvedParams = await resolveBridgeParams(params);
|
|
17629
|
+
// Validate network compatibility
|
|
17630
|
+
this.validateNetworkCompatibility(resolvedParams);
|
|
17631
|
+
// Merge the custom fee config into the resolved params
|
|
17632
|
+
const finalResolvedParams = await this.mergeCustomFeeConfig(resolvedParams);
|
|
17633
|
+
// Find a provider that supports this route
|
|
17634
|
+
const provider = this.findProviderForRoute(finalResolvedParams);
|
|
17635
|
+
// Execute the transfer using the provider
|
|
17636
|
+
// Format the bridge result into human-readable string values for the user
|
|
17637
|
+
const result = formatBridgeResult(await provider.bridge(finalResolvedParams), 'to-human-readable');
|
|
17638
|
+
// Emit error telemetry when the provider returns an error state
|
|
17639
|
+
// (provider records step failures in the result instead of throwing).
|
|
17640
|
+
if (result.state === 'error') {
|
|
17641
|
+
const failedStep = result.steps.find((s) => s.state === 'error');
|
|
17642
|
+
emitResultStepErrorTelemetry(failedStep, BRIDGE_STEP_EVENT_MAP, BRIDGE_EVENT_TYPES.BRIDGE, this.telemetryConfig, {
|
|
17643
|
+
sourceChain: resolveChainName(params.from.chain),
|
|
17644
|
+
destinationChain: resolveChainName(params.to.chain),
|
|
17645
|
+
tokenIn: params.token,
|
|
17646
|
+
});
|
|
17647
|
+
}
|
|
17648
|
+
return result;
|
|
17649
|
+
}, BRIDGE_EVENT_TYPES.BRIDGE, this.telemetryConfig, {
|
|
17650
|
+
sourceChain: resolveChainName(params.from.chain),
|
|
17651
|
+
destinationChain: resolveChainName(params.to.chain),
|
|
17652
|
+
tokenIn: params.token,
|
|
17653
|
+
});
|
|
16855
17654
|
}
|
|
16856
17655
|
/**
|
|
16857
17656
|
* Retry a failed or incomplete cross-chain USDC bridge operation.
|
|
@@ -16923,17 +17722,33 @@ class BridgeKit {
|
|
|
16923
17722
|
* ```
|
|
16924
17723
|
*/
|
|
16925
17724
|
async retry(result, context, invocationMeta) {
|
|
16926
|
-
|
|
16927
|
-
|
|
16928
|
-
|
|
16929
|
-
|
|
16930
|
-
|
|
16931
|
-
|
|
16932
|
-
|
|
16933
|
-
|
|
16934
|
-
|
|
16935
|
-
|
|
16936
|
-
|
|
17725
|
+
return withErrorTelemetry(async () => {
|
|
17726
|
+
const provider = this.providers.find((p) => p.name === result.provider);
|
|
17727
|
+
if (!provider) {
|
|
17728
|
+
throw new Error(`Provider ${result.provider} not found`);
|
|
17729
|
+
}
|
|
17730
|
+
// Merge BridgeKit caller into invocation metadata for retry operation
|
|
17731
|
+
const mergedMeta = mergeRetryInvocationMeta(invocationMeta);
|
|
17732
|
+
// Format the bridge result into bigint string values for internal use
|
|
17733
|
+
const formattedBridgeResultInternal = formatBridgeResult(result, 'to-internal');
|
|
17734
|
+
// Execute the retry using the provider
|
|
17735
|
+
// Format the bridge result into human-readable string values for the user
|
|
17736
|
+
const retryResult = formatBridgeResult(await provider.retry(formattedBridgeResultInternal, context, mergedMeta), 'to-human-readable');
|
|
17737
|
+
// Emit error telemetry when the provider returns an error state.
|
|
17738
|
+
if (retryResult.state === 'error') {
|
|
17739
|
+
const failedStep = retryResult.steps.find((s) => s.state === 'error');
|
|
17740
|
+
emitResultStepErrorTelemetry(failedStep, BRIDGE_STEP_EVENT_MAP, BRIDGE_EVENT_TYPES.RETRY, this.telemetryConfig, {
|
|
17741
|
+
sourceChain: result.source.chain.chain,
|
|
17742
|
+
destinationChain: result.destination.chain.chain,
|
|
17743
|
+
tokenIn: result.token,
|
|
17744
|
+
});
|
|
17745
|
+
}
|
|
17746
|
+
return retryResult;
|
|
17747
|
+
}, BRIDGE_EVENT_TYPES.RETRY, this.telemetryConfig, {
|
|
17748
|
+
sourceChain: result.source.chain.chain,
|
|
17749
|
+
destinationChain: result.destination.chain.chain,
|
|
17750
|
+
tokenIn: result.token,
|
|
17751
|
+
});
|
|
16937
17752
|
}
|
|
16938
17753
|
/**
|
|
16939
17754
|
* Estimate the cost and fees for a cross-chain USDC bridge operation.
|
|
@@ -16972,18 +17787,24 @@ class BridgeKit {
|
|
|
16972
17787
|
* ```
|
|
16973
17788
|
*/
|
|
16974
17789
|
async estimate(params) {
|
|
16975
|
-
|
|
16976
|
-
|
|
16977
|
-
|
|
16978
|
-
|
|
16979
|
-
|
|
16980
|
-
|
|
16981
|
-
|
|
16982
|
-
|
|
16983
|
-
|
|
16984
|
-
|
|
16985
|
-
|
|
16986
|
-
|
|
17790
|
+
return withErrorTelemetry(async () => {
|
|
17791
|
+
// First validate the parameters
|
|
17792
|
+
assertBridgeParams(params, bridgeParamsWithChainIdentifierSchema);
|
|
17793
|
+
// Then resolve chain definitions (includes adapter chain support validation)
|
|
17794
|
+
const resolvedParams = await resolveBridgeParams(params);
|
|
17795
|
+
// Validate network compatibility
|
|
17796
|
+
this.validateNetworkCompatibility(resolvedParams);
|
|
17797
|
+
// Merge the custom fee config into the resolved params
|
|
17798
|
+
const finalResolvedParams = await this.mergeCustomFeeConfig(resolvedParams);
|
|
17799
|
+
// Find a provider that supports this route
|
|
17800
|
+
const provider = this.findProviderForRoute(finalResolvedParams);
|
|
17801
|
+
// Estimate the transfer using the provider and format amounts to human-readable strings
|
|
17802
|
+
return formatBridgeResult(await provider.estimate(finalResolvedParams), 'to-human-readable');
|
|
17803
|
+
}, BRIDGE_EVENT_TYPES.ESTIMATE, this.telemetryConfig, {
|
|
17804
|
+
sourceChain: resolveChainName(params.from.chain),
|
|
17805
|
+
destinationChain: resolveChainName(params.to.chain),
|
|
17806
|
+
tokenIn: params.token,
|
|
17807
|
+
});
|
|
16987
17808
|
}
|
|
16988
17809
|
/**
|
|
16989
17810
|
* Get all chains supported by any provider in the kit, with optional filtering.
|
|
@@ -17300,7 +18121,11 @@ const createBridgeKit = (context) => {
|
|
|
17300
18121
|
const getFee = context.getFee?.bind(context);
|
|
17301
18122
|
const getFeeRecipient = context.getFeeRecipient?.bind(context);
|
|
17302
18123
|
const hasBoth = typeof getFee === 'function' && typeof getFeeRecipient === 'function';
|
|
17303
|
-
const kit = new BridgeKit(
|
|
18124
|
+
const kit = new BridgeKit({
|
|
18125
|
+
...(context.disableErrorReporting != null && {
|
|
18126
|
+
disableErrorReporting: context.disableErrorReporting,
|
|
18127
|
+
}),
|
|
18128
|
+
});
|
|
17304
18129
|
if (hasBoth) {
|
|
17305
18130
|
kit.setCustomFeePolicy({
|
|
17306
18131
|
calculateFee: async (params) => {
|
|
@@ -17317,7 +18142,7 @@ const createBridgeKit = (context) => {
|
|
|
17317
18142
|
};
|
|
17318
18143
|
|
|
17319
18144
|
var name$1 = "@circle-fin/swap-kit";
|
|
17320
|
-
var version$1 = "1.
|
|
18145
|
+
var version$1 = "1.2.0";
|
|
17321
18146
|
var pkg$1 = {
|
|
17322
18147
|
name: name$1,
|
|
17323
18148
|
version: version$1};
|
|
@@ -27778,6 +28603,18 @@ function createSwapKitContext(config = {}) {
|
|
|
27778
28603
|
return context;
|
|
27779
28604
|
}
|
|
27780
28605
|
|
|
28606
|
+
/**
|
|
28607
|
+
* Telemetry event type identifiers for swap-kit operations.
|
|
28608
|
+
*
|
|
28609
|
+
* @internal
|
|
28610
|
+
*/
|
|
28611
|
+
const SWAP_EVENT_TYPES = {
|
|
28612
|
+
SWAP: 'swap_swap',
|
|
28613
|
+
ESTIMATE: 'swap_estimate',
|
|
28614
|
+
};
|
|
28615
|
+
|
|
28616
|
+
/** SDK name used in telemetry payloads. */
|
|
28617
|
+
const SDK_NAME$1 = resolveKitSdkName(pkg$1.name);
|
|
27781
28618
|
/**
|
|
27782
28619
|
* A high-level class-based interface for single-chain token swap operations.
|
|
27783
28620
|
*
|
|
@@ -27849,6 +28686,10 @@ function createSwapKitContext(config = {}) {
|
|
|
27849
28686
|
*/
|
|
27850
28687
|
class SwapKit {
|
|
27851
28688
|
context;
|
|
28689
|
+
/** Whether error telemetry is disabled. */
|
|
28690
|
+
disableErrorReporting;
|
|
28691
|
+
/** Per-kit telemetry identity for shared helpers. */
|
|
28692
|
+
telemetryConfig;
|
|
27852
28693
|
/**
|
|
27853
28694
|
* Create a new SwapKit instance.
|
|
27854
28695
|
*
|
|
@@ -27897,6 +28738,12 @@ class SwapKit {
|
|
|
27897
28738
|
*/
|
|
27898
28739
|
constructor(config = {}) {
|
|
27899
28740
|
this.context = createSwapKitContext(config);
|
|
28741
|
+
this.disableErrorReporting = config.disableErrorReporting === true;
|
|
28742
|
+
this.telemetryConfig = {
|
|
28743
|
+
sdkName: SDK_NAME$1,
|
|
28744
|
+
sdkVersion: pkg$1.version,
|
|
28745
|
+
disabled: this.disableErrorReporting,
|
|
28746
|
+
};
|
|
27900
28747
|
}
|
|
27901
28748
|
/**
|
|
27902
28749
|
* Estimate the output amount and fees for a swap operation.
|
|
@@ -27938,7 +28785,11 @@ class SwapKit {
|
|
|
27938
28785
|
* ```
|
|
27939
28786
|
*/
|
|
27940
28787
|
async estimate(params) {
|
|
27941
|
-
return estimate(this.context, params)
|
|
28788
|
+
return withErrorTelemetry(async () => estimate(this.context, params), SWAP_EVENT_TYPES.ESTIMATE, this.telemetryConfig, {
|
|
28789
|
+
sourceChain: resolveChainName(params.from.chain),
|
|
28790
|
+
tokenIn: params.tokenIn,
|
|
28791
|
+
tokenOut: params.tokenOut,
|
|
28792
|
+
});
|
|
27942
28793
|
}
|
|
27943
28794
|
/**
|
|
27944
28795
|
* Execute a token swap operation on a single chain.
|
|
@@ -27994,7 +28845,11 @@ class SwapKit {
|
|
|
27994
28845
|
* ```
|
|
27995
28846
|
*/
|
|
27996
28847
|
async swap(params) {
|
|
27997
|
-
return swap$1(this.context, params)
|
|
28848
|
+
return withErrorTelemetry(async () => swap$1(this.context, params), SWAP_EVENT_TYPES.SWAP, this.telemetryConfig, {
|
|
28849
|
+
sourceChain: resolveChainName(params.from.chain),
|
|
28850
|
+
tokenIn: params.tokenIn,
|
|
28851
|
+
tokenOut: params.tokenOut,
|
|
28852
|
+
});
|
|
27998
28853
|
}
|
|
27999
28854
|
/**
|
|
28000
28855
|
* Get all chains supported by the configured swap providers.
|
|
@@ -28187,7 +29042,11 @@ const createSwapKit = (context) => {
|
|
|
28187
29042
|
const getFee = context.getFee?.bind(context);
|
|
28188
29043
|
const getFeeRecipient = context.getFeeRecipient?.bind(context);
|
|
28189
29044
|
const hasBoth = typeof getFee === 'function' && typeof getFeeRecipient === 'function';
|
|
28190
|
-
const kit = new SwapKit(
|
|
29045
|
+
const kit = new SwapKit({
|
|
29046
|
+
...(context.disableErrorReporting != null && {
|
|
29047
|
+
disableErrorReporting: context.disableErrorReporting,
|
|
29048
|
+
}),
|
|
29049
|
+
});
|
|
28191
29050
|
if (hasBoth) {
|
|
28192
29051
|
kit.setCustomFeePolicy({
|
|
28193
29052
|
computeFee: async (params) => {
|
|
@@ -28691,7 +29550,7 @@ const prepareSend = async (params) => {
|
|
|
28691
29550
|
const fromContext = params.from;
|
|
28692
29551
|
const fromAdapter = fromContext.adapter;
|
|
28693
29552
|
const fromChain = resolveChainIdentifier(fromContext.chain);
|
|
28694
|
-
const fromAddress = await fromAdapter.getAddress(fromChain);
|
|
29553
|
+
const fromAddress = fromContext.address ?? (await fromAdapter.getAddress(fromChain));
|
|
28695
29554
|
// resolve input parameters
|
|
28696
29555
|
const token = params.token ?? 'USDC';
|
|
28697
29556
|
// Validate token and determine if it's an alias or custom address
|
|
@@ -29136,121 +29995,11 @@ const getSupportedChains$2 = (context, operationType, unifiedBalance) => {
|
|
|
29136
29995
|
};
|
|
29137
29996
|
|
|
29138
29997
|
var name = "@circle-fin/unified-balance-kit";
|
|
29139
|
-
var version = "1.0
|
|
29998
|
+
var version = "1.1.0";
|
|
29140
29999
|
var pkg = {
|
|
29141
30000
|
name: name,
|
|
29142
30001
|
version: version};
|
|
29143
30002
|
|
|
29144
|
-
/**
|
|
29145
|
-
* Default telemetry endpoint.
|
|
29146
|
-
*
|
|
29147
|
-
* Override via the `STABLECOIN_KITS_TELEMETRY_URL` environment variable
|
|
29148
|
-
* (e.g. for staging or local development).
|
|
29149
|
-
*
|
|
29150
|
-
* @internal
|
|
29151
|
-
*/
|
|
29152
|
-
const DEFAULT_LOGS_URL = 'https://api.circle.com/v1/stablecoinKits/logs';
|
|
29153
|
-
/**
|
|
29154
|
-
* Resolve the telemetry endpoint URL.
|
|
29155
|
-
*
|
|
29156
|
-
* @internal
|
|
29157
|
-
*/
|
|
29158
|
-
function getLogsUrl() {
|
|
29159
|
-
if (isNodeEnvironment() &&
|
|
29160
|
-
typeof process.env['STABLECOIN_KITS_TELEMETRY_URL'] === 'string' &&
|
|
29161
|
-
process.env['STABLECOIN_KITS_TELEMETRY_URL'].length > 0) {
|
|
29162
|
-
return process.env['STABLECOIN_KITS_TELEMETRY_URL'];
|
|
29163
|
-
}
|
|
29164
|
-
return DEFAULT_LOGS_URL;
|
|
29165
|
-
}
|
|
29166
|
-
/**
|
|
29167
|
-
* Send a telemetry event to the proxy service.
|
|
29168
|
-
*
|
|
29169
|
-
* @remarks
|
|
29170
|
-
* Fire-and-forget: the returned promise is intentionally not awaited
|
|
29171
|
-
* by the caller. A fetch failure (network error, non-2xx, timeout)
|
|
29172
|
-
* is silently swallowed so telemetry never blocks or fails user
|
|
29173
|
-
* operations.
|
|
29174
|
-
*
|
|
29175
|
-
* @param payload - The structured log payload matching the server schema.
|
|
29176
|
-
*
|
|
29177
|
-
* @example
|
|
29178
|
-
* ```typescript
|
|
29179
|
-
* import { emitAnalyticsLog } from './emitLog'
|
|
29180
|
-
*
|
|
29181
|
-
* // Fire-and-forget — do not await
|
|
29182
|
-
* emitAnalyticsLog(payload).catch(() => {})
|
|
29183
|
-
* ```
|
|
29184
|
-
*
|
|
29185
|
-
* @internal
|
|
29186
|
-
*/
|
|
29187
|
-
async function emitAnalyticsLog(payload) {
|
|
29188
|
-
try {
|
|
29189
|
-
const isNode = isNodeEnvironment();
|
|
29190
|
-
const userAgent = getUserAgent();
|
|
29191
|
-
await fetch(getLogsUrl(), {
|
|
29192
|
-
method: 'POST',
|
|
29193
|
-
headers: {
|
|
29194
|
-
'Content-Type': 'application/json',
|
|
29195
|
-
// Browser restricts setting User-Agent; use X-User-Agent instead.
|
|
29196
|
-
...(isNode
|
|
29197
|
-
? { 'User-Agent': userAgent }
|
|
29198
|
-
: { 'X-User-Agent': userAgent }),
|
|
29199
|
-
},
|
|
29200
|
-
body: JSON.stringify(payload),
|
|
29201
|
-
signal: AbortSignal.timeout(5_000),
|
|
29202
|
-
});
|
|
29203
|
-
}
|
|
29204
|
-
catch {
|
|
29205
|
-
// Silently swallow — telemetry must never break user operations.
|
|
29206
|
-
}
|
|
29207
|
-
}
|
|
29208
|
-
|
|
29209
|
-
/**
|
|
29210
|
-
* Build the `clientContext` object for telemetry payloads.
|
|
29211
|
-
*
|
|
29212
|
-
* @remarks
|
|
29213
|
-
* Uses the exported `getRuntime()` and `isNodeEnvironment()` from
|
|
29214
|
-
* `@core/utils` to detect the runtime environment (per Dominik's
|
|
29215
|
-
* feedback to reuse existing infrastructure). The returned string
|
|
29216
|
-
* is parsed into the structured `ClientContext` fields expected by
|
|
29217
|
-
* the server schema.
|
|
29218
|
-
*
|
|
29219
|
-
* @returns A {@link ClientContext} with platform, OS, and runtime name
|
|
29220
|
-
* populated from the current environment.
|
|
29221
|
-
*
|
|
29222
|
-
* @example
|
|
29223
|
-
* ```typescript
|
|
29224
|
-
* import { buildClientContext } from './clientContext'
|
|
29225
|
-
*
|
|
29226
|
-
* const ctx = buildClientContext()
|
|
29227
|
-
* // Node: { platform: 'node', os: 'darwin', runtimeName: null }
|
|
29228
|
-
* // Browser: { platform: 'browser', os: null, runtimeName: 'chrome' }
|
|
29229
|
-
* ```
|
|
29230
|
-
*/
|
|
29231
|
-
function buildClientContext() {
|
|
29232
|
-
const runtime = getRuntime();
|
|
29233
|
-
if (runtime.startsWith('browser/')) {
|
|
29234
|
-
return {
|
|
29235
|
-
platform: 'browser',
|
|
29236
|
-
os: null,
|
|
29237
|
-
runtimeName: runtime.slice('browser/'.length).toLowerCase(),
|
|
29238
|
-
};
|
|
29239
|
-
}
|
|
29240
|
-
if (runtime.startsWith('node/')) {
|
|
29241
|
-
return {
|
|
29242
|
-
platform: 'node',
|
|
29243
|
-
os: isNodeEnvironment() ? process.platform : null,
|
|
29244
|
-
runtimeName: null,
|
|
29245
|
-
};
|
|
29246
|
-
}
|
|
29247
|
-
return {
|
|
29248
|
-
platform: 'node',
|
|
29249
|
-
os: null,
|
|
29250
|
-
runtimeName: null,
|
|
29251
|
-
};
|
|
29252
|
-
}
|
|
29253
|
-
|
|
29254
30003
|
/**
|
|
29255
30004
|
* Event type identifiers accepted by the server-side logs endpoint.
|
|
29256
30005
|
*
|
|
@@ -29263,6 +30012,11 @@ const EVENT_TYPES = {
|
|
|
29263
30012
|
DEPOSIT_FOR: 'unified_balance_deposit_for',
|
|
29264
30013
|
SPEND: 'unified_balance_spend',
|
|
29265
30014
|
SPEND_FORWARDER: 'unified_balance_spend_forwarder',
|
|
30015
|
+
ESTIMATE_SPEND: 'unified_balance_estimate_spend',
|
|
30016
|
+
GET_BALANCES: 'unified_balance_get_balances',
|
|
30017
|
+
ADD_DELEGATE: 'unified_balance_add_delegate',
|
|
30018
|
+
REMOVE_DELEGATE: 'unified_balance_remove_delegate',
|
|
30019
|
+
GET_DELEGATE_STATUS: 'unified_balance_get_delegate_status',
|
|
29266
30020
|
INITIATE_REMOVE_FUND: 'unified_balance_initiate_remove_fund',
|
|
29267
30021
|
REMOVE_FUND: 'unified_balance_remove_fund',
|
|
29268
30022
|
};
|
|
@@ -29300,33 +30054,29 @@ function extractSingleChainResult(data) {
|
|
|
29300
30054
|
txHash: data.txHash,
|
|
29301
30055
|
};
|
|
29302
30056
|
}
|
|
29303
|
-
/**
|
|
29304
|
-
* Resolve a chain identifier that may be a string or a
|
|
29305
|
-
* `ChainDefinition` object to a plain string.
|
|
29306
|
-
*
|
|
29307
|
-
* @internal
|
|
29308
|
-
*/
|
|
29309
|
-
function resolveChainString(chain) {
|
|
29310
|
-
if (typeof chain === 'string')
|
|
29311
|
-
return chain;
|
|
29312
|
-
return chain.chain;
|
|
29313
|
-
}
|
|
29314
30057
|
/**
|
|
29315
30058
|
* Extract log-relevant fields from a spend result.
|
|
29316
30059
|
*
|
|
30060
|
+
* @remarks
|
|
30061
|
+
* Collects all source chains from allocations and joins them with
|
|
30062
|
+
* commas so multi-chain spends are fully represented.
|
|
30063
|
+
*
|
|
29317
30064
|
* @internal
|
|
29318
30065
|
*/
|
|
29319
30066
|
function extractSpend(data) {
|
|
29320
|
-
const
|
|
29321
|
-
|
|
29322
|
-
|
|
29323
|
-
|
|
30067
|
+
const allocs = data.allocations ?? [];
|
|
30068
|
+
const chains = [];
|
|
30069
|
+
for (const alloc of allocs) {
|
|
30070
|
+
const name = resolveChainName(alloc.chain);
|
|
30071
|
+
if (name != null) {
|
|
30072
|
+
chains.push(name);
|
|
30073
|
+
}
|
|
29324
30074
|
}
|
|
29325
|
-
const
|
|
30075
|
+
const sourceChain = chains.length > 0 ? chains.join(',') : undefined;
|
|
29326
30076
|
return {
|
|
29327
|
-
...(
|
|
30077
|
+
...(sourceChain != null && { sourceChain }),
|
|
29328
30078
|
destinationChain: data.destinationChain,
|
|
29329
|
-
...(
|
|
30079
|
+
...(allocs.length > 0 && { tokenIn: 'USDC' }),
|
|
29330
30080
|
txHash: data.txHash,
|
|
29331
30081
|
};
|
|
29332
30082
|
}
|
|
@@ -29425,10 +30175,9 @@ function mapSucceededEventToLog(actionName, payload, sdkName, sdkVersion) {
|
|
|
29425
30175
|
* telemetry for successful verb operations.
|
|
29426
30176
|
*
|
|
29427
30177
|
* @remarks
|
|
29428
|
-
*
|
|
29429
|
-
*
|
|
29430
|
-
*
|
|
29431
|
-
* subscribed to.
|
|
30178
|
+
* Registers a handler for each verb's `.succeeded` event using the
|
|
30179
|
+
* shared `registerTelemetryHandler` from `@core/utils`. Non-verb and
|
|
30180
|
+
* non-succeeded events are not subscribed to.
|
|
29432
30181
|
*
|
|
29433
30182
|
* The HTTP POST is fire-and-forget — telemetry never blocks or fails
|
|
29434
30183
|
* user operations.
|
|
@@ -29448,20 +30197,7 @@ function mapSucceededEventToLog(actionName, payload, sdkName, sdkVersion) {
|
|
|
29448
30197
|
* @internal
|
|
29449
30198
|
*/
|
|
29450
30199
|
function registerTelemetryHandler(dispatcher, sdkName, sdkVersion) {
|
|
29451
|
-
|
|
29452
|
-
dispatcher.on(actionName, (payload) => {
|
|
29453
|
-
try {
|
|
29454
|
-
const log = mapSucceededEventToLog(actionName, payload, sdkName, sdkVersion);
|
|
29455
|
-
if (log) {
|
|
29456
|
-
// Fire-and-forget — intentionally not awaited.
|
|
29457
|
-
void emitAnalyticsLog(log);
|
|
29458
|
-
}
|
|
29459
|
-
}
|
|
29460
|
-
catch {
|
|
29461
|
-
// Silently swallow — telemetry must never break user operations.
|
|
29462
|
-
}
|
|
29463
|
-
});
|
|
29464
|
-
}
|
|
30200
|
+
registerTelemetryHandler$1(dispatcher, sdkName, sdkVersion, VERB_EVENT_MAP, mapSucceededEventToLog);
|
|
29465
30201
|
}
|
|
29466
30202
|
|
|
29467
30203
|
/**
|
|
@@ -35491,6 +36227,8 @@ function getSupportedChains(context, token, options) {
|
|
|
35491
36227
|
return Object.values(Object.fromEntries(filtered.map((chain) => [chain.chain, chain])));
|
|
35492
36228
|
}
|
|
35493
36229
|
|
|
36230
|
+
/** SDK name used in telemetry payloads. */
|
|
36231
|
+
const SDK_NAME = resolveKitSdkName(pkg.name);
|
|
35494
36232
|
/**
|
|
35495
36233
|
* A high-level class-based interface for cross-chain USDC deposits,
|
|
35496
36234
|
* spending, balance queries, delegation management, and withdrawals.
|
|
@@ -35538,6 +36276,10 @@ class UnifiedBalanceKit {
|
|
|
35538
36276
|
* The action dispatcher for the kit.
|
|
35539
36277
|
*/
|
|
35540
36278
|
actionDispatcher;
|
|
36279
|
+
/** Whether error telemetry is disabled. */
|
|
36280
|
+
disableErrorReporting;
|
|
36281
|
+
/** Per-kit telemetry identity for shared helpers. */
|
|
36282
|
+
telemetryConfig;
|
|
35541
36283
|
/**
|
|
35542
36284
|
* Create a new UnifiedBalanceKit instance.
|
|
35543
36285
|
*
|
|
@@ -35550,14 +36292,49 @@ class UnifiedBalanceKit {
|
|
|
35550
36292
|
constructor(config = {}) {
|
|
35551
36293
|
this.context = createUnifiedBalanceKitContext(config);
|
|
35552
36294
|
this.actionDispatcher = new Actionable();
|
|
36295
|
+
this.disableErrorReporting = config.disableErrorReporting === true;
|
|
36296
|
+
this.telemetryConfig = {
|
|
36297
|
+
sdkName: SDK_NAME,
|
|
36298
|
+
sdkVersion: pkg.version,
|
|
36299
|
+
disabled: this.disableErrorReporting,
|
|
36300
|
+
};
|
|
35553
36301
|
for (const provider of this.context.providers) {
|
|
35554
36302
|
provider.registerDispatcher(this.actionDispatcher);
|
|
35555
36303
|
}
|
|
35556
36304
|
if (!config.disableAnalytics) {
|
|
35557
|
-
|
|
35558
|
-
registerTelemetryHandler(this.actionDispatcher, sdkName, pkg.version);
|
|
36305
|
+
registerTelemetryHandler(this.actionDispatcher, SDK_NAME, pkg.version);
|
|
35559
36306
|
}
|
|
35560
36307
|
}
|
|
36308
|
+
/**
|
|
36309
|
+
* Extract comma-separated source chain names from spend params.
|
|
36310
|
+
*
|
|
36311
|
+
* @internal
|
|
36312
|
+
*/
|
|
36313
|
+
static extractSpendSourceChains(params) {
|
|
36314
|
+
if (params == null || typeof params !== 'object' || !('from' in params)) {
|
|
36315
|
+
return undefined;
|
|
36316
|
+
}
|
|
36317
|
+
const fromVal = params.from;
|
|
36318
|
+
const sources = Array.isArray(fromVal) ? fromVal : [fromVal];
|
|
36319
|
+
const chains = [];
|
|
36320
|
+
for (const src of sources) {
|
|
36321
|
+
const allocs = src?.allocations;
|
|
36322
|
+
let allocArr;
|
|
36323
|
+
if (allocs == null) {
|
|
36324
|
+
allocArr = [];
|
|
36325
|
+
}
|
|
36326
|
+
else {
|
|
36327
|
+
allocArr = Array.isArray(allocs) ? allocs : [allocs];
|
|
36328
|
+
}
|
|
36329
|
+
for (const alloc of allocArr) {
|
|
36330
|
+
const name = resolveChainName(alloc.chain);
|
|
36331
|
+
if (name != null) {
|
|
36332
|
+
chains.push(name);
|
|
36333
|
+
}
|
|
36334
|
+
}
|
|
36335
|
+
}
|
|
36336
|
+
return chains.length > 0 ? chains.join(',') : undefined;
|
|
36337
|
+
}
|
|
35561
36338
|
// implementation just forwards to the bus
|
|
35562
36339
|
on(actionOrWildcard, handler) {
|
|
35563
36340
|
this.actionDispatcher.on(actionOrWildcard, handler);
|
|
@@ -35580,7 +36357,10 @@ class UnifiedBalanceKit {
|
|
|
35580
36357
|
* @see UnifiedBalanceKit.depositFor to deposit into another account.
|
|
35581
36358
|
*/
|
|
35582
36359
|
async deposit(params) {
|
|
35583
|
-
return deposit(this.context, params)
|
|
36360
|
+
return withErrorTelemetry(async () => deposit(this.context, params), EVENT_TYPES.DEPOSIT, this.telemetryConfig, {
|
|
36361
|
+
sourceChain: resolveChainName(params.from?.chain),
|
|
36362
|
+
tokenIn: params.token ?? 'USDC',
|
|
36363
|
+
});
|
|
35584
36364
|
}
|
|
35585
36365
|
/**
|
|
35586
36366
|
* Deposit USDC into another account (not the caller's).
|
|
@@ -35592,7 +36372,10 @@ class UnifiedBalanceKit {
|
|
|
35592
36372
|
* @see UnifiedBalanceKit.deposit to deposit into your own account.
|
|
35593
36373
|
*/
|
|
35594
36374
|
async depositFor(params) {
|
|
35595
|
-
return depositFor(this.context, params)
|
|
36375
|
+
return withErrorTelemetry(async () => depositFor(this.context, params), EVENT_TYPES.DEPOSIT_FOR, this.telemetryConfig, {
|
|
36376
|
+
sourceChain: resolveChainName(params.from?.chain),
|
|
36377
|
+
tokenIn: params.token ?? 'USDC',
|
|
36378
|
+
});
|
|
35596
36379
|
}
|
|
35597
36380
|
/**
|
|
35598
36381
|
* Spend (mint) USDC on a destination chain by pulling funds from one
|
|
@@ -35605,7 +36388,17 @@ class UnifiedBalanceKit {
|
|
|
35605
36388
|
* @see UnifiedBalanceKit.estimateSpend to preview fees before spending.
|
|
35606
36389
|
*/
|
|
35607
36390
|
async spend(params) {
|
|
35608
|
-
|
|
36391
|
+
const destChain = 'to' in params
|
|
36392
|
+
? resolveChainName(params.to.chain)
|
|
36393
|
+
: undefined;
|
|
36394
|
+
const tokenIn = 'token' in params
|
|
36395
|
+
? (params.token ?? 'USDC')
|
|
36396
|
+
: 'USDC';
|
|
36397
|
+
return withErrorTelemetry(async () => spend(this.context, params), EVENT_TYPES.SPEND, this.telemetryConfig, {
|
|
36398
|
+
sourceChain: UnifiedBalanceKit.extractSpendSourceChains(params),
|
|
36399
|
+
...(destChain != null && { destinationChain: destChain }),
|
|
36400
|
+
tokenIn,
|
|
36401
|
+
});
|
|
35609
36402
|
}
|
|
35610
36403
|
/**
|
|
35611
36404
|
* Estimate the fees for a spend operation without executing it.
|
|
@@ -35615,7 +36408,17 @@ class UnifiedBalanceKit {
|
|
|
35615
36408
|
* @returns Promise resolving to the fee estimate.
|
|
35616
36409
|
*/
|
|
35617
36410
|
async estimateSpend(params) {
|
|
35618
|
-
|
|
36411
|
+
const destChain = 'to' in params
|
|
36412
|
+
? resolveChainName(params.to.chain)
|
|
36413
|
+
: undefined;
|
|
36414
|
+
const sourceChain = UnifiedBalanceKit.extractSpendSourceChains(params);
|
|
36415
|
+
return withErrorTelemetry(async () => estimateSpend(this.context, params), EVENT_TYPES.ESTIMATE_SPEND, this.telemetryConfig, {
|
|
36416
|
+
...(sourceChain != null && { sourceChain }),
|
|
36417
|
+
...(destChain != null && { destinationChain: destChain }),
|
|
36418
|
+
tokenIn: 'token' in params
|
|
36419
|
+
? (params.token ?? 'USDC')
|
|
36420
|
+
: 'USDC',
|
|
36421
|
+
});
|
|
35619
36422
|
}
|
|
35620
36423
|
/**
|
|
35621
36424
|
* Fetch aggregated and per-chain balances for one or more accounts.
|
|
@@ -35624,7 +36427,7 @@ class UnifiedBalanceKit {
|
|
|
35624
36427
|
* @returns Promise resolving to the aggregated balance result.
|
|
35625
36428
|
*/
|
|
35626
36429
|
async getBalances(params) {
|
|
35627
|
-
return getBalances(this.context, params);
|
|
36430
|
+
return withErrorTelemetry(async () => getBalances(this.context, params), EVENT_TYPES.GET_BALANCES, this.telemetryConfig);
|
|
35628
36431
|
}
|
|
35629
36432
|
/**
|
|
35630
36433
|
* Grant spending rights to another address on the owner's account.
|
|
@@ -35639,7 +36442,7 @@ class UnifiedBalanceKit {
|
|
|
35639
36442
|
* @see UnifiedBalanceKit.getDelegateStatus to check delegate status.
|
|
35640
36443
|
*/
|
|
35641
36444
|
async addDelegate(params) {
|
|
35642
|
-
return addDelegate(this.context, params);
|
|
36445
|
+
return withErrorTelemetry(async () => addDelegate(this.context, params), EVENT_TYPES.ADD_DELEGATE, this.telemetryConfig, { sourceChain: resolveChainName(params.from?.chain) });
|
|
35643
36446
|
}
|
|
35644
36447
|
/**
|
|
35645
36448
|
* Revoke spending rights from a delegate on the owner's account.
|
|
@@ -35654,7 +36457,7 @@ class UnifiedBalanceKit {
|
|
|
35654
36457
|
* @see UnifiedBalanceKit.getDelegateStatus to check delegate status.
|
|
35655
36458
|
*/
|
|
35656
36459
|
async removeDelegate(params) {
|
|
35657
|
-
return removeDelegate(this.context, params);
|
|
36460
|
+
return withErrorTelemetry(async () => removeDelegate(this.context, params), EVENT_TYPES.REMOVE_DELEGATE, this.telemetryConfig, { sourceChain: resolveChainName(params.from?.chain) });
|
|
35658
36461
|
}
|
|
35659
36462
|
/**
|
|
35660
36463
|
* Kick off a delayed fund removal from an account.
|
|
@@ -35666,7 +36469,10 @@ class UnifiedBalanceKit {
|
|
|
35666
36469
|
* @see UnifiedBalanceKit.removeFund to complete the fund removal.
|
|
35667
36470
|
*/
|
|
35668
36471
|
async initiateRemoveFund(params) {
|
|
35669
|
-
return initiateRemoveFund(this.context, params)
|
|
36472
|
+
return withErrorTelemetry(async () => initiateRemoveFund(this.context, params), EVENT_TYPES.INITIATE_REMOVE_FUND, this.telemetryConfig, {
|
|
36473
|
+
sourceChain: resolveChainName(params.from?.chain),
|
|
36474
|
+
tokenIn: params.token ?? 'USDC',
|
|
36475
|
+
});
|
|
35670
36476
|
}
|
|
35671
36477
|
/**
|
|
35672
36478
|
* Complete a fund removal once the activation period has passed.
|
|
@@ -35678,7 +36484,10 @@ class UnifiedBalanceKit {
|
|
|
35678
36484
|
* @see UnifiedBalanceKit.initiateRemoveFund to start the process.
|
|
35679
36485
|
*/
|
|
35680
36486
|
async removeFund(params) {
|
|
35681
|
-
return removeFund(this.context, params)
|
|
36487
|
+
return withErrorTelemetry(async () => removeFund(this.context, params), EVENT_TYPES.REMOVE_FUND, this.telemetryConfig, {
|
|
36488
|
+
sourceChain: resolveChainName(params.from?.chain),
|
|
36489
|
+
tokenIn: params.token ?? 'USDC',
|
|
36490
|
+
});
|
|
35682
36491
|
}
|
|
35683
36492
|
/**
|
|
35684
36493
|
* Check the finality-aware delegate status of an address.
|
|
@@ -35706,7 +36515,7 @@ class UnifiedBalanceKit {
|
|
|
35706
36515
|
* ```
|
|
35707
36516
|
*/
|
|
35708
36517
|
async getDelegateStatus(params) {
|
|
35709
|
-
return getDelegateStatus(this.context, params);
|
|
36518
|
+
return withErrorTelemetry(async () => getDelegateStatus(this.context, params), EVENT_TYPES.GET_DELEGATE_STATUS, this.telemetryConfig, { sourceChain: resolveChainName(params.from?.chain) });
|
|
35710
36519
|
}
|
|
35711
36520
|
/**
|
|
35712
36521
|
* Get all chains supported by the kit.
|
|
@@ -36196,8 +37005,18 @@ class AppKit {
|
|
|
36196
37005
|
* ```
|
|
36197
37006
|
*/
|
|
36198
37007
|
constructor(config = {}) {
|
|
36199
|
-
this.context = createContext(
|
|
36200
|
-
|
|
37008
|
+
this.context = createContext({
|
|
37009
|
+
...config,
|
|
37010
|
+
...(config.disableErrorReporting != null && {
|
|
37011
|
+
disableErrorReporting: config.disableErrorReporting,
|
|
37012
|
+
}),
|
|
37013
|
+
});
|
|
37014
|
+
this.unifiedBalance = new AppKitUnifiedBalance({
|
|
37015
|
+
...config.unifiedBalance,
|
|
37016
|
+
...(config.disableErrorReporting != null && {
|
|
37017
|
+
disableErrorReporting: config.disableErrorReporting,
|
|
37018
|
+
}),
|
|
37019
|
+
});
|
|
36201
37020
|
}
|
|
36202
37021
|
/**
|
|
36203
37022
|
* Execute a cross-chain USDC bridge transfer.
|