@circle-fin/app-kit 1.8.1 → 1.9.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 +45 -0
- package/README.md +3 -3
- package/bridge.cjs +425 -179
- package/bridge.d.cts +14 -0
- package/bridge.d.mts +14 -0
- package/bridge.d.ts +14 -0
- package/bridge.mjs +425 -179
- package/chains.cjs +94 -0
- package/chains.d.cts +2 -0
- package/chains.d.mts +2 -0
- package/chains.d.ts +2 -0
- package/chains.mjs +94 -0
- package/context.d.cts +14 -0
- package/context.d.mts +14 -0
- package/context.d.ts +14 -0
- package/earn.cjs +211 -30
- package/earn.d.cts +25 -5
- package/earn.d.mts +25 -5
- package/earn.d.ts +25 -5
- package/earn.mjs +211 -30
- package/estimateBridge.cjs +425 -179
- package/estimateBridge.d.cts +14 -0
- package/estimateBridge.d.mts +14 -0
- package/estimateBridge.d.ts +14 -0
- package/estimateBridge.mjs +425 -179
- package/estimateSwap.cjs +108 -7
- package/estimateSwap.d.cts +14 -0
- package/estimateSwap.d.mts +14 -0
- package/estimateSwap.d.ts +14 -0
- package/estimateSwap.mjs +108 -7
- package/index.cjs +586 -224
- package/index.d.cts +274 -17
- package/index.d.mts +274 -17
- package/index.d.ts +274 -17
- package/index.mjs +586 -224
- package/package.json +12 -6
- package/swap.cjs +108 -7
- package/swap.d.cts +14 -0
- package/swap.d.mts +14 -0
- package/swap.d.ts +14 -0
- package/swap.mjs +108 -7
- package/unifiedBalance.cjs +101 -1
- package/unifiedBalance.d.cts +2 -0
- package/unifiedBalance.d.mts +2 -0
- package/unifiedBalance.d.ts +2 -0
- package/unifiedBalance.mjs +101 -1
package/index.mjs
CHANGED
|
@@ -22,6 +22,7 @@ import { parseUnits as parseUnits$1, formatUnits as formatUnits$1 } from '@ether
|
|
|
22
22
|
import { hexlify, hexZeroPad } from '@ethersproject/bytes';
|
|
23
23
|
import { getAddress } from '@ethersproject/address';
|
|
24
24
|
import bs58 from 'bs58';
|
|
25
|
+
import '@ethersproject/abi';
|
|
25
26
|
import { PublicKey } from '@solana/web3.js';
|
|
26
27
|
import 'bn.js';
|
|
27
28
|
import '@coral-xyz/anchor';
|
|
@@ -3551,7 +3552,7 @@ class KitError extends Error {
|
|
|
3551
3552
|
*
|
|
3552
3553
|
* Error code ranges:
|
|
3553
3554
|
* - 1100-1105: INPUT errors — invalid inputs, unsupported configurations
|
|
3554
|
-
* - 8100-
|
|
3555
|
+
* - 8100-8105: SERVICE errors — retryable backend/provider failures
|
|
3555
3556
|
*
|
|
3556
3557
|
* @example
|
|
3557
3558
|
* ```typescript
|
|
@@ -3627,6 +3628,11 @@ class KitError extends Error {
|
|
|
3627
3628
|
code: 8104,
|
|
3628
3629
|
name: 'EARN_PAUSED',
|
|
3629
3630
|
type: 'SERVICE'
|
|
3631
|
+
},
|
|
3632
|
+
/** Position PnL is still reconciling and can be retried. */ POSITION_PNL_PENDING: {
|
|
3633
|
+
code: 8105,
|
|
3634
|
+
name: 'EARN_POSITION_PNL_PENDING',
|
|
3635
|
+
type: 'SERVICE'
|
|
3630
3636
|
}
|
|
3631
3637
|
};
|
|
3632
3638
|
|
|
@@ -3654,7 +3660,7 @@ function getOptionalString(value) {
|
|
|
3654
3660
|
*
|
|
3655
3661
|
* SERVICE errors (RETRYABLE) — try again later:
|
|
3656
3662
|
* - signing-failed, provider-error, rewards-fetch-failed,
|
|
3657
|
-
* internal-error, vault-refresh-busy, off-chain-paused,
|
|
3663
|
+
* internal-error, vault-refresh-busy, off-chain-paused, position-PnL-pending,
|
|
3658
3664
|
* bridge failures/status lookup failures
|
|
3659
3665
|
*
|
|
3660
3666
|
* Unrecognized codes fall through to `parseApiError` for HTTP-status-based
|
|
@@ -3841,6 +3847,13 @@ function getOptionalString(value) {
|
|
|
3841
3847
|
recoverability: 'FATAL'
|
|
3842
3848
|
}
|
|
3843
3849
|
],
|
|
3850
|
+
[
|
|
3851
|
+
380416,
|
|
3852
|
+
{
|
|
3853
|
+
errorDef: EarnError.POSITION_PNL_PENDING,
|
|
3854
|
+
recoverability: 'RETRYABLE'
|
|
3855
|
+
}
|
|
3856
|
+
],
|
|
3844
3857
|
// Bridge (380_5XX)
|
|
3845
3858
|
[
|
|
3846
3859
|
380500,
|
|
@@ -3985,6 +3998,8 @@ function getOptionalString(value) {
|
|
|
3985
3998
|
Blockchain["Celo_Alfajores_Testnet"] = "Celo_Alfajores_Testnet";
|
|
3986
3999
|
Blockchain["Codex"] = "Codex";
|
|
3987
4000
|
Blockchain["Codex_Testnet"] = "Codex_Testnet";
|
|
4001
|
+
Blockchain["Cronos"] = "Cronos";
|
|
4002
|
+
Blockchain["Cronos_Testnet"] = "Cronos_Testnet";
|
|
3988
4003
|
Blockchain["Edge"] = "Edge";
|
|
3989
4004
|
Blockchain["Edge_Testnet"] = "Edge_Testnet";
|
|
3990
4005
|
Blockchain["Ethereum"] = "Ethereum";
|
|
@@ -4067,6 +4082,7 @@ var BridgeChain;
|
|
|
4067
4082
|
BridgeChain["Avalanche"] = "Avalanche";
|
|
4068
4083
|
BridgeChain["Base"] = "Base";
|
|
4069
4084
|
BridgeChain["Codex"] = "Codex";
|
|
4085
|
+
BridgeChain["Cronos"] = "Cronos";
|
|
4070
4086
|
BridgeChain["Edge"] = "Edge";
|
|
4071
4087
|
BridgeChain["Ethereum"] = "Ethereum";
|
|
4072
4088
|
BridgeChain["HyperEVM"] = "HyperEVM";
|
|
@@ -4091,6 +4107,7 @@ var BridgeChain;
|
|
|
4091
4107
|
BridgeChain["Avalanche_Fuji"] = "Avalanche_Fuji";
|
|
4092
4108
|
BridgeChain["Base_Sepolia"] = "Base_Sepolia";
|
|
4093
4109
|
BridgeChain["Codex_Testnet"] = "Codex_Testnet";
|
|
4110
|
+
BridgeChain["Cronos_Testnet"] = "Cronos_Testnet";
|
|
4094
4111
|
BridgeChain["Edge_Testnet"] = "Edge_Testnet";
|
|
4095
4112
|
BridgeChain["Ethereum_Sepolia"] = "Ethereum_Sepolia";
|
|
4096
4113
|
BridgeChain["HyperEVM_Testnet"] = "HyperEVM_Testnet";
|
|
@@ -5157,6 +5174,96 @@ var EarnChain;
|
|
|
5157
5174
|
}
|
|
5158
5175
|
});
|
|
5159
5176
|
|
|
5177
|
+
/**
|
|
5178
|
+
* Cronos Mainnet chain definition
|
|
5179
|
+
* @remarks
|
|
5180
|
+
* This represents the official production network for the Cronos blockchain.
|
|
5181
|
+
* Cronos is an EVM-compatible blockchain.
|
|
5182
|
+
*/ const Cronos = defineChain({
|
|
5183
|
+
type: 'evm',
|
|
5184
|
+
chain: Blockchain.Cronos,
|
|
5185
|
+
name: 'Cronos',
|
|
5186
|
+
title: 'Cronos Mainnet',
|
|
5187
|
+
nativeCurrency: {
|
|
5188
|
+
name: 'Cronos',
|
|
5189
|
+
symbol: 'CRO',
|
|
5190
|
+
decimals: 18
|
|
5191
|
+
},
|
|
5192
|
+
chainId: 25,
|
|
5193
|
+
isTestnet: false,
|
|
5194
|
+
explorerUrl: 'https://cronoscan.com/tx/{hash}',
|
|
5195
|
+
rpcEndpoints: [
|
|
5196
|
+
'https://evm.cronos.org'
|
|
5197
|
+
],
|
|
5198
|
+
eurcAddress: '0xA6dE01a2d62C6B5f3525d768f34d276652C554c8',
|
|
5199
|
+
usdcAddress: '0x3D7F2C478aAfdB65542BCB44bCeeC05849999d2D',
|
|
5200
|
+
usdtAddress: null,
|
|
5201
|
+
cctp: {
|
|
5202
|
+
domain: 32,
|
|
5203
|
+
contracts: {
|
|
5204
|
+
v2: {
|
|
5205
|
+
type: 'split',
|
|
5206
|
+
tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
|
|
5207
|
+
messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
|
|
5208
|
+
confirmations: 1,
|
|
5209
|
+
fastConfirmations: 1
|
|
5210
|
+
}
|
|
5211
|
+
},
|
|
5212
|
+
forwarderSupported: {
|
|
5213
|
+
source: false,
|
|
5214
|
+
destination: false
|
|
5215
|
+
}
|
|
5216
|
+
},
|
|
5217
|
+
kitContracts: {
|
|
5218
|
+
bridge: BRIDGE_CONTRACT_EVM_MAINNET
|
|
5219
|
+
}
|
|
5220
|
+
});
|
|
5221
|
+
|
|
5222
|
+
/**
|
|
5223
|
+
* Cronos Testnet chain definition
|
|
5224
|
+
* @remarks
|
|
5225
|
+
* This represents the official test network for the Cronos blockchain.
|
|
5226
|
+
* Cronos is an EVM-compatible blockchain.
|
|
5227
|
+
*/ const CronosTestnet = defineChain({
|
|
5228
|
+
type: 'evm',
|
|
5229
|
+
chain: Blockchain.Cronos_Testnet,
|
|
5230
|
+
name: 'Cronos Testnet',
|
|
5231
|
+
title: 'Cronos Testnet',
|
|
5232
|
+
nativeCurrency: {
|
|
5233
|
+
name: 'CRO',
|
|
5234
|
+
symbol: 'tCRO',
|
|
5235
|
+
decimals: 18
|
|
5236
|
+
},
|
|
5237
|
+
chainId: 338,
|
|
5238
|
+
isTestnet: true,
|
|
5239
|
+
explorerUrl: 'https://explorer.cronos.org/testnet/tx/{hash}',
|
|
5240
|
+
rpcEndpoints: [
|
|
5241
|
+
'https://evm-t3.cronos.org'
|
|
5242
|
+
],
|
|
5243
|
+
eurcAddress: '0x31f7538adb53cF16350e6B0c89d03D91b7D12c46',
|
|
5244
|
+
usdcAddress: '0xEb33dc5fac03833e132593659e1dE7256aB59794',
|
|
5245
|
+
usdtAddress: null,
|
|
5246
|
+
cctp: {
|
|
5247
|
+
domain: 32,
|
|
5248
|
+
contracts: {
|
|
5249
|
+
v2: {
|
|
5250
|
+
type: 'split',
|
|
5251
|
+
tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
|
|
5252
|
+
messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
|
|
5253
|
+
confirmations: 1,
|
|
5254
|
+
fastConfirmations: 1
|
|
5255
|
+
}
|
|
5256
|
+
},
|
|
5257
|
+
forwarderSupported: {
|
|
5258
|
+
source: false,
|
|
5259
|
+
destination: false
|
|
5260
|
+
}
|
|
5261
|
+
},
|
|
5262
|
+
kitContracts: {
|
|
5263
|
+
bridge: BRIDGE_CONTRACT_EVM_TESTNET
|
|
5264
|
+
}
|
|
5265
|
+
});
|
|
5266
|
+
|
|
5160
5267
|
/**
|
|
5161
5268
|
* Edge Mainnet chain definition
|
|
5162
5269
|
* @remarks
|
|
@@ -7508,6 +7615,8 @@ var Chains = /*#__PURE__*/Object.freeze({
|
|
|
7508
7615
|
CeloAlfajoresTestnet: CeloAlfajoresTestnet,
|
|
7509
7616
|
Codex: Codex,
|
|
7510
7617
|
CodexTestnet: CodexTestnet,
|
|
7618
|
+
Cronos: Cronos,
|
|
7619
|
+
CronosTestnet: CronosTestnet,
|
|
7511
7620
|
Edge: Edge,
|
|
7512
7621
|
EdgeTestnet: EdgeTestnet,
|
|
7513
7622
|
Ethereum: Ethereum,
|
|
@@ -9882,6 +9991,7 @@ function parseOrThrow(value, schema, context) {
|
|
|
9882
9991
|
[Blockchain.Base]: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
|
|
9883
9992
|
[Blockchain.Celo]: '0xcebA9300f2b948710d2653dD7B07f33A8B32118C',
|
|
9884
9993
|
[Blockchain.Codex]: '0xd996633a415985DBd7D6D12f4A4343E31f5037cf',
|
|
9994
|
+
[Blockchain.Cronos]: '0x3D7F2C478aAfdB65542BCB44bCeeC05849999d2D',
|
|
9885
9995
|
[Blockchain.Edge]: '0x98d2919b9A214E6Fa5384AC81E6864bA686Ad74c',
|
|
9886
9996
|
[Blockchain.Ethereum]: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
|
|
9887
9997
|
[Blockchain.Hedera]: '0.0.456858',
|
|
@@ -9915,6 +10025,7 @@ function parseOrThrow(value, schema, context) {
|
|
|
9915
10025
|
[Blockchain.Avalanche_Fuji]: '0x5425890298aed601595a70AB815c96711a31Bc65',
|
|
9916
10026
|
[Blockchain.Base_Sepolia]: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',
|
|
9917
10027
|
[Blockchain.Codex_Testnet]: '0x6d7f141b6819C2c9CC2f818e6ad549E7Ca090F8f',
|
|
10028
|
+
[Blockchain.Cronos_Testnet]: '0xEb33dc5fac03833e132593659e1dE7256aB59794',
|
|
9918
10029
|
[Blockchain.Edge_Testnet]: '0x2d9F7CAD728051AA35Ecdc472a14cf8cDF5CFD6B',
|
|
9919
10030
|
[Blockchain.Ethereum_Sepolia]: '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238',
|
|
9920
10031
|
[Blockchain.Hedera_Testnet]: '0.0.429274',
|
|
@@ -9987,6 +10098,7 @@ function parseOrThrow(value, schema, context) {
|
|
|
9987
10098
|
// =========================================================================
|
|
9988
10099
|
[Blockchain.Avalanche]: '0xc891EB4cbdEFf6e073e859e987815Ed1505c2ACD',
|
|
9989
10100
|
[Blockchain.Base]: '0x60a3E35Cc302bFA44Cb288Bc5a4F316Fdb1adb42',
|
|
10101
|
+
[Blockchain.Cronos]: '0xA6dE01a2d62C6B5f3525d768f34d276652C554c8',
|
|
9990
10102
|
[Blockchain.Ethereum]: '0x1aBaEA1f7C830bD89Acc67eC4af516284b1bC33c',
|
|
9991
10103
|
[Blockchain.Solana]: 'HzwqbKZw8HxMN6bF2yFZNrht3c2iXXzpKcFu7uBEDKtr',
|
|
9992
10104
|
[Blockchain.World_Chain]: '0x1C60ba0A0eD1019e8Eb035E6daF4155A5cE2380B',
|
|
@@ -9995,6 +10107,7 @@ function parseOrThrow(value, schema, context) {
|
|
|
9995
10107
|
// =========================================================================
|
|
9996
10108
|
[Blockchain.Arc_Testnet]: '0x89B50855Aa3bE2F677cD6303Cec089B5F319D72a',
|
|
9997
10109
|
[Blockchain.Base_Sepolia]: '0x808456652fdb597867f38412077A9182bf77359F',
|
|
10110
|
+
[Blockchain.Cronos_Testnet]: '0x31f7538adb53cF16350e6B0c89d03D91b7D12c46',
|
|
9998
10111
|
[Blockchain.Ethereum_Sepolia]: '0x08210F9170F89Ab7658F0B5E3fF39b0E03C594D4'
|
|
9999
10112
|
}
|
|
10000
10113
|
};
|
|
@@ -11509,11 +11622,11 @@ function resolveOptions(options) {
|
|
|
11509
11622
|
void emitAnalyticsLog(buildPayload$1(config, stepEntry?.[1] ?? fallbackEventType, errorDetails, context));
|
|
11510
11623
|
}
|
|
11511
11624
|
|
|
11512
|
-
var name$
|
|
11513
|
-
var version$
|
|
11514
|
-
var pkg$
|
|
11515
|
-
name: name$
|
|
11516
|
-
version: version$
|
|
11625
|
+
var name$4 = "@circle-fin/bridge-kit";
|
|
11626
|
+
var version$5 = "1.12.0";
|
|
11627
|
+
var pkg$5 = {
|
|
11628
|
+
name: name$4,
|
|
11629
|
+
version: version$5};
|
|
11517
11630
|
|
|
11518
11631
|
const assertCustomFeePolicySymbol$2 = Symbol('assertCustomFeePolicy');
|
|
11519
11632
|
/**
|
|
@@ -13539,7 +13652,7 @@ var TransferSpeed;
|
|
|
13539
13652
|
const bridgeKitCaller = {
|
|
13540
13653
|
type: 'kit',
|
|
13541
13654
|
name: 'BridgeKit',
|
|
13542
|
-
version: pkg$
|
|
13655
|
+
version: pkg$5.version
|
|
13543
13656
|
};
|
|
13544
13657
|
// Create default runtime and tokens for invocation context resolution
|
|
13545
13658
|
const defaults = {
|
|
@@ -14209,6 +14322,15 @@ const CUSTOM_BURN_GAS_ESTIMATE_EVM = 201_525n // p99 and max are same here: 201_
|
|
|
14209
14322
|
;
|
|
14210
14323
|
const RECEIVE_MESSAGE_GAS_ESTIMATE_EVM = 237_401n // (99p: 163_963n + max: 310_839n) / 2 = 237_401n
|
|
14211
14324
|
;
|
|
14325
|
+
// Hard execution caps: observed max + ~30% buffer, used as gasLimit overrides on
|
|
14326
|
+
// chains whose eth_estimateGas under-reports (e.g. Cronos EIP-7623 calldata floor).
|
|
14327
|
+
// Kept separate from the fee-estimate averages above.
|
|
14328
|
+
const APPROVE_GAS_LIMIT_EVM = 100_000n // ERC-20 approve observed max ~46k
|
|
14329
|
+
;
|
|
14330
|
+
const DEPOSIT_FOR_BURN_GAS_LIMIT_EVM = 300_000n // observed max 226_506 + ~30%
|
|
14331
|
+
;
|
|
14332
|
+
const RECEIVE_MESSAGE_GAS_LIMIT_EVM = 400_000n // observed max 310_839 + ~30%
|
|
14333
|
+
;
|
|
14212
14334
|
/**
|
|
14213
14335
|
* The minimum finality threshold for CCTPv2 transfers.
|
|
14214
14336
|
*
|
|
@@ -14237,6 +14359,27 @@ const RECEIVE_MESSAGE_GAS_ESTIMATE_EVM = 237_401n // (99p: 163_963n + max: 310_8
|
|
|
14237
14359
|
'Content-Type': 'application/json'
|
|
14238
14360
|
}
|
|
14239
14361
|
};
|
|
14362
|
+
/**
|
|
14363
|
+
* Merges caller-provided polling overrides on top of {@link DEFAULT_CONFIG}.
|
|
14364
|
+
*
|
|
14365
|
+
* Headers are merged independently so caller-supplied headers augment the
|
|
14366
|
+
* defaults (such as `Content-Type`) rather than replacing them wholesale.
|
|
14367
|
+
*
|
|
14368
|
+
* @param config - Caller-provided polling configuration overrides
|
|
14369
|
+
* @param internalDefaults - Internal defaults applied before `config` (for example a
|
|
14370
|
+
* reduced `maxRetries` for one-shot requests); `config` still wins on conflict
|
|
14371
|
+
* @returns The effective polling configuration
|
|
14372
|
+
* @internal
|
|
14373
|
+
*/ const mergeAttestationConfig = (config, internalDefaults = {})=>({
|
|
14374
|
+
...DEFAULT_CONFIG$2,
|
|
14375
|
+
...internalDefaults,
|
|
14376
|
+
...config,
|
|
14377
|
+
headers: {
|
|
14378
|
+
...DEFAULT_CONFIG$2.headers,
|
|
14379
|
+
...internalDefaults.headers,
|
|
14380
|
+
...config.headers
|
|
14381
|
+
}
|
|
14382
|
+
});
|
|
14240
14383
|
/**
|
|
14241
14384
|
* Type guard that verifies if an unknown value matches the AttestationMessage shape
|
|
14242
14385
|
* and has all required properties.
|
|
@@ -14383,10 +14526,7 @@ const RECEIVE_MESSAGE_GAS_ESTIMATE_EVM = 237_401n // (99p: 163_963n + max: 310_8
|
|
|
14383
14526
|
* ```
|
|
14384
14527
|
*/ const fetchAttestation = async (sourceDomainId, transactionHash, isTestnet, config = {})=>{
|
|
14385
14528
|
const url = buildIrisUrl(sourceDomainId, transactionHash, isTestnet);
|
|
14386
|
-
const effectiveConfig =
|
|
14387
|
-
...DEFAULT_CONFIG$2,
|
|
14388
|
-
...config
|
|
14389
|
-
};
|
|
14529
|
+
const effectiveConfig = mergeAttestationConfig(config);
|
|
14390
14530
|
return await pollApiGet(url, isAttestationResponse, effectiveConfig);
|
|
14391
14531
|
};
|
|
14392
14532
|
/**
|
|
@@ -14429,11 +14569,9 @@ const RECEIVE_MESSAGE_GAS_ESTIMATE_EVM = 237_401n // (99p: 163_963n + max: 310_8
|
|
|
14429
14569
|
*/ const fetchAttestationWithoutStatusCheck = async (sourceDomainId, transactionHash, isTestnet, config = {})=>{
|
|
14430
14570
|
const url = buildIrisUrl(sourceDomainId, transactionHash, isTestnet);
|
|
14431
14571
|
// Use minimal retries since we're just fetching existing data
|
|
14432
|
-
const effectiveConfig = {
|
|
14433
|
-
|
|
14434
|
-
|
|
14435
|
-
...config
|
|
14436
|
-
};
|
|
14572
|
+
const effectiveConfig = mergeAttestationConfig(config, {
|
|
14573
|
+
maxRetries: 3
|
|
14574
|
+
});
|
|
14437
14575
|
return await pollApiGet(url, isAttestationResponseWithoutStatusCheck, effectiveConfig);
|
|
14438
14576
|
};
|
|
14439
14577
|
/**
|
|
@@ -14493,10 +14631,7 @@ const RECEIVE_MESSAGE_GAS_ESTIMATE_EVM = 237_401n // (99p: 163_963n + max: 310_8
|
|
|
14493
14631
|
* ```
|
|
14494
14632
|
*/ const fetchReAttestedAttestation = async (sourceDomainId, transactionHash, isTestnet, config = {})=>{
|
|
14495
14633
|
const url = buildIrisUrl(sourceDomainId, transactionHash, isTestnet);
|
|
14496
|
-
const effectiveConfig =
|
|
14497
|
-
...DEFAULT_CONFIG$2,
|
|
14498
|
-
...config
|
|
14499
|
-
};
|
|
14634
|
+
const effectiveConfig = mergeAttestationConfig(config);
|
|
14500
14635
|
return await pollApiGet(url, isReAttestedAttestationResponse, effectiveConfig);
|
|
14501
14636
|
};
|
|
14502
14637
|
/**
|
|
@@ -14562,14 +14697,139 @@ const RECEIVE_MESSAGE_GAS_ESTIMATE_EVM = 237_401n // (99p: 163_963n + max: 310_8
|
|
|
14562
14697
|
*/ const requestReAttestation = async (nonce, isTestnet, config = {})=>{
|
|
14563
14698
|
const url = buildReAttestUrl(nonce, isTestnet);
|
|
14564
14699
|
// Use minimal retries since we're just submitting a request, not polling for state
|
|
14565
|
-
const effectiveConfig = {
|
|
14566
|
-
|
|
14567
|
-
|
|
14568
|
-
...config
|
|
14569
|
-
};
|
|
14700
|
+
const effectiveConfig = mergeAttestationConfig(config, {
|
|
14701
|
+
maxRetries: 3
|
|
14702
|
+
});
|
|
14570
14703
|
return await pollApiPost(url, {}, isReAttestationResponse, effectiveConfig);
|
|
14571
14704
|
};
|
|
14572
14705
|
|
|
14706
|
+
/**
|
|
14707
|
+
* Type guard that checks if the relayer has confirmed the mint transaction.
|
|
14708
|
+
*
|
|
14709
|
+
* This function validates that:
|
|
14710
|
+
* 1. The response has valid AttestationResponse structure
|
|
14711
|
+
* 2. At least one message has forwardState === 'CONFIRMED' (or 'COMPLETE') and a valid forwardTxHash
|
|
14712
|
+
*
|
|
14713
|
+
* If forwardState is 'FAILED', throws a non-retryable KitError.
|
|
14714
|
+
* If forwardState is 'PENDING' or not present, throws a RETRYABLE KitError to continue polling.
|
|
14715
|
+
*
|
|
14716
|
+
* @param obj - The value to check, typically a parsed JSON response
|
|
14717
|
+
* @returns True if the relayer has confirmed the mint
|
|
14718
|
+
* @throws {KitError} With FATAL recoverability if structure is invalid
|
|
14719
|
+
* @throws {KitError} With RESUMABLE recoverability if forwardState is 'FAILED'
|
|
14720
|
+
* @throws {KitError} With RETRYABLE recoverability if still pending
|
|
14721
|
+
* @internal
|
|
14722
|
+
*/ const isRelayerMintConfirmed = (obj)=>{
|
|
14723
|
+
// First check if the structure is valid
|
|
14724
|
+
if (!hasValidAttestationStructure(obj)) {
|
|
14725
|
+
throw new KitError({
|
|
14726
|
+
...InputError.VALIDATION_FAILED,
|
|
14727
|
+
recoverability: 'FATAL',
|
|
14728
|
+
message: 'Invalid attestation response structure from IRIS API.'
|
|
14729
|
+
});
|
|
14730
|
+
}
|
|
14731
|
+
// Find the first message (typically there's only one)
|
|
14732
|
+
const message = obj.messages[0];
|
|
14733
|
+
if (!message) {
|
|
14734
|
+
throw new KitError({
|
|
14735
|
+
...InputError.VALIDATION_FAILED,
|
|
14736
|
+
recoverability: 'FATAL',
|
|
14737
|
+
message: 'No attestation messages found in IRIS API response.'
|
|
14738
|
+
});
|
|
14739
|
+
}
|
|
14740
|
+
// Check for FAILED state - this is a permanent failure
|
|
14741
|
+
if (message.forwardState === 'FAILED') {
|
|
14742
|
+
throw new KitError({
|
|
14743
|
+
...NetworkError.RELAYER_FORWARD_FAILED,
|
|
14744
|
+
recoverability: 'RESUMABLE',
|
|
14745
|
+
message: 'Circle relayer failed to forward the mint transaction. The mint may still have succeeded if another party submitted it. Check the recipient wallet balance before retrying. If the mint did not occur, you can manually submit it using the attestation data in the error cause.',
|
|
14746
|
+
cause: {
|
|
14747
|
+
trace: {
|
|
14748
|
+
eventNonce: message.eventNonce,
|
|
14749
|
+
attestation: message.attestation,
|
|
14750
|
+
message: message.message
|
|
14751
|
+
}
|
|
14752
|
+
}
|
|
14753
|
+
});
|
|
14754
|
+
}
|
|
14755
|
+
// Check if mint is confirmed (or complete) with a valid transaction hash
|
|
14756
|
+
// We accept both CONFIRMED and COMPLETE since COMPLETE implies CONFIRMED
|
|
14757
|
+
if ((message.forwardState === 'CONFIRMED' || message.forwardState === 'COMPLETE') && typeof message.forwardTxHash === 'string' && message.forwardTxHash.trim().length > 0) {
|
|
14758
|
+
return true;
|
|
14759
|
+
}
|
|
14760
|
+
// Still pending or not yet processed - throw RETRYABLE error to continue polling
|
|
14761
|
+
throw new KitError({
|
|
14762
|
+
...NetworkError.RELAYER_PENDING,
|
|
14763
|
+
recoverability: 'RETRYABLE',
|
|
14764
|
+
message: 'Relayer mint not ready. Waiting for confirmation.'
|
|
14765
|
+
});
|
|
14766
|
+
};
|
|
14767
|
+
/**
|
|
14768
|
+
* Polls the attestation API until the relayer's mint transaction is confirmed.
|
|
14769
|
+
*
|
|
14770
|
+
* This function is used when `useForwarder` is enabled. Instead of the user
|
|
14771
|
+
* submitting the mint transaction, Circle's Orbit relayer handles it automatically.
|
|
14772
|
+
* This function polls until the relayer has submitted and confirmed the mint transaction.
|
|
14773
|
+
*
|
|
14774
|
+
* @remarks
|
|
14775
|
+
* - Uses a 20-minute timeout by default (600 retries × 2 seconds)
|
|
14776
|
+
* - Throws immediately if `forwardState` is 'FAILED'
|
|
14777
|
+
* - Waits for `forwardState` to be 'CONFIRMED' or 'COMPLETE' (COMPLETE implies CONFIRMED)
|
|
14778
|
+
* - Returns the attestation message with `forwardTxHash` populated
|
|
14779
|
+
*
|
|
14780
|
+
* @param sourceDomainId - The CCTP domain ID of the source chain
|
|
14781
|
+
* @param transactionHash - The transaction hash of the burn operation
|
|
14782
|
+
* @param isTestnet - Whether this is for a testnet chain (true) or mainnet (false)
|
|
14783
|
+
* @param config - Optional configuration overrides for polling behavior
|
|
14784
|
+
* @returns The attestation message with confirmed forwardTxHash
|
|
14785
|
+
* @throws {KitError} With code 'NETWORK_RELAYER_FORWARD_FAILED' if relayer failed
|
|
14786
|
+
* @throws {KitError} If timeout is reached while still pending
|
|
14787
|
+
*
|
|
14788
|
+
* @example
|
|
14789
|
+
* ```typescript
|
|
14790
|
+
* const attestation = await fetchRelayerMint(0, '0xabc...', false)
|
|
14791
|
+
* console.log('Relayer mint tx:', attestation.forwardTxHash)
|
|
14792
|
+
* ```
|
|
14793
|
+
*/ const fetchRelayerMint = async (sourceDomainId, transactionHash, isTestnet, config = {})=>{
|
|
14794
|
+
const url = buildIrisUrl(sourceDomainId, transactionHash, isTestnet);
|
|
14795
|
+
const effectiveConfig = mergeAttestationConfig(config);
|
|
14796
|
+
let response;
|
|
14797
|
+
try {
|
|
14798
|
+
response = await pollApiGet(url, isRelayerMintConfirmed, effectiveConfig);
|
|
14799
|
+
} catch (error) {
|
|
14800
|
+
// Enrich RELAYER_FORWARD_FAILED errors with the burn transaction hash
|
|
14801
|
+
if (error instanceof KitError && error.name === 'NETWORK_RELAYER_FORWARD_FAILED') {
|
|
14802
|
+
throw new KitError({
|
|
14803
|
+
...NetworkError.RELAYER_FORWARD_FAILED,
|
|
14804
|
+
recoverability: error.recoverability,
|
|
14805
|
+
message: error.message,
|
|
14806
|
+
cause: {
|
|
14807
|
+
...error.cause,
|
|
14808
|
+
trace: {
|
|
14809
|
+
...error.cause?.trace,
|
|
14810
|
+
burnTxHash: transactionHash
|
|
14811
|
+
}
|
|
14812
|
+
}
|
|
14813
|
+
});
|
|
14814
|
+
}
|
|
14815
|
+
throw error;
|
|
14816
|
+
}
|
|
14817
|
+
// Return the first message (which should have forwardTxHash)
|
|
14818
|
+
// Note: This check is needed for TypeScript type safety even though
|
|
14819
|
+
// isRelayerMintConfirmed validates messages[0] exists. The type guard
|
|
14820
|
+
// narrows the type at the call site, but TypeScript can't infer that
|
|
14821
|
+
// the array still has elements after pollApiGet returns.
|
|
14822
|
+
const message = response.messages[0];
|
|
14823
|
+
if (!message) {
|
|
14824
|
+
throw new KitError({
|
|
14825
|
+
...InputError.VALIDATION_FAILED,
|
|
14826
|
+
recoverability: 'FATAL',
|
|
14827
|
+
message: 'No attestation messages found in response after polling.'
|
|
14828
|
+
});
|
|
14829
|
+
}
|
|
14830
|
+
return message;
|
|
14831
|
+
};
|
|
14832
|
+
|
|
14573
14833
|
const assertCCTPv2WalletContextSymbol = Symbol('assertCCTPv2WalletContext');
|
|
14574
14834
|
/**
|
|
14575
14835
|
* Asserts that the provided parameters match the CCTPv2 wallet context interface.
|
|
@@ -15444,6 +15704,8 @@ function hasPendingState(analysis, result) {
|
|
|
15444
15704
|
* - `adapter`: The adapter that will execute the transaction
|
|
15445
15705
|
* - `confirmations`: The number of confirmations to wait for (defaults to 1)
|
|
15446
15706
|
* - `timeout`: The timeout for the request in milliseconds
|
|
15707
|
+
* - `gasLimit`: Optional explicit gas limit (number) forwarded to EVM execute,
|
|
15708
|
+
* bypassing `eth_estimateGas`; ignored for non-EVM requests
|
|
15447
15709
|
* @returns The bridge step with the transaction details and explorer URL
|
|
15448
15710
|
* @throws If the transaction execution fails
|
|
15449
15711
|
*
|
|
@@ -15458,7 +15720,7 @@ function hasPendingState(analysis, result) {
|
|
|
15458
15720
|
* })
|
|
15459
15721
|
* console.log('Transaction hash:', step.txHash)
|
|
15460
15722
|
* ```
|
|
15461
|
-
*/ async function executePreparedChainRequest({ name, request, adapter, chain, confirmations = 1, timeout }) {
|
|
15723
|
+
*/ async function executePreparedChainRequest({ name, request, adapter, chain, confirmations = 1, timeout, gasLimit }) {
|
|
15462
15724
|
const step = {
|
|
15463
15725
|
name,
|
|
15464
15726
|
state: 'pending'
|
|
@@ -15471,7 +15733,9 @@ function hasPendingState(analysis, result) {
|
|
|
15471
15733
|
step.state = 'noop';
|
|
15472
15734
|
return step;
|
|
15473
15735
|
}
|
|
15474
|
-
const txHash = await request.execute(
|
|
15736
|
+
const txHash = request.type === 'evm' && gasLimit !== undefined ? await request.execute({
|
|
15737
|
+
gasLimit
|
|
15738
|
+
}) : await request.execute();
|
|
15475
15739
|
step.txHash = txHash;
|
|
15476
15740
|
const retryOptions = {
|
|
15477
15741
|
isRetryable: (err)=>isRetryableError$1(parseBlockchainError(err, {
|
|
@@ -15543,7 +15807,8 @@ function hasPendingState(analysis, result) {
|
|
|
15543
15807
|
name: 'approve',
|
|
15544
15808
|
adapter: params.source.adapter,
|
|
15545
15809
|
chain: params.source.chain,
|
|
15546
|
-
request: await provider.approve(params.source, approvalAmount)
|
|
15810
|
+
request: await provider.approve(params.source, approvalAmount),
|
|
15811
|
+
gasLimit: Number(APPROVE_GAS_LIMIT_EVM)
|
|
15547
15812
|
});
|
|
15548
15813
|
}
|
|
15549
15814
|
|
|
@@ -15570,7 +15835,8 @@ function hasPendingState(analysis, result) {
|
|
|
15570
15835
|
name: 'burn',
|
|
15571
15836
|
adapter: params.source.adapter,
|
|
15572
15837
|
chain: params.source.chain,
|
|
15573
|
-
request: await provider.burn(params)
|
|
15838
|
+
request: await provider.burn(params),
|
|
15839
|
+
gasLimit: Number(DEPOSIT_FOR_BURN_GAS_LIMIT_EVM)
|
|
15574
15840
|
});
|
|
15575
15841
|
}
|
|
15576
15842
|
|
|
@@ -15656,11 +15922,18 @@ function hasPendingState(analysis, result) {
|
|
|
15656
15922
|
*/ async function bridgeMint({ params, provider }, attestation) {
|
|
15657
15923
|
// Validate attestation message matches transfer params
|
|
15658
15924
|
await assertCCTPv2AttestationParams(attestation, params);
|
|
15925
|
+
const mintRequest = await provider.mint(params.source, params.destination, attestation);
|
|
15659
15926
|
const step = await executePreparedChainRequest({
|
|
15660
15927
|
name: 'mint',
|
|
15661
15928
|
adapter: params.destination.adapter,
|
|
15662
15929
|
chain: params.destination.chain,
|
|
15663
|
-
request:
|
|
15930
|
+
request: mintRequest,
|
|
15931
|
+
// Some chains (e.g. Cronos) enforce an EIP-7623 calldata gas floor that
|
|
15932
|
+
// eth_estimateGas does not account for, returning a below-floor value
|
|
15933
|
+
// without reverting. Pinning to a value above the observed execution max
|
|
15934
|
+
// (310_839) bypasses re-estimation and guarantees we clear both the floor
|
|
15935
|
+
// and the actual execution cost.
|
|
15936
|
+
gasLimit: Number(RECEIVE_MESSAGE_GAS_LIMIT_EVM)
|
|
15664
15937
|
});
|
|
15665
15938
|
// Add forwarded: false for non-relayer mints
|
|
15666
15939
|
return {
|
|
@@ -15698,136 +15971,6 @@ const mockAttestationMessage = {
|
|
|
15698
15971
|
delayReason: null
|
|
15699
15972
|
};
|
|
15700
15973
|
|
|
15701
|
-
/**
|
|
15702
|
-
* Type guard that checks if the relayer has confirmed the mint transaction.
|
|
15703
|
-
*
|
|
15704
|
-
* This function validates that:
|
|
15705
|
-
* 1. The response has valid AttestationResponse structure
|
|
15706
|
-
* 2. At least one message has forwardState === 'CONFIRMED' (or 'COMPLETE') and a valid forwardTxHash
|
|
15707
|
-
*
|
|
15708
|
-
* If forwardState is 'FAILED', throws a non-retryable KitError.
|
|
15709
|
-
* If forwardState is 'PENDING' or not present, throws a RETRYABLE KitError to continue polling.
|
|
15710
|
-
*
|
|
15711
|
-
* @param obj - The value to check, typically a parsed JSON response
|
|
15712
|
-
* @returns True if the relayer has confirmed the mint
|
|
15713
|
-
* @throws {KitError} With FATAL recoverability if structure is invalid
|
|
15714
|
-
* @throws {KitError} With RESUMABLE recoverability if forwardState is 'FAILED'
|
|
15715
|
-
* @throws {KitError} With RETRYABLE recoverability if still pending
|
|
15716
|
-
* @internal
|
|
15717
|
-
*/ const isRelayerMintConfirmed = (obj)=>{
|
|
15718
|
-
// First check if the structure is valid
|
|
15719
|
-
if (!hasValidAttestationStructure(obj)) {
|
|
15720
|
-
throw new KitError({
|
|
15721
|
-
...InputError.VALIDATION_FAILED,
|
|
15722
|
-
recoverability: 'FATAL',
|
|
15723
|
-
message: 'Invalid attestation response structure from IRIS API.'
|
|
15724
|
-
});
|
|
15725
|
-
}
|
|
15726
|
-
// Find the first message (typically there's only one)
|
|
15727
|
-
const message = obj.messages[0];
|
|
15728
|
-
if (!message) {
|
|
15729
|
-
throw new KitError({
|
|
15730
|
-
...InputError.VALIDATION_FAILED,
|
|
15731
|
-
recoverability: 'FATAL',
|
|
15732
|
-
message: 'No attestation messages found in IRIS API response.'
|
|
15733
|
-
});
|
|
15734
|
-
}
|
|
15735
|
-
// Check for FAILED state - this is a permanent failure
|
|
15736
|
-
if (message.forwardState === 'FAILED') {
|
|
15737
|
-
throw new KitError({
|
|
15738
|
-
...NetworkError.RELAYER_FORWARD_FAILED,
|
|
15739
|
-
recoverability: 'RESUMABLE',
|
|
15740
|
-
message: 'Circle relayer failed to forward the mint transaction. The mint may still have succeeded if another party submitted it. Check the recipient wallet balance before retrying. If the mint did not occur, you can manually submit it using the attestation data in the error cause.',
|
|
15741
|
-
cause: {
|
|
15742
|
-
trace: {
|
|
15743
|
-
eventNonce: message.eventNonce,
|
|
15744
|
-
attestation: message.attestation,
|
|
15745
|
-
message: message.message
|
|
15746
|
-
}
|
|
15747
|
-
}
|
|
15748
|
-
});
|
|
15749
|
-
}
|
|
15750
|
-
// Check if mint is confirmed (or complete) with a valid transaction hash
|
|
15751
|
-
// We accept both CONFIRMED and COMPLETE since COMPLETE implies CONFIRMED
|
|
15752
|
-
if ((message.forwardState === 'CONFIRMED' || message.forwardState === 'COMPLETE') && typeof message.forwardTxHash === 'string' && message.forwardTxHash.trim().length > 0) {
|
|
15753
|
-
return true;
|
|
15754
|
-
}
|
|
15755
|
-
// Still pending or not yet processed - throw RETRYABLE error to continue polling
|
|
15756
|
-
throw new KitError({
|
|
15757
|
-
...NetworkError.RELAYER_PENDING,
|
|
15758
|
-
recoverability: 'RETRYABLE',
|
|
15759
|
-
message: 'Relayer mint not ready. Waiting for confirmation.'
|
|
15760
|
-
});
|
|
15761
|
-
};
|
|
15762
|
-
/**
|
|
15763
|
-
* Polls the attestation API until the relayer's mint transaction is confirmed.
|
|
15764
|
-
*
|
|
15765
|
-
* This function is used when `useForwarder` is enabled. Instead of the user
|
|
15766
|
-
* submitting the mint transaction, Circle's Orbit relayer handles it automatically.
|
|
15767
|
-
* This function polls until the relayer has submitted and confirmed the mint transaction.
|
|
15768
|
-
*
|
|
15769
|
-
* @remarks
|
|
15770
|
-
* - Uses a 20-minute timeout by default (600 retries × 2 seconds)
|
|
15771
|
-
* - Throws immediately if `forwardState` is 'FAILED'
|
|
15772
|
-
* - Waits for `forwardState` to be 'CONFIRMED' or 'COMPLETE' (COMPLETE implies CONFIRMED)
|
|
15773
|
-
* - Returns the attestation message with `forwardTxHash` populated
|
|
15774
|
-
*
|
|
15775
|
-
* @param sourceDomainId - The CCTP domain ID of the source chain
|
|
15776
|
-
* @param transactionHash - The transaction hash of the burn operation
|
|
15777
|
-
* @param isTestnet - Whether this is for a testnet chain (true) or mainnet (false)
|
|
15778
|
-
* @param config - Optional configuration overrides for polling behavior
|
|
15779
|
-
* @returns The attestation message with confirmed forwardTxHash
|
|
15780
|
-
* @throws {KitError} With code 'NETWORK_RELAYER_FORWARD_FAILED' if relayer failed
|
|
15781
|
-
* @throws {KitError} If timeout is reached while still pending
|
|
15782
|
-
*
|
|
15783
|
-
* @example
|
|
15784
|
-
* ```typescript
|
|
15785
|
-
* const attestation = await fetchRelayerMint(0, '0xabc...', false)
|
|
15786
|
-
* console.log('Relayer mint tx:', attestation.forwardTxHash)
|
|
15787
|
-
* ```
|
|
15788
|
-
*/ const fetchRelayerMint = async (sourceDomainId, transactionHash, isTestnet, config = {})=>{
|
|
15789
|
-
const url = buildIrisUrl(sourceDomainId, transactionHash, isTestnet);
|
|
15790
|
-
const effectiveConfig = {
|
|
15791
|
-
...DEFAULT_CONFIG$2,
|
|
15792
|
-
...config
|
|
15793
|
-
};
|
|
15794
|
-
let response;
|
|
15795
|
-
try {
|
|
15796
|
-
response = await pollApiGet(url, isRelayerMintConfirmed, effectiveConfig);
|
|
15797
|
-
} catch (error) {
|
|
15798
|
-
// Enrich RELAYER_FORWARD_FAILED errors with the burn transaction hash
|
|
15799
|
-
if (error instanceof KitError && error.name === 'NETWORK_RELAYER_FORWARD_FAILED') {
|
|
15800
|
-
throw new KitError({
|
|
15801
|
-
...NetworkError.RELAYER_FORWARD_FAILED,
|
|
15802
|
-
recoverability: error.recoverability,
|
|
15803
|
-
message: error.message,
|
|
15804
|
-
cause: {
|
|
15805
|
-
...error.cause,
|
|
15806
|
-
trace: {
|
|
15807
|
-
...error.cause?.trace,
|
|
15808
|
-
burnTxHash: transactionHash
|
|
15809
|
-
}
|
|
15810
|
-
}
|
|
15811
|
-
});
|
|
15812
|
-
}
|
|
15813
|
-
throw error;
|
|
15814
|
-
}
|
|
15815
|
-
// Return the first message (which should have forwardTxHash)
|
|
15816
|
-
// Note: This check is needed for TypeScript type safety even though
|
|
15817
|
-
// isRelayerMintConfirmed validates messages[0] exists. The type guard
|
|
15818
|
-
// narrows the type at the call site, but TypeScript can't infer that
|
|
15819
|
-
// the array still has elements after pollApiGet returns.
|
|
15820
|
-
const message = response.messages[0];
|
|
15821
|
-
if (!message) {
|
|
15822
|
-
throw new KitError({
|
|
15823
|
-
...InputError.VALIDATION_FAILED,
|
|
15824
|
-
recoverability: 'FATAL',
|
|
15825
|
-
message: 'No attestation messages found in response after polling.'
|
|
15826
|
-
});
|
|
15827
|
-
}
|
|
15828
|
-
return message;
|
|
15829
|
-
};
|
|
15830
|
-
|
|
15831
15974
|
/**
|
|
15832
15975
|
* Executes the mint step for forwarding mode where Circle's relayer handles the mint.
|
|
15833
15976
|
*
|
|
@@ -15841,6 +15984,7 @@ const mockAttestationMessage = {
|
|
|
15841
15984
|
* immediately after the API confirms the mint.
|
|
15842
15985
|
*
|
|
15843
15986
|
* @param params - The bridge parameters containing source, destination, amount and config
|
|
15987
|
+
* @param provider - The CCTP v2 bridging provider
|
|
15844
15988
|
* @param context - The step context containing burnTxHash from the burn step
|
|
15845
15989
|
* @returns Promise resolving to the bridge step with transaction details
|
|
15846
15990
|
* @throws {KitError} If burnTxHash is not available in context
|
|
@@ -15849,10 +15993,13 @@ const mockAttestationMessage = {
|
|
|
15849
15993
|
*
|
|
15850
15994
|
* @example
|
|
15851
15995
|
* ```typescript
|
|
15852
|
-
* const step = await bridgeRelayerMint(
|
|
15996
|
+
* const step = await bridgeRelayerMint(
|
|
15997
|
+
* { params, provider },
|
|
15998
|
+
* { burnTxHash: '0x...' }
|
|
15999
|
+
* )
|
|
15853
16000
|
* console.log('Relayer mint tx:', step.txHash)
|
|
15854
16001
|
* ```
|
|
15855
|
-
*/ async function bridgeRelayerMint(params, context) {
|
|
16002
|
+
*/ async function bridgeRelayerMint({ params, provider }, context) {
|
|
15856
16003
|
const step = {
|
|
15857
16004
|
name: 'mint',
|
|
15858
16005
|
state: 'pending',
|
|
@@ -15868,7 +16015,7 @@ const mockAttestationMessage = {
|
|
|
15868
16015
|
}
|
|
15869
16016
|
try {
|
|
15870
16017
|
// Poll attestation API until relayer confirms the mint
|
|
15871
|
-
const attestation = await fetchRelayerMint(params.source
|
|
16018
|
+
const attestation = await provider.fetchRelayerMint(params.source, context.burnTxHash);
|
|
15872
16019
|
// Extract the relayer's mint transaction hash
|
|
15873
16020
|
const forwardTxHash = attestation.forwardTxHash;
|
|
15874
16021
|
if (!forwardTxHash) {
|
|
@@ -15962,7 +16109,7 @@ const mockAttestationMessage = {
|
|
|
15962
16109
|
name: 'mint',
|
|
15963
16110
|
// bridgeRelayerMint validates context.burnTxHash internally with a KitError
|
|
15964
16111
|
// bridgeMint requires attestationData which is validated here
|
|
15965
|
-
executor: useForwarder ? async (params,
|
|
16112
|
+
executor: useForwarder ? async (params, provider, context)=>{
|
|
15966
16113
|
if (!context) {
|
|
15967
16114
|
throw new KitError({
|
|
15968
16115
|
...InputError.VALIDATION_FAILED,
|
|
@@ -15970,7 +16117,10 @@ const mockAttestationMessage = {
|
|
|
15970
16117
|
message: 'Step context is required for relayer mint'
|
|
15971
16118
|
});
|
|
15972
16119
|
}
|
|
15973
|
-
return bridgeRelayerMint(
|
|
16120
|
+
return bridgeRelayerMint({
|
|
16121
|
+
params,
|
|
16122
|
+
provider
|
|
16123
|
+
}, context);
|
|
15974
16124
|
} : async (params, provider, context)=>{
|
|
15975
16125
|
if (!context?.attestationData) {
|
|
15976
16126
|
throw new KitError({
|
|
@@ -16301,16 +16451,16 @@ const mockAttestationMessage = {
|
|
|
16301
16451
|
return step;
|
|
16302
16452
|
}
|
|
16303
16453
|
|
|
16304
|
-
var version$
|
|
16305
|
-
var pkg$
|
|
16306
|
-
version: version$
|
|
16454
|
+
var version$4 = "1.9.0";
|
|
16455
|
+
var pkg$4 = {
|
|
16456
|
+
version: version$4};
|
|
16307
16457
|
|
|
16308
16458
|
/**
|
|
16309
16459
|
* Provider caller component for bridge operations.
|
|
16310
16460
|
*/ const BRIDGE_CALLER = {
|
|
16311
16461
|
type: 'provider',
|
|
16312
16462
|
name: 'CCTPV2BridgingProvider.bridge',
|
|
16313
|
-
version: pkg$
|
|
16463
|
+
version: pkg$4.version
|
|
16314
16464
|
};
|
|
16315
16465
|
/**
|
|
16316
16466
|
* Resolve invocation context for bridge operations.
|
|
@@ -16683,7 +16833,7 @@ var pkg$3 = {
|
|
|
16683
16833
|
*/ const RETRY_CALLER = {
|
|
16684
16834
|
type: 'provider',
|
|
16685
16835
|
name: 'CCTPV2BridgingProvider.retry',
|
|
16686
|
-
version: pkg$
|
|
16836
|
+
version: pkg$4.version
|
|
16687
16837
|
};
|
|
16688
16838
|
/**
|
|
16689
16839
|
* Resolve invocation context for retry operations.
|
|
@@ -17007,6 +17157,39 @@ var pkg$3 = {
|
|
|
17007
17157
|
}
|
|
17008
17158
|
}
|
|
17009
17159
|
|
|
17160
|
+
function isPlainObject(value) {
|
|
17161
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
17162
|
+
return false;
|
|
17163
|
+
}
|
|
17164
|
+
const prototype = Object.getPrototypeOf(value);
|
|
17165
|
+
return prototype === Object.prototype || prototype === null;
|
|
17166
|
+
}
|
|
17167
|
+
function assertHeadersConfig(headers, field) {
|
|
17168
|
+
if (headers === undefined) {
|
|
17169
|
+
return;
|
|
17170
|
+
}
|
|
17171
|
+
if (!isPlainObject(headers)) {
|
|
17172
|
+
throw createValidationFailedError$1(field, headers, `${field} must be a plain object with string header values when provided`);
|
|
17173
|
+
}
|
|
17174
|
+
for (const [name, value] of Object.entries(headers)){
|
|
17175
|
+
if (typeof value !== 'string') {
|
|
17176
|
+
throw createValidationFailedError$1(`${field}.${name}`, value, 'header values must be strings');
|
|
17177
|
+
}
|
|
17178
|
+
}
|
|
17179
|
+
}
|
|
17180
|
+
function assertCCTPV2Config(config) {
|
|
17181
|
+
if (!isPlainObject(config)) {
|
|
17182
|
+
throw createValidationFailedError$1('config', config, 'config must be a plain object when provided');
|
|
17183
|
+
}
|
|
17184
|
+
assertHeadersConfig(config['headers'], 'config.headers');
|
|
17185
|
+
const attestation = config['attestation'];
|
|
17186
|
+
if (attestation !== undefined) {
|
|
17187
|
+
if (!isPlainObject(attestation)) {
|
|
17188
|
+
throw createValidationFailedError$1('config.attestation', attestation, 'config.attestation must be a plain object when provided');
|
|
17189
|
+
}
|
|
17190
|
+
assertHeadersConfig(attestation['headers'], 'config.attestation.headers');
|
|
17191
|
+
}
|
|
17192
|
+
}
|
|
17010
17193
|
/**
|
|
17011
17194
|
* All chains that are supported by the CCTP v2 provider.
|
|
17012
17195
|
*
|
|
@@ -17075,9 +17258,38 @@ var pkg$3 = {
|
|
|
17075
17258
|
* @param config - Optional configuration overrides for the provider
|
|
17076
17259
|
*/ constructor(config = {}){
|
|
17077
17260
|
super();
|
|
17261
|
+
assertCCTPV2Config(config);
|
|
17078
17262
|
this.config = config;
|
|
17079
17263
|
}
|
|
17080
17264
|
/**
|
|
17265
|
+
* Resolves the effective polling configuration for an attestation request.
|
|
17266
|
+
*
|
|
17267
|
+
* Precedence (lowest to highest): provider `config.attestation`, then the
|
|
17268
|
+
* per-call `config`. Headers merge independently across
|
|
17269
|
+
* `config.attestation.headers`, the provider-level `config.headers`, and any
|
|
17270
|
+
* per-call `config.headers`, so a more specific header augments rather than
|
|
17271
|
+
* replaces the broader ones. The `headers` key is omitted entirely when no
|
|
17272
|
+
* headers are configured, leaving the attestation fetchers' defaults intact.
|
|
17273
|
+
*
|
|
17274
|
+
* @param config - Optional per-call polling configuration overrides
|
|
17275
|
+
* @returns The merged polling configuration passed to the attestation fetchers
|
|
17276
|
+
*/ resolveAttestationConfig(config) {
|
|
17277
|
+
const headers = {
|
|
17278
|
+
...this.config?.attestation?.headers,
|
|
17279
|
+
...this.config?.headers,
|
|
17280
|
+
...config?.headers
|
|
17281
|
+
};
|
|
17282
|
+
// Polling fields follow normal precedence; headers are merged separately
|
|
17283
|
+
// below so narrower config layers augment rather than replace broader ones.
|
|
17284
|
+
return {
|
|
17285
|
+
...this.config?.attestation,
|
|
17286
|
+
...config,
|
|
17287
|
+
...Object.keys(headers).length > 0 ? {
|
|
17288
|
+
headers
|
|
17289
|
+
} : {}
|
|
17290
|
+
};
|
|
17291
|
+
}
|
|
17292
|
+
/**
|
|
17081
17293
|
* Execute a cross-chain USDC bridge operation using the CCTP v2 protocol.
|
|
17082
17294
|
*
|
|
17083
17295
|
* This method orchestrates the complete CCTP v2 bridge flow including validation,
|
|
@@ -17503,11 +17715,7 @@ var pkg$3 = {
|
|
|
17503
17715
|
*/ async fetchAttestation(source, transactionHash, config) {
|
|
17504
17716
|
assertCCTPv2WalletContext(source);
|
|
17505
17717
|
try {
|
|
17506
|
-
|
|
17507
|
-
const effectiveConfig = {
|
|
17508
|
-
...this.config?.attestation,
|
|
17509
|
-
...config
|
|
17510
|
-
};
|
|
17718
|
+
const effectiveConfig = this.resolveAttestationConfig(config);
|
|
17511
17719
|
const response = await fetchAttestation(source.chain.cctp.domain, transactionHash, source.chain.isTestnet, effectiveConfig);
|
|
17512
17720
|
const message = response.messages[0];
|
|
17513
17721
|
if (!message) {
|
|
@@ -17524,6 +17732,49 @@ var pkg$3 = {
|
|
|
17524
17732
|
}
|
|
17525
17733
|
}
|
|
17526
17734
|
/**
|
|
17735
|
+
* Polls attestation data until Circle's relayer mint transaction is confirmed.
|
|
17736
|
+
*
|
|
17737
|
+
* This method is used by forwarded transfers. It polls the same Iris
|
|
17738
|
+
* attestation endpoint as {@link CCTPV2BridgingProvider.fetchAttestation},
|
|
17739
|
+
* but waits for a completed relayer forward state and returns the attestation
|
|
17740
|
+
* message containing `forwardTxHash`.
|
|
17741
|
+
*
|
|
17742
|
+
* @typeParam TFromAdapterCapabilities - The type representing the capabilities of the source adapter
|
|
17743
|
+
* @param source - The source wallet context containing the chain definition and wallet address
|
|
17744
|
+
* @param transactionHash - The transaction hash of the burn operation
|
|
17745
|
+
* @param config - Optional polling configuration overrides for timeout, retries, delay, and headers
|
|
17746
|
+
* @returns A promise that resolves to the attestation message with `forwardTxHash`
|
|
17747
|
+
* @throws KitError If the relayer forward fails, the response is invalid, or polling times out
|
|
17748
|
+
*
|
|
17749
|
+
* @example
|
|
17750
|
+
* ```typescript
|
|
17751
|
+
* import { CCTPV2BridgingProvider } from '@circle-fin/provider-cctp-v2'
|
|
17752
|
+
* import { Chains } from '@core/chains'
|
|
17753
|
+
*
|
|
17754
|
+
* const provider = new CCTPV2BridgingProvider({
|
|
17755
|
+
* headers: { 'X-Partner-UUID': '00000000-0000-0000-0000-000000000000' },
|
|
17756
|
+
* })
|
|
17757
|
+
*
|
|
17758
|
+
* const attestation = await provider.fetchRelayerMint(
|
|
17759
|
+
* {
|
|
17760
|
+
* adapter,
|
|
17761
|
+
* chain: Chains.EthereumSepolia,
|
|
17762
|
+
* address: '0x1234...',
|
|
17763
|
+
* },
|
|
17764
|
+
* '0xabc123...',
|
|
17765
|
+
* )
|
|
17766
|
+
*
|
|
17767
|
+
* console.log('Relayer mint tx:', attestation.forwardTxHash)
|
|
17768
|
+
* ```
|
|
17769
|
+
*/ async fetchRelayerMint(source, transactionHash, config) {
|
|
17770
|
+
assertCCTPv2WalletContext(source);
|
|
17771
|
+
if (typeof transactionHash !== 'string' || transactionHash.trim() === '') {
|
|
17772
|
+
throw createValidationFailedError$1('transactionHash', transactionHash, 'transactionHash must be a non-empty string');
|
|
17773
|
+
}
|
|
17774
|
+
const effectiveConfig = this.resolveAttestationConfig(config);
|
|
17775
|
+
return await fetchRelayerMint(source.chain.cctp.domain, transactionHash, source.chain.isTestnet, effectiveConfig);
|
|
17776
|
+
}
|
|
17777
|
+
/**
|
|
17527
17778
|
* Requests a fresh attestation for an expired attestation.
|
|
17528
17779
|
*
|
|
17529
17780
|
* This method is used when the original attestation has expired before the mint
|
|
@@ -17577,11 +17828,7 @@ var pkg$3 = {
|
|
|
17577
17828
|
throw new Error('Failed to re-attest: Invalid transaction hash');
|
|
17578
17829
|
}
|
|
17579
17830
|
try {
|
|
17580
|
-
|
|
17581
|
-
const effectiveConfig = {
|
|
17582
|
-
...this.config?.attestation,
|
|
17583
|
-
...config
|
|
17584
|
-
};
|
|
17831
|
+
const effectiveConfig = this.resolveAttestationConfig(config);
|
|
17585
17832
|
// Step 1: Get existing attestation data to extract nonce
|
|
17586
17833
|
const existingAttestation = await fetchAttestationWithoutStatusCheck(source.chain.cctp.domain, transactionHash, source.chain.isTestnet, effectiveConfig);
|
|
17587
17834
|
const nonce = existingAttestation.messages[0]?.eventNonce;
|
|
@@ -17866,8 +18113,13 @@ var pkg$3 = {
|
|
|
17866
18113
|
/**
|
|
17867
18114
|
* The default providers that will be used in addition to the providers provided
|
|
17868
18115
|
* to the BridgeKit constructor.
|
|
17869
|
-
|
|
17870
|
-
|
|
18116
|
+
*
|
|
18117
|
+
* @param config - Optional configuration forwarded to the default providers
|
|
18118
|
+
* @returns The default bridging providers
|
|
18119
|
+
*/ const getDefaultProviders$3 = (config = {})=>[
|
|
18120
|
+
new CCTPV2BridgingProvider(config.headers ? {
|
|
18121
|
+
headers: config.headers
|
|
18122
|
+
} : {})
|
|
17871
18123
|
];
|
|
17872
18124
|
|
|
17873
18125
|
/**
|
|
@@ -17978,7 +18230,7 @@ var pkg$3 = {
|
|
|
17978
18230
|
]
|
|
17979
18231
|
];
|
|
17980
18232
|
|
|
17981
|
-
/** SDK name used in telemetry payloads. */ const SDK_NAME$2 = resolveKitSdkName(pkg$
|
|
18233
|
+
/** SDK name used in telemetry payloads. */ const SDK_NAME$2 = resolveKitSdkName(pkg$5.name);
|
|
17982
18234
|
/**
|
|
17983
18235
|
* Pick the most-relevant `txHash` to attach to an error telemetry payload.
|
|
17984
18236
|
*
|
|
@@ -18019,7 +18271,7 @@ var pkg$3 = {
|
|
|
18019
18271
|
*/ const BRIDGE_KIT_CALLER = {
|
|
18020
18272
|
type: 'kit',
|
|
18021
18273
|
name: 'BridgeKit',
|
|
18022
|
-
version: pkg$
|
|
18274
|
+
version: pkg$5.version
|
|
18023
18275
|
};
|
|
18024
18276
|
/**
|
|
18025
18277
|
* Merge BridgeKit's caller into the invocation metadata for retry operations.
|
|
@@ -18110,7 +18362,9 @@ var pkg$3 = {
|
|
|
18110
18362
|
* ```
|
|
18111
18363
|
*/ constructor(config = {}){
|
|
18112
18364
|
// Handle provider configuration
|
|
18113
|
-
const defaultProviders = getDefaultProviders$3(
|
|
18365
|
+
const defaultProviders = getDefaultProviders$3(config.headers ? {
|
|
18366
|
+
headers: config.headers
|
|
18367
|
+
} : {});
|
|
18114
18368
|
this.providers = [
|
|
18115
18369
|
...defaultProviders,
|
|
18116
18370
|
...config.providers ?? []
|
|
@@ -18119,7 +18373,7 @@ var pkg$3 = {
|
|
|
18119
18373
|
this.disableErrorReporting = config.disableErrorReporting === true;
|
|
18120
18374
|
this.telemetryConfig = {
|
|
18121
18375
|
sdkName: SDK_NAME$2,
|
|
18122
|
-
sdkVersion: pkg$
|
|
18376
|
+
sdkVersion: pkg$5.version,
|
|
18123
18377
|
disabled: this.disableErrorReporting
|
|
18124
18378
|
};
|
|
18125
18379
|
for (const provider of this.providers){
|
|
@@ -18641,7 +18895,7 @@ var pkg$3 = {
|
|
|
18641
18895
|
}
|
|
18642
18896
|
|
|
18643
18897
|
// Auto-register this kit for user agent tracking
|
|
18644
|
-
registerKit(`${pkg$
|
|
18898
|
+
registerKit(`${pkg$5.name}/${pkg$5.version}`);
|
|
18645
18899
|
|
|
18646
18900
|
/**
|
|
18647
18901
|
* Create a BridgeKit instance with optional developer fee configuration.
|
|
@@ -18690,6 +18944,9 @@ registerKit(`${pkg$4.name}/${pkg$4.version}`);
|
|
|
18690
18944
|
const kit = new BridgeKit({
|
|
18691
18945
|
...context.disableErrorReporting != null && {
|
|
18692
18946
|
disableErrorReporting: context.disableErrorReporting
|
|
18947
|
+
},
|
|
18948
|
+
...context.headers != null && {
|
|
18949
|
+
headers: context.headers
|
|
18693
18950
|
}
|
|
18694
18951
|
});
|
|
18695
18952
|
if (hasBoth) {
|
|
@@ -18707,11 +18964,11 @@ registerKit(`${pkg$4.name}/${pkg$4.version}`);
|
|
|
18707
18964
|
return kit;
|
|
18708
18965
|
};
|
|
18709
18966
|
|
|
18710
|
-
var name$
|
|
18711
|
-
var version$
|
|
18712
|
-
var pkg$
|
|
18713
|
-
name: name$
|
|
18714
|
-
version: version$
|
|
18967
|
+
var name$3 = "@circle-fin/swap-kit";
|
|
18968
|
+
var version$3 = "1.3.2";
|
|
18969
|
+
var pkg$3 = {
|
|
18970
|
+
name: name$3,
|
|
18971
|
+
version: version$3};
|
|
18715
18972
|
|
|
18716
18973
|
const chainIdentifierField = z.custom((value)=>chainIdentifierSchema.safeParse(value).success, {
|
|
18717
18974
|
message: 'chain must be a valid chain identifier'
|
|
@@ -30081,7 +30338,7 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
|
|
|
30081
30338
|
ESTIMATE: 'swap_estimate'
|
|
30082
30339
|
};
|
|
30083
30340
|
|
|
30084
|
-
/** SDK name used in telemetry payloads. */ const SDK_NAME$1 = resolveKitSdkName(pkg$
|
|
30341
|
+
/** SDK name used in telemetry payloads. */ const SDK_NAME$1 = resolveKitSdkName(pkg$3.name);
|
|
30085
30342
|
/**
|
|
30086
30343
|
* A high-level class-based interface for same-chain and cross-chain token swap operations.
|
|
30087
30344
|
*
|
|
@@ -30204,7 +30461,7 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
|
|
|
30204
30461
|
this.disableErrorReporting = config.disableErrorReporting === true;
|
|
30205
30462
|
this.telemetryConfig = {
|
|
30206
30463
|
sdkName: SDK_NAME$1,
|
|
30207
|
-
sdkVersion: pkg$
|
|
30464
|
+
sdkVersion: pkg$3.version,
|
|
30208
30465
|
disabled: this.disableErrorReporting
|
|
30209
30466
|
};
|
|
30210
30467
|
}
|
|
@@ -30660,7 +30917,7 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
|
|
|
30660
30917
|
}
|
|
30661
30918
|
|
|
30662
30919
|
// Auto-register this kit for user agent tracking
|
|
30663
|
-
registerKit(`${pkg$
|
|
30920
|
+
registerKit(`${pkg$3.name}/${pkg$3.version}`);
|
|
30664
30921
|
|
|
30665
30922
|
/**
|
|
30666
30923
|
* Create a SwapKit instance with optional developer fee configuration.
|
|
@@ -30755,11 +31012,11 @@ registerKit(`${pkg$2.name}/${pkg$2.version}`);
|
|
|
30755
31012
|
return kit;
|
|
30756
31013
|
};
|
|
30757
31014
|
|
|
30758
|
-
var name$
|
|
30759
|
-
var version$
|
|
30760
|
-
var pkg$
|
|
30761
|
-
name: name$
|
|
30762
|
-
version: version$
|
|
31015
|
+
var name$2 = "@circle-fin/earn-kit";
|
|
31016
|
+
var version$2 = "1.2.2";
|
|
31017
|
+
var pkg$2 = {
|
|
31018
|
+
name: name$2,
|
|
31019
|
+
version: version$2};
|
|
30763
31020
|
|
|
30764
31021
|
const EARN_BRIDGE_ERC3009_TOKEN_SYMBOLS = [
|
|
30765
31022
|
'USDC'
|
|
@@ -32331,10 +32588,11 @@ const bridgeDepositPrepareReviewSchema = z.object({
|
|
|
32331
32588
|
* Zod schema for a fee entry in an EarnKit API response.
|
|
32332
32589
|
*
|
|
32333
32590
|
* Shared across deposit and withdrawal responses (and reusable for real
|
|
32334
|
-
* charged fees, not just quote estimates). `type` identifies the fee category
|
|
32335
|
-
*
|
|
32336
|
-
* (e.g. `'FORWARD'`, `'PRE_FINALITY'`).
|
|
32337
|
-
* `'
|
|
32591
|
+
* charged fees, not just quote estimates). `type` identifies the fee category.
|
|
32592
|
+
* For cross-chain deposit quotes this is the kits-proxy fee-quote item type
|
|
32593
|
+
* (e.g. `'FORWARD'`, `'PRE_FINALITY'`). For withdrawal quotes, Circle fees use
|
|
32594
|
+
* `type: 'circle'`. `status` qualifies the fee (e.g. `'estimated'` for a
|
|
32595
|
+
* pre-sign cross-chain fee). Both are omitted on plain fees.
|
|
32338
32596
|
*
|
|
32339
32597
|
* @internal
|
|
32340
32598
|
*/ const feeSchema = z.object({
|
|
@@ -32606,6 +32864,60 @@ const bridgeDepositPrepareReviewSchema = z.object({
|
|
|
32606
32864
|
return claimRewardsQuoteResponseSchema.safeParse(value).success;
|
|
32607
32865
|
}
|
|
32608
32866
|
|
|
32867
|
+
var name$1 = "@circle-fin/provider-earn-service";
|
|
32868
|
+
var version$1 = "1.2.2";
|
|
32869
|
+
var pkg$1 = {
|
|
32870
|
+
name: name$1,
|
|
32871
|
+
version: version$1};
|
|
32872
|
+
|
|
32873
|
+
/**
|
|
32874
|
+
* HTTP header name used to report the EarnKit SDK version to the backend.
|
|
32875
|
+
*
|
|
32876
|
+
* @internal
|
|
32877
|
+
*/ const SDK_VERSION_HEADER = 'X-EarnKit-SDK-Version';
|
|
32878
|
+
/**
|
|
32879
|
+
* Resolve the SDK version string from its source components.
|
|
32880
|
+
*
|
|
32881
|
+
* Resolution order:
|
|
32882
|
+
* 1. The registered kit identifier (preferred) — e.g. `@circle-fin/earn-kit/1.1.0`
|
|
32883
|
+
* becomes `earn-kit/1.1.0`.
|
|
32884
|
+
* 2. The provider package itself (fallback when no kit is registered) —
|
|
32885
|
+
* e.g. `provider-earn-service/1.1.0`.
|
|
32886
|
+
* 3. The literal `unknown` when neither source is available.
|
|
32887
|
+
*
|
|
32888
|
+
* Kept as a pure function (no global / module reads) so every branch is
|
|
32889
|
+
* unit-testable.
|
|
32890
|
+
*
|
|
32891
|
+
* @param kitId - The registered kit identifier, or `undefined`.
|
|
32892
|
+
* @param providerName - The provider package name (e.g. `@circle-fin/provider-earn-service`).
|
|
32893
|
+
* @param providerVersion - The provider package version, or `undefined`.
|
|
32894
|
+
* @returns The formatted SDK version string.
|
|
32895
|
+
*
|
|
32896
|
+
* @internal
|
|
32897
|
+
*/ function formatSdkVersion(kitId, providerName, providerVersion) {
|
|
32898
|
+
if (kitId !== undefined && kitId !== '') {
|
|
32899
|
+
// e.g. '@circle-fin/earn-kit/1.1.0' -> 'earn-kit/1.1.0'
|
|
32900
|
+
return resolveKitSdkName(kitId);
|
|
32901
|
+
}
|
|
32902
|
+
{
|
|
32903
|
+
// e.g. '@circle-fin/provider-earn-service' + '1.1.0' -> 'provider-earn-service/1.1.0'
|
|
32904
|
+
return `${resolveKitSdkName(providerName)}/${providerVersion}`;
|
|
32905
|
+
}
|
|
32906
|
+
}
|
|
32907
|
+
/**
|
|
32908
|
+
* Resolve the value for the {@link SDK_VERSION_HEADER} header.
|
|
32909
|
+
*
|
|
32910
|
+
* Reads the kit registered at runtime via {@link createRequestContext} and
|
|
32911
|
+
* falls back to this provider package's own version when no kit is registered.
|
|
32912
|
+
*
|
|
32913
|
+
* @returns The SDK version string, e.g. `earn-kit/1.1.0` or
|
|
32914
|
+
* `provider-earn-service/1.1.0`, or `unknown`.
|
|
32915
|
+
*
|
|
32916
|
+
* @internal
|
|
32917
|
+
*/ function resolveSdkVersionHeader() {
|
|
32918
|
+
return formatSdkVersion(createRequestContext().kit, pkg$1.name, pkg$1.version);
|
|
32919
|
+
}
|
|
32920
|
+
|
|
32609
32921
|
/**
|
|
32610
32922
|
* Build an API polling config with optional authorization header,
|
|
32611
32923
|
* and resolve the base URL (configurable for testing).
|
|
@@ -32616,9 +32928,16 @@ const bridgeDepositPrepareReviewSchema = z.object({
|
|
|
32616
32928
|
* @internal
|
|
32617
32929
|
*/ function buildConfig(serviceConfig) {
|
|
32618
32930
|
const baseUrl = serviceConfig?.baseUrl ?? EARN_SERVICE_BASE_URL;
|
|
32931
|
+
const sdkVersion = resolveSdkVersionHeader();
|
|
32619
32932
|
if (serviceConfig?.kitKey === undefined) {
|
|
32620
32933
|
return {
|
|
32621
|
-
pollingConfig:
|
|
32934
|
+
pollingConfig: {
|
|
32935
|
+
...DEFAULT_CONFIG,
|
|
32936
|
+
headers: {
|
|
32937
|
+
...DEFAULT_CONFIG.headers,
|
|
32938
|
+
[SDK_VERSION_HEADER]: sdkVersion
|
|
32939
|
+
}
|
|
32940
|
+
},
|
|
32622
32941
|
baseUrl
|
|
32623
32942
|
};
|
|
32624
32943
|
}
|
|
@@ -32634,6 +32953,7 @@ const bridgeDepositPrepareReviewSchema = z.object({
|
|
|
32634
32953
|
...DEFAULT_CONFIG,
|
|
32635
32954
|
headers: {
|
|
32636
32955
|
...DEFAULT_CONFIG.headers,
|
|
32956
|
+
[SDK_VERSION_HEADER]: sdkVersion,
|
|
32637
32957
|
Authorization: `Bearer ${serviceConfig.kitKey}`
|
|
32638
32958
|
}
|
|
32639
32959
|
},
|
|
@@ -33366,9 +33686,15 @@ function toWithdrawalQuoteInfo(data) {
|
|
|
33366
33686
|
symbol: data.asset,
|
|
33367
33687
|
amount: Amount.fromJSON(data.maxWithdrawable)
|
|
33368
33688
|
},
|
|
33369
|
-
fees: data.fees.map((
|
|
33370
|
-
symbol:
|
|
33371
|
-
amount: Amount.fromJSON(
|
|
33689
|
+
fees: data.fees.map(({ token, amount, type, status })=>({
|
|
33690
|
+
symbol: token,
|
|
33691
|
+
amount: Amount.fromJSON(amount),
|
|
33692
|
+
...type !== undefined && {
|
|
33693
|
+
type
|
|
33694
|
+
},
|
|
33695
|
+
...status !== undefined && {
|
|
33696
|
+
status
|
|
33697
|
+
}
|
|
33372
33698
|
})),
|
|
33373
33699
|
gasFees: [],
|
|
33374
33700
|
// Wire format uses `warnings`, but the SDK surface uses
|
|
@@ -36587,7 +36913,7 @@ function formatRetryResult(operation, result) {
|
|
|
36587
36913
|
}
|
|
36588
36914
|
|
|
36589
36915
|
// Auto-register this kit for user agent tracking
|
|
36590
|
-
registerKit(`${pkg$
|
|
36916
|
+
registerKit(`${pkg$2.name}/${pkg$2.version}`);
|
|
36591
36917
|
|
|
36592
36918
|
/**
|
|
36593
36919
|
* Create an EarnKit instance for AppKit earn operations.
|
|
@@ -36682,12 +37008,17 @@ registerKit(`${pkg$1.name}/${pkg$1.version}`);
|
|
|
36682
37008
|
* The type annotation `readonly TokenAlias[]` ensures this array stays in sync
|
|
36683
37009
|
* with the TokenAlias type definition - TypeScript will enforce any changes.
|
|
36684
37010
|
*
|
|
36685
|
-
*
|
|
37011
|
+
* `USDC`, `USDT`, and `NATIVE` map to dedicated adapter transfer actions.
|
|
37012
|
+
* `EURC` has no dedicated action — it resolves to the chain's `eurcAddress`
|
|
37013
|
+
* and uses the generic token transfer action (see {@link prepareSend}).
|
|
37014
|
+
*
|
|
37015
|
+
* For swap operations, additional tokens (DAI, USDE, PYUSD) are supported
|
|
36686
37016
|
* via SwapKit's SupportedToken type.
|
|
36687
37017
|
*/ const TOKEN_ALIASES = [
|
|
36688
37018
|
'USDC',
|
|
36689
37019
|
'USDT',
|
|
36690
|
-
'NATIVE'
|
|
37020
|
+
'NATIVE',
|
|
37021
|
+
'EURC'
|
|
36691
37022
|
];
|
|
36692
37023
|
/**
|
|
36693
37024
|
* Check if a token string is a known alias.
|
|
@@ -36714,7 +37045,7 @@ registerKit(`${pkg$1.name}/${pkg$1.version}`);
|
|
|
36714
37045
|
* Type guard to check if a string is a valid token address for a chain.
|
|
36715
37046
|
*
|
|
36716
37047
|
* This function verifies that a token string is:
|
|
36717
|
-
* 1. Not a known alias ('USDC', 'USDT', 'NATIVE')
|
|
37048
|
+
* 1. Not a known alias ('USDC', 'USDT', 'NATIVE', 'EURC')
|
|
36718
37049
|
* 2. A valid address format for the specified chain
|
|
36719
37050
|
*
|
|
36720
37051
|
* Use this to narrow the type to `TokenAddress` in TypeScript.
|
|
@@ -36744,7 +37075,7 @@ registerKit(`${pkg$1.name}/${pkg$1.version}`);
|
|
|
36744
37075
|
* Validate and classify a token identifier.
|
|
36745
37076
|
*
|
|
36746
37077
|
* This function determines whether a token string is:
|
|
36747
|
-
* 1. A known alias ('USDC', 'USDT', or '
|
|
37078
|
+
* 1. A known alias ('USDC', 'USDT', 'NATIVE', or 'EURC')
|
|
36748
37079
|
* 2. A valid token address for the given chain
|
|
36749
37080
|
* 3. An invalid/unrecognized token identifier
|
|
36750
37081
|
*
|
|
@@ -36998,8 +37329,11 @@ const tokens = createTokenRegistry();
|
|
|
36998
37329
|
* from `to` (explicit address string or adapter), and normalize the human‑readable
|
|
36999
37330
|
* `amount` into token units.
|
|
37000
37331
|
*
|
|
37001
|
-
* For
|
|
37002
|
-
* with hardcoded decimals (USDC and USDT use 6 decimals; native uses the source chain's native decimals).
|
|
37332
|
+
* For the `USDC`, `USDT`, and `NATIVE` aliases, uses dedicated transfer actions
|
|
37333
|
+
* with hardcoded decimals (USDC and USDT use 6 decimals; native uses the source chain's native decimals).
|
|
37334
|
+
* The `EURC` alias resolves to the chain's `eurcAddress` (6 decimals from the token
|
|
37335
|
+
* registry) and routes through the generic token.transfer action; it is rejected on
|
|
37336
|
+
* chains where `eurcAddress` is not set. For custom token addresses, uses the generic token.transfer
|
|
37003
37337
|
* action and fetches decimals dynamically from the contract.
|
|
37004
37338
|
*
|
|
37005
37339
|
* @param params - The send parameters including source context, destination, amount and token.
|
|
@@ -37092,6 +37426,21 @@ const tokens = createTokenRegistry();
|
|
|
37092
37426
|
preparedSendRequest = await fromAdapter.prepareAction('native.transfer', requestParams, operationContext);
|
|
37093
37427
|
break;
|
|
37094
37428
|
}
|
|
37429
|
+
case 'EURC':
|
|
37430
|
+
{
|
|
37431
|
+
// EURC has no dedicated transfer action. Resolve its contract address
|
|
37432
|
+
// from the chain definition and route through the generic
|
|
37433
|
+
// token.transfer action. `eurcAddress` is null where EURC isn't deployed.
|
|
37434
|
+
const eurcAddress = fromChain.eurcAddress;
|
|
37435
|
+
if (eurcAddress === null) {
|
|
37436
|
+
throw createUnsupportedTokenError(token, fromChain.name);
|
|
37437
|
+
}
|
|
37438
|
+
preparedSendRequest = await fromAdapter.prepareAction('token.transfer', {
|
|
37439
|
+
...requestParams,
|
|
37440
|
+
tokenAddress: eurcAddress
|
|
37441
|
+
}, operationContext);
|
|
37442
|
+
break;
|
|
37443
|
+
}
|
|
37095
37444
|
default:
|
|
37096
37445
|
{
|
|
37097
37446
|
throw createUnsupportedTokenError(String(token), fromChain.name);
|
|
@@ -37118,12 +37467,13 @@ const tokens = createTokenRegistry();
|
|
|
37118
37467
|
* Fully prepares and executes the send transaction to transfer the specified amount and
|
|
37119
37468
|
* token to the specified destination.
|
|
37120
37469
|
*
|
|
37121
|
-
* For
|
|
37122
|
-
*
|
|
37123
|
-
*
|
|
37470
|
+
* For the 'USDC', 'USDT', and 'NATIVE' aliases, uses optimized dedicated actions.
|
|
37471
|
+
* The 'EURC' alias resolves to the chain's `eurcAddress` and routes through the generic
|
|
37472
|
+
* token.transfer action. For custom token addresses, uses the generic token.transfer action
|
|
37473
|
+
* with dynamically fetched decimals.
|
|
37124
37474
|
*
|
|
37125
37475
|
* @param params - The send parameters: source context, destination (address or adapter),
|
|
37126
|
-
* human-readable `amount`, and optional `token` ('USDC' | 'USDT' | 'NATIVE' or custom address, defaults to 'USDC').
|
|
37476
|
+
* human-readable `amount`, and optional `token` ('USDC' | 'USDT' | 'NATIVE' | 'EURC' or custom address, defaults to 'USDC').
|
|
37127
37477
|
* @returns A BridgeStep object with transaction details including hash, status, and explorer URL.
|
|
37128
37478
|
* @throws KitError INPUT_VALIDATION_FAILED if parameters are invalid.
|
|
37129
37479
|
* @throws KitError INPUT_UNSUPPORTED_TOKEN if the token is invalid for the chain.
|
|
@@ -37141,6 +37491,17 @@ const tokens = createTokenRegistry();
|
|
|
37141
37491
|
* console.log('Transaction hash:', step.txHash)
|
|
37142
37492
|
* ```
|
|
37143
37493
|
*
|
|
37494
|
+
* @example Sending EURC on a chain where EURC is deployed (e.g. Arc Testnet)
|
|
37495
|
+
* ```typescript
|
|
37496
|
+
* const step = await send({
|
|
37497
|
+
* from: { adapter: sourceAdapter, chain: 'Arc_Testnet' },
|
|
37498
|
+
* to: '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
|
|
37499
|
+
* amount: '5.0',
|
|
37500
|
+
* token: 'EURC',
|
|
37501
|
+
* })
|
|
37502
|
+
* console.log('Transaction hash:', step.txHash)
|
|
37503
|
+
* ```
|
|
37504
|
+
*
|
|
37144
37505
|
* @example Sending a custom token (DAI) to an explicit address
|
|
37145
37506
|
* ```typescript
|
|
37146
37507
|
* const step = await send({
|
|
@@ -37182,21 +37543,22 @@ const tokens = createTokenRegistry();
|
|
|
37182
37543
|
};
|
|
37183
37544
|
|
|
37184
37545
|
/**
|
|
37185
|
-
* Estimate the network fees to send USDC, USDT, or a supported native token.
|
|
37546
|
+
* Estimate the network fees to send USDC, USDT, EURC, or a supported native token.
|
|
37186
37547
|
*
|
|
37187
37548
|
* Prepare the send operation (including validating inputs and resolving the recipient when
|
|
37188
37549
|
* provided as an adapter) and return an {@link EstimatedGas} object. This function does
|
|
37189
37550
|
* not submit any transaction.
|
|
37190
37551
|
*
|
|
37191
37552
|
* @remarks
|
|
37192
|
-
* - Selects the transfer handler based on `token` ('USDC' by default, 'USDT', or '
|
|
37553
|
+
* - Selects the transfer handler based on `token` ('USDC' by default, 'USDT', 'NATIVE', or 'EURC').
|
|
37554
|
+
* 'EURC' is only supported on chains where `eurcAddress` is configured.
|
|
37193
37555
|
* - When `to` is an {@link Adapter}, the recipient address is derived from the adapter.
|
|
37194
37556
|
* - Rejects transfers where the resolved `to` equals the source `from` address.
|
|
37195
37557
|
* - Interprets `amount` as a human-readable decimal string (USDC and USDT scaled to 6 decimals,
|
|
37196
37558
|
* native EVM value typically scaled to 18 decimals).
|
|
37197
37559
|
*
|
|
37198
37560
|
* @param params - The send parameters: source context, destination (address or adapter),
|
|
37199
|
-
* human-readable `amount`, and optional `token` ('USDC' | 'USDT' | 'NATIVE', defaults to 'USDC').
|
|
37561
|
+
* human-readable `amount`, and optional `token` ('USDC' | 'USDT' | 'NATIVE' | 'EURC', defaults to 'USDC').
|
|
37200
37562
|
* @returns The estimated gas information including `gas`, `gasPrice`, and total `fee`.
|
|
37201
37563
|
* @throws Error If parameters are invalid.
|
|
37202
37564
|
* @throws Error If the token is unsupported or the send cannot be prepared.
|
|
@@ -37903,7 +38265,7 @@ async function deposit$2(context, params) {
|
|
|
37903
38265
|
}
|
|
37904
38266
|
|
|
37905
38267
|
var name = "@circle-fin/unified-balance-kit";
|
|
37906
|
-
var version = "1.2.
|
|
38268
|
+
var version = "1.2.2";
|
|
37907
38269
|
var pkg = {
|
|
37908
38270
|
name: name,
|
|
37909
38271
|
version: version};
|