@escro/sdk 0.4.1 → 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 +239 -59
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +225 -46
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
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,
|
|
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
|
|
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) =>
|
|
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,29 +865,87 @@ 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
|
-
|
|
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
|
|
761
|
-
`Refusing to sign a fund-moving SPL Token instruction (tag ${String(tag)}) in a server-built transaction
|
|
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
|
-
|
|
881
|
+
refuse(
|
|
768
882
|
`Too many instructions (${String(tx.instructions.length)}). Max allowed: ${String(MAX_INSTRUCTIONS)}`
|
|
769
883
|
);
|
|
770
884
|
}
|
|
771
885
|
}
|
|
772
|
-
|
|
773
|
-
|
|
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");
|
|
@@ -831,7 +1004,7 @@ async function buildReleasePaymentTx(params) {
|
|
|
831
1004
|
{ pubkey: import_spl_token.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
832
1005
|
{ pubkey: import_spl_token.ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }
|
|
833
1006
|
],
|
|
834
|
-
data:
|
|
1007
|
+
data: Buffer.from(ESCROW_INSTRUCTIONS.release_payment.discriminator)
|
|
835
1008
|
});
|
|
836
1009
|
const { blockhash } = await connection.getLatestBlockhash("confirmed");
|
|
837
1010
|
const tx = new import_web32.Transaction();
|
|
@@ -862,14 +1035,6 @@ function isRetryableConfirmCode(code) {
|
|
|
862
1035
|
function isRetryableReleaseCode(code) {
|
|
863
1036
|
return code === "ESCROW_NOT_SETTLED" || isRetryableConfirmCode(code);
|
|
864
1037
|
}
|
|
865
|
-
function isUrl(value) {
|
|
866
|
-
try {
|
|
867
|
-
new URL(value);
|
|
868
|
-
return true;
|
|
869
|
-
} catch {
|
|
870
|
-
return false;
|
|
871
|
-
}
|
|
872
|
-
}
|
|
873
1038
|
var sleep2 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
874
1039
|
var Escro = class {
|
|
875
1040
|
constructor(options) {
|
|
@@ -892,7 +1057,15 @@ var Escro = class {
|
|
|
892
1057
|
*/
|
|
893
1058
|
async createEscrow(params) {
|
|
894
1059
|
const { escrowId, escrowPda, unsignedTx } = await this.api.createEscrow(params);
|
|
895
|
-
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
|
+
});
|
|
896
1069
|
await this.confirm(escrowPda, signature);
|
|
897
1070
|
return { escrowId, escrowPda, signature };
|
|
898
1071
|
}
|
|
@@ -936,12 +1109,7 @@ var Escro = class {
|
|
|
936
1109
|
connection: this.connection,
|
|
937
1110
|
cluster: this.cluster
|
|
938
1111
|
});
|
|
939
|
-
const signature = await
|
|
940
|
-
unsignedTx,
|
|
941
|
-
this.options.wallet,
|
|
942
|
-
this.connection,
|
|
943
|
-
this.cluster
|
|
944
|
-
);
|
|
1112
|
+
const signature = await this.send(unsignedTx, { name: "release_payment", escrowPda: address });
|
|
945
1113
|
try {
|
|
946
1114
|
await this.retryRecord(
|
|
947
1115
|
address,
|
|
@@ -964,11 +1132,18 @@ var Escro = class {
|
|
|
964
1132
|
async raiseDispute(address, params) {
|
|
965
1133
|
const reasonError = disputeReasonError(params.reason);
|
|
966
1134
|
if (reasonError !== null) throw new EscroError(reasonError, "VALIDATION_ERROR");
|
|
967
|
-
if (params.evidence !== void 0 && !
|
|
968
|
-
throw new EscroError(
|
|
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
|
+
);
|
|
969
1140
|
}
|
|
970
1141
|
const { unsignedTx } = await this.api.raiseDispute(address, { reason: params.reason });
|
|
971
|
-
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
|
+
});
|
|
972
1147
|
await this.confirm(address, signature, {
|
|
973
1148
|
...params.evidence !== void 0 && { evidence: params.evidence }
|
|
974
1149
|
});
|
|
@@ -983,7 +1158,7 @@ var Escro = class {
|
|
|
983
1158
|
*/
|
|
984
1159
|
async cancelEscrow(address) {
|
|
985
1160
|
const { unsignedTx } = await this.api.cancelEscrow(address);
|
|
986
|
-
return this.sendAndConfirm(address, unsignedTx);
|
|
1161
|
+
return this.sendAndConfirm(address, unsignedTx, { name: "cancel_escrow", escrowPda: address });
|
|
987
1162
|
}
|
|
988
1163
|
// ── Payments (dual-path; x402 reserved) ───────────────────────────────────────
|
|
989
1164
|
/**
|
|
@@ -1014,7 +1189,7 @@ var Escro = class {
|
|
|
1014
1189
|
*/
|
|
1015
1190
|
async claimTask(address) {
|
|
1016
1191
|
const { unsignedTx } = await this.api.claimTask(address);
|
|
1017
|
-
return this.sendAndConfirm(address, unsignedTx);
|
|
1192
|
+
return this.sendAndConfirm(address, unsignedTx, { name: "claim_task", escrowPda: address });
|
|
1018
1193
|
}
|
|
1019
1194
|
/**
|
|
1020
1195
|
* Submit a deliverable for the buyer to review. Worker must be the wallet.
|
|
@@ -1024,7 +1199,12 @@ var Escro = class {
|
|
|
1024
1199
|
*/
|
|
1025
1200
|
async submitDeliverable(address, params) {
|
|
1026
1201
|
const { unsignedTx } = await this.api.submitDeliverable(address, params);
|
|
1027
|
-
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
|
+
});
|
|
1028
1208
|
}
|
|
1029
1209
|
/**
|
|
1030
1210
|
* List tasks assigned to the wallet's public key.
|
|
@@ -1190,11 +1370,11 @@ var Escro = class {
|
|
|
1190
1370
|
delay = Math.min(delay * 2, CONFIRM_MAX_DELAY_MS);
|
|
1191
1371
|
}
|
|
1192
1372
|
}
|
|
1193
|
-
send(unsignedTx) {
|
|
1194
|
-
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);
|
|
1195
1375
|
}
|
|
1196
|
-
async sendAndConfirm(address, unsignedTx) {
|
|
1197
|
-
const signature = await this.send(unsignedTx);
|
|
1376
|
+
async sendAndConfirm(address, unsignedTx, expected) {
|
|
1377
|
+
const signature = await this.send(unsignedTx, expected);
|
|
1198
1378
|
await this.confirm(address, signature);
|
|
1199
1379
|
return signature;
|
|
1200
1380
|
}
|
|
@@ -1228,7 +1408,7 @@ function serviceResultToSubmitParams(result) {
|
|
|
1228
1408
|
}
|
|
1229
1409
|
|
|
1230
1410
|
// src/adapter-contract.ts
|
|
1231
|
-
var
|
|
1411
|
+
var import_crypto3 = require("crypto");
|
|
1232
1412
|
var AdapterContractError = class extends EscroError {
|
|
1233
1413
|
constructor(adapterId, violations) {
|
|
1234
1414
|
super(
|
|
@@ -1244,7 +1424,7 @@ function errMessage(err) {
|
|
|
1244
1424
|
return err instanceof Error ? err.message : String(err);
|
|
1245
1425
|
}
|
|
1246
1426
|
function sha256Hex(content) {
|
|
1247
|
-
return (0,
|
|
1427
|
+
return (0, import_crypto3.createHash)("sha256").update(content).digest("hex");
|
|
1248
1428
|
}
|
|
1249
1429
|
function validateServiceResult(result) {
|
|
1250
1430
|
if (typeof result !== "object" || result === null) {
|
|
@@ -1315,12 +1495,12 @@ async function assertServiceAdapterContract(adapter, options) {
|
|
|
1315
1495
|
}
|
|
1316
1496
|
|
|
1317
1497
|
// src/adapters/bittensor/index.ts
|
|
1318
|
-
var
|
|
1498
|
+
var import_crypto4 = require("crypto");
|
|
1319
1499
|
function tao(amount) {
|
|
1320
1500
|
return amount;
|
|
1321
1501
|
}
|
|
1322
1502
|
function sha256Hex2(content) {
|
|
1323
|
-
return (0,
|
|
1503
|
+
return (0, import_crypto4.createHash)("sha256").update(content).digest("hex");
|
|
1324
1504
|
}
|
|
1325
1505
|
var REFERENCE_MICRO_USDC_PER_TAO = 3e8;
|
|
1326
1506
|
var defaultSwap = (microUsdc) => Promise.resolve(tao(microUsdc / REFERENCE_MICRO_USDC_PER_TAO));
|
|
@@ -1440,12 +1620,12 @@ function createGradientsAdapter(config = {}) {
|
|
|
1440
1620
|
}
|
|
1441
1621
|
|
|
1442
1622
|
// src/adapters/ridges/index.ts
|
|
1443
|
-
var
|
|
1623
|
+
var import_crypto5 = require("crypto");
|
|
1444
1624
|
var RIDGES_ADAPTER_ID = "ridges";
|
|
1445
1625
|
var RIDGES_CAPABILITIES = ["code-generation"];
|
|
1446
1626
|
var DEFAULT_SERVICE = "ridges";
|
|
1447
1627
|
function sha256Hex3(content) {
|
|
1448
|
-
return (0,
|
|
1628
|
+
return (0, import_crypto5.createHash)("sha256").update(content).digest("hex");
|
|
1449
1629
|
}
|
|
1450
1630
|
var RIDGES_DEMO_MARKER = "ridges-demo-v1";
|
|
1451
1631
|
var RIDGES_DEMO_COVERAGE_TARGET = 0.8;
|
|
@@ -1803,12 +1983,12 @@ function createLiumAdapter(config = {}) {
|
|
|
1803
1983
|
}
|
|
1804
1984
|
|
|
1805
1985
|
// src/adapters/akash/index.ts
|
|
1806
|
-
var
|
|
1986
|
+
var import_crypto6 = require("crypto");
|
|
1807
1987
|
function akt(amount) {
|
|
1808
1988
|
return amount;
|
|
1809
1989
|
}
|
|
1810
1990
|
function sha256Hex4(content) {
|
|
1811
|
-
return (0,
|
|
1991
|
+
return (0, import_crypto6.createHash)("sha256").update(content).digest("hex");
|
|
1812
1992
|
}
|
|
1813
1993
|
var AKASH_ADAPTER_ID = "akash";
|
|
1814
1994
|
var AKASH_CAPABILITIES = ["cloud-compute"];
|
|
@@ -1936,7 +2116,7 @@ function createAkashAdapter(config = {}) {
|
|
|
1936
2116
|
}
|
|
1937
2117
|
|
|
1938
2118
|
// src/adapters/render/index.ts
|
|
1939
|
-
var
|
|
2119
|
+
var import_crypto7 = require("crypto");
|
|
1940
2120
|
function renderAmount(amount) {
|
|
1941
2121
|
return amount;
|
|
1942
2122
|
}
|
|
@@ -1945,7 +2125,7 @@ var RENDER_CAPABILITIES = ["3d-rendering", "video-rendering", "gpu-inference"];
|
|
|
1945
2125
|
var DEFAULT_SERVICE2 = "render";
|
|
1946
2126
|
var DEFAULT_TASK_BUDGET_MICRO_USDC5 = 15e6;
|
|
1947
2127
|
function sha256Hex5(content) {
|
|
1948
|
-
return (0,
|
|
2128
|
+
return (0, import_crypto7.createHash)("sha256").update(content).digest("hex");
|
|
1949
2129
|
}
|
|
1950
2130
|
var REFERENCE_MICRO_USDC_PER_RENDER = 2e6;
|
|
1951
2131
|
var defaultSwap3 = (microUsdc) => Promise.resolve(renderAmount(microUsdc / REFERENCE_MICRO_USDC_PER_RENDER));
|
|
@@ -2079,7 +2259,7 @@ function createRenderAdapter(config = {}) {
|
|
|
2079
2259
|
}
|
|
2080
2260
|
|
|
2081
2261
|
// src/adapters/gensyn/index.ts
|
|
2082
|
-
var
|
|
2262
|
+
var import_crypto8 = require("crypto");
|
|
2083
2263
|
var GENSYN_ADAPTER_ID = "gensyn";
|
|
2084
2264
|
var GENSYN_CAPABILITIES = ["verifiable-compute"];
|
|
2085
2265
|
var GENSYN_REE_SCHEME = "gensyn-ree-v1";
|
|
@@ -2087,7 +2267,7 @@ var GENSYN_DEMO_MARKER = "gensyn-ree-demo-v1";
|
|
|
2087
2267
|
var GENSYN_DEMO_SEED = 12345;
|
|
2088
2268
|
var GENSYN_DEMO_STEPS = 16;
|
|
2089
2269
|
function sha256Hex6(content) {
|
|
2090
|
-
return (0,
|
|
2270
|
+
return (0, import_crypto8.createHash)("sha256").update(content).digest("hex");
|
|
2091
2271
|
}
|
|
2092
2272
|
var LCG_MULT = 1103515245n;
|
|
2093
2273
|
var LCG_INC = 12345n;
|
|
@@ -2249,14 +2429,14 @@ function createGensynAdapter(config = {}) {
|
|
|
2249
2429
|
}
|
|
2250
2430
|
|
|
2251
2431
|
// src/adapters/zkml/index.ts
|
|
2252
|
-
var
|
|
2432
|
+
var import_crypto9 = require("crypto");
|
|
2253
2433
|
var ZKML_ADAPTER_ID = "zkml";
|
|
2254
2434
|
var ZKML_CAPABILITIES = ["zk-verified-inference"];
|
|
2255
2435
|
var ZKML_DEMO_MARKER = "zkml-demo-v1";
|
|
2256
2436
|
var ZKML_PROOF_SCHEME = "escro-zkml-ref-v1";
|
|
2257
2437
|
var ZKML_PROOF_URI_PREFIX = "zkml-proof:";
|
|
2258
2438
|
function sha256Hex7(content) {
|
|
2259
|
-
return (0,
|
|
2439
|
+
return (0, import_crypto9.createHash)("sha256").update(content).digest("hex");
|
|
2260
2440
|
}
|
|
2261
2441
|
function computeZkmlVerificationTag(publicInputs) {
|
|
2262
2442
|
return sha256Hex7(
|