@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.cjs
CHANGED
|
@@ -18,6 +18,17 @@
|
|
|
18
18
|
|
|
19
19
|
'use strict';
|
|
20
20
|
|
|
21
|
+
// Buffer polyfill setup - executes before any other code
|
|
22
|
+
// Ensures globalThis.Buffer is available for Solana libraries
|
|
23
|
+
const { Buffer } = require('buffer');
|
|
24
|
+
if (typeof globalThis !== 'undefined' && typeof globalThis.Buffer === 'undefined') {
|
|
25
|
+
globalThis.Buffer = Buffer;
|
|
26
|
+
}
|
|
27
|
+
if (typeof window !== 'undefined' && typeof window.Buffer === 'undefined') {
|
|
28
|
+
window.Buffer = Buffer;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
21
32
|
var zod = require('zod');
|
|
22
33
|
var pino = require('pino');
|
|
23
34
|
var units = require('@ethersproject/units');
|
|
@@ -89,6 +100,51 @@ var bs58__default = /*#__PURE__*/_interopDefault(bs58);
|
|
|
89
100
|
* }
|
|
90
101
|
* ```
|
|
91
102
|
*/ const isNodeEnvironment = ()=>typeof process !== 'undefined' && typeof process.versions === 'object' && typeof process.versions.node === 'string';
|
|
103
|
+
/**
|
|
104
|
+
* Check whether the current runtime exposes a browser DOM.
|
|
105
|
+
*
|
|
106
|
+
* @remarks
|
|
107
|
+
* This intentionally does not treat every non-Node runtime as a browser.
|
|
108
|
+
* Server-side edge runtimes such as Cloudflare Workers, Deno, and Supabase
|
|
109
|
+
* Edge Functions do not expose Node globals but can safely use server
|
|
110
|
+
* credentials. A Node.js runtime remains server-side even when a test or SSR
|
|
111
|
+
* environment provides a DOM shim.
|
|
112
|
+
*
|
|
113
|
+
* @returns `true` when running in a browser window, `false` otherwise.
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```typescript
|
|
117
|
+
* import { isBrowserEnvironment } from '@core/utils'
|
|
118
|
+
*
|
|
119
|
+
* if (isBrowserEnvironment()) {
|
|
120
|
+
* throw new Error('Server-only secrets must not be used in the browser')
|
|
121
|
+
* }
|
|
122
|
+
* ```
|
|
123
|
+
*/ const isBrowserEnvironment = ()=>{
|
|
124
|
+
const browserWindow = globalThis.window;
|
|
125
|
+
return !isNodeEnvironment() && browserWindow?.document !== undefined;
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* Return the SDK User-Agent request header only when running in Node.js.
|
|
129
|
+
*
|
|
130
|
+
* Browsers forbid manually setting `User-Agent`, and a custom fallback header
|
|
131
|
+
* can trigger CORS preflight. Non-Node server runtimes also omit this optional
|
|
132
|
+
* attribution header because they cannot set it reliably.
|
|
133
|
+
*
|
|
134
|
+
* @returns A User-Agent header in Node.js, or an empty object otherwise.
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* ```typescript
|
|
138
|
+
* import { getNodeUserAgentHeader } from '@core/utils'
|
|
139
|
+
*
|
|
140
|
+
* const headers = {
|
|
141
|
+
* 'Content-Type': 'application/json',
|
|
142
|
+
* ...getNodeUserAgentHeader(),
|
|
143
|
+
* }
|
|
144
|
+
* ```
|
|
145
|
+
*/ const getNodeUserAgentHeader = ()=>isNodeEnvironment() ? {
|
|
146
|
+
'User-Agent': getUserAgent()
|
|
147
|
+
} : {};
|
|
92
148
|
/**
|
|
93
149
|
* Detect the runtime environment and return a shortened identifier.
|
|
94
150
|
*
|
|
@@ -9289,13 +9345,12 @@ const swapTokenEnumSchema = zod.z.enum([
|
|
|
9289
9345
|
headers: {
|
|
9290
9346
|
...DEFAULT_CONFIG$3.headers,
|
|
9291
9347
|
...config.headers ?? {},
|
|
9292
|
-
//
|
|
9293
|
-
//
|
|
9294
|
-
|
|
9295
|
-
|
|
9296
|
-
|
|
9297
|
-
|
|
9298
|
-
}
|
|
9348
|
+
// Browsers forbid setting a user-agent request header, and the custom
|
|
9349
|
+
// fallback header the SDK used instead trips CORS preflight against the
|
|
9350
|
+
// Circle APIs (it isn't in their `Access-Control-Allow-Headers`),
|
|
9351
|
+
// blocking the request. So send the SDK user agent only in Node;
|
|
9352
|
+
// browsers omit it entirely.
|
|
9353
|
+
...getNodeUserAgentHeader()
|
|
9299
9354
|
}
|
|
9300
9355
|
};
|
|
9301
9356
|
let lastError;
|
|
@@ -11226,6 +11281,7 @@ function resolveOptions(options) {
|
|
|
11226
11281
|
if (payload.tokenIn !== undefined) safe['tokenIn'] = payload.tokenIn;
|
|
11227
11282
|
if (payload.tokenOut !== undefined) safe['tokenOut'] = payload.tokenOut;
|
|
11228
11283
|
if (payload.txHash !== undefined) safe['txHash'] = payload.txHash;
|
|
11284
|
+
if (payload.correlationId !== undefined) safe['correlationId'] = payload.correlationId;
|
|
11229
11285
|
if (payload.errorDetails !== undefined) {
|
|
11230
11286
|
const errorDetails = {
|
|
11231
11287
|
...payload.errorDetails.errorCode !== undefined && {
|
|
@@ -11296,18 +11352,15 @@ function resolveOptions(options) {
|
|
|
11296
11352
|
timeoutHandle.unref();
|
|
11297
11353
|
}
|
|
11298
11354
|
try {
|
|
11299
|
-
const isNode = isNodeEnvironment();
|
|
11300
|
-
const userAgent = getUserAgent();
|
|
11301
11355
|
await fetch(getLogsUrl(), {
|
|
11302
11356
|
method: 'POST',
|
|
11303
11357
|
headers: {
|
|
11304
11358
|
'Content-Type': 'application/json',
|
|
11305
|
-
//
|
|
11306
|
-
|
|
11307
|
-
|
|
11308
|
-
|
|
11309
|
-
|
|
11310
|
-
}
|
|
11359
|
+
// Browsers forbid setting a user-agent request header, and the custom
|
|
11360
|
+
// fallback header the SDK used instead trips CORS preflight (it isn't
|
|
11361
|
+
// in the telemetry endpoint's `Access-Control-Allow-Headers`), so send
|
|
11362
|
+
// it only in Node; browsers omit it entirely.
|
|
11363
|
+
...getNodeUserAgentHeader()
|
|
11311
11364
|
},
|
|
11312
11365
|
body: JSON.stringify(toSafePayload(payload)),
|
|
11313
11366
|
signal: controller.signal
|
|
@@ -11520,7 +11573,7 @@ function resolveOptions(options) {
|
|
|
11520
11573
|
// discards the stack trace, nested `cause`, and any custom Error
|
|
11521
11574
|
// properties — exactly the context an on-call needs when a
|
|
11522
11575
|
// resolver-closure regression triggers this path.
|
|
11523
|
-
console.warn(`[stablecoin-kits telemetry] dropped
|
|
11576
|
+
console.warn(`[stablecoin-kits telemetry] dropped event '${eventType}':`, cause);
|
|
11524
11577
|
} catch {
|
|
11525
11578
|
// console.warn itself throwing is the user's environment; nothing more we
|
|
11526
11579
|
// can do without risking the original operation error.
|
|
@@ -11536,7 +11589,9 @@ function resolveOptions(options) {
|
|
|
11536
11589
|
sdkVersion: config.sdkVersion,
|
|
11537
11590
|
eventType,
|
|
11538
11591
|
timestamp: new Date().toISOString(),
|
|
11539
|
-
errorDetails
|
|
11592
|
+
...errorDetails !== undefined && {
|
|
11593
|
+
errorDetails
|
|
11594
|
+
},
|
|
11540
11595
|
clientContext: buildClientContext(),
|
|
11541
11596
|
...context?.sourceChain != null && {
|
|
11542
11597
|
sourceChain: context.sourceChain
|
|
@@ -11552,9 +11607,45 @@ function resolveOptions(options) {
|
|
|
11552
11607
|
},
|
|
11553
11608
|
...context?.txHash != null && {
|
|
11554
11609
|
txHash: context.txHash
|
|
11610
|
+
},
|
|
11611
|
+
...context?.correlationId != null && {
|
|
11612
|
+
correlationId: context.correlationId
|
|
11555
11613
|
}
|
|
11556
11614
|
};
|
|
11557
11615
|
}
|
|
11616
|
+
/**
|
|
11617
|
+
* Emit telemetry for a completed operation without affecting its caller.
|
|
11618
|
+
*
|
|
11619
|
+
* No-ops when `config.disabled` is `true`. Like {@link withErrorTelemetry},
|
|
11620
|
+
* failures while constructing or submitting the telemetry payload are reported
|
|
11621
|
+
* as a soft warning and never change a completed operation's result.
|
|
11622
|
+
*
|
|
11623
|
+
* @param eventType - The telemetry event type for the completed operation.
|
|
11624
|
+
* @param config - Per-kit SDK identity and disabled flag.
|
|
11625
|
+
* @param context - Optional chain, token, and transaction context.
|
|
11626
|
+
* @returns Nothing.
|
|
11627
|
+
* @throws Never — telemetry failures are reported as warnings.
|
|
11628
|
+
*
|
|
11629
|
+
* @example
|
|
11630
|
+
* ```typescript
|
|
11631
|
+
* import { emitSuccessTelemetry } from '@core/utils'
|
|
11632
|
+
*
|
|
11633
|
+
* emitSuccessTelemetry(
|
|
11634
|
+
* 'bridge_bridge',
|
|
11635
|
+
* { sdkName: 'bridge-kit', sdkVersion: '1.0.0', disabled: false },
|
|
11636
|
+
* { sourceChain: 'Ethereum', destinationChain: 'Base', tokenIn: 'USDC' },
|
|
11637
|
+
* )
|
|
11638
|
+
* ```
|
|
11639
|
+
*/ function emitSuccessTelemetry(eventType, config, context) {
|
|
11640
|
+
if (config.disabled) {
|
|
11641
|
+
return;
|
|
11642
|
+
}
|
|
11643
|
+
try {
|
|
11644
|
+
void emitAnalyticsLog(buildPayload$1(config, eventType, undefined, context));
|
|
11645
|
+
} catch (telemetryError) {
|
|
11646
|
+
warnTelemetryDrop(eventType, telemetryError);
|
|
11647
|
+
}
|
|
11648
|
+
}
|
|
11558
11649
|
/**
|
|
11559
11650
|
* Wrap an async operation with error telemetry.
|
|
11560
11651
|
*
|
|
@@ -11665,7 +11756,7 @@ function resolveOptions(options) {
|
|
|
11665
11756
|
}
|
|
11666
11757
|
|
|
11667
11758
|
var name$4 = "@circle-fin/bridge-kit";
|
|
11668
|
-
var version$5 = "1.12.
|
|
11759
|
+
var version$5 = "1.12.2";
|
|
11669
11760
|
var pkg$5 = {
|
|
11670
11761
|
name: name$4,
|
|
11671
11762
|
version: version$5};
|
|
@@ -14301,7 +14392,13 @@ const FAST_TIER_FINALITY_THRESHOLD = 1000;
|
|
|
14301
14392
|
/**
|
|
14302
14393
|
* The ASCII "cctp-forward" magic, hex-encoded (no `0x`), that a forward-friendly
|
|
14303
14394
|
* hookData must start with.
|
|
14304
|
-
|
|
14395
|
+
*
|
|
14396
|
+
* Encoded with `TextEncoder` (a browser-safe Web API) rather than `Buffer.from`
|
|
14397
|
+
* so this module-level constant does not reference the Node `Buffer` global at
|
|
14398
|
+
* import time. App Kit inlines this provider into its bundle without a Buffer polyfill, and a
|
|
14399
|
+
* bare `Buffer` here crashes browser bundles (e.g. Vite) on load — even for apps
|
|
14400
|
+
* that never touch the prepaid FORWARD path. Mirrors `buildForwardingHookData`.
|
|
14401
|
+
*/ const CCTP_FORWARD_MAGIC_HEX = Array.from(new TextEncoder().encode(CCTP_FORWARD_MAGIC_PREFIX)).map((byte)=>byte.toString(16).padStart(2, '0')).join('');
|
|
14305
14402
|
/**
|
|
14306
14403
|
* Determine whether a hookData blob begins with the `cctp-forward` envelope.
|
|
14307
14404
|
*
|
|
@@ -16739,7 +16836,7 @@ const mockAttestationMessage = {
|
|
|
16739
16836
|
return step;
|
|
16740
16837
|
}
|
|
16741
16838
|
|
|
16742
|
-
var version$4 = "1.10.
|
|
16839
|
+
var version$4 = "1.10.1";
|
|
16743
16840
|
var pkg$4 = {
|
|
16744
16841
|
version: version$4};
|
|
16745
16842
|
|
|
@@ -18618,7 +18715,7 @@ function assertCCTPV2Config(config) {
|
|
|
18618
18715
|
]
|
|
18619
18716
|
];
|
|
18620
18717
|
|
|
18621
|
-
/** SDK name used in telemetry payloads. */ const SDK_NAME$
|
|
18718
|
+
/** SDK name used in telemetry payloads. */ const SDK_NAME$3 = resolveKitSdkName(pkg$5.name);
|
|
18622
18719
|
/**
|
|
18623
18720
|
* Pick the most-relevant `txHash` to attach to an error telemetry payload.
|
|
18624
18721
|
*
|
|
@@ -18760,7 +18857,7 @@ function assertCCTPV2Config(config) {
|
|
|
18760
18857
|
this.actionDispatcher = new Actionable();
|
|
18761
18858
|
this.disableErrorReporting = config.disableErrorReporting === true;
|
|
18762
18859
|
this.telemetryConfig = {
|
|
18763
|
-
sdkName: SDK_NAME$
|
|
18860
|
+
sdkName: SDK_NAME$3,
|
|
18764
18861
|
sdkVersion: pkg$5.version,
|
|
18765
18862
|
disabled: this.disableErrorReporting
|
|
18766
18863
|
};
|
|
@@ -19353,7 +19450,7 @@ registerKit(`${pkg$5.name}/${pkg$5.version}`);
|
|
|
19353
19450
|
};
|
|
19354
19451
|
|
|
19355
19452
|
var name$3 = "@circle-fin/swap-kit";
|
|
19356
|
-
var version$3 = "1.
|
|
19453
|
+
var version$3 = "1.5.0";
|
|
19357
19454
|
var pkg$3 = {
|
|
19358
19455
|
name: name$3,
|
|
19359
19456
|
version: version$3};
|
|
@@ -20186,6 +20283,16 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
|
|
|
20186
20283
|
required_error: 'estimatedAmount is required',
|
|
20187
20284
|
invalid_type_error: 'estimatedAmount must be a string'
|
|
20188
20285
|
}).min(1, 'estimatedAmount must be a non-empty string'),
|
|
20286
|
+
// Per-swap join key echoed back verbatim on success telemetry. Optional so a
|
|
20287
|
+
// not-yet-upgraded service (no field) still validates during rollout. A
|
|
20288
|
+
// malformed/non-UUID value is coerced to `undefined` (no telemetry id) rather
|
|
20289
|
+
// than throwing: this is a telemetry-only field (stripped from the developer
|
|
20290
|
+
// result, never used for control flow), so it must not be able to abort the
|
|
20291
|
+
// swap via `parseCreateSwapResponse().parse()`. Mirrors the best-effort,
|
|
20292
|
+
// never-throw contract of the rest of the telemetry stack. Implemented with
|
|
20293
|
+
// `preprocess` rather than Zod's `.catch()` because static analysis misreads
|
|
20294
|
+
// `.catch` on the schema chain as an unhandled Promise (S7785).
|
|
20295
|
+
correlationId: zod.z.preprocess((value)=>zod.z.string().uuid().safeParse(value).success ? value : undefined, zod.z.string().optional()),
|
|
20189
20296
|
config: createSwapRequestBaseSchema.shape.config.optional(),
|
|
20190
20297
|
fees: createSwapFeesSchema.optional(),
|
|
20191
20298
|
transaction: createSwapTransactionSchema
|
|
@@ -20311,6 +20418,45 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
|
|
|
20311
20418
|
// Validate without trimming - any whitespace will cause validation to fail
|
|
20312
20419
|
return apiKeyPattern.test(apiKey);
|
|
20313
20420
|
};
|
|
20421
|
+
/**
|
|
20422
|
+
* Assert that a Stablecoin Service kit key is not being supplied from a browser.
|
|
20423
|
+
*
|
|
20424
|
+
* The kit key (`KIT_KEY:<id>:<secret>`) is a server-only secret. Every
|
|
20425
|
+
* Stablecoin Service request that attaches an `Authorization: Bearer` header
|
|
20426
|
+
* funnels through this package, so calling this guard before that header is
|
|
20427
|
+
* built prevents the secret from being sent from — and thus bundled into — a
|
|
20428
|
+
* client application. In Node.js the check is a no-op, preserving the
|
|
20429
|
+
* legitimate "hold the kit key on the server, forward the prepared transaction
|
|
20430
|
+
* to the client" flow. When no kit key is supplied the permissionless (keyless)
|
|
20431
|
+
* client path remains fully allowed.
|
|
20432
|
+
*
|
|
20433
|
+
* @param apiKey - The inline kit key for the request, or `undefined` when none
|
|
20434
|
+
* was supplied (permissionless mode).
|
|
20435
|
+
* @returns Nothing.
|
|
20436
|
+
* @throws KitError with VALIDATION_FAILED when a kit key is supplied while
|
|
20437
|
+
* running in a browser environment. The secret value is never echoed.
|
|
20438
|
+
*
|
|
20439
|
+
* @example
|
|
20440
|
+
* ```typescript
|
|
20441
|
+
* import { assertBrowserSafeApiKey } from '@core/service-client'
|
|
20442
|
+
*
|
|
20443
|
+
* // Server (Node.js): no-op, request proceeds with the Authorization header.
|
|
20444
|
+
* assertBrowserSafeApiKey('KIT_KEY:my-id:my-secret')
|
|
20445
|
+
*
|
|
20446
|
+
* // Browser: throws to stop the secret from leaking into the client bundle.
|
|
20447
|
+
* assertBrowserSafeApiKey('KIT_KEY:my-id:my-secret')
|
|
20448
|
+
*
|
|
20449
|
+
* // Browser, permissionless: allowed.
|
|
20450
|
+
* assertBrowserSafeApiKey(undefined)
|
|
20451
|
+
* ```
|
|
20452
|
+
*/ const assertBrowserSafeApiKey = (apiKey)=>{
|
|
20453
|
+
if (apiKey === undefined) {
|
|
20454
|
+
return;
|
|
20455
|
+
}
|
|
20456
|
+
if (isBrowserEnvironment()) {
|
|
20457
|
+
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');
|
|
20458
|
+
}
|
|
20459
|
+
};
|
|
20314
20460
|
|
|
20315
20461
|
/**
|
|
20316
20462
|
* Create a cross-chain bridge and swap transaction through the Stablecoin Service.
|
|
@@ -20368,6 +20514,8 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
|
|
|
20368
20514
|
const url = new URL('/v1/stablecoinKits/swap', STABLECOIN_SERVICE_BASE_URL).toString();
|
|
20369
20515
|
// Remove the API key from the request body
|
|
20370
20516
|
const { apiKey, ...requestBody } = validatedParams;
|
|
20517
|
+
// Never let a server-only kit key leave a browser (no-op in Node.js).
|
|
20518
|
+
assertBrowserSafeApiKey(apiKey);
|
|
20371
20519
|
const effectiveConfig = {
|
|
20372
20520
|
...DEFAULT_CONFIG$1,
|
|
20373
20521
|
headers: {
|
|
@@ -20522,6 +20670,8 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
|
|
|
20522
20670
|
}
|
|
20523
20671
|
// Use validated data
|
|
20524
20672
|
const validatedParams = result.data;
|
|
20673
|
+
// Never let a server-only kit key leave a browser (no-op in Node.js).
|
|
20674
|
+
assertBrowserSafeApiKey(validatedParams.apiKey);
|
|
20525
20675
|
// Build the API URL
|
|
20526
20676
|
const url = buildQuoteUrl(validatedParams);
|
|
20527
20677
|
// Merge default config with Authorization header
|
|
@@ -20594,6 +20744,8 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
|
|
|
20594
20744
|
toChain: result.data.toChain
|
|
20595
20745
|
}
|
|
20596
20746
|
};
|
|
20747
|
+
// Never let a server-only kit key leave a browser (no-op in Node.js).
|
|
20748
|
+
assertBrowserSafeApiKey(validatedParams.apiKey);
|
|
20597
20749
|
const url = buildSwapStatusUrl(validatedParams);
|
|
20598
20750
|
const effectiveConfig = {
|
|
20599
20751
|
...DEFAULT_CONFIG$1,
|
|
@@ -20698,6 +20850,8 @@ getQuoteRequestBaseSchema.superRefine(requireCrossChainQuoteToAddress);
|
|
|
20698
20850
|
addresses: result.data.addresses
|
|
20699
20851
|
}
|
|
20700
20852
|
};
|
|
20853
|
+
// Never let a server-only kit key leave a browser (no-op in Node.js).
|
|
20854
|
+
assertBrowserSafeApiKey(validatedParams.apiKey);
|
|
20701
20855
|
const url = buildTokenRatesUrl(validatedParams);
|
|
20702
20856
|
const effectiveConfig = {
|
|
20703
20857
|
...DEFAULT_CONFIG$1,
|
|
@@ -27469,6 +27623,11 @@ async function fetchSameChainStatusSnapshot({ isCrossChainSwap, txHash, chain, a
|
|
|
27469
27623
|
apiKey: serviceParams.apiKey
|
|
27470
27624
|
}
|
|
27471
27625
|
});
|
|
27626
|
+
// Per-swap correlation id returned by the service as a top-level response
|
|
27627
|
+
// field for every chain (EVM + Solana). Attached to success telemetry so a
|
|
27628
|
+
// swap can be correlated across records; never used for control flow.
|
|
27629
|
+
// Undefined only against a not-yet-upgraded service that omits it.
|
|
27630
|
+
const correlationId = serviceResponse.correlationId;
|
|
27472
27631
|
// Build and return SwapResult
|
|
27473
27632
|
return {
|
|
27474
27633
|
tokenIn,
|
|
@@ -27478,6 +27637,9 @@ async function fetchSameChainStatusSnapshot({ isCrossChainSwap, txHash, chain, a
|
|
|
27478
27637
|
fromAddress: serviceParams.fromAddress,
|
|
27479
27638
|
toAddress: serviceParams.toAddress,
|
|
27480
27639
|
txHash,
|
|
27640
|
+
...correlationId !== undefined && {
|
|
27641
|
+
correlationId
|
|
27642
|
+
},
|
|
27481
27643
|
executedTransactions,
|
|
27482
27644
|
...config !== undefined && {
|
|
27483
27645
|
config
|
|
@@ -30377,7 +30539,13 @@ async function resolveTokenDecimals(context, resolvedParams) {
|
|
|
30377
30539
|
* amountIn: '50.00'
|
|
30378
30540
|
* })
|
|
30379
30541
|
* ```
|
|
30380
|
-
*/ async function swap$1(context, params, /**
|
|
30542
|
+
*/ async function swap$1(context, params, /**
|
|
30543
|
+
* @internal
|
|
30544
|
+
* Invoked after a successful broadcast with the on-chain `txHash` and the
|
|
30545
|
+
* service-issued `correlationId` (join key for success telemetry). The
|
|
30546
|
+
* service returns `correlationId` for every chain (EVM + Solana); it is
|
|
30547
|
+
* undefined only against a not-yet-upgraded service that omits the field.
|
|
30548
|
+
*/ onBroadcast) {
|
|
30381
30549
|
// Step 1: Validate parameters using schema
|
|
30382
30550
|
assertSwapParams(params, swapParamsSchema);
|
|
30383
30551
|
// Step 2: Resolve parameters (chain definitions, wallet addresses, token aliases preserved)
|
|
@@ -30397,13 +30565,16 @@ async function resolveTokenDecimals(context, resolvedParams) {
|
|
|
30397
30565
|
// Step 5: Execute swap via provider
|
|
30398
30566
|
const swapParams = buildServiceSwapParams(resolvedParams, paramsWithFees);
|
|
30399
30567
|
const providerResult = await provider.swap(swapParams);
|
|
30568
|
+
// `correlationId` is an internal telemetry join key, not part of the public
|
|
30569
|
+
// SwapResult — strip it here so it never leaks into the formatted result.
|
|
30570
|
+
const { correlationId, ...providerResultPublic } = providerResult;
|
|
30400
30571
|
// A throwing `onBroadcast` must never strand the caller after a
|
|
30401
30572
|
// successful swap broadcast — the chain has moved. `safeInvokeCallback`
|
|
30402
30573
|
// swallows the error and surfaces a `console.warn` prefixed with
|
|
30403
30574
|
// `[stablecoin-kits swap-kit] callback threw and was swallowed:` so a
|
|
30404
30575
|
// kit-side closure bug stays debuggable rather than vanishing.
|
|
30405
30576
|
safeInvokeCallback('swap-kit', ()=>{
|
|
30406
|
-
onBroadcast?.(
|
|
30577
|
+
onBroadcast?.(providerResultPublic.txHash, correlationId);
|
|
30407
30578
|
});
|
|
30408
30579
|
const { tokenInDecimals, tokenOutDecimals } = await resolveTokenDecimals(context, resolvedParams);
|
|
30409
30580
|
// Step 6: Compose chain identity (owned by the kit, derived from the
|
|
@@ -30412,10 +30583,10 @@ async function resolveTokenDecimals(context, resolvedParams) {
|
|
|
30412
30583
|
// resolves `progress` — the provider's snapshot, or a terminal `'DONE'` for
|
|
30413
30584
|
// a provider that omits it (a synchronous same-chain completion).
|
|
30414
30585
|
const composedResult = {
|
|
30415
|
-
...
|
|
30586
|
+
...providerResultPublic,
|
|
30416
30587
|
chainIn: resolvedParams.from.chain,
|
|
30417
30588
|
chainOut: resolvedParams.toChain ?? resolvedParams.from.chain,
|
|
30418
|
-
progress:
|
|
30589
|
+
progress: providerResultPublic.progress ?? {
|
|
30419
30590
|
status: 'DONE'
|
|
30420
30591
|
}
|
|
30421
30592
|
};
|
|
@@ -31196,7 +31367,7 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
|
|
|
31196
31367
|
ESTIMATE: 'swap_estimate'
|
|
31197
31368
|
};
|
|
31198
31369
|
|
|
31199
|
-
/** SDK name used in telemetry payloads. */ const SDK_NAME$
|
|
31370
|
+
/** SDK name used in telemetry payloads. */ const SDK_NAME$2 = resolveKitSdkName(pkg$3.name);
|
|
31200
31371
|
/**
|
|
31201
31372
|
* A high-level class-based interface for same-chain and cross-chain token swap operations.
|
|
31202
31373
|
*
|
|
@@ -31268,7 +31439,13 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
|
|
|
31268
31439
|
*/ class SwapKit {
|
|
31269
31440
|
context;
|
|
31270
31441
|
/** Whether error telemetry is disabled. */ disableErrorReporting;
|
|
31271
|
-
/** Per-kit telemetry identity for
|
|
31442
|
+
/** Per-kit telemetry identity for error reporting. */ telemetryConfig;
|
|
31443
|
+
/**
|
|
31444
|
+
* Per-kit telemetry identity for success/analytics events. Gated by
|
|
31445
|
+
* `disableAnalytics` (independent of `disableErrorReporting`) so a developer
|
|
31446
|
+
* can opt out of volume analytics without also silencing error reports —
|
|
31447
|
+
* mirrors EarnKit.
|
|
31448
|
+
*/ analyticsTelemetryConfig;
|
|
31272
31449
|
/**
|
|
31273
31450
|
* Create a new SwapKit instance.
|
|
31274
31451
|
*
|
|
@@ -31318,10 +31495,15 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
|
|
|
31318
31495
|
this.context = createSwapKitContext(config);
|
|
31319
31496
|
this.disableErrorReporting = config.disableErrorReporting === true;
|
|
31320
31497
|
this.telemetryConfig = {
|
|
31321
|
-
sdkName: SDK_NAME$
|
|
31498
|
+
sdkName: SDK_NAME$2,
|
|
31322
31499
|
sdkVersion: pkg$3.version,
|
|
31323
31500
|
disabled: this.disableErrorReporting
|
|
31324
31501
|
};
|
|
31502
|
+
this.analyticsTelemetryConfig = {
|
|
31503
|
+
sdkName: SDK_NAME$2,
|
|
31504
|
+
sdkVersion: pkg$3.version,
|
|
31505
|
+
disabled: config.disableAnalytics === true
|
|
31506
|
+
};
|
|
31325
31507
|
}
|
|
31326
31508
|
/**
|
|
31327
31509
|
* Estimate the output amount and fees for a swap operation.
|
|
@@ -31362,8 +31544,12 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
|
|
|
31362
31544
|
* console.log(`Fees:`, quote.fees)
|
|
31363
31545
|
* ```
|
|
31364
31546
|
*/ async estimate(params) {
|
|
31547
|
+
const destinationChain = params.to?.chain ? resolveChainName(params.to.chain) : undefined;
|
|
31365
31548
|
return withErrorTelemetry(async ()=>estimate(this.context, params), SWAP_EVENT_TYPES.ESTIMATE, this.telemetryConfig, {
|
|
31366
31549
|
sourceChain: resolveChainName(params.from.chain),
|
|
31550
|
+
...destinationChain != null && {
|
|
31551
|
+
destinationChain
|
|
31552
|
+
},
|
|
31367
31553
|
tokenIn: params.tokenIn,
|
|
31368
31554
|
tokenOut: params.tokenOut
|
|
31369
31555
|
});
|
|
@@ -31422,16 +31608,54 @@ function resolveTokenEntry(entry, index, chain, chainDef, context) {
|
|
|
31422
31608
|
* ```
|
|
31423
31609
|
*/ async swap(params) {
|
|
31424
31610
|
let txHash;
|
|
31425
|
-
|
|
31426
|
-
|
|
31427
|
-
|
|
31611
|
+
let correlationId;
|
|
31612
|
+
// Shared context builder so the error resolver and the success emit stay in
|
|
31613
|
+
// lockstep — a field added here reaches both call sites. Reads the per-call
|
|
31614
|
+
// locals lazily, so txHash/correlationId (set during the swap) are captured
|
|
31615
|
+
// whenever it is invoked.
|
|
31616
|
+
// Destination chain is the primary attribution dimension for cross-chain
|
|
31617
|
+
// swaps; resolved once from the (static) params. Omitted for same-chain
|
|
31618
|
+
// swaps that leave `to.chain` unset (destination == source).
|
|
31619
|
+
const destinationChain = params.to?.chain ? resolveChainName(params.to.chain) : undefined;
|
|
31620
|
+
const buildTelemetryContext = ()=>({
|
|
31428
31621
|
sourceChain: resolveChainName(params.from.chain),
|
|
31622
|
+
...destinationChain != null && {
|
|
31623
|
+
destinationChain
|
|
31624
|
+
},
|
|
31429
31625
|
tokenIn: params.tokenIn,
|
|
31430
31626
|
tokenOut: params.tokenOut,
|
|
31431
31627
|
...txHash != null && {
|
|
31432
31628
|
txHash
|
|
31629
|
+
},
|
|
31630
|
+
...correlationId != null && {
|
|
31631
|
+
correlationId
|
|
31433
31632
|
}
|
|
31434
|
-
})
|
|
31633
|
+
});
|
|
31634
|
+
const result = await withErrorTelemetry(async ()=>swap$1(this.context, params, (h, cId)=>{
|
|
31635
|
+
txHash = h;
|
|
31636
|
+
correlationId = cId;
|
|
31637
|
+
}), SWAP_EVENT_TYPES.SWAP, this.telemetryConfig, buildTelemetryContext);
|
|
31638
|
+
// withErrorTelemetry only emits on failure. Record the successful swap here
|
|
31639
|
+
// so the backend can attribute swap volume to a developer: the client event
|
|
31640
|
+
// carries the (burn) txHash + correlationId, which joins to the
|
|
31641
|
+
// server-emitted event carrying entity_id. Best-effort; never throws.
|
|
31642
|
+
//
|
|
31643
|
+
// Emit whenever a broadcast happened, i.e. we have the source/burn txHash.
|
|
31644
|
+
// For a cross-chain swap that is the source-chain burn (progress is still
|
|
31645
|
+
// PENDING while the destination mint settles) — we intentionally attribute
|
|
31646
|
+
// at broadcast using the burn txHash rather than tracking the destination
|
|
31647
|
+
// leg, which keeps the capture simple and self-contained in swap().
|
|
31648
|
+
//
|
|
31649
|
+
// Guard against a terminal-failure result: the EVM provider throws on
|
|
31650
|
+
// revert today, but the kit is provider-agnostic, so a provider that
|
|
31651
|
+
// returns a FAILED/NOT_FOUND result without throwing must not be recorded
|
|
31652
|
+
// as a successful swap. Routed through analyticsTelemetryConfig so it is
|
|
31653
|
+
// gated by disableAnalytics, independent of error reporting.
|
|
31654
|
+
const status = result.progress?.status;
|
|
31655
|
+
if (txHash != null && status !== 'FAILED' && status !== 'NOT_FOUND') {
|
|
31656
|
+
emitSuccessTelemetry(SWAP_EVENT_TYPES.SWAP, this.analyticsTelemetryConfig, buildTelemetryContext());
|
|
31657
|
+
}
|
|
31658
|
+
return result;
|
|
31435
31659
|
}
|
|
31436
31660
|
/**
|
|
31437
31661
|
* Fetch the current status of a swap from the Stablecoin Service.
|
|
@@ -31810,6 +32034,9 @@ registerKit(`${pkg$3.name}/${pkg$3.version}`);
|
|
|
31810
32034
|
const kit = new SwapKit({
|
|
31811
32035
|
...context.disableErrorReporting != null && {
|
|
31812
32036
|
disableErrorReporting: context.disableErrorReporting
|
|
32037
|
+
},
|
|
32038
|
+
...context.disableAnalytics != null && {
|
|
32039
|
+
disableAnalytics: context.disableAnalytics
|
|
31813
32040
|
}
|
|
31814
32041
|
});
|
|
31815
32042
|
if (hasBoth) {
|
|
@@ -31871,7 +32098,7 @@ registerKit(`${pkg$3.name}/${pkg$3.version}`);
|
|
|
31871
32098
|
};
|
|
31872
32099
|
|
|
31873
32100
|
var name$2 = "@circle-fin/earn-kit";
|
|
31874
|
-
var version$2 = "1.
|
|
32101
|
+
var version$2 = "1.4.0";
|
|
31875
32102
|
var pkg$2 = {
|
|
31876
32103
|
name: name$2,
|
|
31877
32104
|
version: version$2};
|
|
@@ -33870,7 +34097,7 @@ const bridgeDepositPrepareReviewSchema = zod.z.object({
|
|
|
33870
34097
|
}
|
|
33871
34098
|
|
|
33872
34099
|
var name$1 = "@circle-fin/provider-earn-service";
|
|
33873
|
-
var version$1 = "1.3.
|
|
34100
|
+
var version$1 = "1.3.1";
|
|
33874
34101
|
var pkg$1 = {
|
|
33875
34102
|
name: name$1,
|
|
33876
34103
|
version: version$1};
|
|
@@ -33932,15 +34159,25 @@ var pkg$1 = {
|
|
|
33932
34159
|
*
|
|
33933
34160
|
* @internal
|
|
33934
34161
|
*/ function buildConfig(serviceConfig) {
|
|
34162
|
+
// The kit key is a server-only secret. Reject it in the browser so it cannot
|
|
34163
|
+
// leak into a client bundle (no-op in Node.js). Keyless usage stays allowed.
|
|
34164
|
+
if (serviceConfig?.kitKey !== undefined && isBrowserEnvironment()) {
|
|
34165
|
+
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');
|
|
34166
|
+
}
|
|
33935
34167
|
const baseUrl = serviceConfig?.baseUrl ?? EARN_SERVICE_BASE_URL;
|
|
33936
|
-
|
|
34168
|
+
// The API CORS policy does not allow this custom header. Keep the existing
|
|
34169
|
+
// per-request version attribution for Node callers, but omit it in browsers
|
|
34170
|
+
// so public EarnKit endpoints do not fail at CORS preflight.
|
|
34171
|
+
const sdkVersionHeader = isNodeEnvironment() ? {
|
|
34172
|
+
[SDK_VERSION_HEADER]: resolveSdkVersionHeader()
|
|
34173
|
+
} : {};
|
|
33937
34174
|
if (serviceConfig?.kitKey === undefined) {
|
|
33938
34175
|
return {
|
|
33939
34176
|
pollingConfig: {
|
|
33940
34177
|
...DEFAULT_CONFIG,
|
|
33941
34178
|
headers: {
|
|
33942
34179
|
...DEFAULT_CONFIG.headers,
|
|
33943
|
-
|
|
34180
|
+
...sdkVersionHeader
|
|
33944
34181
|
}
|
|
33945
34182
|
},
|
|
33946
34183
|
baseUrl
|
|
@@ -33958,7 +34195,7 @@ var pkg$1 = {
|
|
|
33958
34195
|
...DEFAULT_CONFIG,
|
|
33959
34196
|
headers: {
|
|
33960
34197
|
...DEFAULT_CONFIG.headers,
|
|
33961
|
-
|
|
34198
|
+
...sdkVersionHeader,
|
|
33962
34199
|
Authorization: `Bearer ${serviceConfig.kitKey}`
|
|
33963
34200
|
}
|
|
33964
34201
|
},
|
|
@@ -36072,6 +36309,12 @@ function createUnsupportedCrossChainDepositError(chain, reason) {
|
|
|
36072
36309
|
if (config.providers !== undefined && !Array.isArray(config.providers)) {
|
|
36073
36310
|
throw createValidationFailedError$1('config.providers', config.providers, 'providers must be an array of earn providers when provided');
|
|
36074
36311
|
}
|
|
36312
|
+
if (config.disableAnalytics !== undefined && typeof config.disableAnalytics !== 'boolean') {
|
|
36313
|
+
throw createValidationFailedError$1('config.disableAnalytics', config.disableAnalytics, 'disableAnalytics must be a boolean when provided');
|
|
36314
|
+
}
|
|
36315
|
+
if (config.disableErrorReporting !== undefined && typeof config.disableErrorReporting !== 'boolean') {
|
|
36316
|
+
throw createValidationFailedError$1('config.disableErrorReporting', config.disableErrorReporting, 'disableErrorReporting must be a boolean when provided');
|
|
36317
|
+
}
|
|
36075
36318
|
const defaultProviders = getDefaultProviders$1();
|
|
36076
36319
|
const providers = [
|
|
36077
36320
|
...config.providers ?? [],
|
|
@@ -36083,6 +36326,31 @@ function createUnsupportedCrossChainDepositError(chain, reason) {
|
|
|
36083
36326
|
return context;
|
|
36084
36327
|
}
|
|
36085
36328
|
|
|
36329
|
+
/**
|
|
36330
|
+
* Register Earn Kit telemetry event type strings with the shared registry so
|
|
36331
|
+
* error telemetry helpers remain compile-time checked.
|
|
36332
|
+
*
|
|
36333
|
+
* @internal
|
|
36334
|
+
*/ /**
|
|
36335
|
+
* Telemetry event type identifiers for Earn Kit operations.
|
|
36336
|
+
*
|
|
36337
|
+
* @internal
|
|
36338
|
+
*/ const EARN_EVENT_TYPES = {
|
|
36339
|
+
GET_VAULTS: 'earn_get_vaults',
|
|
36340
|
+
EXPLORE_VAULTS: 'earn_explore_vaults',
|
|
36341
|
+
GET_POSITION: 'earn_get_position',
|
|
36342
|
+
GET_CROSS_CHAIN_DEPOSIT_STATUS: 'earn_get_cross_chain_deposit_status',
|
|
36343
|
+
WAIT_FOR_CROSS_CHAIN_DEPOSIT: 'earn_wait_for_cross_chain_deposit',
|
|
36344
|
+
DEPOSIT: 'earn_deposit',
|
|
36345
|
+
CROSS_CHAIN_DEPOSIT: 'earn_cross_chain_deposit',
|
|
36346
|
+
WITHDRAW: 'earn_withdraw',
|
|
36347
|
+
CLAIM_REWARDS: 'earn_claim_rewards',
|
|
36348
|
+
GET_DEPOSIT_QUOTE: 'earn_get_deposit_quote',
|
|
36349
|
+
GET_WITHDRAWAL_QUOTE: 'earn_get_withdrawal_quote',
|
|
36350
|
+
GET_CLAIM_REWARDS_QUOTE: 'earn_get_claim_rewards_quote',
|
|
36351
|
+
RETRY: 'earn_retry'
|
|
36352
|
+
};
|
|
36353
|
+
|
|
36086
36354
|
/**
|
|
36087
36355
|
* Format a provider amount object as a human-readable decimal string.
|
|
36088
36356
|
*
|
|
@@ -37598,6 +37866,14 @@ function hasCrossChainDestination(params) {
|
|
|
37598
37866
|
return formatClaimRewardsQuoteInfo(result);
|
|
37599
37867
|
}
|
|
37600
37868
|
|
|
37869
|
+
/** SDK name used in telemetry payloads. */ const SDK_NAME$1 = resolveKitSdkName(pkg$2.name);
|
|
37870
|
+
/**
|
|
37871
|
+
* Determine whether deposit parameters target a destination chain.
|
|
37872
|
+
*
|
|
37873
|
+
* @internal
|
|
37874
|
+
*/ function isCrossChainDeposit(params) {
|
|
37875
|
+
return 'to' in params && params.to !== undefined;
|
|
37876
|
+
}
|
|
37601
37877
|
function formatRetryResult(operation, result) {
|
|
37602
37878
|
switch(operation){
|
|
37603
37879
|
case 'deposit':
|
|
@@ -37612,6 +37888,70 @@ function formatRetryResult(operation, result) {
|
|
|
37612
37888
|
}
|
|
37613
37889
|
}
|
|
37614
37890
|
}
|
|
37891
|
+
/**
|
|
37892
|
+
* Emit the success event corresponding to a completed retry.
|
|
37893
|
+
*
|
|
37894
|
+
* @internal
|
|
37895
|
+
*/ function emitRetrySuccessTelemetry(trace, result, config) {
|
|
37896
|
+
switch(trace.operation){
|
|
37897
|
+
case 'deposit':
|
|
37898
|
+
{
|
|
37899
|
+
const sourceChain = resolveChainName(trace.params.from.chain);
|
|
37900
|
+
if ('to' in trace.params && trace.params.to !== undefined) {
|
|
37901
|
+
const destinationChain = resolveChainName(trace.params.to.chain);
|
|
37902
|
+
emitSuccessTelemetry(EARN_EVENT_TYPES.CROSS_CHAIN_DEPOSIT, config, {
|
|
37903
|
+
...sourceChain != null && {
|
|
37904
|
+
sourceChain
|
|
37905
|
+
},
|
|
37906
|
+
...destinationChain != null && {
|
|
37907
|
+
destinationChain
|
|
37908
|
+
}
|
|
37909
|
+
});
|
|
37910
|
+
return;
|
|
37911
|
+
}
|
|
37912
|
+
emitSuccessTelemetry(EARN_EVENT_TYPES.DEPOSIT, config, {
|
|
37913
|
+
...sourceChain != null && {
|
|
37914
|
+
sourceChain
|
|
37915
|
+
},
|
|
37916
|
+
...'txHash' in result && {
|
|
37917
|
+
txHash: result.txHash
|
|
37918
|
+
}
|
|
37919
|
+
});
|
|
37920
|
+
return;
|
|
37921
|
+
}
|
|
37922
|
+
case 'withdraw':
|
|
37923
|
+
{
|
|
37924
|
+
const sourceChain = resolveChainName(trace.params.from.chain);
|
|
37925
|
+
emitSuccessTelemetry(EARN_EVENT_TYPES.WITHDRAW, config, {
|
|
37926
|
+
...sourceChain != null && {
|
|
37927
|
+
sourceChain
|
|
37928
|
+
},
|
|
37929
|
+
...'txHash' in result && {
|
|
37930
|
+
txHash: result.txHash
|
|
37931
|
+
}
|
|
37932
|
+
});
|
|
37933
|
+
return;
|
|
37934
|
+
}
|
|
37935
|
+
case 'claimRewards':
|
|
37936
|
+
{
|
|
37937
|
+
if ('rewards' in result && result.status === 'claimed') {
|
|
37938
|
+
const sourceChain = resolveChainName(trace.params.from.chain);
|
|
37939
|
+
emitSuccessTelemetry(EARN_EVENT_TYPES.CLAIM_REWARDS, config, {
|
|
37940
|
+
...sourceChain != null && {
|
|
37941
|
+
sourceChain
|
|
37942
|
+
},
|
|
37943
|
+
txHash: result.txHash
|
|
37944
|
+
});
|
|
37945
|
+
}
|
|
37946
|
+
return;
|
|
37947
|
+
}
|
|
37948
|
+
default:
|
|
37949
|
+
{
|
|
37950
|
+
const exhaustive = trace;
|
|
37951
|
+
throw createValidationFailedError$1('error.cause.trace', exhaustive, 'EarnKit.retry() does not support this earn operation');
|
|
37952
|
+
}
|
|
37953
|
+
}
|
|
37954
|
+
}
|
|
37615
37955
|
/**
|
|
37616
37956
|
* A high-level class-based interface for DeFi lending vault operations.
|
|
37617
37957
|
*
|
|
@@ -37670,6 +38010,8 @@ function formatRetryResult(operation, result) {
|
|
|
37670
38010
|
* ```
|
|
37671
38011
|
*/ class EarnKit {
|
|
37672
38012
|
context;
|
|
38013
|
+
/** Per-kit identity and opt-out state for error telemetry. */ telemetryConfig;
|
|
38014
|
+
/** Per-kit identity and opt-out state for success telemetry. */ analyticsTelemetryConfig;
|
|
37673
38015
|
/**
|
|
37674
38016
|
* Event dispatcher for step-level events emitted during multi-phase earn
|
|
37675
38017
|
* operations. Prefer {@link EarnKit.on} / {@link EarnKit.off} over using
|
|
@@ -37694,6 +38036,16 @@ function formatRetryResult(operation, result) {
|
|
|
37694
38036
|
*/ constructor(config = {}){
|
|
37695
38037
|
this.context = createEarnKitContext(config);
|
|
37696
38038
|
this.actionDispatcher = new Actionable();
|
|
38039
|
+
this.telemetryConfig = {
|
|
38040
|
+
sdkName: SDK_NAME$1,
|
|
38041
|
+
sdkVersion: pkg$2.version,
|
|
38042
|
+
disabled: config.disableErrorReporting === true
|
|
38043
|
+
};
|
|
38044
|
+
this.analyticsTelemetryConfig = {
|
|
38045
|
+
sdkName: SDK_NAME$1,
|
|
38046
|
+
sdkVersion: pkg$2.version,
|
|
38047
|
+
disabled: config.disableAnalytics === true
|
|
38048
|
+
};
|
|
37697
38049
|
for (const provider of this.context.providers){
|
|
37698
38050
|
provider.registerDispatcher(this.actionDispatcher);
|
|
37699
38051
|
}
|
|
@@ -37754,29 +38106,36 @@ function formatRetryResult(operation, result) {
|
|
|
37754
38106
|
* }
|
|
37755
38107
|
* ```
|
|
37756
38108
|
*/ async retry(error) {
|
|
37757
|
-
|
|
37758
|
-
|
|
37759
|
-
|
|
37760
|
-
|
|
37761
|
-
|
|
37762
|
-
|
|
37763
|
-
|
|
37764
|
-
|
|
37765
|
-
|
|
37766
|
-
|
|
37767
|
-
|
|
37768
|
-
|
|
37769
|
-
|
|
37770
|
-
|
|
37771
|
-
|
|
37772
|
-
|
|
37773
|
-
|
|
37774
|
-
|
|
37775
|
-
|
|
37776
|
-
|
|
38109
|
+
const result = await withErrorTelemetry(async ()=>{
|
|
38110
|
+
if (!isKitError(error)) {
|
|
38111
|
+
throw createValidationFailedError$1('error', error, 'EarnKit.retry() requires a KitError thrown by a previous earn operation');
|
|
38112
|
+
}
|
|
38113
|
+
if (!isRetryableError$1(error)) {
|
|
38114
|
+
throw createValidationFailedError$1('error.recoverability', error.recoverability, 'EarnKit.retry() requires a retryable or resumable error — check isRetryableError(error) first');
|
|
38115
|
+
}
|
|
38116
|
+
const trace = error.cause?.trace;
|
|
38117
|
+
if (!isEarnErrorTrace(trace)) {
|
|
38118
|
+
throw createValidationFailedError$1('error.cause.trace', trace, 'EarnKit.retry() requires a KitError carrying earn retry context (operation, steps, provider, params)');
|
|
38119
|
+
}
|
|
38120
|
+
const provider = this.context.providers.find((candidate)=>candidate.name === trace.provider);
|
|
38121
|
+
if (provider === undefined) {
|
|
38122
|
+
throw createValidationFailedError$1('error.cause.trace.provider', trace.provider, `No earn provider named "${trace.provider}" is registered with this kit`);
|
|
38123
|
+
}
|
|
38124
|
+
const result = await provider.retry(error);
|
|
38125
|
+
// `provider.retry` returns a flat result union with no compile-time link to
|
|
38126
|
+
// `trace.operation`, so narrow the operation here to select the matching
|
|
38127
|
+
// overload. The result cast in each branch is sound: the provider always
|
|
38128
|
+
// returns the result type corresponding to the resumed operation.
|
|
38129
|
+
if (trace.operation === 'claimRewards') {
|
|
38130
|
+
return formatRetryResult(trace.operation, result);
|
|
38131
|
+
}
|
|
37777
38132
|
return formatRetryResult(trace.operation, result);
|
|
38133
|
+
}, EARN_EVENT_TYPES.RETRY, this.telemetryConfig);
|
|
38134
|
+
const trace = isKitError(error) ? error.cause?.trace : undefined;
|
|
38135
|
+
if (isEarnErrorTrace(trace)) {
|
|
38136
|
+
emitRetrySuccessTelemetry(trace, result, this.analyticsTelemetryConfig);
|
|
37778
38137
|
}
|
|
37779
|
-
return
|
|
38138
|
+
return result;
|
|
37780
38139
|
}
|
|
37781
38140
|
/**
|
|
37782
38141
|
* Return the chains supported by configured earn providers.
|
|
@@ -37810,7 +38169,9 @@ function formatRetryResult(operation, result) {
|
|
|
37810
38169
|
* result.vaults.forEach(v => console.log(`${v.name}: ${(v.currentApy * 100).toFixed(2)}% APY`))
|
|
37811
38170
|
* ```
|
|
37812
38171
|
*/ async getVaults(params) {
|
|
37813
|
-
|
|
38172
|
+
const result = await withErrorTelemetry(async ()=>getVaults$1(this.context, params), EARN_EVENT_TYPES.GET_VAULTS, this.telemetryConfig);
|
|
38173
|
+
emitSuccessTelemetry(EARN_EVENT_TYPES.GET_VAULTS, this.analyticsTelemetryConfig, {});
|
|
38174
|
+
return result;
|
|
37814
38175
|
}
|
|
37815
38176
|
/**
|
|
37816
38177
|
* Discover vaults available on a chain.
|
|
@@ -37835,7 +38196,12 @@ function formatRetryResult(operation, result) {
|
|
|
37835
38196
|
* const guarded = result.vaults.filter(v => v.circleGuarded) // Circle-guarded vaults only
|
|
37836
38197
|
* ```
|
|
37837
38198
|
*/ async exploreVaults(params) {
|
|
37838
|
-
|
|
38199
|
+
const context = {
|
|
38200
|
+
sourceChain: resolveChainName(params.chain)
|
|
38201
|
+
};
|
|
38202
|
+
const result = await withErrorTelemetry(async ()=>exploreVaults$1(this.context, params), EARN_EVENT_TYPES.EXPLORE_VAULTS, this.telemetryConfig, context);
|
|
38203
|
+
emitSuccessTelemetry(EARN_EVENT_TYPES.EXPLORE_VAULTS, this.analyticsTelemetryConfig, context);
|
|
38204
|
+
return result;
|
|
37839
38205
|
}
|
|
37840
38206
|
/**
|
|
37841
38207
|
* Lazily iterate every vault available on a chain.
|
|
@@ -37882,7 +38248,9 @@ function formatRetryResult(operation, result) {
|
|
|
37882
38248
|
* }
|
|
37883
38249
|
* ```
|
|
37884
38250
|
*/ async getPosition(params) {
|
|
37885
|
-
return getPosition$1(this.context, params)
|
|
38251
|
+
return withErrorTelemetry(async ()=>getPosition$1(this.context, params), EARN_EVENT_TYPES.GET_POSITION, this.telemetryConfig, {
|
|
38252
|
+
sourceChain: resolveChainName(params.from.chain)
|
|
38253
|
+
});
|
|
37886
38254
|
}
|
|
37887
38255
|
/**
|
|
37888
38256
|
* Fetch the current status of a cross-chain deposit by execution ID.
|
|
@@ -37907,7 +38275,7 @@ function formatRetryResult(operation, result) {
|
|
|
37907
38275
|
* console.log(`Bridge ${status.execId} is ${status.status}`)
|
|
37908
38276
|
* ```
|
|
37909
38277
|
*/ async getCrossChainDepositStatus(params) {
|
|
37910
|
-
return getCrossChainDepositStatus$1(this.context, params);
|
|
38278
|
+
return withErrorTelemetry(async ()=>getCrossChainDepositStatus$1(this.context, params), EARN_EVENT_TYPES.GET_CROSS_CHAIN_DEPOSIT_STATUS, this.telemetryConfig);
|
|
37911
38279
|
}
|
|
37912
38280
|
/**
|
|
37913
38281
|
* Poll a cross-chain deposit until it reaches a terminal bridge state.
|
|
@@ -37934,10 +38302,30 @@ function formatRetryResult(operation, result) {
|
|
|
37934
38302
|
* console.log(`Bridge ended as ${result.outcome}`)
|
|
37935
38303
|
* ```
|
|
37936
38304
|
*/ async waitForCrossChainDeposit(params) {
|
|
37937
|
-
return waitForCrossChainDeposit$1(this.context, params);
|
|
38305
|
+
return withErrorTelemetry(async ()=>waitForCrossChainDeposit$1(this.context, params), EARN_EVENT_TYPES.WAIT_FOR_CROSS_CHAIN_DEPOSIT, this.telemetryConfig);
|
|
37938
38306
|
}
|
|
37939
38307
|
async deposit(params) {
|
|
37940
|
-
|
|
38308
|
+
const isCrossChain = isCrossChainDeposit(params);
|
|
38309
|
+
const context = {
|
|
38310
|
+
sourceChain: resolveChainName(params.from.chain),
|
|
38311
|
+
...isCrossChain && {
|
|
38312
|
+
destinationChain: resolveChainName(params.to.chain)
|
|
38313
|
+
}
|
|
38314
|
+
};
|
|
38315
|
+
const eventType = isCrossChain ? EARN_EVENT_TYPES.CROSS_CHAIN_DEPOSIT : EARN_EVENT_TYPES.DEPOSIT;
|
|
38316
|
+
const result = await withErrorTelemetry(async ()=>deposit$3(this.context, params), eventType, this.telemetryConfig, context);
|
|
38317
|
+
if (result.kind === 'cross-chain') {
|
|
38318
|
+
emitSuccessTelemetry(EARN_EVENT_TYPES.CROSS_CHAIN_DEPOSIT, this.analyticsTelemetryConfig, {
|
|
38319
|
+
sourceChain: resolveChainName(result.sourceChain),
|
|
38320
|
+
destinationChain: resolveChainName(result.destinationChain)
|
|
38321
|
+
});
|
|
38322
|
+
} else {
|
|
38323
|
+
emitSuccessTelemetry(EARN_EVENT_TYPES.DEPOSIT, this.analyticsTelemetryConfig, {
|
|
38324
|
+
...context,
|
|
38325
|
+
txHash: result.txHash
|
|
38326
|
+
});
|
|
38327
|
+
}
|
|
38328
|
+
return result;
|
|
37941
38329
|
}
|
|
37942
38330
|
/**
|
|
37943
38331
|
* Execute a withdrawal from a DeFi lending vault.
|
|
@@ -37963,7 +38351,15 @@ function formatRetryResult(operation, result) {
|
|
|
37963
38351
|
* console.log(`Withdrew ${result.amount} from ${result.vaultAddress}, tx: ${result.txHash}`)
|
|
37964
38352
|
* ```
|
|
37965
38353
|
*/ async withdraw(params) {
|
|
37966
|
-
|
|
38354
|
+
const context = {
|
|
38355
|
+
sourceChain: resolveChainName(params.from.chain)
|
|
38356
|
+
};
|
|
38357
|
+
const result = await withErrorTelemetry(async ()=>withdraw$1(this.context, params), EARN_EVENT_TYPES.WITHDRAW, this.telemetryConfig, context);
|
|
38358
|
+
emitSuccessTelemetry(EARN_EVENT_TYPES.WITHDRAW, this.analyticsTelemetryConfig, {
|
|
38359
|
+
...context,
|
|
38360
|
+
txHash: result.txHash
|
|
38361
|
+
});
|
|
38362
|
+
return result;
|
|
37967
38363
|
}
|
|
37968
38364
|
/**
|
|
37969
38365
|
* Claim rewards from earn vaults.
|
|
@@ -37990,7 +38386,17 @@ function formatRetryResult(operation, result) {
|
|
|
37990
38386
|
*
|
|
37991
38387
|
* @internal
|
|
37992
38388
|
*/ async claimRewards(params) {
|
|
37993
|
-
|
|
38389
|
+
const context = {
|
|
38390
|
+
sourceChain: resolveChainName(params.from.chain)
|
|
38391
|
+
};
|
|
38392
|
+
const result = await withErrorTelemetry(async ()=>claimRewards$1(this.context, params), EARN_EVENT_TYPES.CLAIM_REWARDS, this.telemetryConfig, context);
|
|
38393
|
+
if (result.status === 'claimed') {
|
|
38394
|
+
emitSuccessTelemetry(EARN_EVENT_TYPES.CLAIM_REWARDS, this.analyticsTelemetryConfig, {
|
|
38395
|
+
...context,
|
|
38396
|
+
txHash: result.txHash
|
|
38397
|
+
});
|
|
38398
|
+
}
|
|
38399
|
+
return result;
|
|
37994
38400
|
}
|
|
37995
38401
|
/**
|
|
37996
38402
|
* Get an informational quote for a deposit into a vault.
|
|
@@ -38012,7 +38418,9 @@ function formatRetryResult(operation, result) {
|
|
|
38012
38418
|
* console.log(`Expected shares: ${quote.expectedShares.amount}`)
|
|
38013
38419
|
* ```
|
|
38014
38420
|
*/ async getDepositQuote(params) {
|
|
38015
|
-
return getDepositQuote$1(this.context, params)
|
|
38421
|
+
return withErrorTelemetry(async ()=>getDepositQuote$1(this.context, params), EARN_EVENT_TYPES.GET_DEPOSIT_QUOTE, this.telemetryConfig, {
|
|
38422
|
+
sourceChain: resolveChainName(params.from.chain)
|
|
38423
|
+
});
|
|
38016
38424
|
}
|
|
38017
38425
|
/**
|
|
38018
38426
|
* Get an informational quote for a withdrawal from a vault.
|
|
@@ -38034,7 +38442,9 @@ function formatRetryResult(operation, result) {
|
|
|
38034
38442
|
* console.log(`Shares to redeem: ${quote.sharesToRedeem.amount}`)
|
|
38035
38443
|
* ```
|
|
38036
38444
|
*/ async getWithdrawalQuote(params) {
|
|
38037
|
-
return getWithdrawalQuote$1(this.context, params)
|
|
38445
|
+
return withErrorTelemetry(async ()=>getWithdrawalQuote$1(this.context, params), EARN_EVENT_TYPES.GET_WITHDRAWAL_QUOTE, this.telemetryConfig, {
|
|
38446
|
+
sourceChain: resolveChainName(params.from.chain)
|
|
38447
|
+
});
|
|
38038
38448
|
}
|
|
38039
38449
|
/**
|
|
38040
38450
|
* Get an informational quote for claiming rewards.
|
|
@@ -38056,7 +38466,9 @@ function formatRetryResult(operation, result) {
|
|
|
38056
38466
|
*
|
|
38057
38467
|
* @internal
|
|
38058
38468
|
*/ async getClaimRewardsQuote(params) {
|
|
38059
|
-
return getClaimRewardsQuote$1(this.context, params)
|
|
38469
|
+
return withErrorTelemetry(async ()=>getClaimRewardsQuote$1(this.context, params), EARN_EVENT_TYPES.GET_CLAIM_REWARDS_QUOTE, this.telemetryConfig, {
|
|
38470
|
+
sourceChain: resolveChainName(params.from.chain)
|
|
38471
|
+
});
|
|
38060
38472
|
}
|
|
38061
38473
|
}
|
|
38062
38474
|
|
|
@@ -38145,7 +38557,14 @@ registerKit(`${pkg$2.name}/${pkg$2.version}`);
|
|
|
38145
38557
|
* const earnKit = createEarnKit(context)
|
|
38146
38558
|
* ```
|
|
38147
38559
|
*/ const createEarnKit = (context)=>{
|
|
38148
|
-
const kit = new EarnKit(
|
|
38560
|
+
const kit = new EarnKit({
|
|
38561
|
+
...context.disableErrorReporting != null && {
|
|
38562
|
+
disableErrorReporting: context.disableErrorReporting
|
|
38563
|
+
},
|
|
38564
|
+
...context.disableAnalytics != null && {
|
|
38565
|
+
disableAnalytics: context.disableAnalytics
|
|
38566
|
+
}
|
|
38567
|
+
});
|
|
38149
38568
|
registerActionHandlers(kit, context.actions.earn, 'earn');
|
|
38150
38569
|
return kit;
|
|
38151
38570
|
};
|
|
@@ -39454,7 +39873,7 @@ async function deposit$2(context, params) {
|
|
|
39454
39873
|
}
|
|
39455
39874
|
|
|
39456
39875
|
var name = "@circle-fin/unified-balance-kit";
|
|
39457
|
-
var version = "1.3.
|
|
39876
|
+
var version = "1.3.1";
|
|
39458
39877
|
var pkg = {
|
|
39459
39878
|
name: name,
|
|
39460
39879
|
version: version};
|
|
@@ -45964,7 +46383,11 @@ const removeFundParamsSchema = zod.z.object({
|
|
|
45964
46383
|
// Remove Fund Operations
|
|
45965
46384
|
// ---------------------------------------------------------------------------
|
|
45966
46385
|
/**
|
|
45967
|
-
* Kick off a delayed fund removal from an account.
|
|
46386
|
+
* Kick off a delayed recovery fund removal from an account.
|
|
46387
|
+
*
|
|
46388
|
+
* Use `initiateRemoveFund` only as a trustless fallback when the normal spend
|
|
46389
|
+
* flow is unavailable. For day-to-day movement out of a Unified Balance, use
|
|
46390
|
+
* `spend`.
|
|
45968
46391
|
*
|
|
45969
46392
|
* Validates `from` and `amount`, resolves the chain and token via
|
|
45970
46393
|
* {@link resolveRemoveFundParams}, selects the matching provider, then calls
|
|
@@ -46001,7 +46424,10 @@ const removeFundParamsSchema = zod.z.object({
|
|
|
46001
46424
|
return provider.initiateRemoveFund(resolved);
|
|
46002
46425
|
}
|
|
46003
46426
|
/**
|
|
46004
|
-
* Complete a fund removal once the 7-day
|
|
46427
|
+
* Complete a recovery fund removal once the 7-day withdrawal delay has passed.
|
|
46428
|
+
*
|
|
46429
|
+
* Use `removeFund` only as a trustless fallback when the normal spend flow is
|
|
46430
|
+
* unavailable. For day-to-day movement out of a Unified Balance, use `spend`.
|
|
46005
46431
|
*
|
|
46006
46432
|
* Validates `from`, resolves the chain and token via
|
|
46007
46433
|
* {@link resolveRemoveFundParams}, selects the matching provider, then calls
|
|
@@ -46090,13 +46516,18 @@ const removeFundParamsSchema = zod.z.object({
|
|
|
46090
46516
|
/** SDK name used in telemetry payloads. */ const SDK_NAME = resolveKitSdkName(pkg.name);
|
|
46091
46517
|
/**
|
|
46092
46518
|
* A high-level class-based interface for cross-chain USDC deposits,
|
|
46093
|
-
* spending, balance queries, delegation management, and
|
|
46519
|
+
* spending, balance queries, delegation management, and recovery fund removals.
|
|
46094
46520
|
*
|
|
46095
46521
|
* UnifiedBalanceKit provides a familiar class-based API for developers who
|
|
46096
46522
|
* prefer traditional object-oriented patterns. The class maintains an
|
|
46097
46523
|
* internal context and provides methods that delegate to the standalone
|
|
46098
46524
|
* operation functions exported by this package.
|
|
46099
46525
|
*
|
|
46526
|
+
* Use `spend` for normal movement out of a Unified Balance. `removeFund` is a
|
|
46527
|
+
* trustless recovery path for situations where the normal spend flow is
|
|
46528
|
+
* unavailable, and it requires a 7-day withdrawal delay before funds can be
|
|
46529
|
+
* removed.
|
|
46530
|
+
*
|
|
46100
46531
|
* @remarks
|
|
46101
46532
|
* For functional usage, import and use the operations directly:
|
|
46102
46533
|
* ```typescript
|
|
@@ -46317,7 +46748,11 @@ const removeFundParamsSchema = zod.z.object({
|
|
|
46317
46748
|
});
|
|
46318
46749
|
}
|
|
46319
46750
|
/**
|
|
46320
|
-
* Kick off a delayed fund removal from an account.
|
|
46751
|
+
* Kick off a delayed recovery fund removal from an account.
|
|
46752
|
+
*
|
|
46753
|
+
* Use this only as a trustless fallback when the normal spend flow is
|
|
46754
|
+
* unavailable. For day-to-day movement out of a Unified Balance, use
|
|
46755
|
+
* `spend`.
|
|
46321
46756
|
*
|
|
46322
46757
|
* @param params - The account owner's adapter context, amount, and
|
|
46323
46758
|
* optional token type.
|
|
@@ -46331,7 +46766,12 @@ const removeFundParamsSchema = zod.z.object({
|
|
|
46331
46766
|
});
|
|
46332
46767
|
}
|
|
46333
46768
|
/**
|
|
46334
|
-
* Complete a fund removal once the
|
|
46769
|
+
* Complete a recovery fund removal once the 7-day withdrawal delay has
|
|
46770
|
+
* passed.
|
|
46771
|
+
*
|
|
46772
|
+
* Use this only as a trustless fallback when the normal spend flow is
|
|
46773
|
+
* unavailable. For day-to-day movement out of a Unified Balance, use
|
|
46774
|
+
* `spend`.
|
|
46335
46775
|
*
|
|
46336
46776
|
* @param params - The account owner context matching the original
|
|
46337
46777
|
* fund removal initiation.
|
|
@@ -46458,6 +46898,11 @@ registerKit(`${pkg.name}/${pkg.version}`);
|
|
|
46458
46898
|
* Internally holds a persistent {@link UnifiedBalanceKit} instance so that
|
|
46459
46899
|
* event dispatchers and custom fee policies are preserved across calls.
|
|
46460
46900
|
*
|
|
46901
|
+
* Use {@link AppKitUnifiedBalance.spend} for normal movement out of a Unified
|
|
46902
|
+
* Balance. {@link AppKitUnifiedBalance.removeFund} is a trustless recovery path
|
|
46903
|
+
* for situations where the normal spend flow is unavailable, and it requires a
|
|
46904
|
+
* 7-day withdrawal delay after {@link AppKitUnifiedBalance.initiateRemoveFund}.
|
|
46905
|
+
*
|
|
46461
46906
|
* @example
|
|
46462
46907
|
* ```typescript
|
|
46463
46908
|
* import { AppKit } from '@circle-fin/app-kit'
|
|
@@ -46669,7 +47114,12 @@ registerKit(`${pkg.name}/${pkg.version}`);
|
|
|
46669
47114
|
return this.kit.removeDelegate(params);
|
|
46670
47115
|
}
|
|
46671
47116
|
/**
|
|
46672
|
-
*
|
|
47117
|
+
* Initiate a trustless recovery removal from an account.
|
|
47118
|
+
*
|
|
47119
|
+
* Use `spend` for normal movement out of a Unified Balance. `removeFund` is a
|
|
47120
|
+
* recovery path for situations where the normal spend flow is unavailable.
|
|
47121
|
+
* Calling this method starts the 7-day withdrawal delay before the removal can
|
|
47122
|
+
* be completed.
|
|
46673
47123
|
*
|
|
46674
47124
|
* @param params - The account owner's adapter context, amount, and token.
|
|
46675
47125
|
* @returns Promise resolving to the initiation details.
|
|
@@ -46688,11 +47138,16 @@ registerKit(`${pkg.name}/${pkg.version}`);
|
|
|
46688
47138
|
return this.kit.initiateRemoveFund(params);
|
|
46689
47139
|
}
|
|
46690
47140
|
/**
|
|
46691
|
-
* Complete a
|
|
47141
|
+
* Complete a trustless recovery removal after the withdrawal delay.
|
|
47142
|
+
*
|
|
47143
|
+
* Use `spend` for normal movement out of a Unified Balance. `removeFund` is a
|
|
47144
|
+
* recovery path for situations where the normal spend flow is unavailable.
|
|
47145
|
+
* Both EVM and Solana removals require a 7-day withdrawal delay after
|
|
47146
|
+
* `initiateRemoveFund` before funds can be removed.
|
|
46692
47147
|
*
|
|
46693
47148
|
* @param params - The account owner context matching the original initiation.
|
|
46694
47149
|
* @returns Promise resolving to the fund removal details.
|
|
46695
|
-
* @throws {KitError} If the
|
|
47150
|
+
* @throws {KitError} If the withdrawal delay has not elapsed or the
|
|
46696
47151
|
* on-chain transaction fails.
|
|
46697
47152
|
*
|
|
46698
47153
|
* @example
|
|
@@ -46941,6 +47396,9 @@ registerKit(`${pkg.name}/${pkg.version}`);
|
|
|
46941
47396
|
...config.unifiedBalance,
|
|
46942
47397
|
...config.disableErrorReporting != null && {
|
|
46943
47398
|
disableErrorReporting: config.disableErrorReporting
|
|
47399
|
+
},
|
|
47400
|
+
...config.disableAnalytics != null && {
|
|
47401
|
+
disableAnalytics: config.disableAnalytics
|
|
46944
47402
|
}
|
|
46945
47403
|
});
|
|
46946
47404
|
this.earn = {
|