@escro/sdk 0.2.0 → 0.3.0

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/index.js CHANGED
@@ -100,6 +100,26 @@ function verifyBotDescriptorSignature(descriptor) {
100
100
  return false;
101
101
  }
102
102
  }
103
+ function spec(discriminator, escrowAccountIndex, cause) {
104
+ return {
105
+ discriminator: Uint8Array.from(discriminator),
106
+ escrowAccountIndex,
107
+ signerAccountIndex: 0,
108
+ cause
109
+ };
110
+ }
111
+ var ESCROW_INSTRUCTIONS = {
112
+ create_escrow: spec([253, 215, 165, 116, 36, 108, 68, 80], 4, null),
113
+ claim_task: spec([49, 222, 219, 238, 155, 68, 221, 136], 1, null),
114
+ submit_deliverable: spec([38, 137, 64, 44, 237, 11, 125, 101], 1, null),
115
+ raise_dispute: spec([41, 243, 1, 51, 150, 95, 246, 73], 1, null),
116
+ cancel_escrow: spec([156, 203, 54, 179, 38, 72, 33, 21], 3, "CANCELLED"),
117
+ release_payment: spec([24, 34, 191, 86, 145, 160, 183, 233], 3, "EXPLICIT_RELEASE"),
118
+ timeout_release: spec([98, 176, 26, 12, 83, 105, 154, 68], 3, "TIMEOUT_RELEASE"),
119
+ refund_buyer: spec([199, 139, 203, 146, 192, 150, 53, 218], 3, "DEADLINE_REFUND"),
120
+ arbitration_release: spec([118, 157, 141, 26, 104, 117, 94, 229], 4, "ARBITRATION_RELEASE"),
121
+ arbitration_refund: spec([255, 194, 84, 248, 185, 249, 120, 122], 4, "ARBITRATION_REFUND")
122
+ };
103
123
 
104
124
  // src/payments.ts
105
125
  var RAILS = ["escrow", "x402"];
@@ -114,9 +134,10 @@ var EscrowPaymentRouter = class {
114
134
 
115
135
  // src/errors.ts
116
136
  var EscroError = class extends Error {
117
- constructor(message, code = "ESCRO_ERROR") {
137
+ constructor(message, code = "ESCRO_ERROR", retryAfterMs2) {
118
138
  super(message);
119
139
  __publicField(this, "code", code);
140
+ __publicField(this, "retryAfterMs", retryAfterMs2);
120
141
  this.name = "EscroError";
121
142
  }
122
143
  };
@@ -147,6 +168,14 @@ var EscrowTimeoutError = class extends EscroError {
147
168
  this.name = "EscrowTimeoutError";
148
169
  }
149
170
  };
171
+ var EscroConfirmError = class extends EscroError {
172
+ constructor(address, signature, code, message) {
173
+ super(`Confirm failed for escrow ${address} (signature ${signature}): ${message}`, code);
174
+ __publicField(this, "address", address);
175
+ __publicField(this, "signature", signature);
176
+ this.name = "EscroConfirmError";
177
+ }
178
+ };
150
179
  var UnauthorizedError = class extends EscroError {
151
180
  constructor(message = "Unauthorized") {
152
181
  super(message, "UNAUTHORIZED");
@@ -177,7 +206,10 @@ async function handleError(res, address) {
177
206
  if (res.status === 404) throw new EscrowNotFoundError(address ?? msg);
178
207
  if (res.status === 409) throw new EscrowStateError(msg);
179
208
  if (res.status === 401 || res.status === 403) throw new UnauthorizedError(msg);
180
- throw new EscroError(msg, body.code ?? "UNKNOWN");
209
+ throw new EscroError(msg, body.code ?? "UNKNOWN", retryAfterMs(res.headers.get("retry-after")));
210
+ }
211
+ function retryAfterMs(header) {
212
+ return header !== null && /^\d+$/.test(header.trim()) ? Number(header.trim()) * 1e3 : void 0;
181
213
  }
182
214
  var ApiClient = class {
183
215
  constructor(baseUrl, wallet) {
@@ -253,6 +285,22 @@ var ApiClient = class {
253
285
  const body = await res.json();
254
286
  return body.wallets;
255
287
  }
288
+ /**
289
+ * GET /rep/:wallet : one wallet's EscroRep RAW components (ARCHITECTURE §9).
290
+ * Unauthenticated public read (no auth headers). Unknown wallets return zeroed
291
+ * components, never 404; a 404 means the deployment mounted no reputation
292
+ * source and surfaces as {@link ReputationUnavailableError}. Shares the public
293
+ * per-wallet rate budget with every other caller, so fan-outs should use
294
+ * {@link listReputations} instead.
295
+ */
296
+ async getReputation(wallet) {
297
+ const res = await fetch(this.url(`/rep/${encodeURIComponent(wallet)}`));
298
+ if (!res.ok) {
299
+ if (res.status === 404) throw new ReputationUnavailableError();
300
+ await handleError(res);
301
+ }
302
+ return await res.json();
303
+ }
256
304
  /**
257
305
  * POST /v1/escrows — create escrow, returns unsigned tx + ids.
258
306
  * Requires auth.
@@ -342,7 +390,7 @@ var ApiClient = class {
342
390
  */
343
391
  async raiseDispute(address, params) {
344
392
  const path = `/v1/escrows/${address}/dispute`;
345
- const rawBody = JSON.stringify({ reason: params.reason, evidence: params.evidence });
393
+ const rawBody = JSON.stringify({ reason: params.reason });
346
394
  const res = await fetch(this.url(path), {
347
395
  method: "POST",
348
396
  headers: {
@@ -354,6 +402,35 @@ var ApiClient = class {
354
402
  if (!res.ok) await handleError(res, address);
355
403
  return res.json();
356
404
  }
405
+ /**
406
+ * POST /v1/escrows/:address/confirm: the API records the create, claim, submit,
407
+ * cancel or dispute the landed `signature` carries, after verifying it on chain.
408
+ * A non-2xx answer throws an {@link EscroError} with the server's code, or
409
+ * `HTTP_<status>` when the answer carries none; a network failure rejects with
410
+ * fetch's own error. {@link Escro.confirm} decides which to retry.
411
+ */
412
+ async confirm(address, signature, evidence) {
413
+ const path = `/v1/escrows/${address}/confirm`;
414
+ const rawBody = JSON.stringify({ signature, evidence });
415
+ const res = await fetch(this.url(path), {
416
+ method: "POST",
417
+ headers: {
418
+ ...authHeaders(this.wallet, "POST", path, rawBody),
419
+ "content-type": "application/json"
420
+ },
421
+ body: rawBody
422
+ });
423
+ if (!res.ok) {
424
+ const body2 = await res.json().catch(() => ({}));
425
+ throw new EscroError(
426
+ body2.error ?? `HTTP ${String(res.status)}`,
427
+ body2.code ?? `HTTP_${String(res.status)}`,
428
+ retryAfterMs(res.headers.get("retry-after"))
429
+ );
430
+ }
431
+ const body = await res.json();
432
+ return deserialize(body.escrow);
433
+ }
357
434
  /**
358
435
  * GET /v1/stats — public protocol-wide stats.
359
436
  * No auth required. Upstream typing in {@link Escro.getStats} narrows the
@@ -563,6 +640,30 @@ async function buildReleasePaymentTx(params) {
563
640
  }
564
641
 
565
642
  // src/client.ts
643
+ var CONFIRM_WINDOW_MS = 3e4;
644
+ var CONFIRM_FIRST_DELAY_MS = 500;
645
+ var CONFIRM_MAX_DELAY_MS = 4e3;
646
+ var RETRYABLE_CONFIRM_CODES = [
647
+ "TX_NOT_FOUND",
648
+ "RPC_UNAVAILABLE",
649
+ "HTTP_502",
650
+ "HTTP_503",
651
+ "HTTP_504",
652
+ "RATE_LIMITED",
653
+ "HTTP_429"
654
+ ];
655
+ function isRetryableConfirmCode(code) {
656
+ return RETRYABLE_CONFIRM_CODES.includes(code);
657
+ }
658
+ function isUrl(value) {
659
+ try {
660
+ new URL(value);
661
+ return true;
662
+ } catch {
663
+ return false;
664
+ }
665
+ }
666
+ var sleep2 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
566
667
  var Escro = class {
567
668
  constructor(options) {
568
669
  __publicField(this, "connection");
@@ -578,18 +679,14 @@ var Escro = class {
578
679
  // ── Buyer Bot ────────────────────────────────────────────────────────────────
579
680
  /**
580
681
  * Create a new escrow: registers with the API, signs and submits the
581
- * on-chain `create_escrow` transaction.
682
+ * on-chain `create_escrow` transaction, then confirms it with the API.
582
683
  *
583
684
  * @returns `{ escrowId, escrowPda, signature }` — use `escrowPda` for all subsequent calls.
584
685
  */
585
686
  async createEscrow(params) {
586
687
  const { escrowId, escrowPda, unsignedTx } = await this.api.createEscrow(params);
587
- const signature = await signAndSend(
588
- unsignedTx,
589
- this.options.wallet,
590
- this.connection,
591
- this.cluster
592
- );
688
+ const signature = await this.send(unsignedTx);
689
+ await this.confirm(escrowPda, signature);
593
690
  return { escrowId, escrowPda, signature };
594
691
  }
595
692
  /**
@@ -629,24 +726,31 @@ var Escro = class {
629
726
  }
630
727
  /**
631
728
  * Raise a dispute for an escrow. Either the buyer or the assigned worker
632
- * may call this. Signs and submits the `raise_dispute` on-chain tx.
729
+ * may call this. Signs and submits the `raise_dispute` on-chain tx, then confirms it with the API.
633
730
  *
634
731
  * @returns Solana transaction signature.
635
732
  */
636
733
  async raiseDispute(address, params) {
637
- const { unsignedTx } = await this.api.raiseDispute(address, params);
638
- return signAndSend(unsignedTx, this.options.wallet, this.connection, this.cluster);
734
+ if (params.evidence !== void 0 && !isUrl(params.evidence)) {
735
+ throw new EscroError(`evidence must be a URL: ${params.evidence}`, "VALIDATION_ERROR");
736
+ }
737
+ const { unsignedTx } = await this.api.raiseDispute(address, { reason: params.reason });
738
+ const signature = await this.send(unsignedTx);
739
+ await this.confirm(address, signature, {
740
+ ...params.evidence !== void 0 && { evidence: params.evidence }
741
+ });
742
+ return signature;
639
743
  }
640
744
  /**
641
745
  * Cancel a funded escrow before any worker has claimed it.
642
746
  * Buyer must be the wallet in the constructor. Only valid when state is `FUNDED`.
643
- * Signs and submits the `cancel_escrow` on-chain tx; full USDC refund to buyer.
747
+ * Signs and submits the `cancel_escrow` on-chain tx, then confirms it with the API; full USDC refund to buyer.
644
748
  *
645
749
  * @returns Solana transaction signature.
646
750
  */
647
751
  async cancelEscrow(address) {
648
752
  const { unsignedTx } = await this.api.cancelEscrow(address);
649
- return signAndSend(unsignedTx, this.options.wallet, this.connection, this.cluster);
753
+ return this.sendAndConfirm(address, unsignedTx);
650
754
  }
651
755
  // ── Payments (dual-path; x402 reserved) ───────────────────────────────────────
652
756
  /**
@@ -671,23 +775,23 @@ var Escro = class {
671
775
  // ── Worker Bot ───────────────────────────────────────────────────────────────
672
776
  /**
673
777
  * Claim an assigned task. Worker must be the wallet in the constructor.
674
- * Signs and submits the `claim_task` on-chain tx.
778
+ * Signs and submits the `claim_task` on-chain tx, then confirms it with the API.
675
779
  *
676
780
  * @returns Solana transaction signature.
677
781
  */
678
782
  async claimTask(address) {
679
783
  const { unsignedTx } = await this.api.claimTask(address);
680
- return signAndSend(unsignedTx, this.options.wallet, this.connection, this.cluster);
784
+ return this.sendAndConfirm(address, unsignedTx);
681
785
  }
682
786
  /**
683
787
  * Submit a deliverable for the buyer to review. Worker must be the wallet.
684
- * Signs and submits the `submit_deliverable` on-chain tx.
788
+ * Signs and submits the `submit_deliverable` on-chain tx, then confirms it with the API.
685
789
  *
686
790
  * @returns Solana transaction signature.
687
791
  */
688
792
  async submitDeliverable(address, params) {
689
793
  const { unsignedTx } = await this.api.submitDeliverable(address, params);
690
- return signAndSend(unsignedTx, this.options.wallet, this.connection, this.cluster);
794
+ return this.sendAndConfirm(address, unsignedTx);
691
795
  }
692
796
  /**
693
797
  * List tasks assigned to the wallet's public key.
@@ -797,6 +901,51 @@ var Escro = class {
797
901
  return data;
798
902
  }
799
903
  // ── Shared ───────────────────────────────────────────────────────────────────
904
+ /**
905
+ * Ask the API to record the create, claim, submit, cancel or dispute that the
906
+ * landed `signature` carries; the API verifies it on chain first. Retries a
907
+ * not-yet-visible transaction, an RPC failure, a gateway error or a rate limit
908
+ * for about 30 s (waiting at least a sent Retry-After), never a rejection. Throws
909
+ * {@link EscroConfirmError}; calling again is safe (a replay of a recorded
910
+ * transition succeeds).
911
+ */
912
+ async confirm(address, signature, opts = {}) {
913
+ const deadline = Date.now() + CONFIRM_WINDOW_MS;
914
+ let delay = CONFIRM_FIRST_DELAY_MS;
915
+ for (; ; ) {
916
+ let code;
917
+ let message;
918
+ let wait = delay;
919
+ try {
920
+ return await this.api.confirm(address, signature, opts.evidence);
921
+ } catch (err) {
922
+ if (err instanceof EscroError) {
923
+ if (!isRetryableConfirmCode(err.code)) {
924
+ throw new EscroConfirmError(address, signature, err.code, err.message);
925
+ }
926
+ code = err.code;
927
+ message = err.message;
928
+ wait = Math.max(delay, err.retryAfterMs ?? 0);
929
+ } else {
930
+ code = "NETWORK_ERROR";
931
+ message = err instanceof Error ? err.message : String(err);
932
+ }
933
+ }
934
+ if (Date.now() + wait > deadline) {
935
+ throw new EscroConfirmError(address, signature, code, message);
936
+ }
937
+ await sleep2(wait);
938
+ delay = Math.min(delay * 2, CONFIRM_MAX_DELAY_MS);
939
+ }
940
+ }
941
+ send(unsignedTx) {
942
+ return signAndSend(unsignedTx, this.options.wallet, this.connection, this.cluster);
943
+ }
944
+ async sendAndConfirm(address, unsignedTx) {
945
+ const signature = await this.send(unsignedTx);
946
+ await this.confirm(address, signature);
947
+ return signature;
948
+ }
800
949
  /**
801
950
  * Fetch an escrow by its PDA address.
802
951
  * If `options.poll` is true, polls with exponential backoff until the escrow
@@ -930,9 +1079,9 @@ function createBittensorSubnetAdapter(config) {
930
1079
  id,
931
1080
  capabilities: config.capabilities,
932
1081
  healthCheck: config.checkHealth,
933
- async execute(spec) {
1082
+ async execute(spec2) {
934
1083
  const budgetTao = await config.swap(config.taskBudgetMicroUsdc);
935
- const content = await config.callSubnet(spec, budgetTao);
1084
+ const content = await config.callSubnet(spec2, budgetTao);
936
1085
  const contentHash = sha256Hex2(content);
937
1086
  const proofUri = await config.pin(content);
938
1087
  return {
@@ -1015,16 +1164,16 @@ function scoreGradientsDemoDeliverable(content) {
1015
1164
  }
1016
1165
  return matches / expected.length;
1017
1166
  }
1018
- function referencePlaceholder(spec) {
1167
+ function referencePlaceholder(spec2) {
1019
1168
  return canonicalize({
1020
1169
  checkpoint: "reference-sn56-checkpoint",
1021
1170
  eval: { metric: "accuracy", score: 0 },
1022
1171
  note: "reference stub - replace the callSubnet port with a real SN56 miner call.",
1023
- taskType: spec.taskType
1172
+ taskType: spec2.taskType
1024
1173
  });
1025
1174
  }
1026
- var defaultCallSubnet = (spec) => Promise.resolve(
1027
- spec.metadata.demo === GRADIENTS_DEMO_MARKER ? solveGradientsDemo() : referencePlaceholder(spec)
1175
+ var defaultCallSubnet = (spec2) => Promise.resolve(
1176
+ spec2.metadata.demo === GRADIENTS_DEMO_MARKER ? solveGradientsDemo() : referencePlaceholder(spec2)
1028
1177
  );
1029
1178
  function createGradientsAdapter(config = {}) {
1030
1179
  return createBittensorSubnetAdapter({
@@ -1136,17 +1285,17 @@ function scoreRidgesDemoDeliverable(content) {
1136
1285
  }
1137
1286
  return coveredInputs.size / DEMO_INPUTS.length;
1138
1287
  }
1139
- function referencePlaceholder2(spec) {
1288
+ function referencePlaceholder2(spec2) {
1140
1289
  return canonicalize({
1141
1290
  language: "typescript",
1142
1291
  solution: "// reference stub - replace the runAgent port with a real Ridges agent call.",
1143
1292
  passed: false,
1144
1293
  tests: [],
1145
- taskType: spec.taskType
1294
+ taskType: spec2.taskType
1146
1295
  });
1147
1296
  }
1148
- var defaultRunAgent = (spec) => Promise.resolve(
1149
- spec.metadata.demo === RIDGES_DEMO_MARKER ? solveRidgesDemo() : referencePlaceholder2(spec)
1297
+ var defaultRunAgent = (spec2) => Promise.resolve(
1298
+ spec2.metadata.demo === RIDGES_DEMO_MARKER ? solveRidgesDemo() : referencePlaceholder2(spec2)
1150
1299
  );
1151
1300
  var defaultPin2 = (content) => Promise.resolve(`ipfs://placeholder-${sha256Hex3(content).slice(0, 16)}`);
1152
1301
  function createRidgesAdapter(config = {}) {
@@ -1159,8 +1308,8 @@ function createRidgesAdapter(config = {}) {
1159
1308
  id: service,
1160
1309
  capabilities,
1161
1310
  healthCheck: checkHealth,
1162
- async execute(spec) {
1163
- const content = await runAgent(spec);
1311
+ async execute(spec2) {
1312
+ const content = await runAgent(spec2);
1164
1313
  const contentHash = sha256Hex3(content);
1165
1314
  const proofUri = await pin(content);
1166
1315
  return {
@@ -1269,15 +1418,15 @@ function score404genDemoDeliverable(content) {
1269
1418
  }
1270
1419
  return Math.min(batch.assets.length / DEMO_EXPECTATION.requestedAssets, 1);
1271
1420
  }
1272
- function referencePlaceholder3(spec) {
1421
+ function referencePlaceholder3(spec2) {
1273
1422
  return canonicalize({
1274
1423
  assets: [{ format: "GLB", polygonCount: 0, uri: "ipfs://placeholder" }],
1275
1424
  note: "reference stub - replace the callSubnet port with a real SN17 miner call.",
1276
- taskType: spec.taskType
1425
+ taskType: spec2.taskType
1277
1426
  });
1278
1427
  }
1279
- var defaultCallSubnet2 = (spec) => Promise.resolve(
1280
- spec.metadata.demo === GEN404_DEMO_MARKER ? solveGen404Demo() : referencePlaceholder3(spec)
1428
+ var defaultCallSubnet2 = (spec2) => Promise.resolve(
1429
+ spec2.metadata.demo === GEN404_DEMO_MARKER ? solveGen404Demo() : referencePlaceholder3(spec2)
1281
1430
  );
1282
1431
  function create404genAdapter(config = {}) {
1283
1432
  return createBittensorSubnetAdapter({
@@ -1377,17 +1526,17 @@ function scoreLiumDemoDeliverable(content) {
1377
1526
  }
1378
1527
  return parsed.artifact === computeLiumDemoArtifact() ? 1 : 0;
1379
1528
  }
1380
- function referencePlaceholder4(spec) {
1529
+ function referencePlaceholder4(spec2) {
1381
1530
  return canonicalize({
1382
1531
  job: "lium-sn51-generic",
1383
1532
  status: "completed",
1384
1533
  artifact: null,
1385
1534
  note: "reference stub - replace the runJob port with a real SN51 GPU-rental call.",
1386
- taskType: spec.taskType
1535
+ taskType: spec2.taskType
1387
1536
  });
1388
1537
  }
1389
- var defaultRunJob = (spec) => Promise.resolve(
1390
- spec.metadata.demo === LIUM_DEMO_MARKER ? solveLiumDemo() : referencePlaceholder4(spec)
1538
+ var defaultRunJob = (spec2) => Promise.resolve(
1539
+ spec2.metadata.demo === LIUM_DEMO_MARKER ? solveLiumDemo() : referencePlaceholder4(spec2)
1391
1540
  );
1392
1541
  function createLiumAdapter(config = {}) {
1393
1542
  return createBittensorSubnetAdapter({
@@ -1496,17 +1645,17 @@ function scoreAkashDemoDeliverable(content) {
1496
1645
  }
1497
1646
  return parsed.artifact === computeAkashDemoArtifact() ? 1 : 0;
1498
1647
  }
1499
- function referencePlaceholder5(spec) {
1648
+ function referencePlaceholder5(spec2) {
1500
1649
  return canonicalize({
1501
1650
  job: "akash-generic",
1502
1651
  status: "completed",
1503
1652
  artifact: null,
1504
1653
  note: "reference stub - replace the runDeployment port with a real Akash deployment call.",
1505
- taskType: spec.taskType
1654
+ taskType: spec2.taskType
1506
1655
  });
1507
1656
  }
1508
- var defaultRunDeployment = (spec) => Promise.resolve(
1509
- spec.metadata.demo === AKASH_DEMO_MARKER ? solveAkashDemo() : referencePlaceholder5(spec)
1657
+ var defaultRunDeployment = (spec2) => Promise.resolve(
1658
+ spec2.metadata.demo === AKASH_DEMO_MARKER ? solveAkashDemo() : referencePlaceholder5(spec2)
1510
1659
  );
1511
1660
  function createAkashAdapter(config = {}) {
1512
1661
  const capabilities = config.capabilities ?? [...AKASH_CAPABILITIES];
@@ -1519,9 +1668,9 @@ function createAkashAdapter(config = {}) {
1519
1668
  id: AKASH_ADAPTER_ID,
1520
1669
  capabilities,
1521
1670
  healthCheck: checkHealth,
1522
- async execute(spec) {
1671
+ async execute(spec2) {
1523
1672
  const budgetAkt = await swap(taskBudgetMicroUsdc);
1524
- const content = await runDeployment(spec, budgetAkt);
1673
+ const content = await runDeployment(spec2, budgetAkt);
1525
1674
  const contentHash = sha256Hex4(content);
1526
1675
  const proofUri = await pin(content);
1527
1676
  return {
@@ -1638,17 +1787,17 @@ function scoreRenderDemoDeliverable(content) {
1638
1787
  }
1639
1788
  return parsed.frame === computeRenderDemoArtifact() ? 1 : 0;
1640
1789
  }
1641
- function referencePlaceholder6(spec) {
1790
+ function referencePlaceholder6(spec2) {
1642
1791
  return canonicalize({
1643
1792
  job: "render-generic",
1644
1793
  status: "completed",
1645
1794
  frame: null,
1646
1795
  note: "reference stub - replace the runJob port with a real Render Network job submission.",
1647
- taskType: spec.taskType
1796
+ taskType: spec2.taskType
1648
1797
  });
1649
1798
  }
1650
- var defaultRunJob2 = (spec) => Promise.resolve(
1651
- spec.metadata.demo === RENDER_DEMO_MARKER ? solveRenderDemo() : referencePlaceholder6(spec)
1799
+ var defaultRunJob2 = (spec2) => Promise.resolve(
1800
+ spec2.metadata.demo === RENDER_DEMO_MARKER ? solveRenderDemo() : referencePlaceholder6(spec2)
1652
1801
  );
1653
1802
  function createRenderAdapter(config = {}) {
1654
1803
  const service = config.service ?? DEFAULT_SERVICE2;
@@ -1662,9 +1811,9 @@ function createRenderAdapter(config = {}) {
1662
1811
  id: service,
1663
1812
  capabilities,
1664
1813
  healthCheck: checkHealth,
1665
- async execute(spec) {
1814
+ async execute(spec2) {
1666
1815
  const budgetRender = await swap(taskBudgetMicroUsdc);
1667
- const content = await runJob(spec, budgetRender);
1816
+ const content = await runJob(spec2, budgetRender);
1668
1817
  const contentHash = sha256Hex5(content);
1669
1818
  const proofUri = await pin(content);
1670
1819
  return {
@@ -1691,15 +1840,15 @@ function sha256Hex6(content) {
1691
1840
  var LCG_MULT = 1103515245n;
1692
1841
  var LCG_INC = 12345n;
1693
1842
  var LCG_MOD = 1n << 31n;
1694
- function readComputeParams(spec) {
1695
- const rawSeed = spec.metadata.seed;
1696
- const rawSteps = spec.metadata.steps;
1843
+ function readComputeParams(spec2) {
1844
+ const rawSeed = spec2.metadata.seed;
1845
+ const rawSteps = spec2.metadata.steps;
1697
1846
  const seed = typeof rawSeed === "number" && Number.isInteger(rawSeed) ? rawSeed : GENSYN_DEMO_SEED;
1698
1847
  const steps = typeof rawSteps === "number" && Number.isInteger(rawSteps) && rawSteps > 0 ? rawSteps : GENSYN_DEMO_STEPS;
1699
1848
  return { seed, steps };
1700
1849
  }
1701
- var reproduceGensynCompute = (spec) => {
1702
- const { seed, steps } = readComputeParams(spec);
1850
+ var reproduceGensynCompute = (spec2) => {
1851
+ const { seed, steps } = readComputeParams(spec2);
1703
1852
  const states = [];
1704
1853
  let x = BigInt(seed) % LCG_MOD;
1705
1854
  if (x < 0n) {
@@ -1721,10 +1870,10 @@ function commitmentOf(base) {
1721
1870
  )
1722
1871
  );
1723
1872
  }
1724
- function buildReeProof(spec, exec, content) {
1873
+ function buildReeProof(spec2, exec, content) {
1725
1874
  const base = {
1726
1875
  scheme: GENSYN_REE_SCHEME,
1727
- specHash: sha256Hex6(canonicalize(spec)),
1876
+ specHash: sha256Hex6(canonicalize(spec2)),
1728
1877
  outputHash: sha256Hex6(content),
1729
1878
  steps: exec.steps,
1730
1879
  transcriptHash: sha256Hex6(canonicalize(exec.states))
@@ -1831,11 +1980,11 @@ function createGensynAdapter(config = {}) {
1831
1980
  id: GENSYN_ADAPTER_ID,
1832
1981
  capabilities,
1833
1982
  healthCheck: checkHealth,
1834
- async execute(spec) {
1835
- const exec = runCompute(spec);
1983
+ async execute(spec2) {
1984
+ const exec = runCompute(spec2);
1836
1985
  const content = gensynDeliverable(exec);
1837
1986
  const contentHash = sha256Hex6(content);
1838
- const proof = buildReeProof(spec, exec, content);
1987
+ const proof = buildReeProof(spec2, exec, content);
1839
1988
  const proofUri = await pin(content);
1840
1989
  return {
1841
1990
  content,
@@ -2010,21 +2159,21 @@ function solveZkmlDemo() {
2010
2159
  output: { label: "cat", confidence: 0.98 }
2011
2160
  });
2012
2161
  }
2013
- function referencePlaceholderOutput(spec) {
2162
+ function referencePlaceholderOutput(spec2) {
2014
2163
  return {
2015
2164
  content: canonicalize({
2016
2165
  note: "reference stub - replace the runInference port with a real zk-verified inference call.",
2017
- taskType: spec.taskType
2166
+ taskType: spec2.taskType
2018
2167
  }),
2019
2168
  modelCommitment: sha256Hex7("zkml-reference-stub-model"),
2020
- inputCommitment: sha256Hex7(canonicalize(spec))
2169
+ inputCommitment: sha256Hex7(canonicalize(spec2))
2021
2170
  };
2022
2171
  }
2023
- var defaultRunInference = (spec) => spec.metadata.demo === ZKML_DEMO_MARKER ? {
2172
+ var defaultRunInference = (spec2) => spec2.metadata.demo === ZKML_DEMO_MARKER ? {
2024
2173
  content: solveZkmlDemo(),
2025
2174
  modelCommitment: DEMO_MODEL_COMMITMENT,
2026
2175
  inputCommitment: DEMO_INPUT_COMMITMENT
2027
- } : referencePlaceholderOutput(spec);
2176
+ } : referencePlaceholderOutput(spec2);
2028
2177
  function createZkmlAdapter(config = {}) {
2029
2178
  const id = config.id ?? ZKML_ADAPTER_ID;
2030
2179
  const capabilities = config.capabilities ?? [...ZKML_CAPABILITIES];
@@ -2039,10 +2188,10 @@ function createZkmlAdapter(config = {}) {
2039
2188
  return {
2040
2189
  id,
2041
2190
  capabilities,
2042
- async execute(spec) {
2043
- const output = await runInference(spec);
2191
+ async execute(spec2) {
2192
+ const output = await runInference(spec2);
2044
2193
  const contentHash = sha256Hex7(output.content);
2045
- const proof = await prove({ spec, output, outputHash: contentHash });
2194
+ const proof = await prove({ spec: spec2, output, outputHash: contentHash });
2046
2195
  const proofUri = await pin(proof);
2047
2196
  return {
2048
2197
  content: output.content,
@@ -2069,6 +2218,7 @@ export {
2069
2218
  ApiClient,
2070
2219
  ENABLED_RAILS,
2071
2220
  Escro,
2221
+ EscroConfirmError,
2072
2222
  EscroError,
2073
2223
  EscroRailNotEnabledError,
2074
2224
  EscrowNotFoundError,