@circle-fin/app-kit 1.17.0 → 1.18.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 +41 -0
- package/borrow.cjs +6 -6
- package/borrow.d.cts +3 -3
- package/borrow.d.mts +3 -3
- package/borrow.d.ts +3 -3
- package/borrow.mjs +6 -6
- package/bridge.cjs +272 -18
- package/bridge.d.cts +3 -3
- package/bridge.d.mts +3 -3
- package/bridge.d.ts +3 -3
- package/bridge.mjs +272 -18
- package/chains.cjs +2 -2
- package/chains.d.cts +1 -1
- package/chains.d.mts +1 -1
- package/chains.d.ts +1 -1
- package/chains.mjs +2 -2
- package/context.d.cts +3 -3
- package/context.d.mts +3 -3
- package/context.d.ts +3 -3
- package/earn.cjs +365 -14
- package/earn.d.cts +3 -3
- package/earn.d.mts +3 -3
- package/earn.d.ts +3 -3
- package/earn.mjs +365 -14
- package/estimateBridge.cjs +272 -18
- package/estimateBridge.d.cts +3 -3
- package/estimateBridge.d.mts +3 -3
- package/estimateBridge.d.ts +3 -3
- package/estimateBridge.mjs +272 -18
- package/estimateSwap.cjs +6 -6
- package/estimateSwap.d.cts +3 -3
- package/estimateSwap.d.mts +3 -3
- package/estimateSwap.d.ts +3 -3
- package/estimateSwap.mjs +6 -6
- package/index.cjs +558 -27
- package/index.d.cts +42 -8
- package/index.d.mts +42 -8
- package/index.d.ts +42 -8
- package/index.mjs +558 -27
- package/package.json +8 -8
- package/server.cjs +3 -3
- package/server.mjs +3 -3
- package/swap.cjs +6 -6
- package/swap.d.cts +3 -3
- package/swap.d.mts +3 -3
- package/swap.d.ts +3 -3
- package/swap.mjs +6 -6
- package/unifiedBalance.cjs +68 -10
- package/unifiedBalance.mjs +68 -10
package/estimateBridge.mjs
CHANGED
|
@@ -4536,14 +4536,14 @@ var BorrowChain;
|
|
|
4536
4536
|
symbol: 'USDC',
|
|
4537
4537
|
// Arc uses native USDC with 18 decimals for gas payments (EVM standard).
|
|
4538
4538
|
// Note: The ERC-20 USDC contract at usdcAddress uses 6 decimals.
|
|
4539
|
-
// See: https://docs.arc.
|
|
4539
|
+
// See: https://docs.arc.io/arc/references/contract-addresses
|
|
4540
4540
|
decimals: 18
|
|
4541
4541
|
},
|
|
4542
4542
|
chainId: 5042002,
|
|
4543
4543
|
isTestnet: true,
|
|
4544
4544
|
explorerUrl: 'https://testnet.arcscan.app/tx/{hash}',
|
|
4545
4545
|
rpcEndpoints: [
|
|
4546
|
-
'https://rpc.testnet.arc.
|
|
4546
|
+
'https://rpc.testnet.arc.io'
|
|
4547
4547
|
],
|
|
4548
4548
|
eurcAddress: '0x89B50855Aa3bE2F677cD6303Cec089B5F319D72a',
|
|
4549
4549
|
usdcAddress: '0x3600000000000000000000000000000000000000',
|
|
@@ -12180,6 +12180,39 @@ function resolveOptions(options) {
|
|
|
12180
12180
|
}
|
|
12181
12181
|
};
|
|
12182
12182
|
}
|
|
12183
|
+
/**
|
|
12184
|
+
* Emit telemetry for a completed operation without affecting its caller.
|
|
12185
|
+
*
|
|
12186
|
+
* No-ops when `config.disabled` is `true`. Like {@link withErrorTelemetry},
|
|
12187
|
+
* failures while constructing or submitting the telemetry payload are reported
|
|
12188
|
+
* as a soft warning and never change a completed operation's result.
|
|
12189
|
+
*
|
|
12190
|
+
* @param eventType - The telemetry event type for the completed operation.
|
|
12191
|
+
* @param config - Per-kit SDK identity and disabled flag.
|
|
12192
|
+
* @param context - Optional chain, token, and transaction context.
|
|
12193
|
+
* @returns Nothing.
|
|
12194
|
+
* @throws Never — telemetry failures are reported as warnings.
|
|
12195
|
+
*
|
|
12196
|
+
* @example
|
|
12197
|
+
* ```typescript
|
|
12198
|
+
* import { emitSuccessTelemetry } from '@core/utils'
|
|
12199
|
+
*
|
|
12200
|
+
* emitSuccessTelemetry(
|
|
12201
|
+
* 'bridge_bridge',
|
|
12202
|
+
* { sdkName: 'bridge-kit', sdkVersion: '1.0.0', disabled: false },
|
|
12203
|
+
* { sourceChain: 'Ethereum', destinationChain: 'Base', tokenIn: 'USDC' },
|
|
12204
|
+
* )
|
|
12205
|
+
* ```
|
|
12206
|
+
*/ function emitSuccessTelemetry(eventType, config, context) {
|
|
12207
|
+
if (config.disabled) {
|
|
12208
|
+
return;
|
|
12209
|
+
}
|
|
12210
|
+
try {
|
|
12211
|
+
void emitAnalyticsLog(buildPayload(config, eventType, undefined, context));
|
|
12212
|
+
} catch (telemetryError) {
|
|
12213
|
+
warnTelemetryDrop(eventType, telemetryError);
|
|
12214
|
+
}
|
|
12215
|
+
}
|
|
12183
12216
|
/**
|
|
12184
12217
|
* Wrap an async operation with error telemetry.
|
|
12185
12218
|
*
|
|
@@ -12290,7 +12323,7 @@ function resolveOptions(options) {
|
|
|
12290
12323
|
}
|
|
12291
12324
|
|
|
12292
12325
|
var name$3 = "@circle-fin/bridge-kit";
|
|
12293
|
-
var version$4 = "1.
|
|
12326
|
+
var version$4 = "1.16.0";
|
|
12294
12327
|
var pkg$4 = {
|
|
12295
12328
|
name: name$3,
|
|
12296
12329
|
version: version$4};
|
|
@@ -13551,6 +13584,53 @@ const EURC_MAINNET_TOKEN_ID = '0x6ca9e29fa53becc29becaf4a90b9ca7a995ad4d2234880d
|
|
|
13551
13584
|
}
|
|
13552
13585
|
};
|
|
13553
13586
|
|
|
13587
|
+
/**
|
|
13588
|
+
* Map a CCTPx bytes32 token id back to its known display symbol.
|
|
13589
|
+
*
|
|
13590
|
+
* The inverse of the provider's internal symbol -> id resolution: a bridge
|
|
13591
|
+
* resolves a symbol such as `'cirBTC'` to its canonical bytes32 id and reports
|
|
13592
|
+
* that id on `result.token`, dropping the symbol. This helper recovers the
|
|
13593
|
+
* symbol for display. It is scoped to {@link KNOWN_TOKEN_SYMBOLS} — the same
|
|
13594
|
+
* known set the forward resolution covers — and is keyed by network, because a
|
|
13595
|
+
* symbol names a separate registration on each network, whose ids are
|
|
13596
|
+
* unrelated.
|
|
13597
|
+
*
|
|
13598
|
+
* The lookup is best-effort by design: an arbitrary registry token, a
|
|
13599
|
+
* non-canonical bridge of a known symbol, or any unrecognized id has no known
|
|
13600
|
+
* symbol and yields `undefined`. The id is matched case-insensitively (bytes32
|
|
13601
|
+
* ids have no checksum casing).
|
|
13602
|
+
*
|
|
13603
|
+
* @param id - The bytes32 token id to decode (e.g. a `result.token` value).
|
|
13604
|
+
* @param network - The network the id belongs to (`'testnet'` or `'mainnet'`);
|
|
13605
|
+
* derive it from the source chain, e.g. `chain.isTestnet ? 'testnet' :
|
|
13606
|
+
* 'mainnet'`.
|
|
13607
|
+
* @returns The matching {@link KnownTokenSymbol}, or `undefined` when `id` is
|
|
13608
|
+
* not one of the known canonical ids for `network`.
|
|
13609
|
+
* @throws A `KitError` (`INPUT_VALIDATION_FAILED`, FATAL) when `id` is not a
|
|
13610
|
+
* string or `network` is not a recognized network.
|
|
13611
|
+
*
|
|
13612
|
+
* @example
|
|
13613
|
+
* ```typescript
|
|
13614
|
+
* import { resolveToKnownTokenSymbol } from '@circle-fin/provider-cctpx'
|
|
13615
|
+
*
|
|
13616
|
+
* const result = await provider.bridge(params) // params.token === 'cirBTC'
|
|
13617
|
+
* const network = result.source.chain.isTestnet ? 'testnet' : 'mainnet'
|
|
13618
|
+
*
|
|
13619
|
+
* resolveToKnownTokenSymbol(result.token, network) // 'cirBTC'
|
|
13620
|
+
* resolveToKnownTokenSymbol('0xdeadbeef…', network) // undefined (not known)
|
|
13621
|
+
* ```
|
|
13622
|
+
*/ function resolveToKnownTokenSymbol(id, network) {
|
|
13623
|
+
if (typeof id !== 'string') {
|
|
13624
|
+
throw createValidationFailedError$1('id', id, 'must be a string');
|
|
13625
|
+
}
|
|
13626
|
+
if (network !== 'testnet' && network !== 'mainnet') {
|
|
13627
|
+
throw createValidationFailedError$1('network', network, "must be 'testnet' or 'mainnet'");
|
|
13628
|
+
}
|
|
13629
|
+
const row = KNOWN_TOKEN_IDS_BY_NETWORK[network];
|
|
13630
|
+
const target = id.toLowerCase();
|
|
13631
|
+
return KNOWN_TOKEN_SYMBOLS.find((symbol)=>row[symbol].toLowerCase() === target);
|
|
13632
|
+
}
|
|
13633
|
+
|
|
13554
13634
|
/**
|
|
13555
13635
|
* Default clock implementation.
|
|
13556
13636
|
*
|
|
@@ -20735,6 +20815,24 @@ const FAST_TIER_FINALITY_THRESHOLD = 1000;
|
|
|
20735
20815
|
}
|
|
20736
20816
|
};
|
|
20737
20817
|
|
|
20818
|
+
/**
|
|
20819
|
+
* Check whether a forwarded burn to the given destination asks Circle's
|
|
20820
|
+
* Forwarding Service to set up the recipient's token account before minting.
|
|
20821
|
+
*
|
|
20822
|
+
* Must return `true` exactly for the destinations where
|
|
20823
|
+
* {@link getForwarderHookData} emits the `createAta` frame, so the forwarding
|
|
20824
|
+
* fee quote includes the setup rent whenever the burn requests it.
|
|
20825
|
+
*
|
|
20826
|
+
* @internal
|
|
20827
|
+
* @param chainType - The destination blockchain type.
|
|
20828
|
+
* @returns `true` for Solana destinations, `false` otherwise.
|
|
20829
|
+
*
|
|
20830
|
+
* @example
|
|
20831
|
+
* ```typescript
|
|
20832
|
+
* requiresRecipientSetup('solana') // true
|
|
20833
|
+
* requiresRecipientSetup('evm') // false
|
|
20834
|
+
* ```
|
|
20835
|
+
*/ const requiresRecipientSetup = (chainType)=>chainType === 'solana';
|
|
20738
20836
|
/**
|
|
20739
20837
|
* Build the forwarding `hookData` for a forwarded (Orbit-relayed) CCTP v2 burn,
|
|
20740
20838
|
* tailored to the destination chain.
|
|
@@ -21085,10 +21183,12 @@ const FAST_TIER_FINALITY_THRESHOLD = 1000;
|
|
|
21085
21183
|
* @param sourceDomain - The source domain
|
|
21086
21184
|
* @param destinationDomain - The destination domain
|
|
21087
21185
|
* @param isTestnet - Whether the request is for a testnet chain
|
|
21186
|
+
* @param includeRecipientSetup - Whether the quote includes recipient account setup rent
|
|
21088
21187
|
* @returns The complete API URL with forward=true query parameter
|
|
21089
|
-
*/ function buildForwardingFeeUrl(sourceDomain, destinationDomain, isTestnet) {
|
|
21188
|
+
*/ function buildForwardingFeeUrl(sourceDomain, destinationDomain, isTestnet, includeRecipientSetup) {
|
|
21090
21189
|
const baseUrl = isTestnet ? IRIS_API_SANDBOX_BASE_URL$1 : IRIS_API_BASE_URL$1;
|
|
21091
|
-
|
|
21190
|
+
const recipientSetupQuery = includeRecipientSetup ? '&includeRecipientSetup=true' : '';
|
|
21191
|
+
return `${baseUrl}/v2/burn/USDC/fees/${sourceDomain.toString()}/${destinationDomain.toString()}?forward=true${recipientSetupQuery}`;
|
|
21092
21192
|
}
|
|
21093
21193
|
/**
|
|
21094
21194
|
* Fetches the forwarding fee for a USDC transfer operation with retry and timeout handling.
|
|
@@ -21105,6 +21205,10 @@ const FAST_TIER_FINALITY_THRESHOLD = 1000;
|
|
|
21105
21205
|
*
|
|
21106
21206
|
* The high fee tier is always used to provide buffer for destination gas fluctuations.
|
|
21107
21207
|
*
|
|
21208
|
+
* Pass `includeRecipientSetup: true` when the burn asks the Forwarding Service to create
|
|
21209
|
+
* the recipient's token account (Solana destinations). The quote then includes the
|
|
21210
|
+
* account rent, which the quote without this flag leaves out.
|
|
21211
|
+
*
|
|
21108
21212
|
* Implements timeout and retry logic to handle network issues and temporary API failures.
|
|
21109
21213
|
* Each HTTP request is given a maximum of 2 seconds before it is aborted.
|
|
21110
21214
|
* We retry up to 10 times, waiting 200ms between attempts.
|
|
@@ -21113,6 +21217,8 @@ const FAST_TIER_FINALITY_THRESHOLD = 1000;
|
|
|
21113
21217
|
* @param destinationDomain - The destination domain
|
|
21114
21218
|
* @param isTestnet - Whether the request is for a testnet chain
|
|
21115
21219
|
* @param finalityThreshold - The finality threshold to select the fee tier (1000 for FAST, 2000 for SLOW)
|
|
21220
|
+
* @param includeRecipientSetup - Whether to include recipient account setup rent in the
|
|
21221
|
+
* quote. Defaults to `false`.
|
|
21116
21222
|
* @returns The high-tier forwarding fee in USDC minor units (6 decimals)
|
|
21117
21223
|
* @throws Error if the input domains are invalid, the API request fails, returns invalid data, or network errors occur
|
|
21118
21224
|
*
|
|
@@ -21124,8 +21230,11 @@ const FAST_TIER_FINALITY_THRESHOLD = 1000;
|
|
|
21124
21230
|
*
|
|
21125
21231
|
* // SLOW transfer - use 2000ms finality threshold
|
|
21126
21232
|
* const slowForwardingFee = await fetchForwardingFee(0, 6, false, 2000)
|
|
21233
|
+
*
|
|
21234
|
+
* // Ethereum -> Solana: include the recipient token account rent
|
|
21235
|
+
* const solanaForwardingFee = await fetchForwardingFee(0, 5, false, 1000, true)
|
|
21127
21236
|
* ```
|
|
21128
|
-
*/ async function fetchForwardingFee(sourceDomain, destinationDomain, isTestnet, finalityThreshold) {
|
|
21237
|
+
*/ async function fetchForwardingFee(sourceDomain, destinationDomain, isTestnet, finalityThreshold, includeRecipientSetup = false) {
|
|
21129
21238
|
// Validate source domain
|
|
21130
21239
|
if (!Number.isInteger(sourceDomain) || sourceDomain < 0) {
|
|
21131
21240
|
throw new KitError({
|
|
@@ -21153,7 +21262,7 @@ const FAST_TIER_FINALITY_THRESHOLD = 1000;
|
|
|
21153
21262
|
});
|
|
21154
21263
|
}
|
|
21155
21264
|
// Fetch the fee tiers from the API with forward=true
|
|
21156
|
-
const url = buildForwardingFeeUrl(sourceDomain, destinationDomain, isTestnet);
|
|
21265
|
+
const url = buildForwardingFeeUrl(sourceDomain, destinationDomain, isTestnet, includeRecipientSetup);
|
|
21157
21266
|
const response = await pollApiGet(url, isForwardingFeeResponse, DEFAULT_CONFIG$1);
|
|
21158
21267
|
// Validate that we have at least one fee tier
|
|
21159
21268
|
if (response.length === 0) {
|
|
@@ -23489,7 +23598,7 @@ const mockAttestationMessage = {
|
|
|
23489
23598
|
return step;
|
|
23490
23599
|
}
|
|
23491
23600
|
|
|
23492
|
-
var version$3 = "1.14.
|
|
23601
|
+
var version$3 = "1.14.3";
|
|
23493
23602
|
var pkg$3 = {
|
|
23494
23603
|
version: version$3};
|
|
23495
23604
|
|
|
@@ -24408,9 +24517,34 @@ function assertCCTPV2Config(config) {
|
|
|
24408
24517
|
tokenAddress: source.chain.usdcAddress,
|
|
24409
24518
|
operationContext: sourceOperationContext
|
|
24410
24519
|
});
|
|
24520
|
+
await this.assertAmountCoversRecipientSetupFee(params);
|
|
24411
24521
|
return bridge(params, this);
|
|
24412
24522
|
}
|
|
24413
24523
|
/**
|
|
24524
|
+
* Reject a forwarded transfer to Solana whose amount does not exceed the fee.
|
|
24525
|
+
*
|
|
24526
|
+
* CCTP v2 reverts a burn whose `maxFee` is not less than its amount, and the Solana
|
|
24527
|
+
* forwarding fee includes the recipient token account rent. Checking before the
|
|
24528
|
+
* approval avoids sending a transaction that can never be followed by a burn.
|
|
24529
|
+
* Skipped when the caller provides `config.maxFee`.
|
|
24530
|
+
*
|
|
24531
|
+
* @param params - The validated CCTP v2 bridge parameters.
|
|
24532
|
+
* @returns A promise that resolves when the amount covers the fee.
|
|
24533
|
+
* @throws {KitError} INPUT_INVALID_AMOUNT (FATAL) when the fee is greater than or equal
|
|
24534
|
+
* to the amount.
|
|
24535
|
+
*/ async assertAmountCoversRecipientSetupFee(params) {
|
|
24536
|
+
const { destination, amount, config } = params;
|
|
24537
|
+
if (destination.useForwarder !== true || config.maxFee !== undefined || !requiresRecipientSetup(destination.chain.type)) {
|
|
24538
|
+
return;
|
|
24539
|
+
}
|
|
24540
|
+
const { providerFee, forwarderFee } = await this.getMaxFee(params);
|
|
24541
|
+
const maxFee = providerFee + forwarderFee;
|
|
24542
|
+
if (maxFee >= BigInt(amount)) {
|
|
24543
|
+
// Amounts and fees are in USDC minor units (6 decimals)
|
|
24544
|
+
throw createInvalidAmountError(formatUnits(amount, 6), `Amount must be greater than the ${formatUnits(String(maxFee), 6)} USDC fee for forwarded transfers to ${destination.chain.name}, which includes creating the recipient's token account`);
|
|
24545
|
+
}
|
|
24546
|
+
}
|
|
24547
|
+
/**
|
|
24414
24548
|
* Retry a failed or incomplete CCTP v2 bridge operation.
|
|
24415
24549
|
*
|
|
24416
24550
|
* Analyzes the bridge result to determine where to continue and executes
|
|
@@ -25127,6 +25261,9 @@ function assertCCTPV2Config(config) {
|
|
|
25127
25261
|
* | FAST | true | No | maxFee = calculatedBurnFee + forwardingFee |
|
|
25128
25262
|
* | FAST | true | Yes | maxFee = config.maxFee |
|
|
25129
25263
|
*
|
|
25264
|
+
* For forwarded burns to Solana, the forwarding fee includes the rent for creating the
|
|
25265
|
+
* recipient's token account. A caller-provided `maxFee` must cover it too.
|
|
25266
|
+
*
|
|
25130
25267
|
* @param params - The bridge parameters object containing:
|
|
25131
25268
|
* - `source`: The source wallet context with chain definition and adapter
|
|
25132
25269
|
* - `destination`: The destination wallet context with chain definition and adapter
|
|
@@ -25165,6 +25302,7 @@ function assertCCTPV2Config(config) {
|
|
|
25165
25302
|
}
|
|
25166
25303
|
// Get the min finality threshold based on the transfer speed
|
|
25167
25304
|
const minFinalityThreshold = CCTPv2MinFinalityThreshold[transferSpeed];
|
|
25305
|
+
const includeRecipientSetup = requiresRecipientSetup(destination.chain.type);
|
|
25168
25306
|
// SLOW transfer without forwarder: no fee
|
|
25169
25307
|
if (transferSpeed === TransferSpeed.SLOW && !useForwarder) {
|
|
25170
25308
|
return {
|
|
@@ -25174,7 +25312,7 @@ function assertCCTPV2Config(config) {
|
|
|
25174
25312
|
}
|
|
25175
25313
|
// SLOW transfer with forwarder: only forwarding fee
|
|
25176
25314
|
if (transferSpeed === TransferSpeed.SLOW && useForwarder) {
|
|
25177
|
-
const forwarderFee = await fetchForwardingFee(source.chain.cctp.domain, destination.chain.cctp.domain, source.chain.isTestnet, minFinalityThreshold);
|
|
25315
|
+
const forwarderFee = await fetchForwardingFee(source.chain.cctp.domain, destination.chain.cctp.domain, source.chain.isTestnet, minFinalityThreshold, includeRecipientSetup);
|
|
25178
25316
|
return {
|
|
25179
25317
|
providerFee: 0n,
|
|
25180
25318
|
forwarderFee
|
|
@@ -25184,7 +25322,7 @@ function assertCCTPV2Config(config) {
|
|
|
25184
25322
|
// Fetch fees in parallel when forwarder is enabled
|
|
25185
25323
|
const [scaledBps, forwarderFee] = await Promise.all([
|
|
25186
25324
|
fetchUsdcFastBurnFee(source.chain.cctp.domain, destination.chain.cctp.domain, source.chain.isTestnet),
|
|
25187
|
-
useForwarder ? fetchForwardingFee(source.chain.cctp.domain, destination.chain.cctp.domain, source.chain.isTestnet, minFinalityThreshold) : Promise.resolve(0n)
|
|
25325
|
+
useForwarder ? fetchForwardingFee(source.chain.cctp.domain, destination.chain.cctp.domain, source.chain.isTestnet, minFinalityThreshold, includeRecipientSetup) : Promise.resolve(0n)
|
|
25188
25326
|
]);
|
|
25189
25327
|
// Calculate fee proportional to the transfer amount
|
|
25190
25328
|
const amountInMinorUnits = BigInt(amount);
|
|
@@ -25734,6 +25872,21 @@ function assertCCTPV2Config(config) {
|
|
|
25734
25872
|
'bridge_forward'
|
|
25735
25873
|
]
|
|
25736
25874
|
];
|
|
25875
|
+
/**
|
|
25876
|
+
* Provider step names whose `txHash` is the source-chain transaction that
|
|
25877
|
+
* moves funds into the bridge protocol.
|
|
25878
|
+
*
|
|
25879
|
+
* @remarks
|
|
25880
|
+
* The success event carries this hash so the backend can join it to the
|
|
25881
|
+
* on-chain CCTP / CCTPx event for the same transfer. `burn` is the CCTP v2
|
|
25882
|
+
* step (including batched and source-fee flows); `transfer` is the CCTPx
|
|
25883
|
+
* `CrossChainTokenService` step.
|
|
25884
|
+
*
|
|
25885
|
+
* @internal
|
|
25886
|
+
*/ const BRIDGE_SOURCE_TX_STEP_NAMES = [
|
|
25887
|
+
'burn',
|
|
25888
|
+
'transfer'
|
|
25889
|
+
];
|
|
25737
25890
|
|
|
25738
25891
|
/**
|
|
25739
25892
|
* Base URL for Circle's Quote API (hosted in Iris) on mainnet/production.
|
|
@@ -26791,6 +26944,85 @@ async function resolveExecutionQuote(binding, suppliedQuote, refundAddress) {
|
|
|
26791
26944
|
}
|
|
26792
26945
|
return undefined;
|
|
26793
26946
|
}
|
|
26947
|
+
/**
|
|
26948
|
+
* Pick the source-chain transaction hash from a bridge result.
|
|
26949
|
+
*
|
|
26950
|
+
* Walk the steps from the end and return the hash of the most recent
|
|
26951
|
+
* successful source step (`burn` for CCTP v2, `transfer` for CCTPx). Walking
|
|
26952
|
+
* backwards selects the attempt that landed when a retry appended a new
|
|
26953
|
+
* source step after a failed one.
|
|
26954
|
+
*
|
|
26955
|
+
* @param steps - All steps from the bridge result.
|
|
26956
|
+
* @returns The source transaction hash, or `undefined` if no source step recorded one.
|
|
26957
|
+
*
|
|
26958
|
+
* @internal
|
|
26959
|
+
*/ function pickSourceTxHash(steps) {
|
|
26960
|
+
for(let i = steps.length - 1; i >= 0; i--){
|
|
26961
|
+
const step = steps[i];
|
|
26962
|
+
if (step?.txHash != null && step.state === 'success' && BRIDGE_SOURCE_TX_STEP_NAMES.includes(step.name)) {
|
|
26963
|
+
return step.txHash;
|
|
26964
|
+
}
|
|
26965
|
+
}
|
|
26966
|
+
return undefined;
|
|
26967
|
+
}
|
|
26968
|
+
/**
|
|
26969
|
+
* Resolve the token value reported in telemetry.
|
|
26970
|
+
*
|
|
26971
|
+
* CCTPx reports `result.token` as a bytes32 token id, while the backend's
|
|
26972
|
+
* canonical tables key tokens by symbol. Map the canonical id of a known CCTPx
|
|
26973
|
+
* token back to its symbol and pass any other value (USDC, or a registry token
|
|
26974
|
+
* without a known symbol) through unchanged. Registry symbols are not used
|
|
26975
|
+
* because they are not unique across CCTPx tokens. Never throws.
|
|
26976
|
+
*
|
|
26977
|
+
* @param token - The token from a bridge result.
|
|
26978
|
+
* @param sourceChain - The result's source chain; selects testnet or mainnet ids.
|
|
26979
|
+
* @returns The known symbol, or `token` unchanged.
|
|
26980
|
+
*
|
|
26981
|
+
* @internal
|
|
26982
|
+
*/ function toTelemetryToken(token, sourceChain) {
|
|
26983
|
+
try {
|
|
26984
|
+
const network = sourceChain.isTestnet ? 'testnet' : 'mainnet';
|
|
26985
|
+
return resolveToKnownTokenSymbol(token, network) ?? token;
|
|
26986
|
+
} catch {
|
|
26987
|
+
return token;
|
|
26988
|
+
}
|
|
26989
|
+
}
|
|
26990
|
+
/**
|
|
26991
|
+
* Emit the `bridge_bridge` success event for a completed transfer.
|
|
26992
|
+
*
|
|
26993
|
+
* No-ops unless `result.state` is `'success'`. Failed results are already
|
|
26994
|
+
* reported by error telemetry. Never throws: a malformed result (for example
|
|
26995
|
+
* from a custom provider) is reported as a telemetry drop warning and the
|
|
26996
|
+
* caller's result is returned unchanged.
|
|
26997
|
+
*
|
|
26998
|
+
* @param result - The human-readable bridge result returned to the caller.
|
|
26999
|
+
* @param config - Analytics telemetry identity, gated by `disableAnalytics`.
|
|
27000
|
+
*
|
|
27001
|
+
* @internal
|
|
27002
|
+
*/ function emitBridgeSuccessTelemetry(result, config) {
|
|
27003
|
+
if (config.disabled || result.state !== 'success') {
|
|
27004
|
+
return;
|
|
27005
|
+
}
|
|
27006
|
+
try {
|
|
27007
|
+
const txHash = pickSourceTxHash(result.steps);
|
|
27008
|
+
// `JSON.stringify` turns a non-finite number into `null`, which the logs
|
|
27009
|
+
// endpoint's strict schema rejects along with the whole event.
|
|
27010
|
+
const amountIn = Number.parseFloat(result.amount);
|
|
27011
|
+
emitSuccessTelemetry(BRIDGE_EVENT_TYPES.BRIDGE, config, {
|
|
27012
|
+
sourceChain: result.source.chain.chain,
|
|
27013
|
+
destinationChain: result.destination.chain.chain,
|
|
27014
|
+
tokenIn: toTelemetryToken(result.token, result.source.chain),
|
|
27015
|
+
...Number.isFinite(amountIn) && {
|
|
27016
|
+
amountIn
|
|
27017
|
+
},
|
|
27018
|
+
...txHash != null && {
|
|
27019
|
+
txHash
|
|
27020
|
+
}
|
|
27021
|
+
});
|
|
27022
|
+
} catch (telemetryError) {
|
|
27023
|
+
warnTelemetryDrop(BRIDGE_EVENT_TYPES.BRIDGE, telemetryError);
|
|
27024
|
+
}
|
|
27025
|
+
}
|
|
26794
27026
|
/**
|
|
26795
27027
|
* BridgeKit caller component for retry and estimate operations.
|
|
26796
27028
|
*/ const BRIDGE_KIT_CALLER = {
|
|
@@ -26921,6 +27153,10 @@ async function resolveExecutionQuote(binding, suppliedQuote, refundAddress) {
|
|
|
26921
27153
|
/** Whether error telemetry is disabled. */ disableErrorReporting;
|
|
26922
27154
|
/** Per-kit telemetry identity for shared helpers. */ telemetryConfig;
|
|
26923
27155
|
/**
|
|
27156
|
+
* Per-kit telemetry identity for success events. Gated by `disableAnalytics`
|
|
27157
|
+
* independently of `disableErrorReporting`.
|
|
27158
|
+
*/ analyticsTelemetryConfig;
|
|
27159
|
+
/**
|
|
26924
27160
|
* Create a new BridgeKit instance.
|
|
26925
27161
|
*
|
|
26926
27162
|
* @param config - The configuration containing the CCTPv2 provider
|
|
@@ -26947,6 +27183,11 @@ async function resolveExecutionQuote(binding, suppliedQuote, refundAddress) {
|
|
|
26947
27183
|
sdkVersion: pkg$4.version,
|
|
26948
27184
|
disabled: this.disableErrorReporting
|
|
26949
27185
|
};
|
|
27186
|
+
this.analyticsTelemetryConfig = {
|
|
27187
|
+
sdkName: SDK_NAME,
|
|
27188
|
+
sdkVersion: pkg$4.version,
|
|
27189
|
+
disabled: config.disableAnalytics === true
|
|
27190
|
+
};
|
|
26950
27191
|
for (const provider of this.providers){
|
|
26951
27192
|
provider.registerDispatcher(this.actionDispatcher);
|
|
26952
27193
|
}
|
|
@@ -26960,7 +27201,7 @@ async function resolveExecutionQuote(binding, suppliedQuote, refundAddress) {
|
|
|
26960
27201
|
this.actionDispatcher.off(actionOrWildCard, handler);
|
|
26961
27202
|
}
|
|
26962
27203
|
async bridge(params) {
|
|
26963
|
-
|
|
27204
|
+
const bridgeResult = await withErrorTelemetry(async ()=>{
|
|
26964
27205
|
// First validate the parameters
|
|
26965
27206
|
assertBridgeParams(params, bridgeParamsWithChainIdentifierSchema);
|
|
26966
27207
|
// Then resolve chain definitions (includes adapter chain support validation)
|
|
@@ -26997,7 +27238,7 @@ async function resolveExecutionQuote(binding, suppliedQuote, refundAddress) {
|
|
|
26997
27238
|
emitResultStepErrorTelemetry(failedStep, BRIDGE_STEP_EVENT_MAP, BRIDGE_EVENT_TYPES.BRIDGE, this.telemetryConfig, {
|
|
26998
27239
|
sourceChain: resolveChainName(params.from.chain),
|
|
26999
27240
|
destinationChain: resolveChainName(params.to.chain),
|
|
27000
|
-
tokenIn:
|
|
27241
|
+
tokenIn: toTelemetryToken(result.token, result.source.chain),
|
|
27001
27242
|
...txHash != null && {
|
|
27002
27243
|
txHash
|
|
27003
27244
|
}
|
|
@@ -27009,6 +27250,8 @@ async function resolveExecutionQuote(binding, suppliedQuote, refundAddress) {
|
|
|
27009
27250
|
destinationChain: resolveChainName(params.to.chain),
|
|
27010
27251
|
tokenIn: params.token
|
|
27011
27252
|
});
|
|
27253
|
+
emitBridgeSuccessTelemetry(bridgeResult, this.analyticsTelemetryConfig);
|
|
27254
|
+
return bridgeResult;
|
|
27012
27255
|
}
|
|
27013
27256
|
/**
|
|
27014
27257
|
* Retry a failed or incomplete cross-chain USDC bridge operation.
|
|
@@ -27079,7 +27322,7 @@ async function resolveExecutionQuote(binding, suppliedQuote, refundAddress) {
|
|
|
27079
27322
|
* )
|
|
27080
27323
|
* ```
|
|
27081
27324
|
*/ async retry(result, context, invocationMeta) {
|
|
27082
|
-
|
|
27325
|
+
const retriedResult = await withErrorTelemetry(async ()=>{
|
|
27083
27326
|
// Cast the providers list to the wide view here. The tuple
|
|
27084
27327
|
// type on `this.providers` retains concrete provider types
|
|
27085
27328
|
// (CCTPv2 narrows `TToken` to `'USDC'`); calling `.retry`
|
|
@@ -27107,7 +27350,7 @@ async function resolveExecutionQuote(binding, suppliedQuote, refundAddress) {
|
|
|
27107
27350
|
emitResultStepErrorTelemetry(failedStep, BRIDGE_STEP_EVENT_MAP, BRIDGE_EVENT_TYPES.RETRY, this.telemetryConfig, {
|
|
27108
27351
|
sourceChain: result.source.chain.chain,
|
|
27109
27352
|
destinationChain: result.destination.chain.chain,
|
|
27110
|
-
tokenIn: result.token,
|
|
27353
|
+
tokenIn: toTelemetryToken(result.token, result.source.chain),
|
|
27111
27354
|
...txHash != null && {
|
|
27112
27355
|
txHash
|
|
27113
27356
|
}
|
|
@@ -27121,8 +27364,16 @@ async function resolveExecutionQuote(binding, suppliedQuote, refundAddress) {
|
|
|
27121
27364
|
}, BRIDGE_EVENT_TYPES.RETRY, this.telemetryConfig, {
|
|
27122
27365
|
sourceChain: result.source.chain.chain,
|
|
27123
27366
|
destinationChain: result.destination.chain.chain,
|
|
27124
|
-
tokenIn: result.token
|
|
27367
|
+
tokenIn: toTelemetryToken(result.token, result.source.chain)
|
|
27125
27368
|
});
|
|
27369
|
+
// A retry that completes the transfer is the transfer's only success
|
|
27370
|
+
// event, so it reports the same `bridge_bridge` type as `bridge()`. An
|
|
27371
|
+
// input that already succeeded was reported by the call that completed it
|
|
27372
|
+
// (CCTP v2 returns such a result unchanged), so it is not reported again.
|
|
27373
|
+
if (result.state !== 'success') {
|
|
27374
|
+
emitBridgeSuccessTelemetry(retriedResult, this.analyticsTelemetryConfig);
|
|
27375
|
+
}
|
|
27376
|
+
return retriedResult;
|
|
27126
27377
|
}
|
|
27127
27378
|
async estimate(params) {
|
|
27128
27379
|
return withErrorTelemetry(async ()=>{
|
|
@@ -27718,6 +27969,9 @@ registerKit(`${pkg$4.name}/${pkg$4.version}`);
|
|
|
27718
27969
|
...context.disableErrorReporting != null && {
|
|
27719
27970
|
disableErrorReporting: context.disableErrorReporting
|
|
27720
27971
|
},
|
|
27972
|
+
...context.disableAnalytics != null && {
|
|
27973
|
+
disableAnalytics: context.disableAnalytics
|
|
27974
|
+
},
|
|
27721
27975
|
...context.headers != null && {
|
|
27722
27976
|
headers: context.headers
|
|
27723
27977
|
}
|
|
@@ -27740,7 +27994,7 @@ registerKit(`${pkg$4.name}/${pkg$4.version}`);
|
|
|
27740
27994
|
};
|
|
27741
27995
|
|
|
27742
27996
|
var name$2 = "@circle-fin/swap-kit";
|
|
27743
|
-
var version$2 = "1.8.
|
|
27997
|
+
var version$2 = "1.8.1";
|
|
27744
27998
|
var pkg$2 = {
|
|
27745
27999
|
name: name$2,
|
|
27746
28000
|
version: version$2};
|
|
@@ -30012,7 +30266,7 @@ new Set(Object.values(Blockchain));
|
|
|
30012
30266
|
registerKit(`${pkg$2.name}/${pkg$2.version}`);
|
|
30013
30267
|
|
|
30014
30268
|
var name$1 = "@circle-fin/earn-kit";
|
|
30015
|
-
var version$1 = "1.
|
|
30269
|
+
var version$1 = "1.10.0";
|
|
30016
30270
|
var pkg$1 = {
|
|
30017
30271
|
name: name$1,
|
|
30018
30272
|
version: version$1};
|
|
@@ -31452,7 +31706,7 @@ function hasCrossChainDepositQuoteShape(params) {
|
|
|
31452
31706
|
registerKit(`${pkg$1.name}/${pkg$1.version}`);
|
|
31453
31707
|
|
|
31454
31708
|
var name = "@circle-fin/borrow-kit";
|
|
31455
|
-
var version = "1.1.
|
|
31709
|
+
var version = "1.1.1";
|
|
31456
31710
|
var pkg = {
|
|
31457
31711
|
name: name,
|
|
31458
31712
|
version: version};
|
package/estimateSwap.cjs
CHANGED
|
@@ -3895,14 +3895,14 @@ var BorrowChain;
|
|
|
3895
3895
|
symbol: 'USDC',
|
|
3896
3896
|
// Arc uses native USDC with 18 decimals for gas payments (EVM standard).
|
|
3897
3897
|
// Note: The ERC-20 USDC contract at usdcAddress uses 6 decimals.
|
|
3898
|
-
// See: https://docs.arc.
|
|
3898
|
+
// See: https://docs.arc.io/arc/references/contract-addresses
|
|
3899
3899
|
decimals: 18
|
|
3900
3900
|
},
|
|
3901
3901
|
chainId: 5042002,
|
|
3902
3902
|
isTestnet: true,
|
|
3903
3903
|
explorerUrl: 'https://testnet.arcscan.app/tx/{hash}',
|
|
3904
3904
|
rpcEndpoints: [
|
|
3905
|
-
'https://rpc.testnet.arc.
|
|
3905
|
+
'https://rpc.testnet.arc.io'
|
|
3906
3906
|
],
|
|
3907
3907
|
eurcAddress: '0x89B50855Aa3bE2F677cD6303Cec089B5F319D72a',
|
|
3908
3908
|
usdcAddress: '0x3600000000000000000000000000000000000000',
|
|
@@ -10848,7 +10848,7 @@ const swapTokenEnumSchema = zod.z.enum([
|
|
|
10848
10848
|
}
|
|
10849
10849
|
|
|
10850
10850
|
var name$3 = "@circle-fin/bridge-kit";
|
|
10851
|
-
var version$3 = "1.
|
|
10851
|
+
var version$3 = "1.16.0";
|
|
10852
10852
|
var pkg$3 = {
|
|
10853
10853
|
name: name$3,
|
|
10854
10854
|
version: version$3};
|
|
@@ -12503,7 +12503,7 @@ const validateQuoteItemSchema = zod.z.object({
|
|
|
12503
12503
|
registerKit(`${pkg$3.name}/${pkg$3.version}`);
|
|
12504
12504
|
|
|
12505
12505
|
var name$2 = "@circle-fin/swap-kit";
|
|
12506
|
-
var version$2 = "1.8.
|
|
12506
|
+
var version$2 = "1.8.1";
|
|
12507
12507
|
var pkg$2 = {
|
|
12508
12508
|
name: name$2,
|
|
12509
12509
|
version: version$2};
|
|
@@ -23176,7 +23176,7 @@ registerKit(`${pkg$2.name}/${pkg$2.version}`);
|
|
|
23176
23176
|
};
|
|
23177
23177
|
|
|
23178
23178
|
var name$1 = "@circle-fin/earn-kit";
|
|
23179
|
-
var version$1 = "1.
|
|
23179
|
+
var version$1 = "1.10.0";
|
|
23180
23180
|
var pkg$1 = {
|
|
23181
23181
|
name: name$1,
|
|
23182
23182
|
version: version$1};
|
|
@@ -24616,7 +24616,7 @@ function hasCrossChainDepositQuoteShape(params) {
|
|
|
24616
24616
|
registerKit(`${pkg$1.name}/${pkg$1.version}`);
|
|
24617
24617
|
|
|
24618
24618
|
var name = "@circle-fin/borrow-kit";
|
|
24619
|
-
var version = "1.1.
|
|
24619
|
+
var version = "1.1.1";
|
|
24620
24620
|
var pkg = {
|
|
24621
24621
|
name: name,
|
|
24622
24622
|
version: version};
|
package/estimateSwap.d.cts
CHANGED
|
@@ -8466,11 +8466,11 @@ interface AppKitContext {
|
|
|
8466
8466
|
*/
|
|
8467
8467
|
actions: Record<'bridge' | 'earn' | 'borrow', Record<string, ((payload: unknown) => void)[]>>;
|
|
8468
8468
|
/**
|
|
8469
|
-
* Disable success analytics for the underlying EarnKit, SwapKit,
|
|
8469
|
+
* Disable success analytics for the underlying BridgeKit, EarnKit, SwapKit,
|
|
8470
8470
|
* BorrowKit, and UnifiedBalanceKit.
|
|
8471
8471
|
*
|
|
8472
|
-
* When `true`, completed earn, swap, borrow, and unified balance
|
|
8473
|
-
* will not POST analytics events. This does not disable error reporting; use
|
|
8472
|
+
* When `true`, completed bridge, earn, swap, borrow, and unified balance
|
|
8473
|
+
* operations will not POST analytics events. This does not disable error reporting; use
|
|
8474
8474
|
* {@link AppKitContext.disableErrorReporting} for that. Defaults to `false`.
|
|
8475
8475
|
*
|
|
8476
8476
|
* @defaultValue false
|
package/estimateSwap.d.mts
CHANGED
|
@@ -8466,11 +8466,11 @@ interface AppKitContext {
|
|
|
8466
8466
|
*/
|
|
8467
8467
|
actions: Record<'bridge' | 'earn' | 'borrow', Record<string, ((payload: unknown) => void)[]>>;
|
|
8468
8468
|
/**
|
|
8469
|
-
* Disable success analytics for the underlying EarnKit, SwapKit,
|
|
8469
|
+
* Disable success analytics for the underlying BridgeKit, EarnKit, SwapKit,
|
|
8470
8470
|
* BorrowKit, and UnifiedBalanceKit.
|
|
8471
8471
|
*
|
|
8472
|
-
* When `true`, completed earn, swap, borrow, and unified balance
|
|
8473
|
-
* will not POST analytics events. This does not disable error reporting; use
|
|
8472
|
+
* When `true`, completed bridge, earn, swap, borrow, and unified balance
|
|
8473
|
+
* operations will not POST analytics events. This does not disable error reporting; use
|
|
8474
8474
|
* {@link AppKitContext.disableErrorReporting} for that. Defaults to `false`.
|
|
8475
8475
|
*
|
|
8476
8476
|
* @defaultValue false
|
package/estimateSwap.d.ts
CHANGED
|
@@ -8466,11 +8466,11 @@ interface AppKitContext {
|
|
|
8466
8466
|
*/
|
|
8467
8467
|
actions: Record<'bridge' | 'earn' | 'borrow', Record<string, ((payload: unknown) => void)[]>>;
|
|
8468
8468
|
/**
|
|
8469
|
-
* Disable success analytics for the underlying EarnKit, SwapKit,
|
|
8469
|
+
* Disable success analytics for the underlying BridgeKit, EarnKit, SwapKit,
|
|
8470
8470
|
* BorrowKit, and UnifiedBalanceKit.
|
|
8471
8471
|
*
|
|
8472
|
-
* When `true`, completed earn, swap, borrow, and unified balance
|
|
8473
|
-
* will not POST analytics events. This does not disable error reporting; use
|
|
8472
|
+
* When `true`, completed bridge, earn, swap, borrow, and unified balance
|
|
8473
|
+
* operations will not POST analytics events. This does not disable error reporting; use
|
|
8474
8474
|
* {@link AppKitContext.disableErrorReporting} for that. Defaults to `false`.
|
|
8475
8475
|
*
|
|
8476
8476
|
* @defaultValue false
|
package/estimateSwap.mjs
CHANGED
|
@@ -3888,14 +3888,14 @@ var BorrowChain;
|
|
|
3888
3888
|
symbol: 'USDC',
|
|
3889
3889
|
// Arc uses native USDC with 18 decimals for gas payments (EVM standard).
|
|
3890
3890
|
// Note: The ERC-20 USDC contract at usdcAddress uses 6 decimals.
|
|
3891
|
-
// See: https://docs.arc.
|
|
3891
|
+
// See: https://docs.arc.io/arc/references/contract-addresses
|
|
3892
3892
|
decimals: 18
|
|
3893
3893
|
},
|
|
3894
3894
|
chainId: 5042002,
|
|
3895
3895
|
isTestnet: true,
|
|
3896
3896
|
explorerUrl: 'https://testnet.arcscan.app/tx/{hash}',
|
|
3897
3897
|
rpcEndpoints: [
|
|
3898
|
-
'https://rpc.testnet.arc.
|
|
3898
|
+
'https://rpc.testnet.arc.io'
|
|
3899
3899
|
],
|
|
3900
3900
|
eurcAddress: '0x89B50855Aa3bE2F677cD6303Cec089B5F319D72a',
|
|
3901
3901
|
usdcAddress: '0x3600000000000000000000000000000000000000',
|
|
@@ -10841,7 +10841,7 @@ const swapTokenEnumSchema = z.enum([
|
|
|
10841
10841
|
}
|
|
10842
10842
|
|
|
10843
10843
|
var name$3 = "@circle-fin/bridge-kit";
|
|
10844
|
-
var version$3 = "1.
|
|
10844
|
+
var version$3 = "1.16.0";
|
|
10845
10845
|
var pkg$3 = {
|
|
10846
10846
|
name: name$3,
|
|
10847
10847
|
version: version$3};
|
|
@@ -12496,7 +12496,7 @@ const validateQuoteItemSchema = z.object({
|
|
|
12496
12496
|
registerKit(`${pkg$3.name}/${pkg$3.version}`);
|
|
12497
12497
|
|
|
12498
12498
|
var name$2 = "@circle-fin/swap-kit";
|
|
12499
|
-
var version$2 = "1.8.
|
|
12499
|
+
var version$2 = "1.8.1";
|
|
12500
12500
|
var pkg$2 = {
|
|
12501
12501
|
name: name$2,
|
|
12502
12502
|
version: version$2};
|
|
@@ -23169,7 +23169,7 @@ registerKit(`${pkg$2.name}/${pkg$2.version}`);
|
|
|
23169
23169
|
};
|
|
23170
23170
|
|
|
23171
23171
|
var name$1 = "@circle-fin/earn-kit";
|
|
23172
|
-
var version$1 = "1.
|
|
23172
|
+
var version$1 = "1.10.0";
|
|
23173
23173
|
var pkg$1 = {
|
|
23174
23174
|
name: name$1,
|
|
23175
23175
|
version: version$1};
|
|
@@ -24609,7 +24609,7 @@ function hasCrossChainDepositQuoteShape(params) {
|
|
|
24609
24609
|
registerKit(`${pkg$1.name}/${pkg$1.version}`);
|
|
24610
24610
|
|
|
24611
24611
|
var name = "@circle-fin/borrow-kit";
|
|
24612
|
-
var version = "1.1.
|
|
24612
|
+
var version = "1.1.1";
|
|
24613
24613
|
var pkg = {
|
|
24614
24614
|
name: name,
|
|
24615
24615
|
version: version};
|