@unicitylabs/sphere-sdk 0.11.7 → 0.11.8

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.
Files changed (37) hide show
  1. package/dist/connect/index.cjs +1 -1
  2. package/dist/connect/index.cjs.map +1 -1
  3. package/dist/connect/index.js +1 -1
  4. package/dist/connect/index.js.map +1 -1
  5. package/dist/impl/browser/connect/index.cjs +1 -1
  6. package/dist/impl/browser/connect/index.cjs.map +1 -1
  7. package/dist/impl/browser/connect/index.js +1 -1
  8. package/dist/impl/browser/connect/index.js.map +1 -1
  9. package/dist/impl/browser/index.cjs +31 -18
  10. package/dist/impl/browser/index.cjs.map +1 -1
  11. package/dist/impl/browser/index.js +31 -18
  12. package/dist/impl/browser/index.js.map +1 -1
  13. package/dist/impl/nodejs/index.cjs +31 -18
  14. package/dist/impl/nodejs/index.cjs.map +1 -1
  15. package/dist/impl/nodejs/index.d.cts +11 -7
  16. package/dist/impl/nodejs/index.d.ts +11 -7
  17. package/dist/impl/nodejs/index.js +31 -18
  18. package/dist/impl/nodejs/index.js.map +1 -1
  19. package/dist/impl/shared/wallet-api/index.cjs +31 -18
  20. package/dist/impl/shared/wallet-api/index.cjs.map +1 -1
  21. package/dist/impl/shared/wallet-api/index.d.cts +11 -7
  22. package/dist/impl/shared/wallet-api/index.d.ts +11 -7
  23. package/dist/impl/shared/wallet-api/index.js +31 -18
  24. package/dist/impl/shared/wallet-api/index.js.map +1 -1
  25. package/dist/index.cjs +31 -18
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.d.cts +11 -7
  28. package/dist/index.d.ts +11 -7
  29. package/dist/index.js +31 -18
  30. package/dist/index.js.map +1 -1
  31. package/dist/wallet-api/index.cjs +31 -18
  32. package/dist/wallet-api/index.cjs.map +1 -1
  33. package/dist/wallet-api/index.d.cts +11 -7
  34. package/dist/wallet-api/index.d.ts +11 -7
  35. package/dist/wallet-api/index.js +31 -18
  36. package/dist/wallet-api/index.js.map +1 -1
  37. package/package.json +1 -1
@@ -563,11 +563,14 @@ declare class WalletApiClient {
563
563
  /**
564
564
  * Retry transient REST failures with bounded exponential backoff + jitter:
565
565
  * - a thrown transient `NETWORK` failure (dropped/reset connection, DNS blip)
566
- * retries on **idempotent GETs only** — a lost-response retry of a write
567
- * could double-apply;
566
+ * retries on **idempotent requests** — every GET, plus a write the caller
567
+ * marked `idempotentWrite` (the server replays it as a no-op, so a
568
+ * lost-response retry cannot double-apply; today only `inventory/apply`,
569
+ * idempotent by transferId — #664). A non-idempotent write is single-attempt;
568
570
  * - a `429` response retries on **any** method (a 429 is rejected before the
569
571
  * handler runs — the write never executed), honoring the server `Retry-After`;
570
- * - a `503` response retries on **GETs only** (a write may have started).
572
+ * - a `503` response retries on **idempotent requests only** (a non-idempotent
573
+ * write may have started).
571
574
  * Every other outcome (2xx, or a non-retryable status) is returned to the
572
575
  * caller, which maps a non-2xx to a typed {@link WalletApiError}.
573
576
  */
@@ -576,8 +579,8 @@ declare class WalletApiClient {
576
579
  private backoffMs;
577
580
  /**
578
581
  * Delay before retrying a non-2xx response, or `null` to not retry. `429`
579
- * retries on any method (rejected before execution); `503` on idempotent GETs.
580
- * Honors a capped `Retry-After` when present, else falls back to backoff.
582
+ * retries on any method (rejected before execution); `503` on idempotent
583
+ * requests only. Honors a capped `Retry-After` when present, else backoff.
581
584
  */
582
585
  private retryDelayForStatus;
583
586
  /** Parse `Retry-After` (delta-seconds or an HTTP-date) to ms, or `null` if absent/unparseable. */
@@ -587,8 +590,9 @@ declare class WalletApiClient {
587
590
  * Authenticated JSON request. A 401 triggers one silent re-auth
588
591
  * (refresh → challenge fallback) and one retry; {@link rawFetchWithRetry}
589
592
  * additionally rides out transient failures — a dropped connection on an
590
- * idempotent GET, or a `429`/`503` with `Retry-After` — so a single blip or a
591
- * brief rate-limit window doesn't fail the call.
593
+ * idempotent request (any GET, or a write flagged `opts.idempotent`), or a
594
+ * `429`/`503` with `Retry-After` — so a single blip or a brief rate-limit
595
+ * window doesn't fail the call.
592
596
  */
593
597
  private requestJson;
594
598
  /** `GET /v1/inventory?since=` — one page; the caller loops while `more`. */
@@ -563,11 +563,14 @@ declare class WalletApiClient {
563
563
  /**
564
564
  * Retry transient REST failures with bounded exponential backoff + jitter:
565
565
  * - a thrown transient `NETWORK` failure (dropped/reset connection, DNS blip)
566
- * retries on **idempotent GETs only** — a lost-response retry of a write
567
- * could double-apply;
566
+ * retries on **idempotent requests** — every GET, plus a write the caller
567
+ * marked `idempotentWrite` (the server replays it as a no-op, so a
568
+ * lost-response retry cannot double-apply; today only `inventory/apply`,
569
+ * idempotent by transferId — #664). A non-idempotent write is single-attempt;
568
570
  * - a `429` response retries on **any** method (a 429 is rejected before the
569
571
  * handler runs — the write never executed), honoring the server `Retry-After`;
570
- * - a `503` response retries on **GETs only** (a write may have started).
572
+ * - a `503` response retries on **idempotent requests only** (a non-idempotent
573
+ * write may have started).
571
574
  * Every other outcome (2xx, or a non-retryable status) is returned to the
572
575
  * caller, which maps a non-2xx to a typed {@link WalletApiError}.
573
576
  */
@@ -576,8 +579,8 @@ declare class WalletApiClient {
576
579
  private backoffMs;
577
580
  /**
578
581
  * Delay before retrying a non-2xx response, or `null` to not retry. `429`
579
- * retries on any method (rejected before execution); `503` on idempotent GETs.
580
- * Honors a capped `Retry-After` when present, else falls back to backoff.
582
+ * retries on any method (rejected before execution); `503` on idempotent
583
+ * requests only. Honors a capped `Retry-After` when present, else backoff.
581
584
  */
582
585
  private retryDelayForStatus;
583
586
  /** Parse `Retry-After` (delta-seconds or an HTTP-date) to ms, or `null` if absent/unparseable. */
@@ -587,8 +590,9 @@ declare class WalletApiClient {
587
590
  * Authenticated JSON request. A 401 triggers one silent re-auth
588
591
  * (refresh → challenge fallback) and one retry; {@link rawFetchWithRetry}
589
592
  * additionally rides out transient failures — a dropped connection on an
590
- * idempotent GET, or a `429`/`503` with `Retry-After` — so a single blip or a
591
- * brief rate-limit window doesn't fail the call.
593
+ * idempotent request (any GET, or a write flagged `opts.idempotent`), or a
594
+ * `429`/`503` with `Retry-After` — so a single blip or a brief rate-limit
595
+ * window doesn't fail the call.
592
596
  */
593
597
  private requestJson;
594
598
  /** `GET /v1/inventory?since=` — one page; the caller loops while `more`. */
@@ -1249,16 +1249,19 @@ var WalletApiClient = class _WalletApiClient {
1249
1249
  /**
1250
1250
  * Retry transient REST failures with bounded exponential backoff + jitter:
1251
1251
  * - a thrown transient `NETWORK` failure (dropped/reset connection, DNS blip)
1252
- * retries on **idempotent GETs only** — a lost-response retry of a write
1253
- * could double-apply;
1252
+ * retries on **idempotent requests** — every GET, plus a write the caller
1253
+ * marked `idempotentWrite` (the server replays it as a no-op, so a
1254
+ * lost-response retry cannot double-apply; today only `inventory/apply`,
1255
+ * idempotent by transferId — #664). A non-idempotent write is single-attempt;
1254
1256
  * - a `429` response retries on **any** method (a 429 is rejected before the
1255
1257
  * handler runs — the write never executed), honoring the server `Retry-After`;
1256
- * - a `503` response retries on **GETs only** (a write may have started).
1258
+ * - a `503` response retries on **idempotent requests only** (a non-idempotent
1259
+ * write may have started).
1257
1260
  * Every other outcome (2xx, or a non-retryable status) is returned to the
1258
1261
  * caller, which maps a non-2xx to a typed {@link WalletApiError}.
1259
1262
  */
1260
- async rawFetchWithRetry(method, path, body, jwt) {
1261
- const idempotent = method === "GET";
1263
+ async rawFetchWithRetry(method, path, body, jwt, idempotentWrite = false) {
1264
+ const idempotent = method === "GET" || idempotentWrite;
1262
1265
  for (let attempt = 1; ; attempt += 1) {
1263
1266
  let res;
1264
1267
  try {
@@ -1281,8 +1284,8 @@ var WalletApiClient = class _WalletApiClient {
1281
1284
  }
1282
1285
  /**
1283
1286
  * Delay before retrying a non-2xx response, or `null` to not retry. `429`
1284
- * retries on any method (rejected before execution); `503` on idempotent GETs.
1285
- * Honors a capped `Retry-After` when present, else falls back to backoff.
1287
+ * retries on any method (rejected before execution); `503` on idempotent
1288
+ * requests only. Honors a capped `Retry-After` when present, else backoff.
1286
1289
  */
1287
1290
  retryDelayForStatus(res, idempotent, attempt) {
1288
1291
  const retryable = res.status === 429 || res.status === 503 && idempotent;
@@ -1306,16 +1309,18 @@ var WalletApiClient = class _WalletApiClient {
1306
1309
  * Authenticated JSON request. A 401 triggers one silent re-auth
1307
1310
  * (refresh → challenge fallback) and one retry; {@link rawFetchWithRetry}
1308
1311
  * additionally rides out transient failures — a dropped connection on an
1309
- * idempotent GET, or a `429`/`503` with `Retry-After` — so a single blip or a
1310
- * brief rate-limit window doesn't fail the call.
1312
+ * idempotent request (any GET, or a write flagged `opts.idempotent`), or a
1313
+ * `429`/`503` with `Retry-After` — so a single blip or a brief rate-limit
1314
+ * window doesn't fail the call.
1311
1315
  */
1312
- async requestJson(method, path, body) {
1316
+ async requestJson(method, path, body, opts) {
1317
+ const idempotent = opts?.idempotent ?? false;
1313
1318
  if (!this.jwt) await this.signIn();
1314
- let res = await this.rawFetchWithRetry(method, path, body, this.jwt);
1319
+ let res = await this.rawFetchWithRetry(method, path, body, this.jwt, idempotent);
1315
1320
  if (res.status === 401) {
1316
1321
  this.jwt = null;
1317
1322
  await this.signIn();
1318
- res = await this.rawFetchWithRetry(method, path, body, this.jwt);
1323
+ res = await this.rawFetchWithRetry(method, path, body, this.jwt, idempotent);
1319
1324
  }
1320
1325
  if (res.status === 204) return null;
1321
1326
  if (!res.ok) throw await this.toError(res, `${method} ${path}`);
@@ -1347,12 +1352,20 @@ var WalletApiClient = class _WalletApiClient {
1347
1352
  */
1348
1353
  async applyInventoryDelta(req) {
1349
1354
  const cursor = parseApplyResult(
1350
- await this.requestJson("POST", "/v1/inventory/apply", {
1351
- transferId: req.transferId,
1352
- spent: req.spent,
1353
- added: req.added,
1354
- ...req.externalDelivery !== void 0 ? { externalDelivery: req.externalDelivery } : {}
1355
- })
1355
+ await this.requestJson(
1356
+ "POST",
1357
+ "/v1/inventory/apply",
1358
+ {
1359
+ transferId: req.transferId,
1360
+ spent: req.spent,
1361
+ added: req.added,
1362
+ ...req.externalDelivery !== void 0 ? { externalDelivery: req.externalDelivery } : {}
1363
+ },
1364
+ // Idempotent by transferId — the server replays a re-applied transferId
1365
+ // to the same cursor (beginApplied), so a lost-response retry on a flaky
1366
+ // link is safe and won't double-apply (#664).
1367
+ { idempotent: true }
1368
+ )
1356
1369
  );
1357
1370
  await this.setLocalIntentStatus(req.transferId, "completed");
1358
1371
  return cursor;