@unicitylabs/sphere-sdk 0.14.4 → 0.14.6-dev.1
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/dist/connect/index.cjs +1 -1
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/index.js +1 -1
- package/dist/connect/index.js.map +1 -1
- package/dist/core/index.cjs +101 -79
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.js +101 -79
- package/dist/core/index.js.map +1 -1
- package/dist/impl/browser/connect/index.cjs +1 -1
- package/dist/impl/browser/connect/index.cjs.map +1 -1
- package/dist/impl/browser/connect/index.js +1 -1
- package/dist/impl/browser/connect/index.js.map +1 -1
- package/dist/impl/wallet-api-v2/index.cjs.map +1 -1
- package/dist/impl/wallet-api-v2/index.js.map +1 -1
- package/dist/index.cjs +101 -79
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +101 -79
- package/dist/index.js.map +1 -1
- package/dist/modules/payments-v2/index.cjs +20 -14
- package/dist/modules/payments-v2/index.cjs.map +1 -1
- package/dist/modules/payments-v2/index.js +20 -14
- package/dist/modules/payments-v2/index.js.map +1 -1
- package/dist/token-engine/index.cjs +94 -78
- package/dist/token-engine/index.cjs.map +1 -1
- package/dist/token-engine/index.js +94 -78
- package/dist/token-engine/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -297,41 +297,35 @@ function resolveProofTimeoutMs(configured) {
|
|
|
297
297
|
}
|
|
298
298
|
return configured;
|
|
299
299
|
}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
if (prop === "addEventListener") {
|
|
304
|
-
return (type, listener, options) => {
|
|
305
|
-
if (type === "abort" && target.aborted) {
|
|
306
|
-
queueMicrotask(() => {
|
|
307
|
-
listener.call(target, new Event("abort"));
|
|
308
|
-
});
|
|
309
|
-
return;
|
|
310
|
-
}
|
|
311
|
-
target.addEventListener(type, listener, options);
|
|
312
|
-
};
|
|
313
|
-
}
|
|
314
|
-
const value = Reflect.get(target, prop, target);
|
|
315
|
-
return typeof value === "function" ? value.bind(target) : value;
|
|
316
|
-
}
|
|
317
|
-
});
|
|
300
|
+
var TRANSIENT_HTTP_STATUSES = /* @__PURE__ */ new Set([408, 425, 429, 500, 502, 503, 504]);
|
|
301
|
+
function isTransientGatewayError(err) {
|
|
302
|
+
return err instanceof JsonRpcNetworkError && TRANSIENT_HTTP_STATUSES.has(err.status);
|
|
318
303
|
}
|
|
319
|
-
function
|
|
320
|
-
return new Promise((
|
|
321
|
-
|
|
322
|
-
reject(signal.reason);
|
|
323
|
-
return;
|
|
324
|
-
}
|
|
304
|
+
function pause(ms, signal) {
|
|
305
|
+
return new Promise((resolve) => {
|
|
306
|
+
const timer = setTimeout(resolve, ms);
|
|
325
307
|
signal.addEventListener(
|
|
326
308
|
"abort",
|
|
327
309
|
() => {
|
|
328
|
-
|
|
310
|
+
clearTimeout(timer);
|
|
311
|
+
resolve();
|
|
329
312
|
},
|
|
330
313
|
{ once: true }
|
|
331
314
|
);
|
|
332
315
|
});
|
|
333
316
|
}
|
|
334
|
-
async function
|
|
317
|
+
async function retryTransient(attempt, signal, intervalMs) {
|
|
318
|
+
for (; ; ) {
|
|
319
|
+
try {
|
|
320
|
+
return await attempt();
|
|
321
|
+
} catch (err) {
|
|
322
|
+
if (signal.aborted) throw err;
|
|
323
|
+
if (!isTransientGatewayError(err)) throw err;
|
|
324
|
+
await pause(intervalMs, signal);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
function certificationDeadline(timeoutMs, external, label) {
|
|
335
329
|
const controller = new AbortController();
|
|
336
330
|
const relayAbort = () => {
|
|
337
331
|
controller.abort(external?.reason);
|
|
@@ -341,41 +335,29 @@ async function awaitProofBounded(deps, transaction, external) {
|
|
|
341
335
|
else external.addEventListener("abort", relayAbort, { once: true });
|
|
342
336
|
}
|
|
343
337
|
const timer = setTimeout(() => {
|
|
344
|
-
controller.abort(
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
338
|
+
controller.abort(new SphereError(`${label} within ${String(timeoutMs)} ms`, "AGGREGATOR_ERROR"));
|
|
339
|
+
}, timeoutMs);
|
|
340
|
+
return {
|
|
341
|
+
signal: controller.signal,
|
|
342
|
+
dispose: () => {
|
|
343
|
+
clearTimeout(timer);
|
|
344
|
+
external?.removeEventListener("abort", relayAbort);
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
async function awaitProofBounded(deps, transaction, signal) {
|
|
349
|
+
return retryTransient(
|
|
350
|
+
() => waitInclusionProof(
|
|
351
|
+
deps.client,
|
|
352
|
+
deps.trustBase,
|
|
353
|
+
deps.predicateVerifier,
|
|
354
|
+
transaction,
|
|
355
|
+
signal,
|
|
356
|
+
deps.intervalMs
|
|
357
|
+
),
|
|
358
|
+
signal,
|
|
357
359
|
deps.intervalMs
|
|
358
360
|
);
|
|
359
|
-
wait.catch(() => void 0);
|
|
360
|
-
try {
|
|
361
|
-
return await Promise.race([wait, rejectOnAbort(controller.signal)]);
|
|
362
|
-
} finally {
|
|
363
|
-
clearTimeout(timer);
|
|
364
|
-
external?.removeEventListener("abort", relayAbort);
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
// core/uuid.ts
|
|
369
|
-
function randomUUID() {
|
|
370
|
-
const c = globalThis.crypto;
|
|
371
|
-
if (typeof c !== "undefined" && typeof c.randomUUID === "function") {
|
|
372
|
-
return c.randomUUID();
|
|
373
|
-
}
|
|
374
|
-
const b = c.getRandomValues(new Uint8Array(16));
|
|
375
|
-
b[6] = b[6] & 15 | 64;
|
|
376
|
-
b[8] = b[8] & 63 | 128;
|
|
377
|
-
const h = Array.from(b, (x) => x.toString(16).padStart(2, "0"));
|
|
378
|
-
return `${h[0]}${h[1]}${h[2]}${h[3]}-${h[4]}${h[5]}-${h[6]}${h[7]}-${h[8]}${h[9]}-${h[10]}${h[11]}${h[12]}${h[13]}${h[14]}${h[15]}`;
|
|
379
361
|
}
|
|
380
362
|
|
|
381
363
|
// token-engine/errors.ts
|
|
@@ -417,6 +399,34 @@ var CheckpointTrustbaseMismatchError = class extends SphereError {
|
|
|
417
399
|
}
|
|
418
400
|
};
|
|
419
401
|
|
|
402
|
+
// token-engine/certification-outcome.ts
|
|
403
|
+
function certificationFailure(err, failLabel, submitError, submitRejectedCleanly) {
|
|
404
|
+
if (err instanceof Error && err.message === `Invalid inclusion proof status: ${InclusionProofVerificationStatus.TRANSACTION_HASH_MISMATCH}`) {
|
|
405
|
+
return new TransferConflictError(
|
|
406
|
+
`${failLabel}: the source state was already consumed by a different transaction (lost race \u2014 abort this intent and re-plan under a new transferId)`,
|
|
407
|
+
err
|
|
408
|
+
);
|
|
409
|
+
}
|
|
410
|
+
if (submitRejectedCleanly) return submitError;
|
|
411
|
+
return new ProofUnconfirmedError(
|
|
412
|
+
`${failLabel}: certification unconfirmed \u2014 the source spend may be on-chain; keep the intent open and resume under the same transferId`,
|
|
413
|
+
submitError ?? err
|
|
414
|
+
);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// core/uuid.ts
|
|
418
|
+
function randomUUID() {
|
|
419
|
+
const c = globalThis.crypto;
|
|
420
|
+
if (typeof c !== "undefined" && typeof c.randomUUID === "function") {
|
|
421
|
+
return c.randomUUID();
|
|
422
|
+
}
|
|
423
|
+
const b = c.getRandomValues(new Uint8Array(16));
|
|
424
|
+
b[6] = b[6] & 15 | 64;
|
|
425
|
+
b[8] = b[8] & 63 | 128;
|
|
426
|
+
const h = Array.from(b, (x) => x.toString(16).padStart(2, "0"));
|
|
427
|
+
return `${h[0]}${h[1]}${h[2]}${h[3]}-${h[4]}${h[5]}-${h[6]}${h[7]}-${h[8]}${h[9]}-${h[10]}${h[11]}${h[12]}${h[13]}${h[14]}${h[15]}`;
|
|
428
|
+
}
|
|
429
|
+
|
|
420
430
|
// token-engine/token-blob.ts
|
|
421
431
|
var TOKEN_BLOB_TAG = 39051n;
|
|
422
432
|
var TOKEN_BLOB_VERSION = 1;
|
|
@@ -1359,10 +1369,28 @@ var SphereTokenEngine = class {
|
|
|
1359
1369
|
* failure, not a resume case).
|
|
1360
1370
|
*/
|
|
1361
1371
|
async submitAndAwaitProof(certificationData, transaction, failLabel, failCode, options) {
|
|
1372
|
+
const deadline = certificationDeadline(
|
|
1373
|
+
this.proofTimeoutMs,
|
|
1374
|
+
options?.signal,
|
|
1375
|
+
`${failLabel}: not certified`
|
|
1376
|
+
);
|
|
1377
|
+
try {
|
|
1378
|
+
return await this.submitThenProve(certificationData, transaction, failLabel, failCode, deadline.signal);
|
|
1379
|
+
} finally {
|
|
1380
|
+
deadline.dispose();
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
/** One certification attempt under one deadline: the metered submit retries
|
|
1384
|
+
* transient answers instead of falling through to a proof that cannot exist. */
|
|
1385
|
+
async submitThenProve(certificationData, transaction, failLabel, failCode, signal) {
|
|
1362
1386
|
let submitError = null;
|
|
1363
1387
|
let submitRejectedCleanly = false;
|
|
1364
1388
|
try {
|
|
1365
|
-
const response = await
|
|
1389
|
+
const response = await retryTransient(
|
|
1390
|
+
() => this.deps.client.submitCertificationRequest(certificationData),
|
|
1391
|
+
signal,
|
|
1392
|
+
this.deps.proofPollIntervalMs ?? DEFAULT_PROOF_POLL_INTERVAL_MS
|
|
1393
|
+
);
|
|
1366
1394
|
if (response.status !== CertificationStatus.SUCCESS) {
|
|
1367
1395
|
submitError = new SphereError(`${failLabel}: ${response.status}`, failCode);
|
|
1368
1396
|
submitRejectedCleanly = CLEAN_REJECT_STATUSES.has(response.status);
|
|
@@ -1376,33 +1404,21 @@ var SphereTokenEngine = class {
|
|
|
1376
1404
|
client: this.deps.client,
|
|
1377
1405
|
trustBase: this.deps.trustBase,
|
|
1378
1406
|
predicateVerifier: this.deps.predicateVerifier,
|
|
1379
|
-
timeoutMs: this.proofTimeoutMs,
|
|
1380
1407
|
intervalMs: this.deps.proofPollIntervalMs ?? DEFAULT_PROOF_POLL_INTERVAL_MS
|
|
1381
1408
|
// #683
|
|
1382
1409
|
},
|
|
1383
1410
|
transaction,
|
|
1384
|
-
|
|
1411
|
+
signal
|
|
1385
1412
|
);
|
|
1386
1413
|
} catch (err) {
|
|
1387
|
-
|
|
1388
|
-
throw new TransferConflictError(
|
|
1389
|
-
`${failLabel}: the source state was already consumed by a different transaction (lost race \u2014 abort this intent and re-plan under a new transferId)`,
|
|
1390
|
-
err
|
|
1391
|
-
);
|
|
1392
|
-
}
|
|
1393
|
-
if (submitRejectedCleanly) throw submitError;
|
|
1394
|
-
throw new ProofUnconfirmedError(
|
|
1395
|
-
`${failLabel}: certification unconfirmed \u2014 the source spend may be on-chain; keep the intent open and resume under the same transferId`,
|
|
1396
|
-
submitError ?? err
|
|
1397
|
-
);
|
|
1414
|
+
throw certificationFailure(err, failLabel, submitError, submitRejectedCleanly);
|
|
1398
1415
|
}
|
|
1399
1416
|
}
|
|
1400
1417
|
/**
|
|
1401
|
-
* One inclusion-proof wait, with the deadline OWNED here (#739)
|
|
1402
|
-
*
|
|
1403
|
-
*
|
|
1404
|
-
*
|
|
1405
|
-
* (keep-open), which is the correct posture: the spend may be on-chain.
|
|
1418
|
+
* One inclusion-proof wait, with the deadline OWNED here (#739) so it is bounded
|
|
1419
|
+
* and configurable rather than the SDK's fixed default. A hit throws, and the
|
|
1420
|
+
* caller maps it to ProofUnconfirmedError (keep-open) — the correct posture,
|
|
1421
|
+
* since the spend may be on-chain.
|
|
1406
1422
|
*/
|
|
1407
1423
|
/** Fail fast if this engine's key does not own the token's current state. */
|
|
1408
1424
|
assertOwned(token) {
|