@escro/sdk 0.4.0 → 0.4.2

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.cjs CHANGED
@@ -138,10 +138,12 @@ var import_web33 = require("@solana/web3.js");
138
138
 
139
139
  // ../shared/dist/index.js
140
140
  var import_crypto = require("crypto");
141
+ var import_crypto2 = require("crypto");
141
142
  var import_tweetnacl = __toESM(require("tweetnacl"), 1);
142
143
  var import_bs58 = __toESM(require("bs58"), 1);
143
144
  var import_tweetnacl2 = __toESM(require("tweetnacl"), 1);
144
145
  var import_bs582 = __toESM(require("bs58"), 1);
146
+ var import_bs583 = __toESM(require("bs58"), 1);
145
147
  var EscrowState = /* @__PURE__ */ ((EscrowState2) => {
146
148
  EscrowState2["CREATED"] = "CREATED";
147
149
  EscrowState2["FUNDED"] = "FUNDED";
@@ -188,6 +190,33 @@ function canonicalize(value) {
188
190
  }
189
191
  return JSON.stringify(value);
190
192
  }
193
+ var SPEC_KEYS = [
194
+ "version",
195
+ "taskType",
196
+ "description",
197
+ "acceptanceCriteria",
198
+ "deliverableFormat",
199
+ "metadata"
200
+ ];
201
+ var CRITERION_KEYS = ["id", "description", "weight", "required"];
202
+ var FORMAT_KEYS = ["type", "schema", "mimeType", "maxSizeBytes", "language"];
203
+ function pick(value, keys) {
204
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return value;
205
+ const source = value;
206
+ return Object.fromEntries(keys.filter((k) => k in source).map((k) => [k, source[k]]));
207
+ }
208
+ function normalizeTaskSpec(spec2) {
209
+ const top = pick(spec2, SPEC_KEYS);
210
+ const criteria = top.acceptanceCriteria;
211
+ return {
212
+ ...top,
213
+ acceptanceCriteria: Array.isArray(criteria) ? criteria.map((c) => pick(c, CRITERION_KEYS)) : criteria,
214
+ deliverableFormat: pick(top.deliverableFormat, FORMAT_KEYS)
215
+ };
216
+ }
217
+ function computeTaskSpecHash(spec2) {
218
+ return (0, import_crypto.createHash)("sha256").update(canonicalize(normalizeTaskSpec(spec2)), "utf8").digest("hex");
219
+ }
191
220
  function disputeReasonError(reason) {
192
221
  if (reason.length === 0) return "reason must not be empty";
193
222
  const bytes = new TextEncoder().encode(reason).length;
@@ -196,8 +225,16 @@ function disputeReasonError(reason) {
196
225
  }
197
226
  return null;
198
227
  }
228
+ var SAFE_URL_SCHEMES = ["http:", "https:", "ipfs:", "ar:"];
229
+ function isSafeUrl(value) {
230
+ try {
231
+ return SAFE_URL_SCHEMES.includes(new URL(value).protocol);
232
+ } catch {
233
+ return false;
234
+ }
235
+ }
199
236
  function hashBody(rawBody) {
200
- return (0, import_crypto.createHash)("sha256").update(rawBody, "utf8").digest("hex");
237
+ return (0, import_crypto2.createHash)("sha256").update(rawBody, "utf8").digest("hex");
201
238
  }
202
239
  function buildSignedMessage(timestamp, method, fullPath, bodyHash) {
203
240
  return `escro:${String(timestamp)}:${method}:${fullPath}:${bodyHash}`;
@@ -241,6 +278,18 @@ function verifyBotDescriptorSignature(descriptor) {
241
278
  return false;
242
279
  }
243
280
  }
281
+ var ESCROW_INSTRUCTION_NAMES = [
282
+ "create_escrow",
283
+ "claim_task",
284
+ "submit_deliverable",
285
+ "raise_dispute",
286
+ "cancel_escrow",
287
+ "release_payment",
288
+ "timeout_release",
289
+ "refund_buyer",
290
+ "arbitration_release",
291
+ "arbitration_refund"
292
+ ];
244
293
  function spec(discriminator, escrowAccountIndex, cause) {
245
294
  return {
246
295
  discriminator: Uint8Array.from(discriminator),
@@ -261,6 +310,66 @@ var ESCROW_INSTRUCTIONS = {
261
310
  arbitration_release: spec([118, 157, 141, 26, 104, 117, 94, 229], 4, "ARBITRATION_RELEASE"),
262
311
  arbitration_refund: spec([255, 194, 84, 248, 185, 249, 120, 122], 4, "ARBITRATION_REFUND")
263
312
  };
313
+ function escrowInstructionName(data) {
314
+ for (const name of ESCROW_INSTRUCTION_NAMES) {
315
+ const disc2 = ESCROW_INSTRUCTIONS[name].discriminator;
316
+ if (disc2.every((b, i) => data[i] === b)) return name;
317
+ }
318
+ return null;
319
+ }
320
+ var Reader = class {
321
+ constructor(buf) {
322
+ __publicField(this, "buf");
323
+ __publicField(this, "offset", 8);
324
+ this.buf = buf;
325
+ }
326
+ take(n) {
327
+ if (this.offset + n > this.buf.length) {
328
+ throw new Error(
329
+ `instruction data truncated: need ${String(n)} bytes at offset ${String(this.offset)}, have ${String(this.buf.length)}`
330
+ );
331
+ }
332
+ const out = this.buf.subarray(this.offset, this.offset + n);
333
+ this.offset += n;
334
+ return out;
335
+ }
336
+ u8() {
337
+ return this.take(1).readUInt8(0);
338
+ }
339
+ u64() {
340
+ return this.take(8).readBigUInt64LE(0);
341
+ }
342
+ i64() {
343
+ return this.take(8).readBigInt64LE(0);
344
+ }
345
+ string() {
346
+ const len = this.take(4).readUInt32LE(0);
347
+ return this.take(len).toString("utf8");
348
+ }
349
+ option(read) {
350
+ return this.u8() === 0 ? null : read();
351
+ }
352
+ bytes(n) {
353
+ return this.take(n);
354
+ }
355
+ };
356
+ function decodeCreateEscrowArgs(data) {
357
+ const r = new Reader(Buffer.from(data));
358
+ return {
359
+ taskId: r.string(),
360
+ amount: r.u64(),
361
+ deadline: r.i64(),
362
+ specHash: r.string(),
363
+ assignedWorker: r.option(() => import_bs583.default.encode(r.bytes(32)))
364
+ };
365
+ }
366
+ function decodeSubmitDeliverableArgs(data) {
367
+ const r = new Reader(Buffer.from(data));
368
+ return { deliverableHash: r.string(), proofUri: r.option(() => r.string()) };
369
+ }
370
+ function decodeRaiseDisputeArgs(data) {
371
+ return { reason: new Reader(Buffer.from(data)).string() };
372
+ }
264
373
 
265
374
  // src/payments.ts
266
375
  var RAILS = ["escrow", "x402"];
@@ -635,14 +744,19 @@ async function pollUntil(address, fetcher, predicate, timeoutMs = MS_24_H) {
635
744
  }
636
745
 
637
746
  // src/solana.ts
638
- var import_node_crypto = require("crypto");
639
747
  var import_web32 = require("@solana/web3.js");
640
748
  var import_spl_token = require("@solana/spl-token");
641
749
 
642
750
  // ../shared/dist/solana.js
643
751
  var import_web3 = require("@solana/web3.js");
644
- var import_bs583 = __toESM(require("bs58"), 1);
752
+ var import_bs584 = __toESM(require("bs58"), 1);
645
753
  var utf8 = (s) => new TextEncoder().encode(s);
754
+ function deriveEscrowPda(programId, buyer, taskId) {
755
+ return import_web3.PublicKey.findProgramAddressSync(
756
+ [utf8("escrow"), buyer.toBytes(), utf8(taskId)],
757
+ programId
758
+ )[0];
759
+ }
646
760
  function findPlatformConfigPda(programId) {
647
761
  return import_web3.PublicKey.findProgramAddressSync([utf8("config")], programId);
648
762
  }
@@ -679,7 +793,7 @@ function decodePlatformConfig(data) {
679
793
  throw new Error("PlatformConfig discriminator mismatch: not a PlatformConfig account");
680
794
  }
681
795
  const byte = (at) => data[at] ?? 0;
682
- const key = (at) => import_bs583.default.encode(data.subarray(at, at + 32));
796
+ const key = (at) => import_bs584.default.encode(data.subarray(at, at + 32));
683
797
  return {
684
798
  version: byte(L.version),
685
799
  feeBps: byte(L.fee_bps) | byte(L.fee_bps + 1) << 8,
@@ -691,10 +805,6 @@ function decodePlatformConfig(data) {
691
805
  }
692
806
 
693
807
  // src/solana.ts
694
- function disc(name) {
695
- return Buffer.from((0, import_node_crypto.createHash)("sha256").update(`global:${name}`).digest()).subarray(0, 8);
696
- }
697
- var DISC_RELEASE_PAYMENT = disc("release_payment");
698
808
  function resolveProgramId(cluster) {
699
809
  const id = getProgramId(cluster);
700
810
  assertProgramIdNotPlaceholder(id, cluster);
@@ -704,8 +814,7 @@ function allowedProgramIds(programId) {
704
814
  return /* @__PURE__ */ new Set([
705
815
  programId.toBase58(),
706
816
  import_spl_token.TOKEN_PROGRAM_ID.toBase58(),
707
- import_spl_token.ASSOCIATED_TOKEN_PROGRAM_ID.toBase58(),
708
- import_web32.ComputeBudgetProgram.programId.toBase58()
817
+ import_spl_token.ASSOCIATED_TOKEN_PROGRAM_ID.toBase58()
709
818
  ]);
710
819
  }
711
820
  var MAX_INSTRUCTIONS = 6;
@@ -743,6 +852,12 @@ async function fetchPlatformConfig(connection, cluster) {
743
852
  }
744
853
  return { mint: new import_web32.PublicKey(config.usdcMint), treasury: new import_web32.PublicKey(config.treasury) };
745
854
  }
855
+ function refuse(reason) {
856
+ throw new EscroError(
857
+ `Refusing to sign a server-built transaction: ${reason}`,
858
+ "UNEXPECTED_TRANSACTION"
859
+ );
860
+ }
746
861
  function validateTransaction(tx, cluster) {
747
862
  const programId = resolveProgramId(cluster);
748
863
  const allowed = allowedProgramIds(programId);
@@ -750,36 +865,103 @@ function validateTransaction(tx, cluster) {
750
865
  for (const ix of tx.instructions) {
751
866
  const id = ix.programId.toBase58();
752
867
  if (!allowed.has(id)) {
753
- throw new Error(
754
- `Unexpected program in transaction: ${id}. Allowed: ${[...allowed].join(", ")}`
755
- );
868
+ refuse(`Unexpected program in transaction: ${id}. Allowed: ${[...allowed].join(", ")}`);
756
869
  }
757
870
  if (id === tokenProgram) {
758
871
  const tag = ix.data.length > 0 ? ix.data[0] : void 0;
759
872
  if (tag !== void 0 && FORBIDDEN_TOKEN_IX_TAGS.has(tag)) {
760
- throw new Error(
761
- `Refusing to sign a fund-moving SPL Token instruction (tag ${String(tag)}) in a server-built transaction. Escro never requires the wallet to directly sign a token transfer/approve/burn/close; all token movement is a CPI inside the escro program.`
873
+ throw new EscroError(
874
+ `Refusing to sign a fund-moving SPL Token instruction (tag ${String(tag)}) in a server-built transaction`,
875
+ "UNEXPECTED_TRANSACTION"
762
876
  );
763
877
  }
764
878
  }
765
879
  }
766
880
  if (tx.instructions.length > MAX_INSTRUCTIONS) {
767
- throw new Error(
881
+ refuse(
768
882
  `Too many instructions (${String(tx.instructions.length)}). Max allowed: ${String(MAX_INSTRUCTIONS)}`
769
883
  );
770
884
  }
771
885
  }
772
- async function signAndSend(base64Tx, wallet, connection, cluster) {
773
- const buf = Buffer.from(base64Tx, "base64");
774
- const tx = import_web32.Transaction.from(buf);
886
+ var ATA_CREATE_IDEMPOTENT = 1;
887
+ function verifyServerTransaction(tx, cluster, wallet, expected) {
775
888
  validateTransaction(tx, cluster);
889
+ const programId = resolveProgramId(cluster);
890
+ if (!tx.feePayer?.equals(wallet)) refuse("the fee payer is not the wallet");
891
+ const escro = tx.instructions.filter((ix2) => ix2.programId.equals(programId));
892
+ const others = tx.instructions.filter((ix2) => !ix2.programId.equals(programId));
893
+ for (const ix2 of others) {
894
+ const ataCreate = expected.name === "release_payment" && ix2.programId.equals(import_spl_token.ASSOCIATED_TOKEN_PROGRAM_ID) && ix2.data.length === 1 && ix2.data[0] === ATA_CREATE_IDEMPOTENT;
895
+ if (!ataCreate) refuse(`unexpected ${ix2.programId.toBase58()} instruction`);
896
+ }
897
+ if (escro.length !== 1) refuse(`${String(escro.length)} escro instructions, expected 1`);
898
+ const [ix] = escro;
899
+ if (ix === void 0) refuse("no escro instruction");
900
+ const name = escrowInstructionName(ix.data);
901
+ if (name !== expected.name)
902
+ refuse(`${name ?? "an unknown instruction"}, expected ${expected.name}`);
903
+ const spec2 = ESCROW_INSTRUCTIONS[name];
904
+ const actor = ix.keys[spec2.signerAccountIndex];
905
+ if (actor === void 0 || !actor.pubkey.equals(wallet) || !actor.isSigner) {
906
+ refuse("the acting signer is not the wallet");
907
+ }
908
+ if (ix.keys[spec2.escrowAccountIndex]?.pubkey.toBase58() !== expected.escrowPda) {
909
+ refuse(`the escrow is not ${expected.escrowPda}`);
910
+ }
911
+ try {
912
+ switch (expected.name) {
913
+ case "create_escrow": {
914
+ const args = decodeCreateEscrowArgs(ix.data);
915
+ if (args.taskId !== expected.taskId) refuse("the task id differs");
916
+ if (deriveEscrowPda(programId, wallet, args.taskId).toBase58() !== expected.escrowPda) {
917
+ refuse("the escrow is not derived from the wallet and task id");
918
+ }
919
+ if (args.amount !== expected.amount) refuse("the amount differs");
920
+ if (args.deadline !== expected.deadline) refuse("the deadline differs");
921
+ if (args.specHash !== expected.specHash) refuse("the spec hash differs");
922
+ if (args.assignedWorker !== expected.assignedWorker) refuse("the assigned worker differs");
923
+ break;
924
+ }
925
+ case "submit_deliverable": {
926
+ const args = decodeSubmitDeliverableArgs(ix.data);
927
+ if (args.deliverableHash !== expected.deliverableHash)
928
+ refuse("the deliverable hash differs");
929
+ if (args.proofUri !== expected.proofUri) refuse("the proof URI differs");
930
+ break;
931
+ }
932
+ case "raise_dispute":
933
+ if (decodeRaiseDisputeArgs(ix.data).reason !== expected.reason)
934
+ refuse("the reason differs");
935
+ break;
936
+ default:
937
+ if (ix.data.length !== ESCROW_INSTRUCTIONS[name].discriminator.length) {
938
+ refuse(`${name} carries unexpected arguments`);
939
+ }
940
+ }
941
+ } catch (err) {
942
+ if (err instanceof EscroError) throw err;
943
+ refuse(`malformed ${name} arguments`);
944
+ }
945
+ }
946
+ async function signAndSend(base64Tx, wallet, connection, cluster, expected) {
947
+ const tx = import_web32.Transaction.from(Buffer.from(base64Tx, "base64"));
948
+ verifyServerTransaction(tx, cluster, wallet.publicKey, expected);
776
949
  tx.partialSign(wallet);
777
950
  const raw = tx.serialize();
778
951
  const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash("confirmed");
779
952
  const signature = await connection.sendRawTransaction(raw, {
780
953
  skipPreflight: false
781
954
  });
782
- await connection.confirmTransaction({ signature, blockhash, lastValidBlockHeight }, "confirmed");
955
+ const { value } = await connection.confirmTransaction(
956
+ { signature, blockhash, lastValidBlockHeight },
957
+ "confirmed"
958
+ );
959
+ if (value.err !== null) {
960
+ throw new EscroError(
961
+ `Transaction ${signature} failed at execution: ${JSON.stringify(value.err)}`,
962
+ "TX_FAILED"
963
+ );
964
+ }
783
965
  return signature;
784
966
  }
785
967
  async function buildReleasePaymentTx(params) {
@@ -822,7 +1004,7 @@ async function buildReleasePaymentTx(params) {
822
1004
  { pubkey: import_spl_token.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
823
1005
  { pubkey: import_spl_token.ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }
824
1006
  ],
825
- data: DISC_RELEASE_PAYMENT
1007
+ data: Buffer.from(ESCROW_INSTRUCTIONS.release_payment.discriminator)
826
1008
  });
827
1009
  const { blockhash } = await connection.getLatestBlockhash("confirmed");
828
1010
  const tx = new import_web32.Transaction();
@@ -853,14 +1035,6 @@ function isRetryableConfirmCode(code) {
853
1035
  function isRetryableReleaseCode(code) {
854
1036
  return code === "ESCROW_NOT_SETTLED" || isRetryableConfirmCode(code);
855
1037
  }
856
- function isUrl(value) {
857
- try {
858
- new URL(value);
859
- return true;
860
- } catch {
861
- return false;
862
- }
863
- }
864
1038
  var sleep2 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
865
1039
  var Escro = class {
866
1040
  constructor(options) {
@@ -883,7 +1057,15 @@ var Escro = class {
883
1057
  */
884
1058
  async createEscrow(params) {
885
1059
  const { escrowId, escrowPda, unsignedTx } = await this.api.createEscrow(params);
886
- const signature = await this.send(unsignedTx);
1060
+ const signature = await this.send(unsignedTx, {
1061
+ name: "create_escrow",
1062
+ escrowPda,
1063
+ taskId: escrowId,
1064
+ amount: BigInt(params.amountUsdc),
1065
+ deadline: BigInt(params.deadlineUnix),
1066
+ specHash: computeTaskSpecHash(params.taskSpec),
1067
+ assignedWorker: params.assignedWorker
1068
+ });
887
1069
  await this.confirm(escrowPda, signature);
888
1070
  return { escrowId, escrowPda, signature };
889
1071
  }
@@ -904,9 +1086,11 @@ var Escro = class {
904
1086
  * {@link Escro.releasePayment}, reporting whether the API recorded the release.
905
1087
  * `ESCROW_NOT_SETTLED` (the API's RPC does not yet show the escrow closed), the codes
906
1088
  * {@link Escro.confirm} retries and a network failure are retried for about 30 s. A
907
- * failure never throws: the release already landed, so the signature is returned with
908
- * `confirm.landed: false` and an `EscroConfirmError` (the API's code, or
909
- * `NETWORK_ERROR` when the last call never reached it).
1089
+ * failed record never throws: the release already landed, so the signature is returned
1090
+ * with `confirm.landed: false` and an `EscroConfirmError` (the API's code, or
1091
+ * `NETWORK_ERROR` when the last call never reached it). A release that failed at
1092
+ * execution on chain throws an {@link EscroError} with code `TX_FAILED`, and the API is
1093
+ * never asked to record it.
910
1094
  *
911
1095
  * @returns `{ signature, confirm }`.
912
1096
  */
@@ -925,12 +1109,7 @@ var Escro = class {
925
1109
  connection: this.connection,
926
1110
  cluster: this.cluster
927
1111
  });
928
- const signature = await signAndSend(
929
- unsignedTx,
930
- this.options.wallet,
931
- this.connection,
932
- this.cluster
933
- );
1112
+ const signature = await this.send(unsignedTx, { name: "release_payment", escrowPda: address });
934
1113
  try {
935
1114
  await this.retryRecord(
936
1115
  address,
@@ -953,11 +1132,18 @@ var Escro = class {
953
1132
  async raiseDispute(address, params) {
954
1133
  const reasonError = disputeReasonError(params.reason);
955
1134
  if (reasonError !== null) throw new EscroError(reasonError, "VALIDATION_ERROR");
956
- if (params.evidence !== void 0 && !isUrl(params.evidence)) {
957
- throw new EscroError(`evidence must be a URL: ${params.evidence}`, "VALIDATION_ERROR");
1135
+ if (params.evidence !== void 0 && !isSafeUrl(params.evidence)) {
1136
+ throw new EscroError(
1137
+ `evidence must be an http(s), ipfs or ar URL: ${params.evidence}`,
1138
+ "VALIDATION_ERROR"
1139
+ );
958
1140
  }
959
1141
  const { unsignedTx } = await this.api.raiseDispute(address, { reason: params.reason });
960
- const signature = await this.send(unsignedTx);
1142
+ const signature = await this.send(unsignedTx, {
1143
+ name: "raise_dispute",
1144
+ escrowPda: address,
1145
+ reason: params.reason
1146
+ });
961
1147
  await this.confirm(address, signature, {
962
1148
  ...params.evidence !== void 0 && { evidence: params.evidence }
963
1149
  });
@@ -972,7 +1158,7 @@ var Escro = class {
972
1158
  */
973
1159
  async cancelEscrow(address) {
974
1160
  const { unsignedTx } = await this.api.cancelEscrow(address);
975
- return this.sendAndConfirm(address, unsignedTx);
1161
+ return this.sendAndConfirm(address, unsignedTx, { name: "cancel_escrow", escrowPda: address });
976
1162
  }
977
1163
  // ── Payments (dual-path; x402 reserved) ───────────────────────────────────────
978
1164
  /**
@@ -1003,7 +1189,7 @@ var Escro = class {
1003
1189
  */
1004
1190
  async claimTask(address) {
1005
1191
  const { unsignedTx } = await this.api.claimTask(address);
1006
- return this.sendAndConfirm(address, unsignedTx);
1192
+ return this.sendAndConfirm(address, unsignedTx, { name: "claim_task", escrowPda: address });
1007
1193
  }
1008
1194
  /**
1009
1195
  * Submit a deliverable for the buyer to review. Worker must be the wallet.
@@ -1013,7 +1199,12 @@ var Escro = class {
1013
1199
  */
1014
1200
  async submitDeliverable(address, params) {
1015
1201
  const { unsignedTx } = await this.api.submitDeliverable(address, params);
1016
- return this.sendAndConfirm(address, unsignedTx);
1202
+ return this.sendAndConfirm(address, unsignedTx, {
1203
+ name: "submit_deliverable",
1204
+ escrowPda: address,
1205
+ deliverableHash: params.contentHash,
1206
+ proofUri: params.proofUri ?? null
1207
+ });
1017
1208
  }
1018
1209
  /**
1019
1210
  * List tasks assigned to the wallet's public key.
@@ -1179,11 +1370,11 @@ var Escro = class {
1179
1370
  delay = Math.min(delay * 2, CONFIRM_MAX_DELAY_MS);
1180
1371
  }
1181
1372
  }
1182
- send(unsignedTx) {
1183
- return signAndSend(unsignedTx, this.options.wallet, this.connection, this.cluster);
1373
+ send(unsignedTx, expected) {
1374
+ return signAndSend(unsignedTx, this.options.wallet, this.connection, this.cluster, expected);
1184
1375
  }
1185
- async sendAndConfirm(address, unsignedTx) {
1186
- const signature = await this.send(unsignedTx);
1376
+ async sendAndConfirm(address, unsignedTx, expected) {
1377
+ const signature = await this.send(unsignedTx, expected);
1187
1378
  await this.confirm(address, signature);
1188
1379
  return signature;
1189
1380
  }
@@ -1217,7 +1408,7 @@ function serviceResultToSubmitParams(result) {
1217
1408
  }
1218
1409
 
1219
1410
  // src/adapter-contract.ts
1220
- var import_crypto2 = require("crypto");
1411
+ var import_crypto3 = require("crypto");
1221
1412
  var AdapterContractError = class extends EscroError {
1222
1413
  constructor(adapterId, violations) {
1223
1414
  super(
@@ -1233,7 +1424,7 @@ function errMessage(err) {
1233
1424
  return err instanceof Error ? err.message : String(err);
1234
1425
  }
1235
1426
  function sha256Hex(content) {
1236
- return (0, import_crypto2.createHash)("sha256").update(content).digest("hex");
1427
+ return (0, import_crypto3.createHash)("sha256").update(content).digest("hex");
1237
1428
  }
1238
1429
  function validateServiceResult(result) {
1239
1430
  if (typeof result !== "object" || result === null) {
@@ -1304,12 +1495,12 @@ async function assertServiceAdapterContract(adapter, options) {
1304
1495
  }
1305
1496
 
1306
1497
  // src/adapters/bittensor/index.ts
1307
- var import_crypto3 = require("crypto");
1498
+ var import_crypto4 = require("crypto");
1308
1499
  function tao(amount) {
1309
1500
  return amount;
1310
1501
  }
1311
1502
  function sha256Hex2(content) {
1312
- return (0, import_crypto3.createHash)("sha256").update(content).digest("hex");
1503
+ return (0, import_crypto4.createHash)("sha256").update(content).digest("hex");
1313
1504
  }
1314
1505
  var REFERENCE_MICRO_USDC_PER_TAO = 3e8;
1315
1506
  var defaultSwap = (microUsdc) => Promise.resolve(tao(microUsdc / REFERENCE_MICRO_USDC_PER_TAO));
@@ -1429,12 +1620,12 @@ function createGradientsAdapter(config = {}) {
1429
1620
  }
1430
1621
 
1431
1622
  // src/adapters/ridges/index.ts
1432
- var import_crypto4 = require("crypto");
1623
+ var import_crypto5 = require("crypto");
1433
1624
  var RIDGES_ADAPTER_ID = "ridges";
1434
1625
  var RIDGES_CAPABILITIES = ["code-generation"];
1435
1626
  var DEFAULT_SERVICE = "ridges";
1436
1627
  function sha256Hex3(content) {
1437
- return (0, import_crypto4.createHash)("sha256").update(content).digest("hex");
1628
+ return (0, import_crypto5.createHash)("sha256").update(content).digest("hex");
1438
1629
  }
1439
1630
  var RIDGES_DEMO_MARKER = "ridges-demo-v1";
1440
1631
  var RIDGES_DEMO_COVERAGE_TARGET = 0.8;
@@ -1792,12 +1983,12 @@ function createLiumAdapter(config = {}) {
1792
1983
  }
1793
1984
 
1794
1985
  // src/adapters/akash/index.ts
1795
- var import_crypto5 = require("crypto");
1986
+ var import_crypto6 = require("crypto");
1796
1987
  function akt(amount) {
1797
1988
  return amount;
1798
1989
  }
1799
1990
  function sha256Hex4(content) {
1800
- return (0, import_crypto5.createHash)("sha256").update(content).digest("hex");
1991
+ return (0, import_crypto6.createHash)("sha256").update(content).digest("hex");
1801
1992
  }
1802
1993
  var AKASH_ADAPTER_ID = "akash";
1803
1994
  var AKASH_CAPABILITIES = ["cloud-compute"];
@@ -1925,7 +2116,7 @@ function createAkashAdapter(config = {}) {
1925
2116
  }
1926
2117
 
1927
2118
  // src/adapters/render/index.ts
1928
- var import_crypto6 = require("crypto");
2119
+ var import_crypto7 = require("crypto");
1929
2120
  function renderAmount(amount) {
1930
2121
  return amount;
1931
2122
  }
@@ -1934,7 +2125,7 @@ var RENDER_CAPABILITIES = ["3d-rendering", "video-rendering", "gpu-inference"];
1934
2125
  var DEFAULT_SERVICE2 = "render";
1935
2126
  var DEFAULT_TASK_BUDGET_MICRO_USDC5 = 15e6;
1936
2127
  function sha256Hex5(content) {
1937
- return (0, import_crypto6.createHash)("sha256").update(content).digest("hex");
2128
+ return (0, import_crypto7.createHash)("sha256").update(content).digest("hex");
1938
2129
  }
1939
2130
  var REFERENCE_MICRO_USDC_PER_RENDER = 2e6;
1940
2131
  var defaultSwap3 = (microUsdc) => Promise.resolve(renderAmount(microUsdc / REFERENCE_MICRO_USDC_PER_RENDER));
@@ -2068,7 +2259,7 @@ function createRenderAdapter(config = {}) {
2068
2259
  }
2069
2260
 
2070
2261
  // src/adapters/gensyn/index.ts
2071
- var import_crypto7 = require("crypto");
2262
+ var import_crypto8 = require("crypto");
2072
2263
  var GENSYN_ADAPTER_ID = "gensyn";
2073
2264
  var GENSYN_CAPABILITIES = ["verifiable-compute"];
2074
2265
  var GENSYN_REE_SCHEME = "gensyn-ree-v1";
@@ -2076,7 +2267,7 @@ var GENSYN_DEMO_MARKER = "gensyn-ree-demo-v1";
2076
2267
  var GENSYN_DEMO_SEED = 12345;
2077
2268
  var GENSYN_DEMO_STEPS = 16;
2078
2269
  function sha256Hex6(content) {
2079
- return (0, import_crypto7.createHash)("sha256").update(content).digest("hex");
2270
+ return (0, import_crypto8.createHash)("sha256").update(content).digest("hex");
2080
2271
  }
2081
2272
  var LCG_MULT = 1103515245n;
2082
2273
  var LCG_INC = 12345n;
@@ -2238,14 +2429,14 @@ function createGensynAdapter(config = {}) {
2238
2429
  }
2239
2430
 
2240
2431
  // src/adapters/zkml/index.ts
2241
- var import_crypto8 = require("crypto");
2432
+ var import_crypto9 = require("crypto");
2242
2433
  var ZKML_ADAPTER_ID = "zkml";
2243
2434
  var ZKML_CAPABILITIES = ["zk-verified-inference"];
2244
2435
  var ZKML_DEMO_MARKER = "zkml-demo-v1";
2245
2436
  var ZKML_PROOF_SCHEME = "escro-zkml-ref-v1";
2246
2437
  var ZKML_PROOF_URI_PREFIX = "zkml-proof:";
2247
2438
  function sha256Hex7(content) {
2248
- return (0, import_crypto8.createHash)("sha256").update(content).digest("hex");
2439
+ return (0, import_crypto9.createHash)("sha256").update(content).digest("hex");
2249
2440
  }
2250
2441
  function computeZkmlVerificationTag(publicInputs) {
2251
2442
  return sha256Hex7(