@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.cjs +220 -69
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +64 -10
- package/dist/index.d.ts +64 -10
- package/dist/index.js +219 -69
- package/dist/index.js.map +1 -1
- package/package.json +17 -16
package/dist/index.cjs
CHANGED
|
@@ -40,6 +40,7 @@ __export(index_exports, {
|
|
|
40
40
|
ApiClient: () => ApiClient,
|
|
41
41
|
ENABLED_RAILS: () => ENABLED_RAILS,
|
|
42
42
|
Escro: () => Escro,
|
|
43
|
+
EscroConfirmError: () => EscroConfirmError,
|
|
43
44
|
EscroError: () => EscroError,
|
|
44
45
|
EscroRailNotEnabledError: () => EscroRailNotEnabledError,
|
|
45
46
|
EscrowNotFoundError: () => EscrowNotFoundError,
|
|
@@ -230,6 +231,26 @@ function verifyBotDescriptorSignature(descriptor) {
|
|
|
230
231
|
return false;
|
|
231
232
|
}
|
|
232
233
|
}
|
|
234
|
+
function spec(discriminator, escrowAccountIndex, cause) {
|
|
235
|
+
return {
|
|
236
|
+
discriminator: Uint8Array.from(discriminator),
|
|
237
|
+
escrowAccountIndex,
|
|
238
|
+
signerAccountIndex: 0,
|
|
239
|
+
cause
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
var ESCROW_INSTRUCTIONS = {
|
|
243
|
+
create_escrow: spec([253, 215, 165, 116, 36, 108, 68, 80], 4, null),
|
|
244
|
+
claim_task: spec([49, 222, 219, 238, 155, 68, 221, 136], 1, null),
|
|
245
|
+
submit_deliverable: spec([38, 137, 64, 44, 237, 11, 125, 101], 1, null),
|
|
246
|
+
raise_dispute: spec([41, 243, 1, 51, 150, 95, 246, 73], 1, null),
|
|
247
|
+
cancel_escrow: spec([156, 203, 54, 179, 38, 72, 33, 21], 3, "CANCELLED"),
|
|
248
|
+
release_payment: spec([24, 34, 191, 86, 145, 160, 183, 233], 3, "EXPLICIT_RELEASE"),
|
|
249
|
+
timeout_release: spec([98, 176, 26, 12, 83, 105, 154, 68], 3, "TIMEOUT_RELEASE"),
|
|
250
|
+
refund_buyer: spec([199, 139, 203, 146, 192, 150, 53, 218], 3, "DEADLINE_REFUND"),
|
|
251
|
+
arbitration_release: spec([118, 157, 141, 26, 104, 117, 94, 229], 4, "ARBITRATION_RELEASE"),
|
|
252
|
+
arbitration_refund: spec([255, 194, 84, 248, 185, 249, 120, 122], 4, "ARBITRATION_REFUND")
|
|
253
|
+
};
|
|
233
254
|
|
|
234
255
|
// src/payments.ts
|
|
235
256
|
var RAILS = ["escrow", "x402"];
|
|
@@ -244,9 +265,10 @@ var EscrowPaymentRouter = class {
|
|
|
244
265
|
|
|
245
266
|
// src/errors.ts
|
|
246
267
|
var EscroError = class extends Error {
|
|
247
|
-
constructor(message, code = "ESCRO_ERROR") {
|
|
268
|
+
constructor(message, code = "ESCRO_ERROR", retryAfterMs2) {
|
|
248
269
|
super(message);
|
|
249
270
|
__publicField(this, "code", code);
|
|
271
|
+
__publicField(this, "retryAfterMs", retryAfterMs2);
|
|
250
272
|
this.name = "EscroError";
|
|
251
273
|
}
|
|
252
274
|
};
|
|
@@ -277,6 +299,14 @@ var EscrowTimeoutError = class extends EscroError {
|
|
|
277
299
|
this.name = "EscrowTimeoutError";
|
|
278
300
|
}
|
|
279
301
|
};
|
|
302
|
+
var EscroConfirmError = class extends EscroError {
|
|
303
|
+
constructor(address, signature, code, message) {
|
|
304
|
+
super(`Confirm failed for escrow ${address} (signature ${signature}): ${message}`, code);
|
|
305
|
+
__publicField(this, "address", address);
|
|
306
|
+
__publicField(this, "signature", signature);
|
|
307
|
+
this.name = "EscroConfirmError";
|
|
308
|
+
}
|
|
309
|
+
};
|
|
280
310
|
var UnauthorizedError = class extends EscroError {
|
|
281
311
|
constructor(message = "Unauthorized") {
|
|
282
312
|
super(message, "UNAUTHORIZED");
|
|
@@ -307,7 +337,10 @@ async function handleError(res, address) {
|
|
|
307
337
|
if (res.status === 404) throw new EscrowNotFoundError(address ?? msg);
|
|
308
338
|
if (res.status === 409) throw new EscrowStateError(msg);
|
|
309
339
|
if (res.status === 401 || res.status === 403) throw new UnauthorizedError(msg);
|
|
310
|
-
throw new EscroError(msg, body.code ?? "UNKNOWN");
|
|
340
|
+
throw new EscroError(msg, body.code ?? "UNKNOWN", retryAfterMs(res.headers.get("retry-after")));
|
|
341
|
+
}
|
|
342
|
+
function retryAfterMs(header) {
|
|
343
|
+
return header !== null && /^\d+$/.test(header.trim()) ? Number(header.trim()) * 1e3 : void 0;
|
|
311
344
|
}
|
|
312
345
|
var ApiClient = class {
|
|
313
346
|
constructor(baseUrl, wallet) {
|
|
@@ -383,6 +416,22 @@ var ApiClient = class {
|
|
|
383
416
|
const body = await res.json();
|
|
384
417
|
return body.wallets;
|
|
385
418
|
}
|
|
419
|
+
/**
|
|
420
|
+
* GET /rep/:wallet : one wallet's EscroRep RAW components (ARCHITECTURE §9).
|
|
421
|
+
* Unauthenticated public read (no auth headers). Unknown wallets return zeroed
|
|
422
|
+
* components, never 404; a 404 means the deployment mounted no reputation
|
|
423
|
+
* source and surfaces as {@link ReputationUnavailableError}. Shares the public
|
|
424
|
+
* per-wallet rate budget with every other caller, so fan-outs should use
|
|
425
|
+
* {@link listReputations} instead.
|
|
426
|
+
*/
|
|
427
|
+
async getReputation(wallet) {
|
|
428
|
+
const res = await fetch(this.url(`/rep/${encodeURIComponent(wallet)}`));
|
|
429
|
+
if (!res.ok) {
|
|
430
|
+
if (res.status === 404) throw new ReputationUnavailableError();
|
|
431
|
+
await handleError(res);
|
|
432
|
+
}
|
|
433
|
+
return await res.json();
|
|
434
|
+
}
|
|
386
435
|
/**
|
|
387
436
|
* POST /v1/escrows — create escrow, returns unsigned tx + ids.
|
|
388
437
|
* Requires auth.
|
|
@@ -472,7 +521,7 @@ var ApiClient = class {
|
|
|
472
521
|
*/
|
|
473
522
|
async raiseDispute(address, params) {
|
|
474
523
|
const path = `/v1/escrows/${address}/dispute`;
|
|
475
|
-
const rawBody = JSON.stringify({ reason: params.reason
|
|
524
|
+
const rawBody = JSON.stringify({ reason: params.reason });
|
|
476
525
|
const res = await fetch(this.url(path), {
|
|
477
526
|
method: "POST",
|
|
478
527
|
headers: {
|
|
@@ -484,6 +533,35 @@ var ApiClient = class {
|
|
|
484
533
|
if (!res.ok) await handleError(res, address);
|
|
485
534
|
return res.json();
|
|
486
535
|
}
|
|
536
|
+
/**
|
|
537
|
+
* POST /v1/escrows/:address/confirm: the API records the create, claim, submit,
|
|
538
|
+
* cancel or dispute the landed `signature` carries, after verifying it on chain.
|
|
539
|
+
* A non-2xx answer throws an {@link EscroError} with the server's code, or
|
|
540
|
+
* `HTTP_<status>` when the answer carries none; a network failure rejects with
|
|
541
|
+
* fetch's own error. {@link Escro.confirm} decides which to retry.
|
|
542
|
+
*/
|
|
543
|
+
async confirm(address, signature, evidence) {
|
|
544
|
+
const path = `/v1/escrows/${address}/confirm`;
|
|
545
|
+
const rawBody = JSON.stringify({ signature, evidence });
|
|
546
|
+
const res = await fetch(this.url(path), {
|
|
547
|
+
method: "POST",
|
|
548
|
+
headers: {
|
|
549
|
+
...authHeaders(this.wallet, "POST", path, rawBody),
|
|
550
|
+
"content-type": "application/json"
|
|
551
|
+
},
|
|
552
|
+
body: rawBody
|
|
553
|
+
});
|
|
554
|
+
if (!res.ok) {
|
|
555
|
+
const body2 = await res.json().catch(() => ({}));
|
|
556
|
+
throw new EscroError(
|
|
557
|
+
body2.error ?? `HTTP ${String(res.status)}`,
|
|
558
|
+
body2.code ?? `HTTP_${String(res.status)}`,
|
|
559
|
+
retryAfterMs(res.headers.get("retry-after"))
|
|
560
|
+
);
|
|
561
|
+
}
|
|
562
|
+
const body = await res.json();
|
|
563
|
+
return deserialize(body.escrow);
|
|
564
|
+
}
|
|
487
565
|
/**
|
|
488
566
|
* GET /v1/stats — public protocol-wide stats.
|
|
489
567
|
* No auth required. Upstream typing in {@link Escro.getStats} narrows the
|
|
@@ -683,6 +761,30 @@ async function buildReleasePaymentTx(params) {
|
|
|
683
761
|
}
|
|
684
762
|
|
|
685
763
|
// src/client.ts
|
|
764
|
+
var CONFIRM_WINDOW_MS = 3e4;
|
|
765
|
+
var CONFIRM_FIRST_DELAY_MS = 500;
|
|
766
|
+
var CONFIRM_MAX_DELAY_MS = 4e3;
|
|
767
|
+
var RETRYABLE_CONFIRM_CODES = [
|
|
768
|
+
"TX_NOT_FOUND",
|
|
769
|
+
"RPC_UNAVAILABLE",
|
|
770
|
+
"HTTP_502",
|
|
771
|
+
"HTTP_503",
|
|
772
|
+
"HTTP_504",
|
|
773
|
+
"RATE_LIMITED",
|
|
774
|
+
"HTTP_429"
|
|
775
|
+
];
|
|
776
|
+
function isRetryableConfirmCode(code) {
|
|
777
|
+
return RETRYABLE_CONFIRM_CODES.includes(code);
|
|
778
|
+
}
|
|
779
|
+
function isUrl(value) {
|
|
780
|
+
try {
|
|
781
|
+
new URL(value);
|
|
782
|
+
return true;
|
|
783
|
+
} catch {
|
|
784
|
+
return false;
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
var sleep2 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
686
788
|
var Escro = class {
|
|
687
789
|
constructor(options) {
|
|
688
790
|
__publicField(this, "connection");
|
|
@@ -698,18 +800,14 @@ var Escro = class {
|
|
|
698
800
|
// ── Buyer Bot ────────────────────────────────────────────────────────────────
|
|
699
801
|
/**
|
|
700
802
|
* Create a new escrow: registers with the API, signs and submits the
|
|
701
|
-
* on-chain `create_escrow` transaction.
|
|
803
|
+
* on-chain `create_escrow` transaction, then confirms it with the API.
|
|
702
804
|
*
|
|
703
805
|
* @returns `{ escrowId, escrowPda, signature }` — use `escrowPda` for all subsequent calls.
|
|
704
806
|
*/
|
|
705
807
|
async createEscrow(params) {
|
|
706
808
|
const { escrowId, escrowPda, unsignedTx } = await this.api.createEscrow(params);
|
|
707
|
-
const signature = await
|
|
708
|
-
|
|
709
|
-
this.options.wallet,
|
|
710
|
-
this.connection,
|
|
711
|
-
this.cluster
|
|
712
|
-
);
|
|
809
|
+
const signature = await this.send(unsignedTx);
|
|
810
|
+
await this.confirm(escrowPda, signature);
|
|
713
811
|
return { escrowId, escrowPda, signature };
|
|
714
812
|
}
|
|
715
813
|
/**
|
|
@@ -749,24 +847,31 @@ var Escro = class {
|
|
|
749
847
|
}
|
|
750
848
|
/**
|
|
751
849
|
* Raise a dispute for an escrow. Either the buyer or the assigned worker
|
|
752
|
-
* may call this. Signs and submits the `raise_dispute` on-chain tx.
|
|
850
|
+
* may call this. Signs and submits the `raise_dispute` on-chain tx, then confirms it with the API.
|
|
753
851
|
*
|
|
754
852
|
* @returns Solana transaction signature.
|
|
755
853
|
*/
|
|
756
854
|
async raiseDispute(address, params) {
|
|
757
|
-
|
|
758
|
-
|
|
855
|
+
if (params.evidence !== void 0 && !isUrl(params.evidence)) {
|
|
856
|
+
throw new EscroError(`evidence must be a URL: ${params.evidence}`, "VALIDATION_ERROR");
|
|
857
|
+
}
|
|
858
|
+
const { unsignedTx } = await this.api.raiseDispute(address, { reason: params.reason });
|
|
859
|
+
const signature = await this.send(unsignedTx);
|
|
860
|
+
await this.confirm(address, signature, {
|
|
861
|
+
...params.evidence !== void 0 && { evidence: params.evidence }
|
|
862
|
+
});
|
|
863
|
+
return signature;
|
|
759
864
|
}
|
|
760
865
|
/**
|
|
761
866
|
* Cancel a funded escrow before any worker has claimed it.
|
|
762
867
|
* Buyer must be the wallet in the constructor. Only valid when state is `FUNDED`.
|
|
763
|
-
* Signs and submits the `cancel_escrow` on-chain tx; full USDC refund to buyer.
|
|
868
|
+
* Signs and submits the `cancel_escrow` on-chain tx, then confirms it with the API; full USDC refund to buyer.
|
|
764
869
|
*
|
|
765
870
|
* @returns Solana transaction signature.
|
|
766
871
|
*/
|
|
767
872
|
async cancelEscrow(address) {
|
|
768
873
|
const { unsignedTx } = await this.api.cancelEscrow(address);
|
|
769
|
-
return
|
|
874
|
+
return this.sendAndConfirm(address, unsignedTx);
|
|
770
875
|
}
|
|
771
876
|
// ── Payments (dual-path; x402 reserved) ───────────────────────────────────────
|
|
772
877
|
/**
|
|
@@ -791,23 +896,23 @@ var Escro = class {
|
|
|
791
896
|
// ── Worker Bot ───────────────────────────────────────────────────────────────
|
|
792
897
|
/**
|
|
793
898
|
* Claim an assigned task. Worker must be the wallet in the constructor.
|
|
794
|
-
* Signs and submits the `claim_task` on-chain tx.
|
|
899
|
+
* Signs and submits the `claim_task` on-chain tx, then confirms it with the API.
|
|
795
900
|
*
|
|
796
901
|
* @returns Solana transaction signature.
|
|
797
902
|
*/
|
|
798
903
|
async claimTask(address) {
|
|
799
904
|
const { unsignedTx } = await this.api.claimTask(address);
|
|
800
|
-
return
|
|
905
|
+
return this.sendAndConfirm(address, unsignedTx);
|
|
801
906
|
}
|
|
802
907
|
/**
|
|
803
908
|
* Submit a deliverable for the buyer to review. Worker must be the wallet.
|
|
804
|
-
* Signs and submits the `submit_deliverable` on-chain tx.
|
|
909
|
+
* Signs and submits the `submit_deliverable` on-chain tx, then confirms it with the API.
|
|
805
910
|
*
|
|
806
911
|
* @returns Solana transaction signature.
|
|
807
912
|
*/
|
|
808
913
|
async submitDeliverable(address, params) {
|
|
809
914
|
const { unsignedTx } = await this.api.submitDeliverable(address, params);
|
|
810
|
-
return
|
|
915
|
+
return this.sendAndConfirm(address, unsignedTx);
|
|
811
916
|
}
|
|
812
917
|
/**
|
|
813
918
|
* List tasks assigned to the wallet's public key.
|
|
@@ -917,6 +1022,51 @@ var Escro = class {
|
|
|
917
1022
|
return data;
|
|
918
1023
|
}
|
|
919
1024
|
// ── Shared ───────────────────────────────────────────────────────────────────
|
|
1025
|
+
/**
|
|
1026
|
+
* Ask the API to record the create, claim, submit, cancel or dispute that the
|
|
1027
|
+
* landed `signature` carries; the API verifies it on chain first. Retries a
|
|
1028
|
+
* not-yet-visible transaction, an RPC failure, a gateway error or a rate limit
|
|
1029
|
+
* for about 30 s (waiting at least a sent Retry-After), never a rejection. Throws
|
|
1030
|
+
* {@link EscroConfirmError}; calling again is safe (a replay of a recorded
|
|
1031
|
+
* transition succeeds).
|
|
1032
|
+
*/
|
|
1033
|
+
async confirm(address, signature, opts = {}) {
|
|
1034
|
+
const deadline = Date.now() + CONFIRM_WINDOW_MS;
|
|
1035
|
+
let delay = CONFIRM_FIRST_DELAY_MS;
|
|
1036
|
+
for (; ; ) {
|
|
1037
|
+
let code;
|
|
1038
|
+
let message;
|
|
1039
|
+
let wait = delay;
|
|
1040
|
+
try {
|
|
1041
|
+
return await this.api.confirm(address, signature, opts.evidence);
|
|
1042
|
+
} catch (err) {
|
|
1043
|
+
if (err instanceof EscroError) {
|
|
1044
|
+
if (!isRetryableConfirmCode(err.code)) {
|
|
1045
|
+
throw new EscroConfirmError(address, signature, err.code, err.message);
|
|
1046
|
+
}
|
|
1047
|
+
code = err.code;
|
|
1048
|
+
message = err.message;
|
|
1049
|
+
wait = Math.max(delay, err.retryAfterMs ?? 0);
|
|
1050
|
+
} else {
|
|
1051
|
+
code = "NETWORK_ERROR";
|
|
1052
|
+
message = err instanceof Error ? err.message : String(err);
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
if (Date.now() + wait > deadline) {
|
|
1056
|
+
throw new EscroConfirmError(address, signature, code, message);
|
|
1057
|
+
}
|
|
1058
|
+
await sleep2(wait);
|
|
1059
|
+
delay = Math.min(delay * 2, CONFIRM_MAX_DELAY_MS);
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
send(unsignedTx) {
|
|
1063
|
+
return signAndSend(unsignedTx, this.options.wallet, this.connection, this.cluster);
|
|
1064
|
+
}
|
|
1065
|
+
async sendAndConfirm(address, unsignedTx) {
|
|
1066
|
+
const signature = await this.send(unsignedTx);
|
|
1067
|
+
await this.confirm(address, signature);
|
|
1068
|
+
return signature;
|
|
1069
|
+
}
|
|
920
1070
|
/**
|
|
921
1071
|
* Fetch an escrow by its PDA address.
|
|
922
1072
|
* If `options.poll` is true, polls with exponential backoff until the escrow
|
|
@@ -1050,9 +1200,9 @@ function createBittensorSubnetAdapter(config) {
|
|
|
1050
1200
|
id,
|
|
1051
1201
|
capabilities: config.capabilities,
|
|
1052
1202
|
healthCheck: config.checkHealth,
|
|
1053
|
-
async execute(
|
|
1203
|
+
async execute(spec2) {
|
|
1054
1204
|
const budgetTao = await config.swap(config.taskBudgetMicroUsdc);
|
|
1055
|
-
const content = await config.callSubnet(
|
|
1205
|
+
const content = await config.callSubnet(spec2, budgetTao);
|
|
1056
1206
|
const contentHash = sha256Hex2(content);
|
|
1057
1207
|
const proofUri = await config.pin(content);
|
|
1058
1208
|
return {
|
|
@@ -1135,16 +1285,16 @@ function scoreGradientsDemoDeliverable(content) {
|
|
|
1135
1285
|
}
|
|
1136
1286
|
return matches / expected.length;
|
|
1137
1287
|
}
|
|
1138
|
-
function referencePlaceholder(
|
|
1288
|
+
function referencePlaceholder(spec2) {
|
|
1139
1289
|
return canonicalize({
|
|
1140
1290
|
checkpoint: "reference-sn56-checkpoint",
|
|
1141
1291
|
eval: { metric: "accuracy", score: 0 },
|
|
1142
1292
|
note: "reference stub - replace the callSubnet port with a real SN56 miner call.",
|
|
1143
|
-
taskType:
|
|
1293
|
+
taskType: spec2.taskType
|
|
1144
1294
|
});
|
|
1145
1295
|
}
|
|
1146
|
-
var defaultCallSubnet = (
|
|
1147
|
-
|
|
1296
|
+
var defaultCallSubnet = (spec2) => Promise.resolve(
|
|
1297
|
+
spec2.metadata.demo === GRADIENTS_DEMO_MARKER ? solveGradientsDemo() : referencePlaceholder(spec2)
|
|
1148
1298
|
);
|
|
1149
1299
|
function createGradientsAdapter(config = {}) {
|
|
1150
1300
|
return createBittensorSubnetAdapter({
|
|
@@ -1256,17 +1406,17 @@ function scoreRidgesDemoDeliverable(content) {
|
|
|
1256
1406
|
}
|
|
1257
1407
|
return coveredInputs.size / DEMO_INPUTS.length;
|
|
1258
1408
|
}
|
|
1259
|
-
function referencePlaceholder2(
|
|
1409
|
+
function referencePlaceholder2(spec2) {
|
|
1260
1410
|
return canonicalize({
|
|
1261
1411
|
language: "typescript",
|
|
1262
1412
|
solution: "// reference stub - replace the runAgent port with a real Ridges agent call.",
|
|
1263
1413
|
passed: false,
|
|
1264
1414
|
tests: [],
|
|
1265
|
-
taskType:
|
|
1415
|
+
taskType: spec2.taskType
|
|
1266
1416
|
});
|
|
1267
1417
|
}
|
|
1268
|
-
var defaultRunAgent = (
|
|
1269
|
-
|
|
1418
|
+
var defaultRunAgent = (spec2) => Promise.resolve(
|
|
1419
|
+
spec2.metadata.demo === RIDGES_DEMO_MARKER ? solveRidgesDemo() : referencePlaceholder2(spec2)
|
|
1270
1420
|
);
|
|
1271
1421
|
var defaultPin2 = (content) => Promise.resolve(`ipfs://placeholder-${sha256Hex3(content).slice(0, 16)}`);
|
|
1272
1422
|
function createRidgesAdapter(config = {}) {
|
|
@@ -1279,8 +1429,8 @@ function createRidgesAdapter(config = {}) {
|
|
|
1279
1429
|
id: service,
|
|
1280
1430
|
capabilities,
|
|
1281
1431
|
healthCheck: checkHealth,
|
|
1282
|
-
async execute(
|
|
1283
|
-
const content = await runAgent(
|
|
1432
|
+
async execute(spec2) {
|
|
1433
|
+
const content = await runAgent(spec2);
|
|
1284
1434
|
const contentHash = sha256Hex3(content);
|
|
1285
1435
|
const proofUri = await pin(content);
|
|
1286
1436
|
return {
|
|
@@ -1389,15 +1539,15 @@ function score404genDemoDeliverable(content) {
|
|
|
1389
1539
|
}
|
|
1390
1540
|
return Math.min(batch.assets.length / DEMO_EXPECTATION.requestedAssets, 1);
|
|
1391
1541
|
}
|
|
1392
|
-
function referencePlaceholder3(
|
|
1542
|
+
function referencePlaceholder3(spec2) {
|
|
1393
1543
|
return canonicalize({
|
|
1394
1544
|
assets: [{ format: "GLB", polygonCount: 0, uri: "ipfs://placeholder" }],
|
|
1395
1545
|
note: "reference stub - replace the callSubnet port with a real SN17 miner call.",
|
|
1396
|
-
taskType:
|
|
1546
|
+
taskType: spec2.taskType
|
|
1397
1547
|
});
|
|
1398
1548
|
}
|
|
1399
|
-
var defaultCallSubnet2 = (
|
|
1400
|
-
|
|
1549
|
+
var defaultCallSubnet2 = (spec2) => Promise.resolve(
|
|
1550
|
+
spec2.metadata.demo === GEN404_DEMO_MARKER ? solveGen404Demo() : referencePlaceholder3(spec2)
|
|
1401
1551
|
);
|
|
1402
1552
|
function create404genAdapter(config = {}) {
|
|
1403
1553
|
return createBittensorSubnetAdapter({
|
|
@@ -1497,17 +1647,17 @@ function scoreLiumDemoDeliverable(content) {
|
|
|
1497
1647
|
}
|
|
1498
1648
|
return parsed.artifact === computeLiumDemoArtifact() ? 1 : 0;
|
|
1499
1649
|
}
|
|
1500
|
-
function referencePlaceholder4(
|
|
1650
|
+
function referencePlaceholder4(spec2) {
|
|
1501
1651
|
return canonicalize({
|
|
1502
1652
|
job: "lium-sn51-generic",
|
|
1503
1653
|
status: "completed",
|
|
1504
1654
|
artifact: null,
|
|
1505
1655
|
note: "reference stub - replace the runJob port with a real SN51 GPU-rental call.",
|
|
1506
|
-
taskType:
|
|
1656
|
+
taskType: spec2.taskType
|
|
1507
1657
|
});
|
|
1508
1658
|
}
|
|
1509
|
-
var defaultRunJob = (
|
|
1510
|
-
|
|
1659
|
+
var defaultRunJob = (spec2) => Promise.resolve(
|
|
1660
|
+
spec2.metadata.demo === LIUM_DEMO_MARKER ? solveLiumDemo() : referencePlaceholder4(spec2)
|
|
1511
1661
|
);
|
|
1512
1662
|
function createLiumAdapter(config = {}) {
|
|
1513
1663
|
return createBittensorSubnetAdapter({
|
|
@@ -1616,17 +1766,17 @@ function scoreAkashDemoDeliverable(content) {
|
|
|
1616
1766
|
}
|
|
1617
1767
|
return parsed.artifact === computeAkashDemoArtifact() ? 1 : 0;
|
|
1618
1768
|
}
|
|
1619
|
-
function referencePlaceholder5(
|
|
1769
|
+
function referencePlaceholder5(spec2) {
|
|
1620
1770
|
return canonicalize({
|
|
1621
1771
|
job: "akash-generic",
|
|
1622
1772
|
status: "completed",
|
|
1623
1773
|
artifact: null,
|
|
1624
1774
|
note: "reference stub - replace the runDeployment port with a real Akash deployment call.",
|
|
1625
|
-
taskType:
|
|
1775
|
+
taskType: spec2.taskType
|
|
1626
1776
|
});
|
|
1627
1777
|
}
|
|
1628
|
-
var defaultRunDeployment = (
|
|
1629
|
-
|
|
1778
|
+
var defaultRunDeployment = (spec2) => Promise.resolve(
|
|
1779
|
+
spec2.metadata.demo === AKASH_DEMO_MARKER ? solveAkashDemo() : referencePlaceholder5(spec2)
|
|
1630
1780
|
);
|
|
1631
1781
|
function createAkashAdapter(config = {}) {
|
|
1632
1782
|
const capabilities = config.capabilities ?? [...AKASH_CAPABILITIES];
|
|
@@ -1639,9 +1789,9 @@ function createAkashAdapter(config = {}) {
|
|
|
1639
1789
|
id: AKASH_ADAPTER_ID,
|
|
1640
1790
|
capabilities,
|
|
1641
1791
|
healthCheck: checkHealth,
|
|
1642
|
-
async execute(
|
|
1792
|
+
async execute(spec2) {
|
|
1643
1793
|
const budgetAkt = await swap(taskBudgetMicroUsdc);
|
|
1644
|
-
const content = await runDeployment(
|
|
1794
|
+
const content = await runDeployment(spec2, budgetAkt);
|
|
1645
1795
|
const contentHash = sha256Hex4(content);
|
|
1646
1796
|
const proofUri = await pin(content);
|
|
1647
1797
|
return {
|
|
@@ -1758,17 +1908,17 @@ function scoreRenderDemoDeliverable(content) {
|
|
|
1758
1908
|
}
|
|
1759
1909
|
return parsed.frame === computeRenderDemoArtifact() ? 1 : 0;
|
|
1760
1910
|
}
|
|
1761
|
-
function referencePlaceholder6(
|
|
1911
|
+
function referencePlaceholder6(spec2) {
|
|
1762
1912
|
return canonicalize({
|
|
1763
1913
|
job: "render-generic",
|
|
1764
1914
|
status: "completed",
|
|
1765
1915
|
frame: null,
|
|
1766
1916
|
note: "reference stub - replace the runJob port with a real Render Network job submission.",
|
|
1767
|
-
taskType:
|
|
1917
|
+
taskType: spec2.taskType
|
|
1768
1918
|
});
|
|
1769
1919
|
}
|
|
1770
|
-
var defaultRunJob2 = (
|
|
1771
|
-
|
|
1920
|
+
var defaultRunJob2 = (spec2) => Promise.resolve(
|
|
1921
|
+
spec2.metadata.demo === RENDER_DEMO_MARKER ? solveRenderDemo() : referencePlaceholder6(spec2)
|
|
1772
1922
|
);
|
|
1773
1923
|
function createRenderAdapter(config = {}) {
|
|
1774
1924
|
const service = config.service ?? DEFAULT_SERVICE2;
|
|
@@ -1782,9 +1932,9 @@ function createRenderAdapter(config = {}) {
|
|
|
1782
1932
|
id: service,
|
|
1783
1933
|
capabilities,
|
|
1784
1934
|
healthCheck: checkHealth,
|
|
1785
|
-
async execute(
|
|
1935
|
+
async execute(spec2) {
|
|
1786
1936
|
const budgetRender = await swap(taskBudgetMicroUsdc);
|
|
1787
|
-
const content = await runJob(
|
|
1937
|
+
const content = await runJob(spec2, budgetRender);
|
|
1788
1938
|
const contentHash = sha256Hex5(content);
|
|
1789
1939
|
const proofUri = await pin(content);
|
|
1790
1940
|
return {
|
|
@@ -1811,15 +1961,15 @@ function sha256Hex6(content) {
|
|
|
1811
1961
|
var LCG_MULT = 1103515245n;
|
|
1812
1962
|
var LCG_INC = 12345n;
|
|
1813
1963
|
var LCG_MOD = 1n << 31n;
|
|
1814
|
-
function readComputeParams(
|
|
1815
|
-
const rawSeed =
|
|
1816
|
-
const rawSteps =
|
|
1964
|
+
function readComputeParams(spec2) {
|
|
1965
|
+
const rawSeed = spec2.metadata.seed;
|
|
1966
|
+
const rawSteps = spec2.metadata.steps;
|
|
1817
1967
|
const seed = typeof rawSeed === "number" && Number.isInteger(rawSeed) ? rawSeed : GENSYN_DEMO_SEED;
|
|
1818
1968
|
const steps = typeof rawSteps === "number" && Number.isInteger(rawSteps) && rawSteps > 0 ? rawSteps : GENSYN_DEMO_STEPS;
|
|
1819
1969
|
return { seed, steps };
|
|
1820
1970
|
}
|
|
1821
|
-
var reproduceGensynCompute = (
|
|
1822
|
-
const { seed, steps } = readComputeParams(
|
|
1971
|
+
var reproduceGensynCompute = (spec2) => {
|
|
1972
|
+
const { seed, steps } = readComputeParams(spec2);
|
|
1823
1973
|
const states = [];
|
|
1824
1974
|
let x = BigInt(seed) % LCG_MOD;
|
|
1825
1975
|
if (x < 0n) {
|
|
@@ -1841,10 +1991,10 @@ function commitmentOf(base) {
|
|
|
1841
1991
|
)
|
|
1842
1992
|
);
|
|
1843
1993
|
}
|
|
1844
|
-
function buildReeProof(
|
|
1994
|
+
function buildReeProof(spec2, exec, content) {
|
|
1845
1995
|
const base = {
|
|
1846
1996
|
scheme: GENSYN_REE_SCHEME,
|
|
1847
|
-
specHash: sha256Hex6(canonicalize(
|
|
1997
|
+
specHash: sha256Hex6(canonicalize(spec2)),
|
|
1848
1998
|
outputHash: sha256Hex6(content),
|
|
1849
1999
|
steps: exec.steps,
|
|
1850
2000
|
transcriptHash: sha256Hex6(canonicalize(exec.states))
|
|
@@ -1951,11 +2101,11 @@ function createGensynAdapter(config = {}) {
|
|
|
1951
2101
|
id: GENSYN_ADAPTER_ID,
|
|
1952
2102
|
capabilities,
|
|
1953
2103
|
healthCheck: checkHealth,
|
|
1954
|
-
async execute(
|
|
1955
|
-
const exec = runCompute(
|
|
2104
|
+
async execute(spec2) {
|
|
2105
|
+
const exec = runCompute(spec2);
|
|
1956
2106
|
const content = gensynDeliverable(exec);
|
|
1957
2107
|
const contentHash = sha256Hex6(content);
|
|
1958
|
-
const proof = buildReeProof(
|
|
2108
|
+
const proof = buildReeProof(spec2, exec, content);
|
|
1959
2109
|
const proofUri = await pin(content);
|
|
1960
2110
|
return {
|
|
1961
2111
|
content,
|
|
@@ -2130,21 +2280,21 @@ function solveZkmlDemo() {
|
|
|
2130
2280
|
output: { label: "cat", confidence: 0.98 }
|
|
2131
2281
|
});
|
|
2132
2282
|
}
|
|
2133
|
-
function referencePlaceholderOutput(
|
|
2283
|
+
function referencePlaceholderOutput(spec2) {
|
|
2134
2284
|
return {
|
|
2135
2285
|
content: canonicalize({
|
|
2136
2286
|
note: "reference stub - replace the runInference port with a real zk-verified inference call.",
|
|
2137
|
-
taskType:
|
|
2287
|
+
taskType: spec2.taskType
|
|
2138
2288
|
}),
|
|
2139
2289
|
modelCommitment: sha256Hex7("zkml-reference-stub-model"),
|
|
2140
|
-
inputCommitment: sha256Hex7(canonicalize(
|
|
2290
|
+
inputCommitment: sha256Hex7(canonicalize(spec2))
|
|
2141
2291
|
};
|
|
2142
2292
|
}
|
|
2143
|
-
var defaultRunInference = (
|
|
2293
|
+
var defaultRunInference = (spec2) => spec2.metadata.demo === ZKML_DEMO_MARKER ? {
|
|
2144
2294
|
content: solveZkmlDemo(),
|
|
2145
2295
|
modelCommitment: DEMO_MODEL_COMMITMENT,
|
|
2146
2296
|
inputCommitment: DEMO_INPUT_COMMITMENT
|
|
2147
|
-
} : referencePlaceholderOutput(
|
|
2297
|
+
} : referencePlaceholderOutput(spec2);
|
|
2148
2298
|
function createZkmlAdapter(config = {}) {
|
|
2149
2299
|
const id = config.id ?? ZKML_ADAPTER_ID;
|
|
2150
2300
|
const capabilities = config.capabilities ?? [...ZKML_CAPABILITIES];
|
|
@@ -2159,10 +2309,10 @@ function createZkmlAdapter(config = {}) {
|
|
|
2159
2309
|
return {
|
|
2160
2310
|
id,
|
|
2161
2311
|
capabilities,
|
|
2162
|
-
async execute(
|
|
2163
|
-
const output = await runInference(
|
|
2312
|
+
async execute(spec2) {
|
|
2313
|
+
const output = await runInference(spec2);
|
|
2164
2314
|
const contentHash = sha256Hex7(output.content);
|
|
2165
|
-
const proof = await prove({ spec, output, outputHash: contentHash });
|
|
2315
|
+
const proof = await prove({ spec: spec2, output, outputHash: contentHash });
|
|
2166
2316
|
const proofUri = await pin(proof);
|
|
2167
2317
|
return {
|
|
2168
2318
|
content: output.content,
|
|
@@ -2190,6 +2340,7 @@ function createZkmlAdapter(config = {}) {
|
|
|
2190
2340
|
ApiClient,
|
|
2191
2341
|
ENABLED_RAILS,
|
|
2192
2342
|
Escro,
|
|
2343
|
+
EscroConfirmError,
|
|
2193
2344
|
EscroError,
|
|
2194
2345
|
EscroRailNotEnabledError,
|
|
2195
2346
|
EscrowNotFoundError,
|