@unicitylabs/sphere-sdk 0.14.5 → 0.14.6
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 +94 -61
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.js +94 -61
- 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 +94 -61
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +94 -61
- 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 +86 -59
- package/dist/token-engine/index.cjs.map +1 -1
- package/dist/token-engine/index.js +86 -59
- package/dist/token-engine/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -349,7 +349,18 @@ function pause(ms, signal) {
|
|
|
349
349
|
);
|
|
350
350
|
});
|
|
351
351
|
}
|
|
352
|
-
async function
|
|
352
|
+
async function retryTransient(attempt, signal, intervalMs) {
|
|
353
|
+
for (; ; ) {
|
|
354
|
+
try {
|
|
355
|
+
return await attempt();
|
|
356
|
+
} catch (err) {
|
|
357
|
+
if (signal.aborted) throw err;
|
|
358
|
+
if (!isTransientGatewayError(err)) throw err;
|
|
359
|
+
await pause(intervalMs, signal);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
function certificationDeadline(timeoutMs, external, label) {
|
|
353
364
|
const controller = new AbortController();
|
|
354
365
|
const relayAbort = () => {
|
|
355
366
|
controller.abort(external?.reason);
|
|
@@ -359,47 +370,29 @@ async function awaitProofBounded(deps, transaction, external) {
|
|
|
359
370
|
else external.addEventListener("abort", relayAbort, { once: true });
|
|
360
371
|
}
|
|
361
372
|
const timer = setTimeout(() => {
|
|
362
|
-
controller.abort(
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
try {
|
|
370
|
-
for (; ; ) {
|
|
371
|
-
try {
|
|
372
|
-
return await (0, import_InclusionProofUtils.waitInclusionProof)(
|
|
373
|
-
deps.client,
|
|
374
|
-
deps.trustBase,
|
|
375
|
-
deps.predicateVerifier,
|
|
376
|
-
transaction,
|
|
377
|
-
controller.signal,
|
|
378
|
-
deps.intervalMs
|
|
379
|
-
);
|
|
380
|
-
} catch (err) {
|
|
381
|
-
if (controller.signal.aborted) throw err;
|
|
382
|
-
if (!isTransientGatewayError(err)) throw err;
|
|
383
|
-
await pause(deps.intervalMs, controller.signal);
|
|
384
|
-
}
|
|
373
|
+
controller.abort(new SphereError(`${label} within ${String(timeoutMs)} ms`, "AGGREGATOR_ERROR"));
|
|
374
|
+
}, timeoutMs);
|
|
375
|
+
return {
|
|
376
|
+
signal: controller.signal,
|
|
377
|
+
dispose: () => {
|
|
378
|
+
clearTimeout(timer);
|
|
379
|
+
external?.removeEventListener("abort", relayAbort);
|
|
385
380
|
}
|
|
386
|
-
}
|
|
387
|
-
clearTimeout(timer);
|
|
388
|
-
external?.removeEventListener("abort", relayAbort);
|
|
389
|
-
}
|
|
381
|
+
};
|
|
390
382
|
}
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
383
|
+
async function awaitProofBounded(deps, transaction, signal) {
|
|
384
|
+
return retryTransient(
|
|
385
|
+
() => (0, import_InclusionProofUtils.waitInclusionProof)(
|
|
386
|
+
deps.client,
|
|
387
|
+
deps.trustBase,
|
|
388
|
+
deps.predicateVerifier,
|
|
389
|
+
transaction,
|
|
390
|
+
signal,
|
|
391
|
+
deps.intervalMs
|
|
392
|
+
),
|
|
393
|
+
signal,
|
|
394
|
+
deps.intervalMs
|
|
395
|
+
);
|
|
403
396
|
}
|
|
404
397
|
|
|
405
398
|
// token-engine/errors.ts
|
|
@@ -441,6 +434,34 @@ var CheckpointTrustbaseMismatchError = class extends SphereError {
|
|
|
441
434
|
}
|
|
442
435
|
};
|
|
443
436
|
|
|
437
|
+
// token-engine/certification-outcome.ts
|
|
438
|
+
function certificationFailure(err, failLabel, submitError, submitRejectedCleanly) {
|
|
439
|
+
if (err instanceof Error && err.message === `Invalid inclusion proof status: ${import_InclusionProofVerificationRule.InclusionProofVerificationStatus.TRANSACTION_HASH_MISMATCH}`) {
|
|
440
|
+
return new TransferConflictError(
|
|
441
|
+
`${failLabel}: the source state was already consumed by a different transaction (lost race \u2014 abort this intent and re-plan under a new transferId)`,
|
|
442
|
+
err
|
|
443
|
+
);
|
|
444
|
+
}
|
|
445
|
+
if (submitRejectedCleanly) return submitError;
|
|
446
|
+
return new ProofUnconfirmedError(
|
|
447
|
+
`${failLabel}: certification unconfirmed \u2014 the source spend may be on-chain; keep the intent open and resume under the same transferId`,
|
|
448
|
+
submitError ?? err
|
|
449
|
+
);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// core/uuid.ts
|
|
453
|
+
function randomUUID() {
|
|
454
|
+
const c = globalThis.crypto;
|
|
455
|
+
if (typeof c !== "undefined" && typeof c.randomUUID === "function") {
|
|
456
|
+
return c.randomUUID();
|
|
457
|
+
}
|
|
458
|
+
const b = c.getRandomValues(new Uint8Array(16));
|
|
459
|
+
b[6] = b[6] & 15 | 64;
|
|
460
|
+
b[8] = b[8] & 63 | 128;
|
|
461
|
+
const h = Array.from(b, (x) => x.toString(16).padStart(2, "0"));
|
|
462
|
+
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]}`;
|
|
463
|
+
}
|
|
464
|
+
|
|
444
465
|
// token-engine/token-blob.ts
|
|
445
466
|
var TOKEN_BLOB_TAG = 39051n;
|
|
446
467
|
var TOKEN_BLOB_VERSION = 1;
|
|
@@ -1383,10 +1404,28 @@ var SphereTokenEngine = class {
|
|
|
1383
1404
|
* failure, not a resume case).
|
|
1384
1405
|
*/
|
|
1385
1406
|
async submitAndAwaitProof(certificationData, transaction, failLabel, failCode, options) {
|
|
1407
|
+
const deadline = certificationDeadline(
|
|
1408
|
+
this.proofTimeoutMs,
|
|
1409
|
+
options?.signal,
|
|
1410
|
+
`${failLabel}: not certified`
|
|
1411
|
+
);
|
|
1412
|
+
try {
|
|
1413
|
+
return await this.submitThenProve(certificationData, transaction, failLabel, failCode, deadline.signal);
|
|
1414
|
+
} finally {
|
|
1415
|
+
deadline.dispose();
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
/** One certification attempt under one deadline: the metered submit retries
|
|
1419
|
+
* transient answers instead of falling through to a proof that cannot exist. */
|
|
1420
|
+
async submitThenProve(certificationData, transaction, failLabel, failCode, signal) {
|
|
1386
1421
|
let submitError = null;
|
|
1387
1422
|
let submitRejectedCleanly = false;
|
|
1388
1423
|
try {
|
|
1389
|
-
const response = await
|
|
1424
|
+
const response = await retryTransient(
|
|
1425
|
+
() => this.deps.client.submitCertificationRequest(certificationData),
|
|
1426
|
+
signal,
|
|
1427
|
+
this.deps.proofPollIntervalMs ?? DEFAULT_PROOF_POLL_INTERVAL_MS
|
|
1428
|
+
);
|
|
1390
1429
|
if (response.status !== import_CertificationResponse.CertificationStatus.SUCCESS) {
|
|
1391
1430
|
submitError = new SphereError(`${failLabel}: ${response.status}`, failCode);
|
|
1392
1431
|
submitRejectedCleanly = CLEAN_REJECT_STATUSES.has(response.status);
|
|
@@ -1400,33 +1439,21 @@ var SphereTokenEngine = class {
|
|
|
1400
1439
|
client: this.deps.client,
|
|
1401
1440
|
trustBase: this.deps.trustBase,
|
|
1402
1441
|
predicateVerifier: this.deps.predicateVerifier,
|
|
1403
|
-
timeoutMs: this.proofTimeoutMs,
|
|
1404
1442
|
intervalMs: this.deps.proofPollIntervalMs ?? DEFAULT_PROOF_POLL_INTERVAL_MS
|
|
1405
1443
|
// #683
|
|
1406
1444
|
},
|
|
1407
1445
|
transaction,
|
|
1408
|
-
|
|
1446
|
+
signal
|
|
1409
1447
|
);
|
|
1410
1448
|
} catch (err) {
|
|
1411
|
-
|
|
1412
|
-
throw new TransferConflictError(
|
|
1413
|
-
`${failLabel}: the source state was already consumed by a different transaction (lost race \u2014 abort this intent and re-plan under a new transferId)`,
|
|
1414
|
-
err
|
|
1415
|
-
);
|
|
1416
|
-
}
|
|
1417
|
-
if (submitRejectedCleanly) throw submitError;
|
|
1418
|
-
throw new ProofUnconfirmedError(
|
|
1419
|
-
`${failLabel}: certification unconfirmed \u2014 the source spend may be on-chain; keep the intent open and resume under the same transferId`,
|
|
1420
|
-
submitError ?? err
|
|
1421
|
-
);
|
|
1449
|
+
throw certificationFailure(err, failLabel, submitError, submitRejectedCleanly);
|
|
1422
1450
|
}
|
|
1423
1451
|
}
|
|
1424
1452
|
/**
|
|
1425
|
-
* One inclusion-proof wait, with the deadline OWNED here (#739)
|
|
1426
|
-
*
|
|
1427
|
-
*
|
|
1428
|
-
*
|
|
1429
|
-
* (keep-open), which is the correct posture: the spend may be on-chain.
|
|
1453
|
+
* One inclusion-proof wait, with the deadline OWNED here (#739) so it is bounded
|
|
1454
|
+
* and configurable rather than the SDK's fixed default. A hit throws, and the
|
|
1455
|
+
* caller maps it to ProofUnconfirmedError (keep-open) — the correct posture,
|
|
1456
|
+
* since the spend may be on-chain.
|
|
1430
1457
|
*/
|
|
1431
1458
|
/** Fail fast if this engine's key does not own the token's current state. */
|
|
1432
1459
|
assertOwned(token) {
|