@supercuts-walrus/backend 0.0.0-stage → 0.1.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.
Files changed (149) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +249 -2
  3. package/dist/audit.d.ts +52 -0
  4. package/dist/audit.js +157 -0
  5. package/dist/backend.d.ts +27 -0
  6. package/dist/backend.js +62 -0
  7. package/dist/buyer-setup.d.ts +6 -0
  8. package/dist/buyer-setup.js +241 -0
  9. package/dist/capability.d.ts +32 -0
  10. package/dist/capability.js +87 -0
  11. package/dist/claude.d.ts +44 -0
  12. package/dist/claude.js +98 -0
  13. package/dist/cli.d.ts +2 -0
  14. package/dist/cli.js +29 -0
  15. package/dist/config.d.ts +20 -0
  16. package/dist/config.js +58 -0
  17. package/dist/dashboard.d.ts +5 -0
  18. package/dist/dashboard.js +21 -0
  19. package/dist/deal-adapter.d.ts +3 -0
  20. package/dist/deal-adapter.js +39 -0
  21. package/dist/deal-engine.d.ts +62 -0
  22. package/dist/deal-engine.js +211 -0
  23. package/dist/deal-wire.d.ts +16 -0
  24. package/dist/deal-wire.js +65 -0
  25. package/dist/deal.d.ts +79 -0
  26. package/dist/deal.js +228 -0
  27. package/dist/demo.d.ts +2 -0
  28. package/dist/demo.js +449 -0
  29. package/dist/errors.d.ts +6 -0
  30. package/dist/errors.js +13 -0
  31. package/dist/events.d.ts +27 -0
  32. package/dist/events.js +68 -0
  33. package/dist/facilitator.d.ts +21 -0
  34. package/dist/facilitator.js +173 -0
  35. package/dist/finality.d.ts +2 -0
  36. package/dist/finality.js +27 -0
  37. package/dist/hosted-exit-cli.d.ts +2 -0
  38. package/dist/hosted-exit-cli.js +37 -0
  39. package/dist/hosted-exit.d.ts +24 -0
  40. package/dist/hosted-exit.js +70 -0
  41. package/dist/hosted-seller-import.d.ts +2 -0
  42. package/dist/hosted-seller-import.js +70 -0
  43. package/dist/hosted-seller-repository.d.ts +31 -0
  44. package/dist/hosted-seller-repository.js +214 -0
  45. package/dist/index.d.ts +37 -0
  46. package/dist/index.js +37 -0
  47. package/dist/indexer.d.ts +63 -0
  48. package/dist/indexer.js +60 -0
  49. package/dist/live-deal-ports.d.ts +41 -0
  50. package/dist/live-deal-ports.js +212 -0
  51. package/dist/live-index.d.ts +28 -0
  52. package/dist/live-index.js +149 -0
  53. package/dist/live-runtime.d.ts +82 -0
  54. package/dist/live-runtime.js +570 -0
  55. package/dist/live-seller-transport.d.ts +30 -0
  56. package/dist/live-seller-transport.js +169 -0
  57. package/dist/live-seller-verifier.d.ts +11 -0
  58. package/dist/live-seller-verifier.js +65 -0
  59. package/dist/mandate.d.ts +34 -0
  60. package/dist/mandate.js +178 -0
  61. package/dist/mcp-bootstrap.d.ts +2 -0
  62. package/dist/mcp-bootstrap.js +39 -0
  63. package/dist/mcp.d.ts +2 -0
  64. package/dist/mcp.js +187 -0
  65. package/dist/memory-worker.d.ts +2 -0
  66. package/dist/memory-worker.js +38 -0
  67. package/dist/memory.d.ts +15 -0
  68. package/dist/memory.js +17 -0
  69. package/dist/memwal.d.ts +35 -0
  70. package/dist/memwal.js +83 -0
  71. package/dist/negotiation.d.ts +23 -0
  72. package/dist/negotiation.js +58 -0
  73. package/dist/notes.d.ts +11 -0
  74. package/dist/notes.js +26 -0
  75. package/dist/onboarding-doctor.d.ts +1 -0
  76. package/dist/onboarding-doctor.js +76 -0
  77. package/dist/phase3.d.ts +100 -0
  78. package/dist/phase3.js +1144 -0
  79. package/dist/procurement.d.ts +8 -0
  80. package/dist/procurement.js +19 -0
  81. package/dist/protocol-engine.d.ts +121 -0
  82. package/dist/protocol-engine.js +149 -0
  83. package/dist/prover.d.ts +28 -0
  84. package/dist/prover.js +70 -0
  85. package/dist/relayer.d.ts +32 -0
  86. package/dist/relayer.js +43 -0
  87. package/dist/remote-buyer.d.ts +67 -0
  88. package/dist/remote-buyer.js +231 -0
  89. package/dist/resource-server.d.ts +2 -0
  90. package/dist/resource-server.js +24 -0
  91. package/dist/resource.d.ts +22 -0
  92. package/dist/resource.js +55 -0
  93. package/dist/seam.d.ts +2 -0
  94. package/dist/seam.js +117 -0
  95. package/dist/seller-catalog-generate.d.ts +2 -0
  96. package/dist/seller-catalog-generate.js +68 -0
  97. package/dist/seller-database.d.ts +41 -0
  98. package/dist/seller-database.js +80 -0
  99. package/dist/seller-directory-cli.d.ts +2 -0
  100. package/dist/seller-directory-cli.js +24 -0
  101. package/dist/seller-directory.d.ts +5 -0
  102. package/dist/seller-directory.js +50 -0
  103. package/dist/seller-live-cli.d.ts +2 -0
  104. package/dist/seller-live-cli.js +53 -0
  105. package/dist/seller-provision.d.ts +2 -0
  106. package/dist/seller-provision.js +84 -0
  107. package/dist/seller-register-cli.d.ts +2 -0
  108. package/dist/seller-register-cli.js +40 -0
  109. package/dist/seller-runtime.d.ts +60 -0
  110. package/dist/seller-runtime.js +96 -0
  111. package/dist/seller-service.d.ts +34 -0
  112. package/dist/seller-service.js +416 -0
  113. package/dist/seller-state.d.ts +19 -0
  114. package/dist/seller-state.js +60 -0
  115. package/dist/seller-stdio.d.ts +6 -0
  116. package/dist/seller-stdio.js +29 -0
  117. package/dist/seller-v2-provision.d.ts +2 -0
  118. package/dist/seller-v2-provision.js +71 -0
  119. package/dist/seller-watch.d.ts +2 -0
  120. package/dist/seller-watch.js +45 -0
  121. package/dist/settlement.d.ts +95 -0
  122. package/dist/settlement.js +141 -0
  123. package/dist/store.d.ts +36 -0
  124. package/dist/store.js +193 -0
  125. package/dist/sui.d.ts +49 -0
  126. package/dist/sui.js +77 -0
  127. package/dist/tatum.d.ts +17 -0
  128. package/dist/tatum.js +83 -0
  129. package/dist/transcript.d.ts +31 -0
  130. package/dist/transcript.js +52 -0
  131. package/dist/v2-exit-relayer.d.ts +34 -0
  132. package/dist/v2-exit-relayer.js +102 -0
  133. package/dist/v2-exit-worker.d.ts +2 -0
  134. package/dist/v2-exit-worker.js +97 -0
  135. package/dist/v2-exits.d.ts +30 -0
  136. package/dist/v2-exits.js +78 -0
  137. package/dist/v2-prefund.d.ts +19 -0
  138. package/dist/v2-prefund.js +43 -0
  139. package/dist/v2-relayer-cli.d.ts +2 -0
  140. package/dist/v2-relayer-cli.js +39 -0
  141. package/dist/wallet.d.ts +32 -0
  142. package/dist/wallet.js +90 -0
  143. package/dist/workflow-memory.d.ts +22 -0
  144. package/dist/workflow-memory.js +49 -0
  145. package/dist/x402-resource-service.d.ts +34 -0
  146. package/dist/x402-resource-service.js +154 -0
  147. package/dist/x402.d.ts +46 -0
  148. package/dist/x402.js +136 -0
  149. package/package.json +60 -3
package/dist/x402.js ADDED
@@ -0,0 +1,136 @@
1
+ import { createHash } from "node:crypto";
2
+ import { fail } from "./errors.js";
3
+ function canonical(value) {
4
+ if (Array.isArray(value))
5
+ return `[${value.map(canonical).join(",")}]`;
6
+ if (value && typeof value === "object")
7
+ return `{${Object.entries(value).sort(([a], [b]) => a.localeCompare(b)).map(([key, item]) => `${JSON.stringify(key)}:${canonical(item)}`).join(",")}}`;
8
+ const result = JSON.stringify(value);
9
+ if (result === undefined)
10
+ fail("X402_REQUIREMENTS_INVALID", "x402 values must be JSON-compatible");
11
+ return result;
12
+ }
13
+ export function requirementsHash(requirements) { return createHash("sha256").update(canonical(requirements)).digest("hex"); }
14
+ export function paymentBindingBytes(binding) {
15
+ return Buffer.from(canonical({ domain: "supercuts-x402-binding-v1", ...binding }));
16
+ }
17
+ export class PaymentConsumptionLedger {
18
+ store;
19
+ constructor(store) {
20
+ this.store = store;
21
+ }
22
+ claim(payment, requestId) {
23
+ if (!payment.finalized)
24
+ fail("PAYMENT_PENDING", "payment is not finalized");
25
+ if (!payment.network || !payment.digest || payment.network.length > 256 || payment.digest.length > 256 || !requestId || requestId.length > 256)
26
+ fail("PAYMENT_ID_INVALID", "payment or request identity is invalid");
27
+ const key = createHash("sha256").update(canonical([payment.network, payment.digest])).digest("hex");
28
+ this.store.db.exec("BEGIN IMMEDIATE");
29
+ try {
30
+ const request = this.store.db.prepare("SELECT payment_key FROM deliveries WHERE request_id = ?").get(requestId);
31
+ if (request && request.payment_key !== key)
32
+ fail("REQUEST_PAYMENT_CONFLICT", "request is already bound to another payment");
33
+ const existing = this.store.db.prepare("SELECT request_id FROM deliveries WHERE payment_key = ?").get(key);
34
+ if (existing && existing.request_id !== requestId)
35
+ fail("PAYMENT_CONSUMED", "payment was already used for another request");
36
+ if (!existing)
37
+ this.store.db.prepare("INSERT INTO deliveries(request_id, payment_key, response, finalized) VALUES (?, ?, ?, 1)").run(requestId, key, Buffer.alloc(0));
38
+ this.store.db.exec("COMMIT");
39
+ }
40
+ catch (error) {
41
+ this.store.db.exec("ROLLBACK");
42
+ throw error;
43
+ }
44
+ }
45
+ recordDelivery(requestId, response) {
46
+ const result = this.store.db.prepare("UPDATE deliveries SET response = ?, finalized = 1 WHERE request_id = ?").run(Buffer.from(response), requestId);
47
+ if (result.changes !== 1)
48
+ fail("PAYMENT_NOT_CLAIMED", "resource cannot be delivered before payment consumption");
49
+ }
50
+ getDelivery(requestId) {
51
+ const row = this.store.db.prepare("SELECT response FROM deliveries WHERE request_id = ?").get(requestId);
52
+ return row ? Buffer.from(row.response) : undefined;
53
+ }
54
+ isDeliveryComplete(requestId) {
55
+ const row = this.store.db.prepare("SELECT status FROM delivery_jobs WHERE request_id = ?").get(requestId);
56
+ return row?.status === "delivered";
57
+ }
58
+ acquireDelivery(requestId, now = Date.now(), leaseMs = 30_000) {
59
+ this.store.db.exec("BEGIN IMMEDIATE");
60
+ try {
61
+ const row = this.store.db.prepare("SELECT status, lease_until FROM delivery_jobs WHERE request_id = ?").get(requestId);
62
+ if (row?.status === "delivered" || (row?.status === "producing" && row.lease_until > now)) {
63
+ this.store.db.exec("COMMIT");
64
+ return false;
65
+ }
66
+ this.store.db.prepare("INSERT INTO delivery_jobs(request_id, status, lease_until) VALUES (?, 'producing', ?) ON CONFLICT(request_id) DO UPDATE SET status='producing', lease_until=excluded.lease_until").run(requestId, now + leaseMs);
67
+ this.store.db.exec("COMMIT");
68
+ return true;
69
+ }
70
+ catch (error) {
71
+ this.store.db.exec("ROLLBACK");
72
+ throw error;
73
+ }
74
+ }
75
+ releaseDelivery(requestId) { this.store.db.prepare("UPDATE delivery_jobs SET status = 'pending', lease_until = 0 WHERE request_id = ? AND status = 'producing'").run(requestId); }
76
+ completeDelivery(requestId, response) {
77
+ this.store.db.exec("BEGIN IMMEDIATE");
78
+ try {
79
+ this.recordDelivery(requestId, response);
80
+ this.store.db.prepare("INSERT INTO delivery_jobs(request_id, status, lease_until) VALUES (?, 'delivered', 0) ON CONFLICT(request_id) DO UPDATE SET status='delivered', lease_until=0").run(requestId);
81
+ this.store.db.exec("COMMIT");
82
+ }
83
+ catch (error) {
84
+ this.store.db.exec("ROLLBACK");
85
+ throw error;
86
+ }
87
+ }
88
+ challenge(requestId, requirementsHashValue, createNonce) {
89
+ const existing = this.store.db.prepare("SELECT nonce, requirements_hash FROM x402_challenges WHERE request_id = ?").get(requestId);
90
+ if (existing) {
91
+ if (existing.requirements_hash !== requirementsHashValue)
92
+ fail("X402_REQUEST_CONFLICT", "request identity was reused with different requirements");
93
+ return existing.nonce;
94
+ }
95
+ const nonce = createNonce();
96
+ this.store.db.prepare("INSERT INTO x402_challenges(request_id, nonce, requirements_hash, created_at) VALUES (?, ?, ?, ?)").run(requestId, nonce, requirementsHashValue, Date.now());
97
+ return nonce;
98
+ }
99
+ getChallenge(requestId, requirementsHashValue) {
100
+ const row = this.store.db.prepare("SELECT nonce, requirements_hash, created_at FROM x402_challenges WHERE request_id = ?").get(requestId);
101
+ if (row && row.requirements_hash !== requirementsHashValue)
102
+ fail("X402_REQUEST_CONFLICT", "request identity was reused with different requirements");
103
+ return row ? { nonce: row.nonce, createdAt: row.created_at } : undefined;
104
+ }
105
+ }
106
+ export function verifyBinding(binding, requestId, nonce, requirements, transactionDigest) {
107
+ if (!binding.payer || !binding.payerSignature || binding.payer.length > 256 || binding.payerSignature.length > 2048)
108
+ fail("X402_REQUEST_BINDING_INVALID", "payer binding identity or signature is invalid");
109
+ if (binding.requestId !== requestId || binding.nonce !== nonce || binding.transactionDigest !== transactionDigest || binding.requirementsHash !== requirementsHash(requirements))
110
+ fail("X402_REQUEST_BINDING_INVALID", "payment does not bind to this request");
111
+ }
112
+ export function verifyExactPayment(payment, requirements) {
113
+ if (requirements.scheme !== "exact" || !Number.isSafeInteger(requirements.maxTimeoutSeconds) || requirements.maxTimeoutSeconds <= 0)
114
+ fail("X402_REQUIREMENTS_INVALID", "exact requirements need a positive integer timeout");
115
+ if (!requirements.network || !requirements.asset || !requirements.payTo || requirements.network.length > 256 || requirements.asset.length > 512 || requirements.payTo.length > 256)
116
+ fail("X402_REQUIREMENTS_INVALID", "payment network, asset, or recipient is invalid");
117
+ if (!payment.finalized)
118
+ fail("PAYMENT_PENDING", "payment is not finalized");
119
+ let required;
120
+ try {
121
+ required = BigInt(requirements.amount);
122
+ }
123
+ catch (error) {
124
+ return fail("X402_REQUIREMENTS_INVALID", "payment amount is not an integer", error);
125
+ }
126
+ if (payment.network !== requirements.network)
127
+ fail("X402_NETWORK_MISMATCH", "payment used the wrong network");
128
+ if (payment.asset !== requirements.asset)
129
+ fail("X402_ASSET_MISMATCH", "payment used the wrong asset");
130
+ if (required <= 0n)
131
+ fail("X402_REQUIREMENTS_INVALID", "payment amount must be positive");
132
+ if (payment.amount !== required)
133
+ fail("X402_AMOUNT_MISMATCH", "payment used the wrong exact amount");
134
+ if (payment.payTo !== requirements.payTo)
135
+ fail("X402_PAYEE_MISMATCH", "payment used the wrong recipient");
136
+ }
package/package.json CHANGED
@@ -1,6 +1,63 @@
1
1
  {
2
2
  "name": "@supercuts-walrus/backend",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.1.0",
4
+ "private": false,
5
+ "type": "module",
6
+ "exports": {
7
+ "./seam": "./dist/seam.js",
8
+ "./package.json": "./package.json"
9
+ },
10
+ "bin": {
11
+ "supercuts": "dist/cli.js",
12
+ "supercuts-demo": "dist/demo.js",
13
+ "supercuts-mcp": "dist/mcp-bootstrap.js",
14
+ "supercuts-resource": "dist/resource-server.js",
15
+ "supercuts-seller-service": "dist/seller-service.js",
16
+ "supercuts-seller-provision": "dist/seller-provision.js",
17
+ "supercuts-seller-watch": "dist/seller-watch.js",
18
+ "supercuts-seller-catalog": "dist/seller-catalog-generate.js",
19
+ "supercuts-facilitator": "dist/facilitator.js",
20
+ "supercuts-seam": "dist/seam.js",
21
+ "supercuts-v2-relayer": "dist/v2-relayer-cli.js",
22
+ "supercuts-memory-worker": "dist/memory-worker.js",
23
+ "supercuts-seller-live": "dist/seller-live-cli.js",
24
+ "supercuts-seller-register": "dist/seller-register-cli.js",
25
+ "supercuts-seller-v2-provision": "dist/seller-v2-provision.js",
26
+ "supercuts-hosted-exit": "dist/hosted-exit-cli.js",
27
+ "supercuts-hosted-seller-import": "dist/hosted-seller-import.js",
28
+ "supercuts-seller-directory": "dist/seller-directory-cli.js"
29
+ },
30
+ "files": [
31
+ "dist",
32
+ "README.md"
33
+ ],
34
+ "license": "Apache-2.0",
35
+ "engines": {
36
+ "node": ">=22.13"
37
+ },
38
+ "dependencies": {
39
+ "@mysten-incubation/memwal": "0.1.11",
40
+ "@mysten/seal": "1.5.2",
41
+ "@mysten/sui": "2.38.0",
42
+ "@mysten/walrus": "1.2.37",
43
+ "ajv": "8.17.1",
44
+ "circomlibjs": "0.1.7",
45
+ "pg": "^8.23.1"
46
+ },
47
+ "devDependencies": {
48
+ "@types/node": "^22.10.0",
49
+ "@types/pg": "^8.23.1",
50
+ "tsx": "^4.19.2",
51
+ "typescript": "^5.7.2"
52
+ },
53
+ "scripts": {
54
+ "build": "tsc -p tsconfig.build.json",
55
+ "check": "tsc --noEmit",
56
+ "test": "tsx --test test/**/*.test.ts",
57
+ "test:e2e": "tsx --test test/phase2.e2e.test.ts",
58
+ "test:phase3": "tsx --test test/phase3.e2e.test.ts",
59
+ "test:sdk": "pnpm --dir packages/sdk test",
60
+ "release:gate": "node scripts/release-gate.mjs",
61
+ "test:seal-live": "tsx scripts/seal-live-e2e.ts"
62
+ }
6
63
  }