@circle-fin/app-kit 1.10.0 → 1.11.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 +34 -0
- package/bridge.cjs +74 -22
- package/bridge.d.cts +12 -1
- package/bridge.d.mts +12 -1
- package/bridge.d.ts +12 -1
- package/bridge.mjs +74 -22
- package/chains.cjs +11 -0
- package/chains.mjs +11 -0
- package/context.cjs +11 -0
- package/context.d.cts +12 -1
- package/context.d.mts +12 -1
- package/context.d.ts +12 -1
- package/context.mjs +11 -0
- package/earn.cjs +701 -49
- package/earn.d.cts +12 -1
- package/earn.d.mts +12 -1
- package/earn.d.ts +12 -1
- package/earn.mjs +701 -49
- package/estimateBridge.cjs +74 -22
- package/estimateBridge.d.cts +12 -1
- package/estimateBridge.d.mts +12 -1
- package/estimateBridge.d.ts +12 -1
- package/estimateBridge.mjs +74 -22
- package/estimateSwap.cjs +259 -30
- package/estimateSwap.d.cts +12 -1
- package/estimateSwap.d.mts +12 -1
- package/estimateSwap.d.ts +12 -1
- package/estimateSwap.mjs +259 -30
- package/index.cjs +539 -81
- package/index.d.cts +101 -7
- package/index.d.mts +101 -7
- package/index.d.ts +101 -7
- package/index.mjs +539 -81
- package/package.json +7 -6
- package/swap.cjs +259 -30
- package/swap.d.cts +12 -1
- package/swap.d.mts +12 -1
- package/swap.d.ts +12 -1
- package/swap.mjs +259 -30
- package/unifiedBalance.cjs +96 -26
- package/unifiedBalance.d.cts +28 -5
- package/unifiedBalance.d.mts +28 -5
- package/unifiedBalance.d.ts +28 -5
- package/unifiedBalance.mjs +96 -26
package/index.mjs
CHANGED
|
@@ -16,6 +16,17 @@
|
|
|
16
16
|
* limitations under the License.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
+
// Buffer polyfill setup - executes before any other code
|
|
20
|
+
// Ensures globalThis.Buffer is available for Solana libraries
|
|
21
|
+
import { Buffer } from 'buffer';
|
|
22
|
+
if (typeof globalThis !== 'undefined' && typeof globalThis.Buffer === 'undefined') {
|
|
23
|
+
globalThis.Buffer = Buffer;
|
|
24
|
+
}
|
|
25
|
+
if (typeof window !== 'undefined' && typeof window.Buffer === 'undefined') {
|
|
26
|
+
window.Buffer = Buffer;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
|
|
19
30
|
import { z } from 'zod';
|
|
20
31
|
import pino from 'pino';
|
|
21
32
|
import { parseUnits as parseUnits$1, formatUnits as formatUnits$1 } from '@ethersproject/units';
|
|
@@ -82,6 +93,51 @@ import { keccak256 } from '@ethersproject/keccak256';
|
|
|
82
93
|
* }
|
|
83
94
|
* ```
|
|
84
95
|
*/ const isNodeEnvironment = ()=>typeof process !== 'undefined' && typeof process.versions === 'object' && typeof process.versions.node === 'string';
|
|
96
|
+
/**
|
|
97
|
+
* Check whether the current runtime exposes a browser DOM.
|
|
98
|
+
*
|
|
99
|
+
* @remarks
|
|
100
|
+
* This intentionally does not treat every non-Node runtime as a browser.
|
|
101
|
+
* Server-side edge runtimes such as Cloudflare Workers, Deno, and Supabase
|
|
102
|
+
* Edge Functions do not expose Node globals but can safely use server
|
|
103
|
+
* credentials. A Node.js runtime remains server-side even when a test or SSR
|
|
104
|
+
* environment provides a DOM shim.
|
|
105
|
+
*
|
|
106
|
+
* @returns `true` when running in a browser window, `false` otherwise.
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```typescript
|
|
110
|
+
* import { isBrowserEnvironment } from '@core/utils'
|
|
111
|
+
*
|
|
112
|
+
* if (isBrowserEnvironment()) {
|
|
113
|
+
* throw new Error('Server-only secrets must not be used in the browser')
|
|
114
|
+
* }
|
|
115
|
+
* ```
|
|
116
|
+
*/ const isBrowserEnvironment = ()=>{
|
|
117
|
+
const browserWindow = globalThis.window;
|
|
118
|
+
return !isNodeEnvironment() && browserWindow?.document !== undefined;
|
|
119
|
+
};
|
|
120
|
+
/**
|
|
121
|
+
* Return the SDK User-Agent request header only when running in Node.js.
|
|
122
|
+
*
|
|
123
|
+
* Browsers forbid manually setting `User-Agent`, and a custom fallback header
|
|
124
|
+
* can trigger CORS preflight. Non-Node server runtimes also omit this optional
|
|
125
|
+
* attribution header because they cannot set it reliably.
|
|
126
|
+
*
|
|
127
|
+
* @returns A User-Agent header in Node.js, or an empty object otherwise.
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* ```typescript
|
|
131
|
+
* import { getNodeUserAgentHeader } from '@core/utils'
|
|
132
|
+
*
|
|
133
|
+
* const headers = {
|
|
134
|
+
* 'Content-Type': 'application/json',
|
|
135
|
+
* ...getNodeUserAgentHeader(),
|
|
136
|
+
* }
|
|
137
|
+
* ```
|
|
138
|
+
*/ const getNodeUserAgentHeader = ()=>isNodeEnvironment() ? {
|
|
139
|
+
'User-Agent': getUserAgent()
|
|
140
|
+
} : {};
|
|
85
141
|
/**
|
|
86
142
|
* Detect the runtime environment and return a shortened identifier.
|
|
87
143
|
*
|
|
@@ -9282,13 +9338,12 @@ const swapTokenEnumSchema = z.enum([
|
|
|
9282
9338
|
headers: {
|
|
9283
9339
|
...DEFAULT_CONFIG$3.headers,
|
|
9284
9340
|
...config.headers ?? {},
|
|
9285
|
-
//
|
|
9286
|
-
//
|
|
9287
|
-
|
|
9288
|
-
|
|
9289
|
-
|
|
9290
|
-
|
|
9291
|
-
}
|
|
9341
|
+
// Browsers forbid setting a user-agent request header, and the custom
|
|
9342
|
+
// fallback header the SDK used instead trips CORS preflight against the
|
|
9343
|
+
// Circle APIs (it isn't in their `Access-Control-Allow-Headers`),
|
|
9344
|
+
// blocking the request. So send the SDK user agent only in Node;
|
|
9345
|
+
// browsers omit it entirely.
|
|
9346
|
+
...getNodeUserAgentHeader()
|
|
9292
9347
|
}
|
|
9293
9348
|
};
|
|
9294
9349
|
let lastError;
|
|
@@ -11219,6 +11274,7 @@ function resolveOptions(options) {
|
|
|
11219
11274
|
if (payload.tokenIn !== undefined) safe['tokenIn'] = payload.tokenIn;
|
|
11220
11275
|
if (payload.tokenOut !== undefined) safe['tokenOut'] = payload.tokenOut;
|
|
11221
11276
|
if (payload.txHash !== undefined) safe['txHash'] = payload.txHash;
|
|
11277
|
+
if (payload.correlationId !== undefined) safe['correlationId'] = payload.correlationId;
|
|
11222
11278
|
if (payload.errorDetails !== undefined) {
|
|
11223
11279
|
const errorDetails = {
|
|
11224
11280
|
...payload.errorDetails.errorCode !== undefined && {
|
|
@@ -11289,18 +11345,15 @@ function resolveOptions(options) {
|
|
|
11289
11345
|
timeoutHandle.unref();
|
|
11290
11346
|
}
|
|
11291
11347
|
try {
|
|
11292
|
-
const isNode = isNodeEnvironment();
|
|
11293
|
-
const userAgent = getUserAgent();
|
|
11294
11348
|
await fetch(getLogsUrl(), {
|
|
11295
11349
|
method: 'POST',
|
|
11296
11350
|
headers: {
|
|
11297
11351
|
'Content-Type': 'application/json',
|
|
11298
|
-
//
|
|
11299
|
-
|
|
11300
|
-
|
|
11301
|
-
|
|
11302
|
-
|
|
11303
|
-
}
|
|
11352
|
+
// Browsers forbid setting a user-agent request header, and the custom
|
|
11353
|
+
// fallback header the SDK used instead trips CORS preflight (it isn't
|
|
11354
|
+
// in the telemetry endpoint's `Access-Control-Allow-Headers`), so send
|
|
11355
|
+
// it only in Node; browsers omit it entirely.
|
|
11356
|
+
...getNodeUserAgentHeader()
|
|
11304
11357
|
},
|
|
11305
11358
|
body: JSON.stringify(toSafePayload(payload)),
|
|
11306
11359
|
signal: controller.signal
|
|
@@ -11513,7 +11566,7 @@ function resolveOptions(options) {
|
|
|
11513
11566
|
// discards the stack trace, nested `cause`, and any custom Error
|
|
11514
11567
|
// properties — exactly the context an on-call needs when a
|
|
11515
11568
|
// resolver-closure regression triggers this path.
|
|
11516
|
-
console.warn(`[stablecoin-kits telemetry] dropped
|
|
11569
|
+
console.warn(`[stablecoin-kits telemetry] dropped event '${eventType}':`, cause);
|
|
11517
11570
|
} catch {
|
|
11518
11571
|
// console.warn itself throwing is the user's environment; nothing more we
|
|
11519
11572
|
// can do without risking the original operation error.
|
|
@@ -11529,7 +11582,9 @@ function resolveOptions(options) {
|
|
|
11529
11582
|
sdkVersion: config.sdkVersion,
|
|
11530
11583
|
eventType,
|
|
11531
11584
|
timestamp: new Date().toISOString(),
|
|
11532
|
-
errorDetails
|
|
11585
|
+
...errorDetails !== undefined && {
|
|
11586
|
+
errorDetails
|
|
11587
|
+
},
|
|
11533
11588
|
clientContext: buildClientContext(),
|
|
11534
11589
|
...context?.sourceChain != null && {
|
|
11535
11590
|
sourceChain: context.sourceChain
|
|
@@ -11545,9 +11600,45 @@ function resolveOptions(options) {
|
|
|
11545
11600
|
},
|
|
11546
11601
|
...context?.txHash != null && {
|
|
11547
11602
|
txHash: context.txHash
|
|
11603
|
+
},
|
|
11604
|
+
...context?.correlationId != null && {
|
|
11605
|
+
correlationId: context.correlationId
|
|
11548
11606
|
}
|
|
11549
11607
|
};
|
|
11550
11608
|
}
|
|
11609
|
+
/**
|
|
11610
|
+
* Emit telemetry for a completed operation without affecting its caller.
|
|
11611
|
+
*
|
|
11612
|
+
* No-ops when `config.disabled` is `true`. Like {@link withErrorTelemetry},
|
|
11613
|
+
* failures while constructing or submitting the telemetry payload are reported
|
|
11614
|
+
* as a soft warning and never change a completed operation's result.
|
|
11615
|
+
*
|
|
11616
|
+
* @param eventType - The telemetry event type for the completed operation.
|
|
11617
|
+
* @param config - Per-kit SDK identity and disabled flag.
|
|
11618
|
+
* @param context - Optional chain, token, and transaction context.
|
|
11619
|
+
* @returns Nothing.
|
|
11620
|
+
* @throws Never — telemetry failures are reported as warnings.
|
|
11621
|
+
*
|
|
11622
|
+
* @example
|
|
11623
|
+
* ```typescript
|
|
11624
|
+
* import { emitSuccessTelemetry } from '@core/utils'
|
|
11625
|
+
*
|
|
11626
|
+
* emitSuccessTelemetry(
|
|
11627
|
+
* 'bridge_bridge',
|
|
11628
|
+
* { sdkName: 'bridge-kit', sdkVersion: '1.0.0', disabled: false },
|
|
11629
|
+
* { sourceChain: 'Ethereum', destinationChain: 'Base', tokenIn: 'USDC' },
|
|
11630
|
+
* )
|
|
11631
|
+
* ```
|
|
11632
|
+
*/ function emitSuccessTelemetry(eventType, config, context) {
|
|
11633
|
+
if (config.disabled) {
|
|
11634
|
+
return;
|
|
11635
|
+
}
|
|
11636
|
+
try {
|
|
11637
|
+
void emitAnalyticsLog(buildPayload$1(config, eventType, undefined, context));
|
|
11638
|
+
} catch (telemetryError) {
|
|
11639
|
+
warnTelemetryDrop(eventType, telemetryError);
|
|
11640
|
+
}
|
|
11641
|
+
}
|
|
11551
11642
|
/**
|
|
11552
11643
|
* Wrap an async operation with error telemetry.
|
|
11553
11644
|
*
|
|
@@ -11658,7 +11749,7 @@ function resolveOptions(options) {
|
|
|
11658
11749
|
}
|
|
11659
11750
|
|
|
11660
11751
|
var name$4 = "@circle-fin/bridge-kit";
|
|
11661
|
-
var version$5 = "1.12.
|
|
11752
|
+
var version$5 = "1.12.2";
|
|
11662
11753
|
var pkg$5 = {
|
|
11663
11754
|
name: name$4,
|
|
11664
11755
|
version: version$5};
|
|
@@ -14294,7 +14385,13 @@ const FAST_TIER_FINALITY_THRESHOLD = 1000;
|
|
|
14294
14385
|
/**
|
|
14295
14386
|
* The ASCII "cctp-forward" magic, hex-encoded (no `0x`), that a forward-friendly
|
|
14296
14387
|
* hookData must start with.
|
|
14297
|
-
|
|
14388
|
+
*
|
|
14389
|
+
* Encoded with `TextEncoder` (a browser-safe Web API) rather than `Buffer.from`
|
|
14390
|
+
* so this module-level constant does not reference the Node `Buffer` global at
|
|
14391
|
+
* import time. App Kit inlines this provider into its bundle without a Buffer polyfill, and a
|
|
14392
|
+
* bare `Buffer` here crashes browser bundles (e.g. Vite) on load — even for apps
|
|
14393
|
+
* that never touch the prepaid FORWARD path. Mirrors `buildForwardingHookData`.
|
|
14394
|
+
*/ const CCTP_FORWARD_MAGIC_HEX = Array.from(new TextEncoder().encode(CCTP_FORWARD_MAGIC_PREFIX)).map((byte)=>byte.toString(16).padStart(2, '0')).join('');
|
|
14298
14395
|
/**
|
|
14299
14396
|
* Determine whether a hookData blob begins with the `cctp-forward` envelope.
|
|
14300
14397
|
*
|
|
@@ -16732,7 +16829,7 @@ const mockAttestationMessage = {
|
|
|
16732
16829
|
return step;
|
|
16733
16830
|
}
|
|
16734
16831
|
|
|
16735
|
-
var version$4 = "1.10.
|
|
16832
|
+
var version$4 = "1.10.1";
|
|
16736
16833
|
var pkg$4 = {
|
|
16737
16834
|
version: version$4};
|
|
16738
16835
|
|
|
@@ -18611,7 +18708,7 @@ function assertCCTPV2Config(config) {
|
|
|
18611
18708
|
]
|
|
18612
18709
|
];
|
|
18613
18710
|
|
|
18614
|
-
/** SDK name used in telemetry payloads. */ const SDK_NAME$
|
|
18711
|
+
/** SDK name used in telemetry payloads. */ const SDK_NAME$3 = resolveKitSdkName(pkg$5.name);
|
|
18615
18712
|
/**
|
|
18616
18713
|
* Pick the most-relevant `txHash` to attach to an error telemetry payload.
|
|
18617
18714
|
*
|
|
@@ -18753,7 +18850,7 @@ function assertCCTPV2Config(config) {
|
|
|
18753
18850
|
this.actionDispatcher = new Actionable();
|
|
18754
18851
|
this.disableErrorReporting = config.disableErrorReporting === true;
|
|
18755
18852
|
this.telemetryConfig = {
|
|
18756
|
-
sdkName: SDK_NAME$
|
|
18853
|
+
sdkName: SDK_NAME$3,
|
|
18757
18854
|
sdkVersion: pkg$5.version,
|
|
18758
18855
|
disabled: this.disableErrorReporting
|
|
18759
18856
|
};
|
|
@@ -19346,7 +19443,7 @@ registerKit(`${pkg$5.name}/${pkg$5.version}`);
|
|
|
19346
19443
|
};
|
|
19347
19444
|
|
|
19348
19445
|
var name$3 = "@circle-fin/swap-kit";
|
|
19349
|
-
var version$3 = "1.
|
|
19446
|
+
var version$3 = "1.5.0";
|
|
19350
19447
|
var pkg$3 = {
|
|
19351
19448
|
name: name$3,
|
|
19352
19449
|
version: version$3};
|
|
@@ -20179,6 +20276,16 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
|
|
|
20179
20276
|
required_error: 'estimatedAmount is required',
|
|
20180
20277
|
invalid_type_error: 'estimatedAmount must be a string'
|
|
20181
20278
|
}).min(1, 'estimatedAmount must be a non-empty string'),
|
|
20279
|
+
// Per-swap join key echoed back verbatim on success telemetry. Optional so a
|
|
20280
|
+
// not-yet-upgraded service (no field) still validates during rollout. A
|
|
20281
|
+
// malformed/non-UUID value is coerced to `undefined` (no telemetry id) rather
|
|
20282
|
+
// than throwing: this is a telemetry-only field (stripped from the developer
|
|
20283
|
+
// result, never used for control flow), so it must not be able to abort the
|
|
20284
|
+
// swap via `parseCreateSwapResponse().parse()`. Mirrors the best-effort,
|
|
20285
|
+
// never-throw contract of the rest of the telemetry stack. Implemented with
|
|
20286
|
+
// `preprocess` rather than Zod's `.catch()` because static analysis misreads
|
|
20287
|
+
// `.catch` on the schema chain as an unhandled Promise (S7785).
|
|
20288
|
+
correlationId: z.preprocess((value)=>z.string().uuid().safeParse(value).success ? value : undefined, z.string().optional()),
|
|
20182
20289
|
config: createSwapRequestBaseSchema.shape.config.optional(),
|
|
20183
20290
|
fees: createSwapFeesSchema.optional(),
|
|
20184
20291
|
transaction: createSwapTransactionSchema
|
|
@@ -20304,6 +20411,45 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
|
|
|
20304
20411
|
// Validate without trimming - any whitespace will cause validation to fail
|
|
20305
20412
|
return apiKeyPattern.test(apiKey);
|
|
20306
20413
|
};
|
|
20414
|
+
/**
|
|
20415
|
+
* Assert that a Stablecoin Service kit key is not being supplied from a browser.
|
|
20416
|
+
*
|
|
20417
|
+
* The kit key (`KIT_KEY:<id>:<secret>`) is a server-only secret. Every
|
|
20418
|
+
* Stablecoin Service request that attaches an `Authorization: Bearer` header
|
|
20419
|
+
* funnels through this package, so calling this guard before that header is
|
|
20420
|
+
* built prevents the secret from being sent from — and thus bundled into — a
|
|
20421
|
+
* client application. In Node.js the check is a no-op, preserving the
|
|
20422
|
+
* legitimate "hold the kit key on the server, forward the prepared transaction
|
|
20423
|
+
* to the client" flow. When no kit key is supplied the permissionless (keyless)
|
|
20424
|
+
* client path remains fully allowed.
|
|
20425
|
+
*
|
|
20426
|
+
* @param apiKey - The inline kit key for the request, or `undefined` when none
|
|
20427
|
+
* was supplied (permissionless mode).
|
|
20428
|
+
* @returns Nothing.
|
|
20429
|
+
* @throws KitError with VALIDATION_FAILED when a kit key is supplied while
|
|
20430
|
+
* running in a browser environment. The secret value is never echoed.
|
|
20431
|
+
*
|
|
20432
|
+
* @example
|
|
20433
|
+
* ```typescript
|
|
20434
|
+
* import { assertBrowserSafeApiKey } from '@core/service-client'
|
|
20435
|
+
*
|
|
20436
|
+
* // Server (Node.js): no-op, request proceeds with the Authorization header.
|
|
20437
|
+
* assertBrowserSafeApiKey('KIT_KEY:my-id:my-secret')
|
|
20438
|
+
*
|
|
20439
|
+
* // Browser: throws to stop the secret from leaking into the client bundle.
|
|
20440
|
+
* assertBrowserSafeApiKey('KIT_KEY:my-id:my-secret')
|
|
20441
|
+
*
|
|
20442
|
+
* // Browser, permissionless: allowed.
|
|
20443
|
+
* assertBrowserSafeApiKey(undefined)
|
|
20444
|
+
* ```
|
|
20445
|
+
*/ const assertBrowserSafeApiKey = (apiKey)=>{
|
|
20446
|
+
if (apiKey === undefined) {
|
|
20447
|
+
return;
|
|
20448
|
+
}
|
|
20449
|
+
if (isBrowserEnvironment()) {
|
|
20450
|
+
throw createValidationFailedError$1('kitKey', '[redacted]', 'kitKey must not be provided in a browser environment — it is a server-only secret. Run kit operations that use a kit key on your server, or omit kitKey to use the permissionless (keyless) client path');
|
|
20451
|
+
}
|
|
20452
|
+
};
|
|
20307
20453
|
|
|
20308
20454
|
/**
|
|
20309
20455
|
* Create a cross-chain bridge and swap transaction through the Stablecoin Service.
|
|
@@ -20361,6 +20507,8 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
|
|
|
20361
20507
|
const url = new URL('/v1/stablecoinKits/swap', STABLECOIN_SERVICE_BASE_URL).toString();
|
|
20362
20508
|
// Remove the API key from the request body
|
|
20363
20509
|
const { apiKey, ...requestBody } = validatedParams;
|
|
20510
|
+
// Never let a server-only kit key leave a browser (no-op in Node.js).
|
|
20511
|
+
assertBrowserSafeApiKey(apiKey);
|
|
20364
20512
|
const effectiveConfig = {
|
|
20365
20513
|
...DEFAULT_CONFIG$1,
|
|
20366
20514
|
headers: {
|
|
@@ -20515,6 +20663,8 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
|
|
|
20515
20663
|
}
|
|
20516
20664
|
// Use validated data
|
|
20517
20665
|
const validatedParams = result.data;
|
|
20666
|
+
// Never let a server-only kit key leave a browser (no-op in Node.js).
|
|
20667
|
+
assertBrowserSafeApiKey(validatedParams.apiKey);
|
|
20518
20668
|
// Build the API URL
|
|
20519
20669
|
const url = buildQuoteUrl(validatedParams);
|
|
20520
20670
|
// Merge default config with Authorization header
|
|
@@ -20587,6 +20737,8 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
|
|
|
20587
20737
|
toChain: result.data.toChain
|
|
20588
20738
|
}
|
|
20589
20739
|
};
|
|
20740
|
+
// Never let a server-only kit key leave a browser (no-op in Node.js).
|
|
20741
|
+
assertBrowserSafeApiKey(validatedParams.apiKey);
|
|
20590
20742
|
const url = buildSwapStatusUrl(validatedParams);
|
|
20591
20743
|
const effectiveConfig = {
|
|
20592
20744
|
...DEFAULT_CONFIG$1,
|
|
@@ -20691,6 +20843,8 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
|
|
|
20691
20843
|
addresses: result.data.addresses
|
|
20692
20844
|
}
|
|
20693
20845
|
};
|
|
20846
|
+
// Never let a server-only kit key leave a browser (no-op in Node.js).
|
|
20847
|
+
assertBrowserSafeApiKey(validatedParams.apiKey);
|
|
20694
20848
|
const url = buildTokenRatesUrl(validatedParams);
|
|
20695
20849
|
const effectiveConfig = {
|
|
20696
20850
|
...DEFAULT_CONFIG$1,
|
|
@@ -27462,6 +27616,11 @@ async function fetchSameChainStatusSnapshot({ isCrossChainSwap, txHash, chain, a
|
|
|
27462
27616
|
apiKey: serviceParams.apiKey
|
|
27463
27617
|
}
|
|
27464
27618
|
});
|
|
27619
|
+
// Per-swap correlation id returned by the service as a top-level response
|
|
27620
|
+
// field for every chain (EVM + Solana). Attached to success telemetry so a
|
|
27621
|
+
// swap can be correlated across records; never used for control flow.
|
|
27622
|
+
// Undefined only against a not-yet-upgraded service that omits it.
|
|
27623
|
+
const correlationId = serviceResponse.correlationId;
|
|
27465
27624
|
// Build and return SwapResult
|
|
27466
27625
|
return {
|
|
27467
27626
|
tokenIn,
|
|
@@ -27471,6 +27630,9 @@ async function fetchSameChainStatusSnapshot({ isCrossChainSwap, txHash, chain, a
|
|
|
27471
27630
|
fromAddress: serviceParams.fromAddress,
|
|
27472
27631
|
toAddress: serviceParams.toAddress,
|
|
27473
27632
|
txHash,
|
|
27633
|
+
...correlationId !== undefined && {
|
|
27634
|
+
correlationId
|
|
27635
|
+
},
|
|
27474
27636
|
executedTransactions,
|
|
27475
27637
|
...config !== undefined && {
|
|
27476
27638
|
config
|
|
@@ -30370,7 +30532,13 @@ async function resolveTokenDecimals(context, resolvedParams) {
|
|
|
30370
30532
|
* amountIn: '50.00'
|
|
30371
30533
|
* })
|
|
30372
30534
|
* ```
|
|
30373
|
-
*/ async function swap$1(context, params, /**
|
|
30535
|
+
*/ async function swap$1(context, params, /**
|
|
30536
|
+
* @internal
|
|
30537
|
+
* Invoked after a successful broadcast with the on-chain `txHash` and the
|
|
30538
|
+
* service-issued `correlationId` (join key for success telemetry). The
|
|
30539
|
+
* service returns `correlationId` for every chain (EVM + Solana); it is
|
|
30540
|
+
* undefined only against a not-yet-upgraded service that omits the field.
|
|
30541
|
+
*/ onBroadcast) {
|
|
30374
30542
|
// Step 1: Validate parameters using schema
|
|
30375
30543
|
assertSwapParams(params, swapParamsSchema);
|
|
30376
30544
|
// Step 2: Resolve parameters (chain definitions, wallet addresses, token aliases preserved)
|
|
@@ -30390,13 +30558,16 @@ async function resolveTokenDecimals(context, resolvedParams) {
|
|
|
30390
30558
|
// Step 5: Execute swap via provider
|
|
30391
30559
|
const swapParams = buildServiceSwapParams(resolvedParams, paramsWithFees);
|
|
30392
30560
|
const providerResult = await provider.swap(swapParams);
|
|
30561
|
+
// `correlationId` is an internal telemetry join key, not part of the public
|
|
30562
|
+
// SwapResult — strip it here so it never leaks into the formatted result.
|
|
30563
|
+
const { correlationId, ...providerResultPublic } = providerResult;
|
|
30393
30564
|
// A throwing `onBroadcast` must never strand the caller after a
|
|
30394
30565
|
// successful swap broadcast — the chain has moved. `safeInvokeCallback`
|
|
30395
30566
|
// swallows the error and surfaces a `console.warn` prefixed with
|
|
30396
30567
|
// `[stablecoin-kits swap-kit] callback threw and was swallowed:` so a
|
|
30397
30568
|
// kit-side closure bug stays debuggable rather than vanishing.
|
|
30398
30569
|
safeInvokeCallback('swap-kit', ()=>{
|
|
30399
|
-
onBroadcast?.(
|
|
30570
|
+
onBroadcast?.(providerResultPublic.txHash, correlationId);
|
|
30400
30571
|
});
|
|
30401
30572
|
const { tokenInDecimals, tokenOutDecimals } = await resolveTokenDecimals(context, resolvedParams);
|
|
30402
30573
|
// Step 6: Compose chain identity (owned by the kit, derived from the
|
|
@@ -30405,10 +30576,10 @@ async function resolveTokenDecimals(context, resolvedParams) {
|
|
|
30405
30576
|
// resolves `progress` — the provider's snapshot, or a terminal `'DONE'` for
|
|
30406
30577
|
// a provider that omits it (a synchronous same-chain completion).
|
|
30407
30578
|
const composedResult = {
|
|
30408
|
-
...
|
|
30579
|
+
...providerResultPublic,
|
|
30409
30580
|
chainIn: resolvedParams.from.chain,
|
|
30410
30581
|
chainOut: resolvedParams.toChain ?? resolvedParams.from.chain,
|
|
30411
|
-
progress:
|
|
30582
|
+
progress: providerResultPublic.progress ?? {
|
|
30412
30583
|
status: 'DONE'
|
|
30413
30584
|
}
|
|
30414
30585
|
};
|
|
@@ -31189,7 +31360,7 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
|
|
|
31189
31360
|
ESTIMATE: 'swap_estimate'
|
|
31190
31361
|
};
|
|
31191
31362
|
|
|
31192
|
-
/** SDK name used in telemetry payloads. */ const SDK_NAME$
|
|
31363
|
+
/** SDK name used in telemetry payloads. */ const SDK_NAME$2 = resolveKitSdkName(pkg$3.name);
|
|
31193
31364
|
/**
|
|
31194
31365
|
* A high-level class-based interface for same-chain and cross-chain token swap operations.
|
|
31195
31366
|
*
|
|
@@ -31261,7 +31432,13 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
|
|
|
31261
31432
|
*/ class SwapKit {
|
|
31262
31433
|
context;
|
|
31263
31434
|
/** Whether error telemetry is disabled. */ disableErrorReporting;
|
|
31264
|
-
/** Per-kit telemetry identity for
|
|
31435
|
+
/** Per-kit telemetry identity for error reporting. */ telemetryConfig;
|
|
31436
|
+
/**
|
|
31437
|
+
* Per-kit telemetry identity for success/analytics events. Gated by
|
|
31438
|
+
* `disableAnalytics` (independent of `disableErrorReporting`) so a developer
|
|
31439
|
+
* can opt out of volume analytics without also silencing error reports —
|
|
31440
|
+
* mirrors EarnKit.
|
|
31441
|
+
*/ analyticsTelemetryConfig;
|
|
31265
31442
|
/**
|
|
31266
31443
|
* Create a new SwapKit instance.
|
|
31267
31444
|
*
|
|
@@ -31311,10 +31488,15 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
|
|
|
31311
31488
|
this.context = createSwapKitContext(config);
|
|
31312
31489
|
this.disableErrorReporting = config.disableErrorReporting === true;
|
|
31313
31490
|
this.telemetryConfig = {
|
|
31314
|
-
sdkName: SDK_NAME$
|
|
31491
|
+
sdkName: SDK_NAME$2,
|
|
31315
31492
|
sdkVersion: pkg$3.version,
|
|
31316
31493
|
disabled: this.disableErrorReporting
|
|
31317
31494
|
};
|
|
31495
|
+
this.analyticsTelemetryConfig = {
|
|
31496
|
+
sdkName: SDK_NAME$2,
|
|
31497
|
+
sdkVersion: pkg$3.version,
|
|
31498
|
+
disabled: config.disableAnalytics === true
|
|
31499
|
+
};
|
|
31318
31500
|
}
|
|
31319
31501
|
/**
|
|
31320
31502
|
* Estimate the output amount and fees for a swap operation.
|
|
@@ -31355,8 +31537,12 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
|
|
|
31355
31537
|
* console.log(`Fees:`, quote.fees)
|
|
31356
31538
|
* ```
|
|
31357
31539
|
*/ async estimate(params) {
|
|
31540
|
+
const destinationChain = params.to?.chain ? resolveChainName(params.to.chain) : undefined;
|
|
31358
31541
|
return withErrorTelemetry(async ()=>estimate(this.context, params), SWAP_EVENT_TYPES.ESTIMATE, this.telemetryConfig, {
|
|
31359
31542
|
sourceChain: resolveChainName(params.from.chain),
|
|
31543
|
+
...destinationChain != null && {
|
|
31544
|
+
destinationChain
|
|
31545
|
+
},
|
|
31360
31546
|
tokenIn: params.tokenIn,
|
|
31361
31547
|
tokenOut: params.tokenOut
|
|
31362
31548
|
});
|
|
@@ -31415,16 +31601,54 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
|
|
|
31415
31601
|
* ```
|
|
31416
31602
|
*/ async swap(params) {
|
|
31417
31603
|
let txHash;
|
|
31418
|
-
|
|
31419
|
-
|
|
31420
|
-
|
|
31604
|
+
let correlationId;
|
|
31605
|
+
// Shared context builder so the error resolver and the success emit stay in
|
|
31606
|
+
// lockstep — a field added here reaches both call sites. Reads the per-call
|
|
31607
|
+
// locals lazily, so txHash/correlationId (set during the swap) are captured
|
|
31608
|
+
// whenever it is invoked.
|
|
31609
|
+
// Destination chain is the primary attribution dimension for cross-chain
|
|
31610
|
+
// swaps; resolved once from the (static) params. Omitted for same-chain
|
|
31611
|
+
// swaps that leave `to.chain` unset (destination == source).
|
|
31612
|
+
const destinationChain = params.to?.chain ? resolveChainName(params.to.chain) : undefined;
|
|
31613
|
+
const buildTelemetryContext = ()=>({
|
|
31421
31614
|
sourceChain: resolveChainName(params.from.chain),
|
|
31615
|
+
...destinationChain != null && {
|
|
31616
|
+
destinationChain
|
|
31617
|
+
},
|
|
31422
31618
|
tokenIn: params.tokenIn,
|
|
31423
31619
|
tokenOut: params.tokenOut,
|
|
31424
31620
|
...txHash != null && {
|
|
31425
31621
|
txHash
|
|
31622
|
+
},
|
|
31623
|
+
...correlationId != null && {
|
|
31624
|
+
correlationId
|
|
31426
31625
|
}
|
|
31427
|
-
})
|
|
31626
|
+
});
|
|
31627
|
+
const result = await withErrorTelemetry(async ()=>swap$1(this.context, params, (h, cId)=>{
|
|
31628
|
+
txHash = h;
|
|
31629
|
+
correlationId = cId;
|
|
31630
|
+
}), SWAP_EVENT_TYPES.SWAP, this.telemetryConfig, buildTelemetryContext);
|
|
31631
|
+
// withErrorTelemetry only emits on failure. Record the successful swap here
|
|
31632
|
+
// so the backend can attribute swap volume to a developer: the client event
|
|
31633
|
+
// carries the (burn) txHash + correlationId, which joins to the
|
|
31634
|
+
// server-emitted event carrying entity_id. Best-effort; never throws.
|
|
31635
|
+
//
|
|
31636
|
+
// Emit whenever a broadcast happened, i.e. we have the source/burn txHash.
|
|
31637
|
+
// For a cross-chain swap that is the source-chain burn (progress is still
|
|
31638
|
+
// PENDING while the destination mint settles) — we intentionally attribute
|
|
31639
|
+
// at broadcast using the burn txHash rather than tracking the destination
|
|
31640
|
+
// leg, which keeps the capture simple and self-contained in swap().
|
|
31641
|
+
//
|
|
31642
|
+
// Guard against a terminal-failure result: the EVM provider throws on
|
|
31643
|
+
// revert today, but the kit is provider-agnostic, so a provider that
|
|
31644
|
+
// returns a FAILED/NOT_FOUND result without throwing must not be recorded
|
|
31645
|
+
// as a successful swap. Routed through analyticsTelemetryConfig so it is
|
|
31646
|
+
// gated by disableAnalytics, independent of error reporting.
|
|
31647
|
+
const status = result.progress?.status;
|
|
31648
|
+
if (txHash != null && status !== 'FAILED' && status !== 'NOT_FOUND') {
|
|
31649
|
+
emitSuccessTelemetry(SWAP_EVENT_TYPES.SWAP, this.analyticsTelemetryConfig, buildTelemetryContext());
|
|
31650
|
+
}
|
|
31651
|
+
return result;
|
|
31428
31652
|
}
|
|
31429
31653
|
/**
|
|
31430
31654
|
* Fetch the current status of a swap from the Stablecoin Service.
|
|
@@ -31803,6 +32027,9 @@ registerKit(`${pkg$3.name}/${pkg$3.version}`);
|
|
|
31803
32027
|
const kit = new SwapKit({
|
|
31804
32028
|
...context.disableErrorReporting != null && {
|
|
31805
32029
|
disableErrorReporting: context.disableErrorReporting
|
|
32030
|
+
},
|
|
32031
|
+
...context.disableAnalytics != null && {
|
|
32032
|
+
disableAnalytics: context.disableAnalytics
|
|
31806
32033
|
}
|
|
31807
32034
|
});
|
|
31808
32035
|
if (hasBoth) {
|
|
@@ -31864,7 +32091,7 @@ registerKit(`${pkg$3.name}/${pkg$3.version}`);
|
|
|
31864
32091
|
};
|
|
31865
32092
|
|
|
31866
32093
|
var name$2 = "@circle-fin/earn-kit";
|
|
31867
|
-
var version$2 = "1.
|
|
32094
|
+
var version$2 = "1.4.0";
|
|
31868
32095
|
var pkg$2 = {
|
|
31869
32096
|
name: name$2,
|
|
31870
32097
|
version: version$2};
|
|
@@ -33863,7 +34090,7 @@ const bridgeDepositPrepareReviewSchema = z.object({
|
|
|
33863
34090
|
}
|
|
33864
34091
|
|
|
33865
34092
|
var name$1 = "@circle-fin/provider-earn-service";
|
|
33866
|
-
var version$1 = "1.3.
|
|
34093
|
+
var version$1 = "1.3.1";
|
|
33867
34094
|
var pkg$1 = {
|
|
33868
34095
|
name: name$1,
|
|
33869
34096
|
version: version$1};
|
|
@@ -33925,15 +34152,25 @@ var pkg$1 = {
|
|
|
33925
34152
|
*
|
|
33926
34153
|
* @internal
|
|
33927
34154
|
*/ function buildConfig(serviceConfig) {
|
|
34155
|
+
// The kit key is a server-only secret. Reject it in the browser so it cannot
|
|
34156
|
+
// leak into a client bundle (no-op in Node.js). Keyless usage stays allowed.
|
|
34157
|
+
if (serviceConfig?.kitKey !== undefined && isBrowserEnvironment()) {
|
|
34158
|
+
throw createValidationFailedError$1('kitKey', '[redacted]', 'kitKey must not be provided in a browser environment — it is a server-only secret. Run EarnKit operations that use a kit key on your server, or omit kitKey to use the permissionless (keyless) client path');
|
|
34159
|
+
}
|
|
33928
34160
|
const baseUrl = serviceConfig?.baseUrl ?? EARN_SERVICE_BASE_URL;
|
|
33929
|
-
|
|
34161
|
+
// The API CORS policy does not allow this custom header. Keep the existing
|
|
34162
|
+
// per-request version attribution for Node callers, but omit it in browsers
|
|
34163
|
+
// so public EarnKit endpoints do not fail at CORS preflight.
|
|
34164
|
+
const sdkVersionHeader = isNodeEnvironment() ? {
|
|
34165
|
+
[SDK_VERSION_HEADER]: resolveSdkVersionHeader()
|
|
34166
|
+
} : {};
|
|
33930
34167
|
if (serviceConfig?.kitKey === undefined) {
|
|
33931
34168
|
return {
|
|
33932
34169
|
pollingConfig: {
|
|
33933
34170
|
...DEFAULT_CONFIG,
|
|
33934
34171
|
headers: {
|
|
33935
34172
|
...DEFAULT_CONFIG.headers,
|
|
33936
|
-
|
|
34173
|
+
...sdkVersionHeader
|
|
33937
34174
|
}
|
|
33938
34175
|
},
|
|
33939
34176
|
baseUrl
|
|
@@ -33951,7 +34188,7 @@ var pkg$1 = {
|
|
|
33951
34188
|
...DEFAULT_CONFIG,
|
|
33952
34189
|
headers: {
|
|
33953
34190
|
...DEFAULT_CONFIG.headers,
|
|
33954
|
-
|
|
34191
|
+
...sdkVersionHeader,
|
|
33955
34192
|
Authorization: `Bearer ${serviceConfig.kitKey}`
|
|
33956
34193
|
}
|
|
33957
34194
|
},
|
|
@@ -36065,6 +36302,12 @@ function createUnsupportedCrossChainDepositError(chain, reason) {
|
|
|
36065
36302
|
if (config.providers !== undefined && !Array.isArray(config.providers)) {
|
|
36066
36303
|
throw createValidationFailedError$1('config.providers', config.providers, 'providers must be an array of earn providers when provided');
|
|
36067
36304
|
}
|
|
36305
|
+
if (config.disableAnalytics !== undefined && typeof config.disableAnalytics !== 'boolean') {
|
|
36306
|
+
throw createValidationFailedError$1('config.disableAnalytics', config.disableAnalytics, 'disableAnalytics must be a boolean when provided');
|
|
36307
|
+
}
|
|
36308
|
+
if (config.disableErrorReporting !== undefined && typeof config.disableErrorReporting !== 'boolean') {
|
|
36309
|
+
throw createValidationFailedError$1('config.disableErrorReporting', config.disableErrorReporting, 'disableErrorReporting must be a boolean when provided');
|
|
36310
|
+
}
|
|
36068
36311
|
const defaultProviders = getDefaultProviders$1();
|
|
36069
36312
|
const providers = [
|
|
36070
36313
|
...config.providers ?? [],
|
|
@@ -36076,6 +36319,31 @@ function createUnsupportedCrossChainDepositError(chain, reason) {
|
|
|
36076
36319
|
return context;
|
|
36077
36320
|
}
|
|
36078
36321
|
|
|
36322
|
+
/**
|
|
36323
|
+
* Register Earn Kit telemetry event type strings with the shared registry so
|
|
36324
|
+
* error telemetry helpers remain compile-time checked.
|
|
36325
|
+
*
|
|
36326
|
+
* @internal
|
|
36327
|
+
*/ /**
|
|
36328
|
+
* Telemetry event type identifiers for Earn Kit operations.
|
|
36329
|
+
*
|
|
36330
|
+
* @internal
|
|
36331
|
+
*/ const EARN_EVENT_TYPES = {
|
|
36332
|
+
GET_VAULTS: 'earn_get_vaults',
|
|
36333
|
+
EXPLORE_VAULTS: 'earn_explore_vaults',
|
|
36334
|
+
GET_POSITION: 'earn_get_position',
|
|
36335
|
+
GET_CROSS_CHAIN_DEPOSIT_STATUS: 'earn_get_cross_chain_deposit_status',
|
|
36336
|
+
WAIT_FOR_CROSS_CHAIN_DEPOSIT: 'earn_wait_for_cross_chain_deposit',
|
|
36337
|
+
DEPOSIT: 'earn_deposit',
|
|
36338
|
+
CROSS_CHAIN_DEPOSIT: 'earn_cross_chain_deposit',
|
|
36339
|
+
WITHDRAW: 'earn_withdraw',
|
|
36340
|
+
CLAIM_REWARDS: 'earn_claim_rewards',
|
|
36341
|
+
GET_DEPOSIT_QUOTE: 'earn_get_deposit_quote',
|
|
36342
|
+
GET_WITHDRAWAL_QUOTE: 'earn_get_withdrawal_quote',
|
|
36343
|
+
GET_CLAIM_REWARDS_QUOTE: 'earn_get_claim_rewards_quote',
|
|
36344
|
+
RETRY: 'earn_retry'
|
|
36345
|
+
};
|
|
36346
|
+
|
|
36079
36347
|
/**
|
|
36080
36348
|
* Format a provider amount object as a human-readable decimal string.
|
|
36081
36349
|
*
|
|
@@ -37591,6 +37859,14 @@ function hasCrossChainDestination(params) {
|
|
|
37591
37859
|
return formatClaimRewardsQuoteInfo(result);
|
|
37592
37860
|
}
|
|
37593
37861
|
|
|
37862
|
+
/** SDK name used in telemetry payloads. */ const SDK_NAME$1 = resolveKitSdkName(pkg$2.name);
|
|
37863
|
+
/**
|
|
37864
|
+
* Determine whether deposit parameters target a destination chain.
|
|
37865
|
+
*
|
|
37866
|
+
* @internal
|
|
37867
|
+
*/ function isCrossChainDeposit(params) {
|
|
37868
|
+
return 'to' in params && params.to !== undefined;
|
|
37869
|
+
}
|
|
37594
37870
|
function formatRetryResult(operation, result) {
|
|
37595
37871
|
switch(operation){
|
|
37596
37872
|
case 'deposit':
|
|
@@ -37605,6 +37881,70 @@ function formatRetryResult(operation, result) {
|
|
|
37605
37881
|
}
|
|
37606
37882
|
}
|
|
37607
37883
|
}
|
|
37884
|
+
/**
|
|
37885
|
+
* Emit the success event corresponding to a completed retry.
|
|
37886
|
+
*
|
|
37887
|
+
* @internal
|
|
37888
|
+
*/ function emitRetrySuccessTelemetry(trace, result, config) {
|
|
37889
|
+
switch(trace.operation){
|
|
37890
|
+
case 'deposit':
|
|
37891
|
+
{
|
|
37892
|
+
const sourceChain = resolveChainName(trace.params.from.chain);
|
|
37893
|
+
if ('to' in trace.params && trace.params.to !== undefined) {
|
|
37894
|
+
const destinationChain = resolveChainName(trace.params.to.chain);
|
|
37895
|
+
emitSuccessTelemetry(EARN_EVENT_TYPES.CROSS_CHAIN_DEPOSIT, config, {
|
|
37896
|
+
...sourceChain != null && {
|
|
37897
|
+
sourceChain
|
|
37898
|
+
},
|
|
37899
|
+
...destinationChain != null && {
|
|
37900
|
+
destinationChain
|
|
37901
|
+
}
|
|
37902
|
+
});
|
|
37903
|
+
return;
|
|
37904
|
+
}
|
|
37905
|
+
emitSuccessTelemetry(EARN_EVENT_TYPES.DEPOSIT, config, {
|
|
37906
|
+
...sourceChain != null && {
|
|
37907
|
+
sourceChain
|
|
37908
|
+
},
|
|
37909
|
+
...'txHash' in result && {
|
|
37910
|
+
txHash: result.txHash
|
|
37911
|
+
}
|
|
37912
|
+
});
|
|
37913
|
+
return;
|
|
37914
|
+
}
|
|
37915
|
+
case 'withdraw':
|
|
37916
|
+
{
|
|
37917
|
+
const sourceChain = resolveChainName(trace.params.from.chain);
|
|
37918
|
+
emitSuccessTelemetry(EARN_EVENT_TYPES.WITHDRAW, config, {
|
|
37919
|
+
...sourceChain != null && {
|
|
37920
|
+
sourceChain
|
|
37921
|
+
},
|
|
37922
|
+
...'txHash' in result && {
|
|
37923
|
+
txHash: result.txHash
|
|
37924
|
+
}
|
|
37925
|
+
});
|
|
37926
|
+
return;
|
|
37927
|
+
}
|
|
37928
|
+
case 'claimRewards':
|
|
37929
|
+
{
|
|
37930
|
+
if ('rewards' in result && result.status === 'claimed') {
|
|
37931
|
+
const sourceChain = resolveChainName(trace.params.from.chain);
|
|
37932
|
+
emitSuccessTelemetry(EARN_EVENT_TYPES.CLAIM_REWARDS, config, {
|
|
37933
|
+
...sourceChain != null && {
|
|
37934
|
+
sourceChain
|
|
37935
|
+
},
|
|
37936
|
+
txHash: result.txHash
|
|
37937
|
+
});
|
|
37938
|
+
}
|
|
37939
|
+
return;
|
|
37940
|
+
}
|
|
37941
|
+
default:
|
|
37942
|
+
{
|
|
37943
|
+
const exhaustive = trace;
|
|
37944
|
+
throw createValidationFailedError$1('error.cause.trace', exhaustive, 'EarnKit.retry() does not support this earn operation');
|
|
37945
|
+
}
|
|
37946
|
+
}
|
|
37947
|
+
}
|
|
37608
37948
|
/**
|
|
37609
37949
|
* A high-level class-based interface for DeFi lending vault operations.
|
|
37610
37950
|
*
|
|
@@ -37663,6 +38003,8 @@ function formatRetryResult(operation, result) {
|
|
|
37663
38003
|
* ```
|
|
37664
38004
|
*/ class EarnKit {
|
|
37665
38005
|
context;
|
|
38006
|
+
/** Per-kit identity and opt-out state for error telemetry. */ telemetryConfig;
|
|
38007
|
+
/** Per-kit identity and opt-out state for success telemetry. */ analyticsTelemetryConfig;
|
|
37666
38008
|
/**
|
|
37667
38009
|
* Event dispatcher for step-level events emitted during multi-phase earn
|
|
37668
38010
|
* operations. Prefer {@link EarnKit.on} / {@link EarnKit.off} over using
|
|
@@ -37687,6 +38029,16 @@ function formatRetryResult(operation, result) {
|
|
|
37687
38029
|
*/ constructor(config = {}){
|
|
37688
38030
|
this.context = createEarnKitContext(config);
|
|
37689
38031
|
this.actionDispatcher = new Actionable();
|
|
38032
|
+
this.telemetryConfig = {
|
|
38033
|
+
sdkName: SDK_NAME$1,
|
|
38034
|
+
sdkVersion: pkg$2.version,
|
|
38035
|
+
disabled: config.disableErrorReporting === true
|
|
38036
|
+
};
|
|
38037
|
+
this.analyticsTelemetryConfig = {
|
|
38038
|
+
sdkName: SDK_NAME$1,
|
|
38039
|
+
sdkVersion: pkg$2.version,
|
|
38040
|
+
disabled: config.disableAnalytics === true
|
|
38041
|
+
};
|
|
37690
38042
|
for (const provider of this.context.providers){
|
|
37691
38043
|
provider.registerDispatcher(this.actionDispatcher);
|
|
37692
38044
|
}
|
|
@@ -37747,29 +38099,36 @@ function formatRetryResult(operation, result) {
|
|
|
37747
38099
|
* }
|
|
37748
38100
|
* ```
|
|
37749
38101
|
*/ async retry(error) {
|
|
37750
|
-
|
|
37751
|
-
|
|
37752
|
-
|
|
37753
|
-
|
|
37754
|
-
|
|
37755
|
-
|
|
37756
|
-
|
|
37757
|
-
|
|
37758
|
-
|
|
37759
|
-
|
|
37760
|
-
|
|
37761
|
-
|
|
37762
|
-
|
|
37763
|
-
|
|
37764
|
-
|
|
37765
|
-
|
|
37766
|
-
|
|
37767
|
-
|
|
37768
|
-
|
|
37769
|
-
|
|
38102
|
+
const result = await withErrorTelemetry(async ()=>{
|
|
38103
|
+
if (!isKitError(error)) {
|
|
38104
|
+
throw createValidationFailedError$1('error', error, 'EarnKit.retry() requires a KitError thrown by a previous earn operation');
|
|
38105
|
+
}
|
|
38106
|
+
if (!isRetryableError$1(error)) {
|
|
38107
|
+
throw createValidationFailedError$1('error.recoverability', error.recoverability, 'EarnKit.retry() requires a retryable or resumable error — check isRetryableError(error) first');
|
|
38108
|
+
}
|
|
38109
|
+
const trace = error.cause?.trace;
|
|
38110
|
+
if (!isEarnErrorTrace(trace)) {
|
|
38111
|
+
throw createValidationFailedError$1('error.cause.trace', trace, 'EarnKit.retry() requires a KitError carrying earn retry context (operation, steps, provider, params)');
|
|
38112
|
+
}
|
|
38113
|
+
const provider = this.context.providers.find((candidate)=>candidate.name === trace.provider);
|
|
38114
|
+
if (provider === undefined) {
|
|
38115
|
+
throw createValidationFailedError$1('error.cause.trace.provider', trace.provider, `No earn provider named "${trace.provider}" is registered with this kit`);
|
|
38116
|
+
}
|
|
38117
|
+
const result = await provider.retry(error);
|
|
38118
|
+
// `provider.retry` returns a flat result union with no compile-time link to
|
|
38119
|
+
// `trace.operation`, so narrow the operation here to select the matching
|
|
38120
|
+
// overload. The result cast in each branch is sound: the provider always
|
|
38121
|
+
// returns the result type corresponding to the resumed operation.
|
|
38122
|
+
if (trace.operation === 'claimRewards') {
|
|
38123
|
+
return formatRetryResult(trace.operation, result);
|
|
38124
|
+
}
|
|
37770
38125
|
return formatRetryResult(trace.operation, result);
|
|
38126
|
+
}, EARN_EVENT_TYPES.RETRY, this.telemetryConfig);
|
|
38127
|
+
const trace = isKitError(error) ? error.cause?.trace : undefined;
|
|
38128
|
+
if (isEarnErrorTrace(trace)) {
|
|
38129
|
+
emitRetrySuccessTelemetry(trace, result, this.analyticsTelemetryConfig);
|
|
37771
38130
|
}
|
|
37772
|
-
return
|
|
38131
|
+
return result;
|
|
37773
38132
|
}
|
|
37774
38133
|
/**
|
|
37775
38134
|
* Return the chains supported by configured earn providers.
|
|
@@ -37803,7 +38162,9 @@ function formatRetryResult(operation, result) {
|
|
|
37803
38162
|
* result.vaults.forEach(v => console.log(`${v.name}: ${(v.currentApy * 100).toFixed(2)}% APY`))
|
|
37804
38163
|
* ```
|
|
37805
38164
|
*/ async getVaults(params) {
|
|
37806
|
-
|
|
38165
|
+
const result = await withErrorTelemetry(async ()=>getVaults$1(this.context, params), EARN_EVENT_TYPES.GET_VAULTS, this.telemetryConfig);
|
|
38166
|
+
emitSuccessTelemetry(EARN_EVENT_TYPES.GET_VAULTS, this.analyticsTelemetryConfig, {});
|
|
38167
|
+
return result;
|
|
37807
38168
|
}
|
|
37808
38169
|
/**
|
|
37809
38170
|
* Discover vaults available on a chain.
|
|
@@ -37828,7 +38189,12 @@ function formatRetryResult(operation, result) {
|
|
|
37828
38189
|
* const guarded = result.vaults.filter(v => v.circleGuarded) // Circle-guarded vaults only
|
|
37829
38190
|
* ```
|
|
37830
38191
|
*/ async exploreVaults(params) {
|
|
37831
|
-
|
|
38192
|
+
const context = {
|
|
38193
|
+
sourceChain: resolveChainName(params.chain)
|
|
38194
|
+
};
|
|
38195
|
+
const result = await withErrorTelemetry(async ()=>exploreVaults$1(this.context, params), EARN_EVENT_TYPES.EXPLORE_VAULTS, this.telemetryConfig, context);
|
|
38196
|
+
emitSuccessTelemetry(EARN_EVENT_TYPES.EXPLORE_VAULTS, this.analyticsTelemetryConfig, context);
|
|
38197
|
+
return result;
|
|
37832
38198
|
}
|
|
37833
38199
|
/**
|
|
37834
38200
|
* Lazily iterate every vault available on a chain.
|
|
@@ -37875,7 +38241,9 @@ function formatRetryResult(operation, result) {
|
|
|
37875
38241
|
* }
|
|
37876
38242
|
* ```
|
|
37877
38243
|
*/ async getPosition(params) {
|
|
37878
|
-
return getPosition$1(this.context, params)
|
|
38244
|
+
return withErrorTelemetry(async ()=>getPosition$1(this.context, params), EARN_EVENT_TYPES.GET_POSITION, this.telemetryConfig, {
|
|
38245
|
+
sourceChain: resolveChainName(params.from.chain)
|
|
38246
|
+
});
|
|
37879
38247
|
}
|
|
37880
38248
|
/**
|
|
37881
38249
|
* Fetch the current status of a cross-chain deposit by execution ID.
|
|
@@ -37900,7 +38268,7 @@ function formatRetryResult(operation, result) {
|
|
|
37900
38268
|
* console.log(`Bridge ${status.execId} is ${status.status}`)
|
|
37901
38269
|
* ```
|
|
37902
38270
|
*/ async getCrossChainDepositStatus(params) {
|
|
37903
|
-
return getCrossChainDepositStatus$1(this.context, params);
|
|
38271
|
+
return withErrorTelemetry(async ()=>getCrossChainDepositStatus$1(this.context, params), EARN_EVENT_TYPES.GET_CROSS_CHAIN_DEPOSIT_STATUS, this.telemetryConfig);
|
|
37904
38272
|
}
|
|
37905
38273
|
/**
|
|
37906
38274
|
* Poll a cross-chain deposit until it reaches a terminal bridge state.
|
|
@@ -37927,10 +38295,30 @@ function formatRetryResult(operation, result) {
|
|
|
37927
38295
|
* console.log(`Bridge ended as ${result.outcome}`)
|
|
37928
38296
|
* ```
|
|
37929
38297
|
*/ async waitForCrossChainDeposit(params) {
|
|
37930
|
-
return waitForCrossChainDeposit$1(this.context, params);
|
|
38298
|
+
return withErrorTelemetry(async ()=>waitForCrossChainDeposit$1(this.context, params), EARN_EVENT_TYPES.WAIT_FOR_CROSS_CHAIN_DEPOSIT, this.telemetryConfig);
|
|
37931
38299
|
}
|
|
37932
38300
|
async deposit(params) {
|
|
37933
|
-
|
|
38301
|
+
const isCrossChain = isCrossChainDeposit(params);
|
|
38302
|
+
const context = {
|
|
38303
|
+
sourceChain: resolveChainName(params.from.chain),
|
|
38304
|
+
...isCrossChain && {
|
|
38305
|
+
destinationChain: resolveChainName(params.to.chain)
|
|
38306
|
+
}
|
|
38307
|
+
};
|
|
38308
|
+
const eventType = isCrossChain ? EARN_EVENT_TYPES.CROSS_CHAIN_DEPOSIT : EARN_EVENT_TYPES.DEPOSIT;
|
|
38309
|
+
const result = await withErrorTelemetry(async ()=>deposit$3(this.context, params), eventType, this.telemetryConfig, context);
|
|
38310
|
+
if (result.kind === 'cross-chain') {
|
|
38311
|
+
emitSuccessTelemetry(EARN_EVENT_TYPES.CROSS_CHAIN_DEPOSIT, this.analyticsTelemetryConfig, {
|
|
38312
|
+
sourceChain: resolveChainName(result.sourceChain),
|
|
38313
|
+
destinationChain: resolveChainName(result.destinationChain)
|
|
38314
|
+
});
|
|
38315
|
+
} else {
|
|
38316
|
+
emitSuccessTelemetry(EARN_EVENT_TYPES.DEPOSIT, this.analyticsTelemetryConfig, {
|
|
38317
|
+
...context,
|
|
38318
|
+
txHash: result.txHash
|
|
38319
|
+
});
|
|
38320
|
+
}
|
|
38321
|
+
return result;
|
|
37934
38322
|
}
|
|
37935
38323
|
/**
|
|
37936
38324
|
* Execute a withdrawal from a DeFi lending vault.
|
|
@@ -37956,7 +38344,15 @@ function formatRetryResult(operation, result) {
|
|
|
37956
38344
|
* console.log(`Withdrew ${result.amount} from ${result.vaultAddress}, tx: ${result.txHash}`)
|
|
37957
38345
|
* ```
|
|
37958
38346
|
*/ async withdraw(params) {
|
|
37959
|
-
|
|
38347
|
+
const context = {
|
|
38348
|
+
sourceChain: resolveChainName(params.from.chain)
|
|
38349
|
+
};
|
|
38350
|
+
const result = await withErrorTelemetry(async ()=>withdraw$1(this.context, params), EARN_EVENT_TYPES.WITHDRAW, this.telemetryConfig, context);
|
|
38351
|
+
emitSuccessTelemetry(EARN_EVENT_TYPES.WITHDRAW, this.analyticsTelemetryConfig, {
|
|
38352
|
+
...context,
|
|
38353
|
+
txHash: result.txHash
|
|
38354
|
+
});
|
|
38355
|
+
return result;
|
|
37960
38356
|
}
|
|
37961
38357
|
/**
|
|
37962
38358
|
* Claim rewards from earn vaults.
|
|
@@ -37983,7 +38379,17 @@ function formatRetryResult(operation, result) {
|
|
|
37983
38379
|
*
|
|
37984
38380
|
* @internal
|
|
37985
38381
|
*/ async claimRewards(params) {
|
|
37986
|
-
|
|
38382
|
+
const context = {
|
|
38383
|
+
sourceChain: resolveChainName(params.from.chain)
|
|
38384
|
+
};
|
|
38385
|
+
const result = await withErrorTelemetry(async ()=>claimRewards$1(this.context, params), EARN_EVENT_TYPES.CLAIM_REWARDS, this.telemetryConfig, context);
|
|
38386
|
+
if (result.status === 'claimed') {
|
|
38387
|
+
emitSuccessTelemetry(EARN_EVENT_TYPES.CLAIM_REWARDS, this.analyticsTelemetryConfig, {
|
|
38388
|
+
...context,
|
|
38389
|
+
txHash: result.txHash
|
|
38390
|
+
});
|
|
38391
|
+
}
|
|
38392
|
+
return result;
|
|
37987
38393
|
}
|
|
37988
38394
|
/**
|
|
37989
38395
|
* Get an informational quote for a deposit into a vault.
|
|
@@ -38005,7 +38411,9 @@ function formatRetryResult(operation, result) {
|
|
|
38005
38411
|
* console.log(`Expected shares: ${quote.expectedShares.amount}`)
|
|
38006
38412
|
* ```
|
|
38007
38413
|
*/ async getDepositQuote(params) {
|
|
38008
|
-
return getDepositQuote$1(this.context, params)
|
|
38414
|
+
return withErrorTelemetry(async ()=>getDepositQuote$1(this.context, params), EARN_EVENT_TYPES.GET_DEPOSIT_QUOTE, this.telemetryConfig, {
|
|
38415
|
+
sourceChain: resolveChainName(params.from.chain)
|
|
38416
|
+
});
|
|
38009
38417
|
}
|
|
38010
38418
|
/**
|
|
38011
38419
|
* Get an informational quote for a withdrawal from a vault.
|
|
@@ -38027,7 +38435,9 @@ function formatRetryResult(operation, result) {
|
|
|
38027
38435
|
* console.log(`Shares to redeem: ${quote.sharesToRedeem.amount}`)
|
|
38028
38436
|
* ```
|
|
38029
38437
|
*/ async getWithdrawalQuote(params) {
|
|
38030
|
-
return getWithdrawalQuote$1(this.context, params)
|
|
38438
|
+
return withErrorTelemetry(async ()=>getWithdrawalQuote$1(this.context, params), EARN_EVENT_TYPES.GET_WITHDRAWAL_QUOTE, this.telemetryConfig, {
|
|
38439
|
+
sourceChain: resolveChainName(params.from.chain)
|
|
38440
|
+
});
|
|
38031
38441
|
}
|
|
38032
38442
|
/**
|
|
38033
38443
|
* Get an informational quote for claiming rewards.
|
|
@@ -38049,7 +38459,9 @@ function formatRetryResult(operation, result) {
|
|
|
38049
38459
|
*
|
|
38050
38460
|
* @internal
|
|
38051
38461
|
*/ async getClaimRewardsQuote(params) {
|
|
38052
|
-
return getClaimRewardsQuote$1(this.context, params)
|
|
38462
|
+
return withErrorTelemetry(async ()=>getClaimRewardsQuote$1(this.context, params), EARN_EVENT_TYPES.GET_CLAIM_REWARDS_QUOTE, this.telemetryConfig, {
|
|
38463
|
+
sourceChain: resolveChainName(params.from.chain)
|
|
38464
|
+
});
|
|
38053
38465
|
}
|
|
38054
38466
|
}
|
|
38055
38467
|
|
|
@@ -38138,7 +38550,14 @@ registerKit(`${pkg$2.name}/${pkg$2.version}`);
|
|
|
38138
38550
|
* const earnKit = createEarnKit(context)
|
|
38139
38551
|
* ```
|
|
38140
38552
|
*/ const createEarnKit = (context)=>{
|
|
38141
|
-
const kit = new EarnKit(
|
|
38553
|
+
const kit = new EarnKit({
|
|
38554
|
+
...context.disableErrorReporting != null && {
|
|
38555
|
+
disableErrorReporting: context.disableErrorReporting
|
|
38556
|
+
},
|
|
38557
|
+
...context.disableAnalytics != null && {
|
|
38558
|
+
disableAnalytics: context.disableAnalytics
|
|
38559
|
+
}
|
|
38560
|
+
});
|
|
38142
38561
|
registerActionHandlers(kit, context.actions.earn, 'earn');
|
|
38143
38562
|
return kit;
|
|
38144
38563
|
};
|
|
@@ -39447,7 +39866,7 @@ async function deposit$2(context, params) {
|
|
|
39447
39866
|
}
|
|
39448
39867
|
|
|
39449
39868
|
var name = "@circle-fin/unified-balance-kit";
|
|
39450
|
-
var version = "1.3.
|
|
39869
|
+
var version = "1.3.1";
|
|
39451
39870
|
var pkg = {
|
|
39452
39871
|
name: name,
|
|
39453
39872
|
version: version};
|
|
@@ -45957,7 +46376,11 @@ const removeFundParamsSchema = z.object({
|
|
|
45957
46376
|
// Remove Fund Operations
|
|
45958
46377
|
// ---------------------------------------------------------------------------
|
|
45959
46378
|
/**
|
|
45960
|
-
* Kick off a delayed fund removal from an account.
|
|
46379
|
+
* Kick off a delayed recovery fund removal from an account.
|
|
46380
|
+
*
|
|
46381
|
+
* Use `initiateRemoveFund` only as a trustless fallback when the normal spend
|
|
46382
|
+
* flow is unavailable. For day-to-day movement out of a Unified Balance, use
|
|
46383
|
+
* `spend`.
|
|
45961
46384
|
*
|
|
45962
46385
|
* Validates `from` and `amount`, resolves the chain and token via
|
|
45963
46386
|
* {@link resolveRemoveFundParams}, selects the matching provider, then calls
|
|
@@ -45994,7 +46417,10 @@ const removeFundParamsSchema = z.object({
|
|
|
45994
46417
|
return provider.initiateRemoveFund(resolved);
|
|
45995
46418
|
}
|
|
45996
46419
|
/**
|
|
45997
|
-
* Complete a fund removal once the 7-day
|
|
46420
|
+
* Complete a recovery fund removal once the 7-day withdrawal delay has passed.
|
|
46421
|
+
*
|
|
46422
|
+
* Use `removeFund` only as a trustless fallback when the normal spend flow is
|
|
46423
|
+
* unavailable. For day-to-day movement out of a Unified Balance, use `spend`.
|
|
45998
46424
|
*
|
|
45999
46425
|
* Validates `from`, resolves the chain and token via
|
|
46000
46426
|
* {@link resolveRemoveFundParams}, selects the matching provider, then calls
|
|
@@ -46083,13 +46509,18 @@ const removeFundParamsSchema = z.object({
|
|
|
46083
46509
|
/** SDK name used in telemetry payloads. */ const SDK_NAME = resolveKitSdkName(pkg.name);
|
|
46084
46510
|
/**
|
|
46085
46511
|
* A high-level class-based interface for cross-chain USDC deposits,
|
|
46086
|
-
* spending, balance queries, delegation management, and
|
|
46512
|
+
* spending, balance queries, delegation management, and recovery fund removals.
|
|
46087
46513
|
*
|
|
46088
46514
|
* UnifiedBalanceKit provides a familiar class-based API for developers who
|
|
46089
46515
|
* prefer traditional object-oriented patterns. The class maintains an
|
|
46090
46516
|
* internal context and provides methods that delegate to the standalone
|
|
46091
46517
|
* operation functions exported by this package.
|
|
46092
46518
|
*
|
|
46519
|
+
* Use `spend` for normal movement out of a Unified Balance. `removeFund` is a
|
|
46520
|
+
* trustless recovery path for situations where the normal spend flow is
|
|
46521
|
+
* unavailable, and it requires a 7-day withdrawal delay before funds can be
|
|
46522
|
+
* removed.
|
|
46523
|
+
*
|
|
46093
46524
|
* @remarks
|
|
46094
46525
|
* For functional usage, import and use the operations directly:
|
|
46095
46526
|
* ```typescript
|
|
@@ -46310,7 +46741,11 @@ const removeFundParamsSchema = z.object({
|
|
|
46310
46741
|
});
|
|
46311
46742
|
}
|
|
46312
46743
|
/**
|
|
46313
|
-
* Kick off a delayed fund removal from an account.
|
|
46744
|
+
* Kick off a delayed recovery fund removal from an account.
|
|
46745
|
+
*
|
|
46746
|
+
* Use this only as a trustless fallback when the normal spend flow is
|
|
46747
|
+
* unavailable. For day-to-day movement out of a Unified Balance, use
|
|
46748
|
+
* `spend`.
|
|
46314
46749
|
*
|
|
46315
46750
|
* @param params - The account owner's adapter context, amount, and
|
|
46316
46751
|
* optional token type.
|
|
@@ -46324,7 +46759,12 @@ const removeFundParamsSchema = z.object({
|
|
|
46324
46759
|
});
|
|
46325
46760
|
}
|
|
46326
46761
|
/**
|
|
46327
|
-
* Complete a fund removal once the
|
|
46762
|
+
* Complete a recovery fund removal once the 7-day withdrawal delay has
|
|
46763
|
+
* passed.
|
|
46764
|
+
*
|
|
46765
|
+
* Use this only as a trustless fallback when the normal spend flow is
|
|
46766
|
+
* unavailable. For day-to-day movement out of a Unified Balance, use
|
|
46767
|
+
* `spend`.
|
|
46328
46768
|
*
|
|
46329
46769
|
* @param params - The account owner context matching the original
|
|
46330
46770
|
* fund removal initiation.
|
|
@@ -46451,6 +46891,11 @@ registerKit(`${pkg.name}/${pkg.version}`);
|
|
|
46451
46891
|
* Internally holds a persistent {@link UnifiedBalanceKit} instance so that
|
|
46452
46892
|
* event dispatchers and custom fee policies are preserved across calls.
|
|
46453
46893
|
*
|
|
46894
|
+
* Use {@link AppKitUnifiedBalance.spend} for normal movement out of a Unified
|
|
46895
|
+
* Balance. {@link AppKitUnifiedBalance.removeFund} is a trustless recovery path
|
|
46896
|
+
* for situations where the normal spend flow is unavailable, and it requires a
|
|
46897
|
+
* 7-day withdrawal delay after {@link AppKitUnifiedBalance.initiateRemoveFund}.
|
|
46898
|
+
*
|
|
46454
46899
|
* @example
|
|
46455
46900
|
* ```typescript
|
|
46456
46901
|
* import { AppKit } from '@circle-fin/app-kit'
|
|
@@ -46662,7 +47107,12 @@ registerKit(`${pkg.name}/${pkg.version}`);
|
|
|
46662
47107
|
return this.kit.removeDelegate(params);
|
|
46663
47108
|
}
|
|
46664
47109
|
/**
|
|
46665
|
-
*
|
|
47110
|
+
* Initiate a trustless recovery removal from an account.
|
|
47111
|
+
*
|
|
47112
|
+
* Use `spend` for normal movement out of a Unified Balance. `removeFund` is a
|
|
47113
|
+
* recovery path for situations where the normal spend flow is unavailable.
|
|
47114
|
+
* Calling this method starts the 7-day withdrawal delay before the removal can
|
|
47115
|
+
* be completed.
|
|
46666
47116
|
*
|
|
46667
47117
|
* @param params - The account owner's adapter context, amount, and token.
|
|
46668
47118
|
* @returns Promise resolving to the initiation details.
|
|
@@ -46681,11 +47131,16 @@ registerKit(`${pkg.name}/${pkg.version}`);
|
|
|
46681
47131
|
return this.kit.initiateRemoveFund(params);
|
|
46682
47132
|
}
|
|
46683
47133
|
/**
|
|
46684
|
-
* Complete a
|
|
47134
|
+
* Complete a trustless recovery removal after the withdrawal delay.
|
|
47135
|
+
*
|
|
47136
|
+
* Use `spend` for normal movement out of a Unified Balance. `removeFund` is a
|
|
47137
|
+
* recovery path for situations where the normal spend flow is unavailable.
|
|
47138
|
+
* Both EVM and Solana removals require a 7-day withdrawal delay after
|
|
47139
|
+
* `initiateRemoveFund` before funds can be removed.
|
|
46685
47140
|
*
|
|
46686
47141
|
* @param params - The account owner context matching the original initiation.
|
|
46687
47142
|
* @returns Promise resolving to the fund removal details.
|
|
46688
|
-
* @throws {KitError} If the
|
|
47143
|
+
* @throws {KitError} If the withdrawal delay has not elapsed or the
|
|
46689
47144
|
* on-chain transaction fails.
|
|
46690
47145
|
*
|
|
46691
47146
|
* @example
|
|
@@ -46934,6 +47389,9 @@ registerKit(`${pkg.name}/${pkg.version}`);
|
|
|
46934
47389
|
...config.unifiedBalance,
|
|
46935
47390
|
...config.disableErrorReporting != null && {
|
|
46936
47391
|
disableErrorReporting: config.disableErrorReporting
|
|
47392
|
+
},
|
|
47393
|
+
...config.disableAnalytics != null && {
|
|
47394
|
+
disableAnalytics: config.disableAnalytics
|
|
46937
47395
|
}
|
|
46938
47396
|
});
|
|
46939
47397
|
this.earn = {
|