@prismnetwork/agent-sdk 0.7.11 → 0.7.12

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/decision.mjs CHANGED
@@ -124,6 +124,13 @@ export function leaseReference(quoteId, d) {
124
124
  return keccak256(concatBytes([hexToBytes(quoteDigest), hexToBytes(keccak256(canonical(d)))]));
125
125
  }
126
126
 
127
+ /// The hex digest the control plane needs to know which derivation to expect.
128
+ /// It is the decision's hash, not the decision: the service can check that the
129
+ /// funding log commits to something, and cannot read what that something says.
130
+ export function decisionDigest(d) {
131
+ return d ? keccak256(canonical(d)) : null;
132
+ }
133
+
127
134
  /// Whether this decision is the one that funded that lease.
128
135
  export function referenceMatches(quoteId, d, reference) {
129
136
  return leaseReference(quoteId, d).toLowerCase() === String(reference).toLowerCase();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prismnetwork/agent-sdk",
3
- "version": "0.7.11",
3
+ "version": "0.7.12",
4
4
  "description": "Headless GPU leasing and renter-encrypted storage on Prism Network for wallet-holding agents.",
5
5
  "type": "module",
6
6
  "main": "prism.mjs",
package/prism.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  // Prism Network agent SDK: headless GPU leasing for wallet-holding agents.
2
2
  // No browser, no Privy. Authenticate with a wallet signature, pay on-chain, run.
3
3
  import { execFileSync, spawn } from "node:child_process";
4
- import { authorise, leaseReference } from "./decision.mjs";
4
+ import { authorise, decisionDigest, leaseReference } from "./decision.mjs";
5
5
  import { mkdtempSync, readFileSync, rmSync } from "node:fs";
6
6
  import { tmpdir } from "node:os";
7
7
  import { join } from "node:path";
@@ -334,12 +334,17 @@ export class PrismAgent {
334
334
  }
335
335
  }
336
336
 
337
- async confirm({ quoteId, transactionHash, sshAuthorizedKey }) {
337
+ /// `decisionHash` travels when the lease was authorised: the client
338
+ /// reference on chain is derived from it, and the control plane cannot check
339
+ /// the funding log without knowing which derivation to expect. The digest is
340
+ /// all it gets; the decision stays here.
341
+ async confirm({ quoteId, transactionHash, sshAuthorizedKey, decisionHash = null }) {
338
342
  return this.#proxy("POST", ["leases", "confirm"], {
339
343
  body: {
340
344
  quote_id: quoteId,
341
345
  transaction_hash: transactionHash,
342
346
  ssh_authorized_key: sshAuthorizedKey,
347
+ ...(decisionHash ? { decision_hash: decisionHash } : {}),
343
348
  },
344
349
  });
345
350
  }
@@ -426,7 +431,12 @@ export class PrismAgent {
426
431
  maxDeposit = null,
427
432
  minTrustClass = "open",
428
433
  command = null,
434
+ decision = null,
435
+ policy = null,
429
436
  } = {}) {
437
+ // Checked before a quote is taken, so a refusal costs nothing and does not
438
+ // hold capacity against other renters while it expires.
439
+ if (policy) authorise(policy, decision ?? { action: "unstated", source: "none", answers: [] });
430
440
  if (!this.session) await this.authenticate();
431
441
  // A wallet with no balance at all cannot fund anything, and a doomed quote
432
442
  // still holds capacity against other renters until it expires. Refuse
@@ -463,11 +473,12 @@ export class PrismAgent {
463
473
  if (maxDeposit != null && parseBaseUnits(quote.maximum_escrow, "maximum_escrow") > BigInt(maxDeposit)) {
464
474
  throw new PrismError(402, "cost_exceeds_max", { required: quote.maximum_escrow, max: String(maxDeposit) });
465
475
  }
466
- funded = await this.#fundNow(quote);
476
+ funded = await this.#fundNow(quote, decision);
467
477
  return this.confirm({
468
478
  quoteId: quote.quote_id,
469
479
  transactionHash: funded.hash,
470
480
  sshAuthorizedKey: key.publicKey,
481
+ decisionHash: decisionDigest(decision),
471
482
  });
472
483
  });
473
484
  if (!Number.isInteger(record?.lease_id)) {