@unicitylabs/sphere-sdk 0.14.6 → 0.14.8-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.
@@ -9398,12 +9398,15 @@ function pause(ms, signal) {
9398
9398
  });
9399
9399
  }
9400
9400
  async function retryTransient(attempt, signal, intervalMs) {
9401
+ let retried = false;
9401
9402
  for (; ; ) {
9403
+ if (signal.aborted) throw signal.reason;
9402
9404
  try {
9403
- return await attempt();
9405
+ return { value: await attempt(), retried };
9404
9406
  } catch (err) {
9405
9407
  if (signal.aborted) throw err;
9406
9408
  if (!isTransientGatewayError(err)) throw err;
9409
+ retried = true;
9407
9410
  await pause(intervalMs, signal);
9408
9411
  }
9409
9412
  }
@@ -9429,7 +9432,7 @@ function certificationDeadline(timeoutMs, external, label) {
9429
9432
  };
9430
9433
  }
9431
9434
  async function awaitProofBounded(deps, transaction, signal) {
9432
- return retryTransient(
9435
+ const { value } = await retryTransient(
9433
9436
  () => waitInclusionProof(
9434
9437
  deps.client,
9435
9438
  deps.trustBase,
@@ -9441,6 +9444,7 @@ async function awaitProofBounded(deps, transaction, signal) {
9441
9444
  signal,
9442
9445
  deps.intervalMs
9443
9446
  );
9447
+ return value;
9444
9448
  }
9445
9449
 
9446
9450
  // token-engine/errors.ts
@@ -10036,14 +10040,14 @@ var SphereTokenEngine = class {
10036
10040
  let submitError = null;
10037
10041
  let submitRejectedCleanly = false;
10038
10042
  try {
10039
- const response = await retryTransient(
10043
+ const { value: response, retried } = await retryTransient(
10040
10044
  () => this.deps.client.submitCertificationRequest(certificationData),
10041
10045
  signal,
10042
10046
  this.deps.proofPollIntervalMs ?? DEFAULT_PROOF_POLL_INTERVAL_MS
10043
10047
  );
10044
10048
  if (response.status !== CertificationStatus.SUCCESS) {
10045
10049
  submitError = new SphereError(`${failLabel}: ${response.status}`, failCode);
10046
- submitRejectedCleanly = CLEAN_REJECT_STATUSES.has(response.status);
10050
+ submitRejectedCleanly = !retried && CLEAN_REJECT_STATUSES.has(response.status);
10047
10051
  }
10048
10052
  } catch (err) {
10049
10053
  submitError = err ?? new SphereError(`${failLabel}: submit failed`, failCode);
@@ -11440,6 +11444,9 @@ function classifyError(e) {
11440
11444
  }
11441
11445
  return "other";
11442
11446
  }
11447
+ function firstNonConflictError(outcomes) {
11448
+ return outcomes.find((o) => o.error !== void 0 && classifyError(o.error) !== "conflict");
11449
+ }
11443
11450
  function summarize(outcomes) {
11444
11451
  const committed = outcomes.filter((o) => o.certified);
11445
11452
  const rank = { "keep-open": 3, conflict: 2, other: 1 };
@@ -11500,14 +11507,15 @@ var TransferMachine = class {
11500
11507
  ...r.payload.memo !== void 0 ? { memo: r.payload.memo } : {}
11501
11508
  };
11502
11509
  const outcomes = await this.resumeOps(ctx, engine, r);
11503
- const { committed, cls, firstError } = summarize(outcomes);
11510
+ const { committed } = summarize(outcomes);
11504
11511
  const conflicts = this.toConflicts(engine, r, outcomes);
11505
11512
  if (committed.length === 0 && conflicts.length > 0) throw conflicts[0].error;
11506
11513
  let deliveryPending = false;
11507
11514
  if (committed.length > 0) {
11508
11515
  deliveryPending = await this.deliverSet(r.transferId, r.payload.recipient, r.payload.memo, committed);
11509
11516
  }
11510
- if (cls !== null && cls !== "conflict") throw firstError;
11517
+ const blocking = firstNonConflictError(outcomes);
11518
+ if (blocking !== void 0) throw blocking.error;
11511
11519
  await this.applyCommitted(engine, r.transferId, committed);
11512
11520
  if (conflicts.length > 0) {
11513
11521
  return { deliveryPending, partial: await this.settlePartial(engine, r, committed, conflicts) };
@@ -11533,16 +11541,37 @@ var TransferMachine = class {
11533
11541
  ...plan.memo !== void 0 ? { memo: plan.memo } : {}
11534
11542
  };
11535
11543
  const outcomes = [];
11544
+ const certified = [];
11536
11545
  for (let at = 0; at < plan.ops.length; at += CERTIFY_WIDTH) {
11537
11546
  const batch = plan.ops.slice(at, at + CERTIFY_WIDTH);
11538
11547
  const settled = await Promise.all(
11539
- batch.map((op) => this.certifyOne(ctx, engine, op, plan.sources.get(op.sourceTokenId)))
11548
+ batch.map(
11549
+ (op) => this.certifyOne(ctx, engine, op, plan.sources.get(op.sourceTokenId)).then((o) => {
11550
+ if (o.certified) {
11551
+ certified.push(o);
11552
+ this.emitProgress(plan, certified);
11553
+ }
11554
+ return o;
11555
+ })
11556
+ )
11540
11557
  );
11541
11558
  outcomes.push(...settled);
11542
11559
  if (settled.some((o) => o.error !== void 0 && !o.certified)) break;
11543
11560
  }
11544
11561
  return outcomes;
11545
11562
  }
11563
+ /** In-flight snapshot: `tokenTransfers` holds the legs certified SO FAR. */
11564
+ emitProgress(plan, certified) {
11565
+ this.deps.emit("transfer:updated", {
11566
+ id: plan.transferId,
11567
+ status: "submitted",
11568
+ tokens: [],
11569
+ tokenTransfers: certified.map((o) => ({
11570
+ sourceTokenId: o.op.sourceTokenId,
11571
+ method: o.op.kind
11572
+ }))
11573
+ });
11574
+ }
11546
11575
  async certifyOne(ctx, engine, op, source) {
11547
11576
  if (source === void 0) {
11548
11577
  return {