@circle-fin/app-kit 1.4.0 → 1.4.2
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 +16 -0
- package/README.md +98 -36
- package/chains.cjs +102 -2
- package/chains.d.ts +4 -2
- package/chains.mjs +102 -2
- package/index.cjs +301 -11
- package/index.d.ts +173 -2
- package/index.mjs +301 -11
- package/package.json +5 -5
package/index.cjs
CHANGED
|
@@ -3419,6 +3419,8 @@ exports.Blockchain = void 0;
|
|
|
3419
3419
|
Blockchain["Noble_Testnet"] = "Noble_Testnet";
|
|
3420
3420
|
Blockchain["Optimism"] = "Optimism";
|
|
3421
3421
|
Blockchain["Optimism_Sepolia"] = "Optimism_Sepolia";
|
|
3422
|
+
Blockchain["Pharos"] = "Pharos";
|
|
3423
|
+
Blockchain["Pharos_Testnet"] = "Pharos_Testnet";
|
|
3422
3424
|
Blockchain["Polkadot_Asset_Hub"] = "Polkadot_Asset_Hub";
|
|
3423
3425
|
Blockchain["Polkadot_Westmint"] = "Polkadot_Westmint";
|
|
3424
3426
|
Blockchain["Plume"] = "Plume";
|
|
@@ -3627,6 +3629,7 @@ exports.BridgeChain = void 0;
|
|
|
3627
3629
|
BridgeChain["Monad"] = "Monad";
|
|
3628
3630
|
BridgeChain["Morph"] = "Morph";
|
|
3629
3631
|
BridgeChain["Optimism"] = "Optimism";
|
|
3632
|
+
BridgeChain["Pharos"] = "Pharos";
|
|
3630
3633
|
BridgeChain["Plume"] = "Plume";
|
|
3631
3634
|
BridgeChain["Polygon"] = "Polygon";
|
|
3632
3635
|
BridgeChain["Sei"] = "Sei";
|
|
@@ -3649,6 +3652,7 @@ exports.BridgeChain = void 0;
|
|
|
3649
3652
|
BridgeChain["Monad_Testnet"] = "Monad_Testnet";
|
|
3650
3653
|
BridgeChain["Morph_Testnet"] = "Morph_Testnet";
|
|
3651
3654
|
BridgeChain["Optimism_Sepolia"] = "Optimism_Sepolia";
|
|
3655
|
+
BridgeChain["Pharos_Testnet"] = "Pharos_Testnet";
|
|
3652
3656
|
BridgeChain["Plume_Testnet"] = "Plume_Testnet";
|
|
3653
3657
|
BridgeChain["Polygon_Amoy_Testnet"] = "Polygon_Amoy_Testnet";
|
|
3654
3658
|
BridgeChain["Sei_Testnet"] = "Sei_Testnet";
|
|
@@ -3994,6 +3998,12 @@ const SWAP_TOKEN_REGISTRY = {
|
|
|
3994
3998
|
category: 'wrapped',
|
|
3995
3999
|
description: 'Wrapped Polygon',
|
|
3996
4000
|
},
|
|
4001
|
+
CIRBTC: {
|
|
4002
|
+
symbol: 'CIRBTC',
|
|
4003
|
+
decimals: 8,
|
|
4004
|
+
category: 'wrapped',
|
|
4005
|
+
description: 'Circle Bitcoin',
|
|
4006
|
+
},
|
|
3997
4007
|
};
|
|
3998
4008
|
/**
|
|
3999
4009
|
* Special NATIVE token constant for swap operations.
|
|
@@ -5690,6 +5700,96 @@ const OptimismSepolia = defineChain({
|
|
|
5690
5700
|
},
|
|
5691
5701
|
});
|
|
5692
5702
|
|
|
5703
|
+
/**
|
|
5704
|
+
* Pharos Mainnet chain definition
|
|
5705
|
+
* @remarks
|
|
5706
|
+
* This represents the official production network for the Pharos blockchain.
|
|
5707
|
+
* Pharos is a modular, full-stack parallel Layer 1 blockchain with
|
|
5708
|
+
* sub-second finality and EVM compatibility.
|
|
5709
|
+
*/
|
|
5710
|
+
const Pharos = defineChain({
|
|
5711
|
+
type: 'evm',
|
|
5712
|
+
chain: exports.Blockchain.Pharos,
|
|
5713
|
+
name: 'Pharos',
|
|
5714
|
+
title: 'Pharos Mainnet',
|
|
5715
|
+
nativeCurrency: {
|
|
5716
|
+
name: 'Pharos',
|
|
5717
|
+
symbol: 'PHAROS',
|
|
5718
|
+
decimals: 18,
|
|
5719
|
+
},
|
|
5720
|
+
chainId: 1672,
|
|
5721
|
+
isTestnet: false,
|
|
5722
|
+
explorerUrl: 'https://pharos.socialscan.io/tx/{hash}',
|
|
5723
|
+
rpcEndpoints: ['https://rpc.pharos.xyz'],
|
|
5724
|
+
eurcAddress: null,
|
|
5725
|
+
usdcAddress: '0xC879C018dB60520F4355C26eD1a6D572cdAC1815',
|
|
5726
|
+
usdtAddress: null,
|
|
5727
|
+
cctp: {
|
|
5728
|
+
domain: 31,
|
|
5729
|
+
contracts: {
|
|
5730
|
+
v2: {
|
|
5731
|
+
type: 'split',
|
|
5732
|
+
tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
|
|
5733
|
+
messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
|
|
5734
|
+
confirmations: 1,
|
|
5735
|
+
fastConfirmations: 1,
|
|
5736
|
+
},
|
|
5737
|
+
},
|
|
5738
|
+
forwarderSupported: {
|
|
5739
|
+
source: false,
|
|
5740
|
+
destination: false,
|
|
5741
|
+
},
|
|
5742
|
+
},
|
|
5743
|
+
kitContracts: {
|
|
5744
|
+
bridge: BRIDGE_CONTRACT_EVM_MAINNET,
|
|
5745
|
+
},
|
|
5746
|
+
});
|
|
5747
|
+
|
|
5748
|
+
/**
|
|
5749
|
+
* Pharos Atlantic Testnet chain definition
|
|
5750
|
+
* @remarks
|
|
5751
|
+
* This represents the official test network for the Pharos blockchain.
|
|
5752
|
+
* Pharos is a modular, full-stack parallel Layer 1 blockchain with
|
|
5753
|
+
* sub-second finality and EVM compatibility.
|
|
5754
|
+
*/
|
|
5755
|
+
const PharosTestnet = defineChain({
|
|
5756
|
+
type: 'evm',
|
|
5757
|
+
chain: exports.Blockchain.Pharos_Testnet,
|
|
5758
|
+
name: 'Pharos Atlantic',
|
|
5759
|
+
title: 'Pharos Atlantic Testnet',
|
|
5760
|
+
nativeCurrency: {
|
|
5761
|
+
name: 'Pharos',
|
|
5762
|
+
symbol: 'PHAROS',
|
|
5763
|
+
decimals: 18,
|
|
5764
|
+
},
|
|
5765
|
+
chainId: 688689,
|
|
5766
|
+
isTestnet: true,
|
|
5767
|
+
explorerUrl: 'https://atlantic.pharosscan.xyz/tx/{hash}',
|
|
5768
|
+
rpcEndpoints: ['https://atlantic.dplabs-internal.com'],
|
|
5769
|
+
eurcAddress: null,
|
|
5770
|
+
usdcAddress: '0xcfC8330f4BCAB529c625D12781b1C19466A9Fc8B',
|
|
5771
|
+
usdtAddress: null,
|
|
5772
|
+
cctp: {
|
|
5773
|
+
domain: 31,
|
|
5774
|
+
contracts: {
|
|
5775
|
+
v2: {
|
|
5776
|
+
type: 'split',
|
|
5777
|
+
tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
|
|
5778
|
+
messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
|
|
5779
|
+
confirmations: 1,
|
|
5780
|
+
fastConfirmations: 1,
|
|
5781
|
+
},
|
|
5782
|
+
},
|
|
5783
|
+
forwarderSupported: {
|
|
5784
|
+
source: false,
|
|
5785
|
+
destination: false,
|
|
5786
|
+
},
|
|
5787
|
+
},
|
|
5788
|
+
kitContracts: {
|
|
5789
|
+
bridge: BRIDGE_CONTRACT_EVM_TESTNET,
|
|
5790
|
+
},
|
|
5791
|
+
});
|
|
5792
|
+
|
|
5693
5793
|
/**
|
|
5694
5794
|
* Plume Mainnet chain definition
|
|
5695
5795
|
* @remarks
|
|
@@ -5972,7 +6072,7 @@ const Sei = defineChain({
|
|
|
5972
6072
|
},
|
|
5973
6073
|
chainId: 1329,
|
|
5974
6074
|
isTestnet: false,
|
|
5975
|
-
explorerUrl: 'https://
|
|
6075
|
+
explorerUrl: 'https://seiscan.io/tx/{hash}',
|
|
5976
6076
|
rpcEndpoints: ['https://evm-rpc.sei-apis.com'],
|
|
5977
6077
|
eurcAddress: null,
|
|
5978
6078
|
usdcAddress: '0xe15fC38F6D8c56aF07bbCBe3BAf5708A2Bf42392',
|
|
@@ -6030,7 +6130,7 @@ const SeiTestnet = defineChain({
|
|
|
6030
6130
|
},
|
|
6031
6131
|
chainId: 1328,
|
|
6032
6132
|
isTestnet: true,
|
|
6033
|
-
explorerUrl: 'https://
|
|
6133
|
+
explorerUrl: 'https://testnet.seiscan.io/tx/{hash}',
|
|
6034
6134
|
rpcEndpoints: ['https://evm-rpc-testnet.sei-apis.com'],
|
|
6035
6135
|
eurcAddress: null,
|
|
6036
6136
|
usdcAddress: '0x4fCF1784B31630811181f670Aea7A7bEF803eaED',
|
|
@@ -6847,6 +6947,8 @@ var Chains = {
|
|
|
6847
6947
|
NobleTestnet: NobleTestnet,
|
|
6848
6948
|
Optimism: Optimism,
|
|
6849
6949
|
OptimismSepolia: OptimismSepolia,
|
|
6950
|
+
Pharos: Pharos,
|
|
6951
|
+
PharosTestnet: PharosTestnet,
|
|
6850
6952
|
Plume: Plume,
|
|
6851
6953
|
PlumeTestnet: PlumeTestnet,
|
|
6852
6954
|
PolkadotAssetHub: PolkadotAssetHub,
|
|
@@ -9115,6 +9217,7 @@ const USDC = {
|
|
|
9115
9217
|
[exports.Blockchain.NEAR]: '17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1',
|
|
9116
9218
|
[exports.Blockchain.Noble]: 'uusdc',
|
|
9117
9219
|
[exports.Blockchain.Optimism]: '0x0b2c639c533813f4aa9d7837caf62653d097ff85',
|
|
9220
|
+
[exports.Blockchain.Pharos]: '0xC879C018dB60520F4355C26eD1a6D572cdAC1815',
|
|
9118
9221
|
[exports.Blockchain.Plume]: '0x222365EF19F7947e5484218551B56bb3965Aa7aF',
|
|
9119
9222
|
[exports.Blockchain.Polkadot_Asset_Hub]: '1337',
|
|
9120
9223
|
[exports.Blockchain.Polygon]: '0x3c499c542cef5e3811e1192ce70d8cc03d5c3359',
|
|
@@ -9146,6 +9249,7 @@ const USDC = {
|
|
|
9146
9249
|
[exports.Blockchain.NEAR_Testnet]: '3e2210e1184b45b64c8a434c0a7e7b23cc04ea7eb7a6c3c32520d03d4afcb8af',
|
|
9147
9250
|
[exports.Blockchain.Noble_Testnet]: 'uusdc',
|
|
9148
9251
|
[exports.Blockchain.Optimism_Sepolia]: '0x5fd84259d66Cd46123540766Be93DFE6D43130D7',
|
|
9252
|
+
[exports.Blockchain.Pharos_Testnet]: '0xcfC8330f4BCAB529c625D12781b1C19466A9Fc8B',
|
|
9149
9253
|
[exports.Blockchain.Plume_Testnet]: '0xcB5f30e335672893c7eb944B374c196392C19D18',
|
|
9150
9254
|
[exports.Blockchain.Polkadot_Westmint]: '31337',
|
|
9151
9255
|
[exports.Blockchain.Polygon_Amoy_Testnet]: '0x41e94eb019c0762f9bfcf9fb1e58725bfb0e7582',
|
|
@@ -9426,6 +9530,32 @@ const MON = {
|
|
|
9426
9530
|
},
|
|
9427
9531
|
};
|
|
9428
9532
|
|
|
9533
|
+
/**
|
|
9534
|
+
* cirBTC (Circle Bitcoin) token definition with addresses and metadata.
|
|
9535
|
+
*
|
|
9536
|
+
* @remarks
|
|
9537
|
+
* Built-in cirBTC definition for the TokenRegistry. Currently deployed
|
|
9538
|
+
* on Arc Testnet.
|
|
9539
|
+
*
|
|
9540
|
+
* @example
|
|
9541
|
+
* ```typescript
|
|
9542
|
+
* import { CIRBTC } from '@core/tokens'
|
|
9543
|
+
* import { Blockchain } from '@core/chains'
|
|
9544
|
+
*
|
|
9545
|
+
* console.log(CIRBTC.symbol) // 'cirBTC'
|
|
9546
|
+
* console.log(CIRBTC.decimals) // 8
|
|
9547
|
+
* console.log(CIRBTC.locators[Blockchain.Arc_Testnet])
|
|
9548
|
+
* // '0xf0C4a4CE82A5746AbAAd9425360Ab04fbBA432BF'
|
|
9549
|
+
* ```
|
|
9550
|
+
*/
|
|
9551
|
+
const CIRBTC = {
|
|
9552
|
+
symbol: 'cirBTC',
|
|
9553
|
+
decimals: 8,
|
|
9554
|
+
locators: {
|
|
9555
|
+
[exports.Blockchain.Arc_Testnet]: '0xf0C4a4CE82A5746AbAAd9425360Ab04fbBA432BF',
|
|
9556
|
+
},
|
|
9557
|
+
};
|
|
9558
|
+
|
|
9429
9559
|
// Re-export for consumers
|
|
9430
9560
|
/**
|
|
9431
9561
|
* All default token definitions.
|
|
@@ -9434,7 +9564,7 @@ const MON = {
|
|
|
9434
9564
|
* These tokens are automatically included in the TokenRegistry when created
|
|
9435
9565
|
* without explicit defaults. Extensions can override these definitions.
|
|
9436
9566
|
* Includes USDC, USDT, EURC, DAI, USDE, PYUSD, WETH, WBTC, WSOL, WAVAX,
|
|
9437
|
-
* WPOL, ETH, POL, PLUME, and
|
|
9567
|
+
* WPOL, ETH, POL, PLUME, MON, and cirBTC.
|
|
9438
9568
|
*
|
|
9439
9569
|
* @example
|
|
9440
9570
|
* ```typescript
|
|
@@ -9465,6 +9595,7 @@ const DEFAULT_TOKENS = [
|
|
|
9465
9595
|
POL,
|
|
9466
9596
|
PLUME,
|
|
9467
9597
|
MON,
|
|
9598
|
+
CIRBTC,
|
|
9468
9599
|
];
|
|
9469
9600
|
/**
|
|
9470
9601
|
* Uppercased token symbols approved for swap fee collection.
|
|
@@ -10213,7 +10344,7 @@ async function retryAsync(fn, options) {
|
|
|
10213
10344
|
}
|
|
10214
10345
|
|
|
10215
10346
|
var name$2 = "@circle-fin/bridge-kit";
|
|
10216
|
-
var version$3 = "1.
|
|
10347
|
+
var version$3 = "1.9.0";
|
|
10217
10348
|
var pkg$3 = {
|
|
10218
10349
|
name: name$2,
|
|
10219
10350
|
version: version$3};
|
|
@@ -14344,11 +14475,18 @@ async function executePreparedChainRequest({ name, request, adapter, chain, conf
|
|
|
14344
14475
|
step.explorerUrl = buildExplorerUrl(chain, txHash);
|
|
14345
14476
|
if (outcome.errorMessage) {
|
|
14346
14477
|
step.errorMessage = outcome.errorMessage;
|
|
14478
|
+
// Transaction was mined but reverted on-chain.
|
|
14479
|
+
step.errorCategory = 'chain_revert';
|
|
14347
14480
|
}
|
|
14348
14481
|
}
|
|
14349
14482
|
catch (err) {
|
|
14350
14483
|
step.state = 'error';
|
|
14351
14484
|
step.error = err;
|
|
14485
|
+
// Sequential path does not yet attempt fine-grained classification of
|
|
14486
|
+
// pre-submission errors (user_rejected, capability errors, etc.). Mark
|
|
14487
|
+
// as `unknown` so consumers can at least detect the category is
|
|
14488
|
+
// populated uniformly across batched and sequential flows.
|
|
14489
|
+
step.errorCategory = 'unknown';
|
|
14352
14490
|
// Optionally parse for common blockchain error formats
|
|
14353
14491
|
if (err instanceof Error) {
|
|
14354
14492
|
step.errorMessage = err.message;
|
|
@@ -15014,16 +15152,70 @@ async function executeBatchedApproveAndBurn(params, provider) {
|
|
|
15014
15152
|
const batchResult = await adapter.batchExecute([approveCallData, burnCallData], chain);
|
|
15015
15153
|
const approveReceipt = batchResult.receipts[0];
|
|
15016
15154
|
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);
|
|
15155
|
+
const approveStep = await buildBatchedStep('approve', approveReceipt, batchResult.batchId, adapter, chain, batchResult.statusCode, batchResult.error);
|
|
15156
|
+
const burnStep = await buildBatchedStep('burn', burnReceipt, batchResult.batchId, adapter, chain, batchResult.statusCode, batchResult.error);
|
|
15019
15157
|
if (burnStep.state !== 'error' && !burnStep.txHash) {
|
|
15020
15158
|
burnStep.state = 'error';
|
|
15021
15159
|
burnStep.errorMessage =
|
|
15022
15160
|
'Batched burn step completed but no transaction hash was returned.';
|
|
15161
|
+
burnStep.errorCategory = 'unknown';
|
|
15023
15162
|
}
|
|
15024
15163
|
const context = { burnTxHash: burnStep.txHash ?? '' };
|
|
15025
15164
|
return { approveStep, burnStep, context };
|
|
15026
15165
|
}
|
|
15166
|
+
/**
|
|
15167
|
+
* Derive a {@link BridgeStepErrorCategory} for a missing receipt.
|
|
15168
|
+
*
|
|
15169
|
+
* Combines the EIP-5792 `statusCode` (when present) with the underlying
|
|
15170
|
+
* polling error (when set) to produce the most specific category available.
|
|
15171
|
+
* Falls back to `'unknown'` when neither signal is conclusive.
|
|
15172
|
+
*
|
|
15173
|
+
* @param statusCode - The terminal `statusCode` from `wallet_getCallsStatus`, if any.
|
|
15174
|
+
* @param batchError - The polling error from `batchExecute`, if any.
|
|
15175
|
+
* @returns The derived error category for a missing-receipt step.
|
|
15176
|
+
*
|
|
15177
|
+
* @internal
|
|
15178
|
+
*/
|
|
15179
|
+
function categorizeMissingReceipt(statusCode, batchError) {
|
|
15180
|
+
if (statusCode === 400)
|
|
15181
|
+
return 'failed_offchain';
|
|
15182
|
+
if (statusCode === 500)
|
|
15183
|
+
return 'reverted_onchain';
|
|
15184
|
+
if (statusCode === 600)
|
|
15185
|
+
return 'partial_reverted';
|
|
15186
|
+
if (batchError instanceof KitError &&
|
|
15187
|
+
batchError.code === NetworkError.TIMEOUT.code) {
|
|
15188
|
+
return 'polling_timeout';
|
|
15189
|
+
}
|
|
15190
|
+
return 'unknown';
|
|
15191
|
+
}
|
|
15192
|
+
/**
|
|
15193
|
+
* Derive a {@link BridgeStepErrorCategory} for a receipt that was returned
|
|
15194
|
+
* but whose per-call `status` is not `'success'`.
|
|
15195
|
+
*
|
|
15196
|
+
* A numeric EIP-5792 `statusCode` of 500 or 600 tells us the whole batch
|
|
15197
|
+
* reverted on-chain (completely or partially); otherwise the receipt
|
|
15198
|
+
* itself signalled a revert without a distinguishing code, so classify
|
|
15199
|
+
* as a plain on-chain revert.
|
|
15200
|
+
*
|
|
15201
|
+
* @param statusCode - The terminal `statusCode` from `wallet_getCallsStatus`, if any.
|
|
15202
|
+
* @returns The derived error category for a failed-receipt step.
|
|
15203
|
+
*
|
|
15204
|
+
* @internal
|
|
15205
|
+
*/
|
|
15206
|
+
function categorizeFailedReceipt(statusCode) {
|
|
15207
|
+
// Mirror categorizeMissingReceipt: if the wallet's terminal status is
|
|
15208
|
+
// 400 ("batch not included onchain"), that judgement is authoritative
|
|
15209
|
+
// even when a non-success receipt is attached. Without this, a wrapped
|
|
15210
|
+
// 400 receipt would fall through to `chain_revert` and mislead UX.
|
|
15211
|
+
if (statusCode === 400)
|
|
15212
|
+
return 'failed_offchain';
|
|
15213
|
+
if (statusCode === 600)
|
|
15214
|
+
return 'partial_reverted';
|
|
15215
|
+
if (statusCode === 500)
|
|
15216
|
+
return 'reverted_onchain';
|
|
15217
|
+
return 'chain_revert';
|
|
15218
|
+
}
|
|
15027
15219
|
/**
|
|
15028
15220
|
* Build a {@link BridgeStep} from a single receipt within a batch.
|
|
15029
15221
|
*
|
|
@@ -15038,11 +15230,17 @@ async function executeBatchedApproveAndBurn(params, provider) {
|
|
|
15038
15230
|
* @param batchId - Wallet-assigned batch identifier.
|
|
15039
15231
|
* @param adapter - The batch-capable adapter (used for confirmation).
|
|
15040
15232
|
* @param chain - The EVM chain the batch was executed on.
|
|
15233
|
+
* @param statusCode - Optional EIP-5792 `statusCode` for the batch.
|
|
15234
|
+
* Used to classify the step's error category when the receipt is
|
|
15235
|
+
* missing or failed.
|
|
15236
|
+
* @param batchError - Optional polling error from `batchExecute`.
|
|
15237
|
+
* Preserved on the step so callers can inspect underlying timeouts
|
|
15238
|
+
* or RPC failures.
|
|
15041
15239
|
* @returns A fully-populated bridge step with state, tx hash and explorer URL.
|
|
15042
15240
|
*
|
|
15043
15241
|
* @internal
|
|
15044
15242
|
*/
|
|
15045
|
-
async function buildBatchedStep(name, receipt, batchId, adapter, chain) {
|
|
15243
|
+
async function buildBatchedStep(name, receipt, batchId, adapter, chain, statusCode, batchError) {
|
|
15046
15244
|
const step = {
|
|
15047
15245
|
name,
|
|
15048
15246
|
state: 'pending',
|
|
@@ -15052,6 +15250,10 @@ async function buildBatchedStep(name, receipt, batchId, adapter, chain) {
|
|
|
15052
15250
|
if (!receipt) {
|
|
15053
15251
|
step.state = 'error';
|
|
15054
15252
|
step.errorMessage = `No receipt returned for ${name} in batch ${batchId}.`;
|
|
15253
|
+
step.errorCategory = categorizeMissingReceipt(statusCode, batchError);
|
|
15254
|
+
if (batchError !== undefined) {
|
|
15255
|
+
step.error = batchError;
|
|
15256
|
+
}
|
|
15055
15257
|
return step;
|
|
15056
15258
|
}
|
|
15057
15259
|
step.txHash = receipt.txHash;
|
|
@@ -15061,11 +15263,13 @@ async function buildBatchedStep(name, receipt, batchId, adapter, chain) {
|
|
|
15061
15263
|
if (receipt.status !== 'success') {
|
|
15062
15264
|
step.state = 'error';
|
|
15063
15265
|
step.errorMessage = `${name} call failed within batch ${batchId}.`;
|
|
15266
|
+
step.errorCategory = categorizeFailedReceipt(statusCode);
|
|
15064
15267
|
return step;
|
|
15065
15268
|
}
|
|
15066
15269
|
if (!receipt.txHash) {
|
|
15067
15270
|
step.state = 'error';
|
|
15068
15271
|
step.errorMessage = `${name} succeeded in batch but returned an empty transaction hash.`;
|
|
15272
|
+
step.errorCategory = 'unknown';
|
|
15069
15273
|
return step;
|
|
15070
15274
|
}
|
|
15071
15275
|
try {
|
|
@@ -15080,6 +15284,7 @@ async function buildBatchedStep(name, receipt, batchId, adapter, chain) {
|
|
|
15080
15284
|
step.data = transaction;
|
|
15081
15285
|
if (outcome.errorMessage) {
|
|
15082
15286
|
step.errorMessage = outcome.errorMessage;
|
|
15287
|
+
step.errorCategory = 'chain_revert';
|
|
15083
15288
|
}
|
|
15084
15289
|
}
|
|
15085
15290
|
catch (err) {
|
|
@@ -15087,11 +15292,12 @@ async function buildBatchedStep(name, receipt, batchId, adapter, chain) {
|
|
|
15087
15292
|
step.error = err;
|
|
15088
15293
|
step.errorMessage =
|
|
15089
15294
|
err instanceof Error ? err.message : 'Unknown error during confirmation.';
|
|
15295
|
+
step.errorCategory = 'unknown';
|
|
15090
15296
|
}
|
|
15091
15297
|
return step;
|
|
15092
15298
|
}
|
|
15093
15299
|
|
|
15094
|
-
var version$2 = "1.
|
|
15300
|
+
var version$2 = "1.7.0";
|
|
15095
15301
|
var pkg$2 = {
|
|
15096
15302
|
version: version$2};
|
|
15097
15303
|
|
|
@@ -15167,6 +15373,7 @@ async function executeBatchedPath(params, provider, result, invocation) {
|
|
|
15167
15373
|
errorMessage: error_ instanceof Error
|
|
15168
15374
|
? error_.message
|
|
15169
15375
|
: 'Batched approve + burn failed.',
|
|
15376
|
+
errorCategory: classifyPreSubmissionError(error_),
|
|
15170
15377
|
});
|
|
15171
15378
|
return undefined;
|
|
15172
15379
|
}
|
|
@@ -15181,6 +15388,89 @@ function ensureStepErrorMessage(name, step) {
|
|
|
15181
15388
|
step.errorMessage = `${name} step failed: ${getErrorMessage(step.error)}`;
|
|
15182
15389
|
}
|
|
15183
15390
|
}
|
|
15391
|
+
/**
|
|
15392
|
+
* Coerce a raw JSON-RPC `code` to a number.
|
|
15393
|
+
*
|
|
15394
|
+
* Some wallet SDKs serialize the JSON-RPC `code` as a string ("4001")
|
|
15395
|
+
* after round-tripping through JSON; accept both shapes so strict `===`
|
|
15396
|
+
* comparisons downstream still classify 5720/5730/5740 correctly — those
|
|
15397
|
+
* codes have no message-pattern fallback.
|
|
15398
|
+
*
|
|
15399
|
+
* @param rawCode - The raw `code` extracted from the error object.
|
|
15400
|
+
* @returns The numeric code, or `undefined` if the value cannot be parsed.
|
|
15401
|
+
*
|
|
15402
|
+
* @internal
|
|
15403
|
+
*/
|
|
15404
|
+
function coerceRpcCode(rawCode) {
|
|
15405
|
+
if (typeof rawCode === 'number') {
|
|
15406
|
+
return rawCode;
|
|
15407
|
+
}
|
|
15408
|
+
if (typeof rawCode === 'string') {
|
|
15409
|
+
return Number.parseInt(rawCode, 10);
|
|
15410
|
+
}
|
|
15411
|
+
return undefined;
|
|
15412
|
+
}
|
|
15413
|
+
/**
|
|
15414
|
+
* Classify a pre-submission error thrown during `wallet_sendCalls`.
|
|
15415
|
+
*
|
|
15416
|
+
* Inspect the error's JSON-RPC `code` (falling back to message pattern
|
|
15417
|
+
* matching for wrapper errors like viem's `ChainMismatchError`) and map
|
|
15418
|
+
* it to a {@link BridgeStepErrorCategory}. This lets downstream consumers
|
|
15419
|
+
* distinguish user rejections, wallet capability gaps, and unknown
|
|
15420
|
+
* failures without parsing error messages.
|
|
15421
|
+
*
|
|
15422
|
+
* @remarks
|
|
15423
|
+
* Does NOT alter control flow — the SDK continues to surface a
|
|
15424
|
+
* `state: 'error'` step. Auto-fallback to sequential execution is
|
|
15425
|
+
* intentionally out of scope for this helper.
|
|
15426
|
+
*
|
|
15427
|
+
* @param err - The error thrown by `wallet_sendCalls`.
|
|
15428
|
+
* @returns The derived error category, or `'unknown'` if no match.
|
|
15429
|
+
*
|
|
15430
|
+
* @internal
|
|
15431
|
+
*/
|
|
15432
|
+
function classifyPreSubmissionError(err) {
|
|
15433
|
+
// Cross-realm-safe duck typing: `instanceof Error` returns false for
|
|
15434
|
+
// errors thrown in a different JavaScript realm (e.g., a wallet
|
|
15435
|
+
// provider running inside an iframe, which is common with WalletConnect
|
|
15436
|
+
// and the Coinbase Wallet SDK).
|
|
15437
|
+
if (typeof err !== 'object' || err === null || !('message' in err)) {
|
|
15438
|
+
return 'unknown';
|
|
15439
|
+
}
|
|
15440
|
+
const code = coerceRpcCode(err.code);
|
|
15441
|
+
const message = String(err.message);
|
|
15442
|
+
// Numeric JSON-RPC codes are authoritative; check them before falling
|
|
15443
|
+
// back to message-pattern matching. Order matters: an error carrying
|
|
15444
|
+
// `code === 5750` with a message like "user rejected the upgrade"
|
|
15445
|
+
// is a capability problem, not a plain user rejection.
|
|
15446
|
+
if (code === 4001) {
|
|
15447
|
+
return 'user_rejected';
|
|
15448
|
+
}
|
|
15449
|
+
if (code === 5700 || code === 5710 || code === 5750) {
|
|
15450
|
+
return 'atomic_unsupported';
|
|
15451
|
+
}
|
|
15452
|
+
if (code === 5720) {
|
|
15453
|
+
return 'duplicate_batch_id';
|
|
15454
|
+
}
|
|
15455
|
+
if (code === 5730) {
|
|
15456
|
+
return 'unknown_bundle';
|
|
15457
|
+
}
|
|
15458
|
+
if (code === 5740) {
|
|
15459
|
+
return 'batch_too_large';
|
|
15460
|
+
}
|
|
15461
|
+
// Fall back to message patterns when no specific code is available —
|
|
15462
|
+
// viem (and other wrapper layers) sometimes strip the numeric code
|
|
15463
|
+
// while preserving the original wallet message in `Details:`.
|
|
15464
|
+
if (/EIP-7702 not supported/i.test(message) ||
|
|
15465
|
+
/does not support the requested chain/i.test(message) ||
|
|
15466
|
+
/rejected the upgrade/i.test(message)) {
|
|
15467
|
+
return 'atomic_unsupported';
|
|
15468
|
+
}
|
|
15469
|
+
if (/user rejected/i.test(message)) {
|
|
15470
|
+
return 'user_rejected';
|
|
15471
|
+
}
|
|
15472
|
+
return 'unknown';
|
|
15473
|
+
}
|
|
15184
15474
|
/**
|
|
15185
15475
|
* Execute a cross-chain USDC bridge using the CCTP v2 protocol.
|
|
15186
15476
|
*
|
|
@@ -17324,7 +17614,7 @@ const createBridgeKit = (context) => {
|
|
|
17324
17614
|
};
|
|
17325
17615
|
|
|
17326
17616
|
var name$1 = "@circle-fin/swap-kit";
|
|
17327
|
-
var version$1 = "1.1.
|
|
17617
|
+
var version$1 = "1.1.1";
|
|
17328
17618
|
var pkg$1 = {
|
|
17329
17619
|
name: name$1,
|
|
17330
17620
|
version: version$1};
|
|
@@ -28698,7 +28988,7 @@ const prepareSend = async (params) => {
|
|
|
28698
28988
|
const fromContext = params.from;
|
|
28699
28989
|
const fromAdapter = fromContext.adapter;
|
|
28700
28990
|
const fromChain = resolveChainIdentifier(fromContext.chain);
|
|
28701
|
-
const fromAddress = await fromAdapter.getAddress(fromChain);
|
|
28991
|
+
const fromAddress = fromContext.address ?? (await fromAdapter.getAddress(fromChain));
|
|
28702
28992
|
// resolve input parameters
|
|
28703
28993
|
const token = params.token ?? 'USDC';
|
|
28704
28994
|
// Validate token and determine if it's an alias or custom address
|
|
@@ -29143,7 +29433,7 @@ const getSupportedChains$2 = (context, operationType, unifiedBalance) => {
|
|
|
29143
29433
|
};
|
|
29144
29434
|
|
|
29145
29435
|
var name = "@circle-fin/unified-balance-kit";
|
|
29146
|
-
var version = "1.0.
|
|
29436
|
+
var version = "1.0.2";
|
|
29147
29437
|
var pkg = {
|
|
29148
29438
|
name: name,
|
|
29149
29439
|
version: version};
|