@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
|
@@ -314,7 +314,18 @@ function pause(ms, signal) {
|
|
|
314
314
|
);
|
|
315
315
|
});
|
|
316
316
|
}
|
|
317
|
-
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) {
|
|
318
329
|
const controller = new AbortController();
|
|
319
330
|
const relayAbort = () => {
|
|
320
331
|
controller.abort(external?.reason);
|
|
@@ -324,47 +335,29 @@ async function awaitProofBounded(deps, transaction, external) {
|
|
|
324
335
|
else external.addEventListener("abort", relayAbort, { once: true });
|
|
325
336
|
}
|
|
326
337
|
const timer = setTimeout(() => {
|
|
327
|
-
controller.abort(
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
try {
|
|
335
|
-
for (; ; ) {
|
|
336
|
-
try {
|
|
337
|
-
return await waitInclusionProof(
|
|
338
|
-
deps.client,
|
|
339
|
-
deps.trustBase,
|
|
340
|
-
deps.predicateVerifier,
|
|
341
|
-
transaction,
|
|
342
|
-
controller.signal,
|
|
343
|
-
deps.intervalMs
|
|
344
|
-
);
|
|
345
|
-
} catch (err) {
|
|
346
|
-
if (controller.signal.aborted) throw err;
|
|
347
|
-
if (!isTransientGatewayError(err)) throw err;
|
|
348
|
-
await pause(deps.intervalMs, controller.signal);
|
|
349
|
-
}
|
|
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);
|
|
350
345
|
}
|
|
351
|
-
}
|
|
352
|
-
clearTimeout(timer);
|
|
353
|
-
external?.removeEventListener("abort", relayAbort);
|
|
354
|
-
}
|
|
346
|
+
};
|
|
355
347
|
}
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
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,
|
|
359
|
+
deps.intervalMs
|
|
360
|
+
);
|
|
368
361
|
}
|
|
369
362
|
|
|
370
363
|
// token-engine/errors.ts
|
|
@@ -406,6 +399,34 @@ var CheckpointTrustbaseMismatchError = class extends SphereError {
|
|
|
406
399
|
}
|
|
407
400
|
};
|
|
408
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
|
+
|
|
409
430
|
// token-engine/token-blob.ts
|
|
410
431
|
var TOKEN_BLOB_TAG = 39051n;
|
|
411
432
|
var TOKEN_BLOB_VERSION = 1;
|
|
@@ -1348,10 +1369,28 @@ var SphereTokenEngine = class {
|
|
|
1348
1369
|
* failure, not a resume case).
|
|
1349
1370
|
*/
|
|
1350
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) {
|
|
1351
1386
|
let submitError = null;
|
|
1352
1387
|
let submitRejectedCleanly = false;
|
|
1353
1388
|
try {
|
|
1354
|
-
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
|
+
);
|
|
1355
1394
|
if (response.status !== CertificationStatus.SUCCESS) {
|
|
1356
1395
|
submitError = new SphereError(`${failLabel}: ${response.status}`, failCode);
|
|
1357
1396
|
submitRejectedCleanly = CLEAN_REJECT_STATUSES.has(response.status);
|
|
@@ -1365,33 +1404,21 @@ var SphereTokenEngine = class {
|
|
|
1365
1404
|
client: this.deps.client,
|
|
1366
1405
|
trustBase: this.deps.trustBase,
|
|
1367
1406
|
predicateVerifier: this.deps.predicateVerifier,
|
|
1368
|
-
timeoutMs: this.proofTimeoutMs,
|
|
1369
1407
|
intervalMs: this.deps.proofPollIntervalMs ?? DEFAULT_PROOF_POLL_INTERVAL_MS
|
|
1370
1408
|
// #683
|
|
1371
1409
|
},
|
|
1372
1410
|
transaction,
|
|
1373
|
-
|
|
1411
|
+
signal
|
|
1374
1412
|
);
|
|
1375
1413
|
} catch (err) {
|
|
1376
|
-
|
|
1377
|
-
throw new TransferConflictError(
|
|
1378
|
-
`${failLabel}: the source state was already consumed by a different transaction (lost race \u2014 abort this intent and re-plan under a new transferId)`,
|
|
1379
|
-
err
|
|
1380
|
-
);
|
|
1381
|
-
}
|
|
1382
|
-
if (submitRejectedCleanly) throw submitError;
|
|
1383
|
-
throw new ProofUnconfirmedError(
|
|
1384
|
-
`${failLabel}: certification unconfirmed \u2014 the source spend may be on-chain; keep the intent open and resume under the same transferId`,
|
|
1385
|
-
submitError ?? err
|
|
1386
|
-
);
|
|
1414
|
+
throw certificationFailure(err, failLabel, submitError, submitRejectedCleanly);
|
|
1387
1415
|
}
|
|
1388
1416
|
}
|
|
1389
1417
|
/**
|
|
1390
|
-
* One inclusion-proof wait, with the deadline OWNED here (#739)
|
|
1391
|
-
*
|
|
1392
|
-
*
|
|
1393
|
-
*
|
|
1394
|
-
* (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.
|
|
1395
1422
|
*/
|
|
1396
1423
|
/** Fail fast if this engine's key does not own the token's current state. */
|
|
1397
1424
|
assertOwned(token) {
|