@arc402/daemon 1.2.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 (122) hide show
  1. package/bin/arc402-daemon +3 -0
  2. package/dist/abis.d.ts +20 -0
  3. package/dist/abis.d.ts.map +1 -0
  4. package/dist/abis.js +214 -0
  5. package/dist/abis.js.map +1 -0
  6. package/dist/api.d.ts +32 -0
  7. package/dist/api.d.ts.map +1 -0
  8. package/dist/api.js +430 -0
  9. package/dist/api.js.map +1 -0
  10. package/dist/auth-server.d.ts +50 -0
  11. package/dist/auth-server.d.ts.map +1 -0
  12. package/dist/auth-server.js +266 -0
  13. package/dist/auth-server.js.map +1 -0
  14. package/dist/bundler.d.ts +68 -0
  15. package/dist/bundler.d.ts.map +1 -0
  16. package/dist/bundler.js +181 -0
  17. package/dist/bundler.js.map +1 -0
  18. package/dist/capabilities.d.ts +17 -0
  19. package/dist/capabilities.d.ts.map +1 -0
  20. package/dist/capabilities.js +57 -0
  21. package/dist/capabilities.js.map +1 -0
  22. package/dist/compute-metering.d.ts +61 -0
  23. package/dist/compute-metering.d.ts.map +1 -0
  24. package/dist/compute-metering.js +299 -0
  25. package/dist/compute-metering.js.map +1 -0
  26. package/dist/compute-session.d.ts +100 -0
  27. package/dist/compute-session.d.ts.map +1 -0
  28. package/dist/compute-session.js +231 -0
  29. package/dist/compute-session.js.map +1 -0
  30. package/dist/config.d.ts +121 -0
  31. package/dist/config.d.ts.map +1 -0
  32. package/dist/config.js +397 -0
  33. package/dist/config.js.map +1 -0
  34. package/dist/context-manager.d.ts +17 -0
  35. package/dist/context-manager.d.ts.map +1 -0
  36. package/dist/context-manager.js +123 -0
  37. package/dist/context-manager.js.map +1 -0
  38. package/dist/credentials.d.ts +24 -0
  39. package/dist/credentials.d.ts.map +1 -0
  40. package/dist/credentials.js +80 -0
  41. package/dist/credentials.js.map +1 -0
  42. package/dist/delivery-client.d.ts +35 -0
  43. package/dist/delivery-client.d.ts.map +1 -0
  44. package/dist/delivery-client.js +231 -0
  45. package/dist/delivery-client.js.map +1 -0
  46. package/dist/endpoint-policy.d.ts +11 -0
  47. package/dist/endpoint-policy.d.ts.map +1 -0
  48. package/dist/endpoint-policy.js +107 -0
  49. package/dist/endpoint-policy.js.map +1 -0
  50. package/dist/event-watchers.d.ts +11 -0
  51. package/dist/event-watchers.d.ts.map +1 -0
  52. package/dist/event-watchers.js +24 -0
  53. package/dist/event-watchers.js.map +1 -0
  54. package/dist/exec-state.d.ts +37 -0
  55. package/dist/exec-state.d.ts.map +1 -0
  56. package/dist/exec-state.js +53 -0
  57. package/dist/exec-state.js.map +1 -0
  58. package/dist/file-delivery.d.ts +98 -0
  59. package/dist/file-delivery.d.ts.map +1 -0
  60. package/dist/file-delivery.js +473 -0
  61. package/dist/file-delivery.js.map +1 -0
  62. package/dist/handshake-watcher.d.ts +31 -0
  63. package/dist/handshake-watcher.d.ts.map +1 -0
  64. package/dist/handshake-watcher.js +157 -0
  65. package/dist/handshake-watcher.js.map +1 -0
  66. package/dist/hire-listener.d.ts +32 -0
  67. package/dist/hire-listener.d.ts.map +1 -0
  68. package/dist/hire-listener.js +237 -0
  69. package/dist/hire-listener.js.map +1 -0
  70. package/dist/index.d.ts +3 -0
  71. package/dist/index.d.ts.map +1 -0
  72. package/dist/index.js +182 -0
  73. package/dist/index.js.map +1 -0
  74. package/dist/job-lifecycle.d.ts +62 -0
  75. package/dist/job-lifecycle.d.ts.map +1 -0
  76. package/dist/job-lifecycle.js +201 -0
  77. package/dist/job-lifecycle.js.map +1 -0
  78. package/dist/notify.d.ts +51 -0
  79. package/dist/notify.d.ts.map +1 -0
  80. package/dist/notify.js +276 -0
  81. package/dist/notify.js.map +1 -0
  82. package/dist/permission-gate.d.ts +30 -0
  83. package/dist/permission-gate.d.ts.map +1 -0
  84. package/dist/permission-gate.js +180 -0
  85. package/dist/permission-gate.js.map +1 -0
  86. package/dist/prompt-guard.d.ts +18 -0
  87. package/dist/prompt-guard.d.ts.map +1 -0
  88. package/dist/prompt-guard.js +70 -0
  89. package/dist/prompt-guard.js.map +1 -0
  90. package/dist/server.d.ts +27 -0
  91. package/dist/server.d.ts.map +1 -0
  92. package/dist/server.js +1956 -0
  93. package/dist/server.js.map +1 -0
  94. package/dist/session-manager.d.ts +55 -0
  95. package/dist/session-manager.d.ts.map +1 -0
  96. package/dist/session-manager.js +139 -0
  97. package/dist/session-manager.js.map +1 -0
  98. package/dist/signer.d.ts +19 -0
  99. package/dist/signer.d.ts.map +1 -0
  100. package/dist/signer.js +195 -0
  101. package/dist/signer.js.map +1 -0
  102. package/dist/token-metering.d.ts +42 -0
  103. package/dist/token-metering.d.ts.map +1 -0
  104. package/dist/token-metering.js +178 -0
  105. package/dist/token-metering.js.map +1 -0
  106. package/dist/userops.d.ts +24 -0
  107. package/dist/userops.d.ts.map +1 -0
  108. package/dist/userops.js +156 -0
  109. package/dist/userops.js.map +1 -0
  110. package/dist/wallet-monitor.d.ts +16 -0
  111. package/dist/wallet-monitor.d.ts.map +1 -0
  112. package/dist/wallet-monitor.js +57 -0
  113. package/dist/wallet-monitor.js.map +1 -0
  114. package/dist/worker-executor.d.ts +81 -0
  115. package/dist/worker-executor.d.ts.map +1 -0
  116. package/dist/worker-executor.js +527 -0
  117. package/dist/worker-executor.js.map +1 -0
  118. package/dist/worker-router.d.ts +63 -0
  119. package/dist/worker-router.d.ts.map +1 -0
  120. package/dist/worker-router.js +263 -0
  121. package/dist/worker-router.js.map +1 -0
  122. package/package.json +30 -0
@@ -0,0 +1,98 @@
1
+ import * as http from "http";
2
+ export interface DeliveryFileEntry {
3
+ name: string;
4
+ size: number;
5
+ hash: string;
6
+ }
7
+ export interface DeliveryManifest {
8
+ agreement_id: string;
9
+ files: DeliveryFileEntry[];
10
+ root_hash: string;
11
+ total_size: number;
12
+ created_at: string;
13
+ updated_at: string;
14
+ }
15
+ /**
16
+ * Resolves agreement parties (hirer + provider) for access control.
17
+ * Injected by the daemon so file-delivery doesn't depend on the DB schema.
18
+ */
19
+ export type AgreementPartyResolver = (agreementId: string) => {
20
+ hirerAddress: string;
21
+ providerAddress: string;
22
+ } | null;
23
+ export declare class FileDeliveryManager {
24
+ private readonly maxFileSizeBytes;
25
+ private readonly maxJobSizeBytes;
26
+ private partyResolver;
27
+ /** Temporary arbitrator access tokens: token → { agreementId, expiresAt } */
28
+ private readonly arbitratorTokens;
29
+ constructor(opts?: {
30
+ maxFileSizeMb?: number;
31
+ maxJobSizeMb?: number;
32
+ });
33
+ setPartyResolver(resolver: AgreementPartyResolver): void;
34
+ /**
35
+ * Generate a time-limited arbitrator access token for dispute resolution.
36
+ * Valid for the specified agreement only.
37
+ */
38
+ generateArbitratorToken(agreementId: string, ttlSeconds?: number): string;
39
+ /**
40
+ * Verify that a request has valid party auth for a given agreement.
41
+ * Returns true if:
42
+ * 1. X-ARC402-Signature is a valid EIP-191 sig of "arc402:download:<agreementId>"
43
+ * from an address that is the hirer or provider on the agreement, OR
44
+ * 2. Authorization: Bearer <daemon-token> (local access), OR
45
+ * 3. X-Arbitrator-Token is a valid unexpired arbitrator token for this agreement
46
+ */
47
+ verifyPartyAccess(req: http.IncomingMessage, agreementId: string, daemonToken: string): {
48
+ allowed: boolean;
49
+ party?: string;
50
+ reason?: string;
51
+ };
52
+ deliveryDir(agreementId: string): string;
53
+ manifestPath(agreementId: string): string;
54
+ filePath(agreementId: string, filename: string): string;
55
+ computeFileHash(data: Buffer): string;
56
+ computeRootHash(fileHashes: string[]): string;
57
+ getManifest(agreementId: string): DeliveryManifest | null;
58
+ private writeManifest;
59
+ private recomputeManifest;
60
+ /**
61
+ * Store a file for an agreement. Immutable — returns existing entry if
62
+ * the file already exists (no overwrite).
63
+ */
64
+ storeFile(agreementId: string, filename: string, data: Buffer): {
65
+ entry: DeliveryFileEntry;
66
+ manifest: DeliveryManifest;
67
+ alreadyExisted: boolean;
68
+ };
69
+ /**
70
+ * Scan a directory for output files and store all of them.
71
+ * Returns the final manifest with root_hash.
72
+ */
73
+ storeDirectory(agreementId: string, sourceDir: string, excludes?: string[]): DeliveryManifest;
74
+ /**
75
+ * POST /job/:id/upload
76
+ * Auth required. Accepts raw binary body with X-Filename header.
77
+ * Also accepts Content-Disposition: attachment; filename="..."
78
+ */
79
+ handleUpload(req: http.IncomingMessage, res: http.ServerResponse, agreementId: string, log: (entry: Record<string, unknown>) => void): Promise<void>;
80
+ /**
81
+ * GET /job/:id/files
82
+ * Party-gated. Returns list of files (same as manifest but concise).
83
+ * Requires valid party auth (signature, daemon token, or arbitrator token).
84
+ */
85
+ handleListFiles(req: http.IncomingMessage, res: http.ServerResponse, agreementId: string, daemonToken: string, log: (entry: Record<string, unknown>) => void): void;
86
+ /**
87
+ * GET /job/:id/files/:filename
88
+ * Party-gated. Streams the file content to authenticated agreement parties.
89
+ */
90
+ handleDownloadFile(req: http.IncomingMessage, res: http.ServerResponse, agreementId: string, filename: string, daemonToken: string, log: (entry: Record<string, unknown>) => void): void;
91
+ /**
92
+ * GET /job/:id/manifest
93
+ * Party-gated. Returns full manifest with hashes for verification.
94
+ */
95
+ handleManifest(req: http.IncomingMessage, res: http.ServerResponse, agreementId: string, daemonToken: string, log: (entry: Record<string, unknown>) => void): void;
96
+ private readUploadBody;
97
+ }
98
+ //# sourceMappingURL=file-delivery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-delivery.d.ts","sourceRoot":"","sources":["../src/file-delivery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,473 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.FileDeliveryManager = void 0;
37
+ /**
38
+ * ARC-402 File Delivery Manager
39
+ *
40
+ * Content-addressed file serving with keccak256 hashing.
41
+ * Storage: ~/.arc402/deliveries/<agreement-id>/
42
+ *
43
+ * Root hash = keccak256(sorted concat of individual file hashes)
44
+ * This root hash is what goes on-chain via deliver().
45
+ *
46
+ * PRIVACY MODEL:
47
+ * Files are private IP between agreement parties by default.
48
+ * Downloads require proof of party membership:
49
+ * - X-ARC402-Signature: EIP-191 signed message "arc402:download:<agreementId>"
50
+ * - X-ARC402-Signer: the wallet address (must be hirer or provider on the agreement)
51
+ * - OR: Bearer token (daemon API token — for local/automated access)
52
+ * Only the hash is public (on-chain). Files are never public by default.
53
+ * For disputes: arbitrator gets temporary access via a time-limited token.
54
+ *
55
+ * Upload: POST /job/:id/upload (daemon auth — local worker only)
56
+ * List: GET /job/:id/files (party auth or daemon auth)
57
+ * Get: GET /job/:id/files/:name (party auth or daemon auth)
58
+ * Manifest: GET /job/:id/manifest (party auth or daemon auth)
59
+ */
60
+ const fs = __importStar(require("fs"));
61
+ const path = __importStar(require("path"));
62
+ const os = __importStar(require("os"));
63
+ const ethers_1 = require("ethers");
64
+ const DELIVERIES_DIR = path.join(os.homedir(), ".arc402", "deliveries");
65
+ const MANIFEST_FILENAME = "_manifest.json";
66
+ class FileDeliveryManager {
67
+ constructor(opts = {}) {
68
+ this.partyResolver = null;
69
+ /** Temporary arbitrator access tokens: token → { agreementId, expiresAt } */
70
+ this.arbitratorTokens = new Map();
71
+ this.maxFileSizeBytes = (opts.maxFileSizeMb ?? 100) * 1024 * 1024;
72
+ this.maxJobSizeBytes = (opts.maxJobSizeMb ?? 500) * 1024 * 1024;
73
+ fs.mkdirSync(DELIVERIES_DIR, { recursive: true });
74
+ }
75
+ setPartyResolver(resolver) {
76
+ this.partyResolver = resolver;
77
+ }
78
+ /**
79
+ * Generate a time-limited arbitrator access token for dispute resolution.
80
+ * Valid for the specified agreement only.
81
+ */
82
+ generateArbitratorToken(agreementId, ttlSeconds = 86400) {
83
+ const token = ethers_1.ethers.hexlify(ethers_1.ethers.randomBytes(32));
84
+ this.arbitratorTokens.set(token, {
85
+ agreementId,
86
+ expiresAt: Date.now() + ttlSeconds * 1000,
87
+ });
88
+ return token;
89
+ }
90
+ /**
91
+ * Verify that a request has valid party auth for a given agreement.
92
+ * Returns true if:
93
+ * 1. X-ARC402-Signature is a valid EIP-191 sig of "arc402:download:<agreementId>"
94
+ * from an address that is the hirer or provider on the agreement, OR
95
+ * 2. Authorization: Bearer <daemon-token> (local access), OR
96
+ * 3. X-Arbitrator-Token is a valid unexpired arbitrator token for this agreement
97
+ */
98
+ verifyPartyAccess(req, agreementId, daemonToken) {
99
+ // Check daemon bearer token (local/automated access)
100
+ const authHeader = (req.headers["authorization"] ?? "");
101
+ if (authHeader.startsWith("Bearer ") && authHeader.slice(7) === daemonToken) {
102
+ return { allowed: true, party: "daemon" };
103
+ }
104
+ // Check arbitrator token
105
+ const arbToken = req.headers["x-arbitrator-token"];
106
+ if (arbToken) {
107
+ const entry = this.arbitratorTokens.get(arbToken);
108
+ if (entry && entry.agreementId === agreementId && entry.expiresAt > Date.now()) {
109
+ return { allowed: true, party: "arbitrator" };
110
+ }
111
+ // Clean up expired
112
+ if (entry && entry.expiresAt <= Date.now()) {
113
+ this.arbitratorTokens.delete(arbToken);
114
+ }
115
+ }
116
+ // Check party signature
117
+ const sig = req.headers["x-arc402-signature"];
118
+ const signer = req.headers["x-arc402-signer"];
119
+ if (!sig || !signer) {
120
+ return { allowed: false, reason: "missing_auth: provide Bearer token, X-ARC402-Signature+X-ARC402-Signer, or X-Arbitrator-Token" };
121
+ }
122
+ // Verify EIP-191 signature
123
+ const message = `arc402:download:${agreementId}`;
124
+ let recovered;
125
+ try {
126
+ recovered = ethers_1.ethers.verifyMessage(message, sig);
127
+ }
128
+ catch {
129
+ return { allowed: false, reason: "invalid_signature" };
130
+ }
131
+ if (recovered.toLowerCase() !== signer.toLowerCase()) {
132
+ return { allowed: false, reason: "signature_signer_mismatch" };
133
+ }
134
+ // Check if signer is a party to the agreement
135
+ if (!this.partyResolver) {
136
+ return { allowed: false, reason: "no_party_resolver_configured" };
137
+ }
138
+ const parties = this.partyResolver(agreementId);
139
+ if (!parties) {
140
+ return { allowed: false, reason: "agreement_not_found" };
141
+ }
142
+ const signerLower = signer.toLowerCase();
143
+ if (signerLower === parties.hirerAddress.toLowerCase()) {
144
+ return { allowed: true, party: "hirer" };
145
+ }
146
+ if (signerLower === parties.providerAddress.toLowerCase()) {
147
+ return { allowed: true, party: "provider" };
148
+ }
149
+ // Also accept machine key EOA if the X-ARC402-Wallet header identifies a party wallet.
150
+ // V6 smart wallets sign protocol actions via an authorized machine key (EOA),
151
+ // so the recovered signer is the EOA, not the wallet contract address.
152
+ const walletHeader = req.headers["x-arc402-wallet"]?.toLowerCase();
153
+ if (walletHeader) {
154
+ if (walletHeader === parties.hirerAddress.toLowerCase()) {
155
+ return { allowed: true, party: "hirer" };
156
+ }
157
+ if (walletHeader === parties.providerAddress.toLowerCase()) {
158
+ return { allowed: true, party: "provider" };
159
+ }
160
+ }
161
+ return { allowed: false, reason: "signer_not_party_to_agreement" };
162
+ }
163
+ // ── Paths ────────────────────────────────────────────────────────────────
164
+ deliveryDir(agreementId) {
165
+ return path.join(DELIVERIES_DIR, agreementId);
166
+ }
167
+ manifestPath(agreementId) {
168
+ return path.join(this.deliveryDir(agreementId), MANIFEST_FILENAME);
169
+ }
170
+ filePath(agreementId, filename) {
171
+ // Sanitize filename — prevent path traversal
172
+ const safe = path.basename(filename);
173
+ return path.join(this.deliveryDir(agreementId), safe);
174
+ }
175
+ // ── Hashing ──────────────────────────────────────────────────────────────
176
+ computeFileHash(data) {
177
+ return ethers_1.ethers.keccak256(data);
178
+ }
179
+ computeRootHash(fileHashes) {
180
+ if (fileHashes.length === 0) {
181
+ return ethers_1.ethers.keccak256(new Uint8Array(0));
182
+ }
183
+ const sorted = [...fileHashes].sort();
184
+ const allBytes = Buffer.concat(sorted.map(h => Buffer.from(ethers_1.ethers.getBytes(h))));
185
+ return ethers_1.ethers.keccak256(allBytes);
186
+ }
187
+ // ── Manifest ─────────────────────────────────────────────────────────────
188
+ getManifest(agreementId) {
189
+ const mpath = this.manifestPath(agreementId);
190
+ if (!fs.existsSync(mpath))
191
+ return null;
192
+ try {
193
+ return JSON.parse(fs.readFileSync(mpath, "utf-8"));
194
+ }
195
+ catch {
196
+ return null;
197
+ }
198
+ }
199
+ writeManifest(agreementId, manifest) {
200
+ const dir = this.deliveryDir(agreementId);
201
+ fs.mkdirSync(dir, { recursive: true });
202
+ fs.writeFileSync(this.manifestPath(agreementId), JSON.stringify(manifest, null, 2));
203
+ }
204
+ recomputeManifest(agreementId) {
205
+ const dir = this.deliveryDir(agreementId);
206
+ fs.mkdirSync(dir, { recursive: true });
207
+ const existing = this.getManifest(agreementId);
208
+ const now = new Date().toISOString();
209
+ const entries = fs.readdirSync(dir)
210
+ .filter(f => f !== MANIFEST_FILENAME)
211
+ .map((name) => {
212
+ const fp = path.join(dir, name);
213
+ const data = fs.readFileSync(fp);
214
+ return {
215
+ name,
216
+ size: data.length,
217
+ hash: this.computeFileHash(data),
218
+ };
219
+ })
220
+ .sort((a, b) => a.name.localeCompare(b.name));
221
+ const rootHash = this.computeRootHash(entries.map(e => e.hash));
222
+ const totalSize = entries.reduce((s, e) => s + e.size, 0);
223
+ const manifest = {
224
+ agreement_id: agreementId,
225
+ files: entries,
226
+ root_hash: rootHash,
227
+ total_size: totalSize,
228
+ created_at: existing?.created_at ?? now,
229
+ updated_at: now,
230
+ };
231
+ this.writeManifest(agreementId, manifest);
232
+ return manifest;
233
+ }
234
+ // ── File storage ──────────────────────────────────────────────────────────
235
+ /**
236
+ * Store a file for an agreement. Immutable — returns existing entry if
237
+ * the file already exists (no overwrite).
238
+ */
239
+ storeFile(agreementId, filename, data) {
240
+ const safe = path.basename(filename);
241
+ if (!safe || safe === MANIFEST_FILENAME) {
242
+ throw new Error("invalid_filename");
243
+ }
244
+ const dir = this.deliveryDir(agreementId);
245
+ fs.mkdirSync(dir, { recursive: true });
246
+ const fp = path.join(dir, safe);
247
+ // Immutable — refuse overwrite
248
+ if (fs.existsSync(fp)) {
249
+ const manifest = this.getManifest(agreementId) ?? this.recomputeManifest(agreementId);
250
+ const entry = manifest.files.find(f => f.name === safe);
251
+ if (!entry)
252
+ throw new Error("manifest_inconsistent");
253
+ return { entry, manifest, alreadyExisted: true };
254
+ }
255
+ // Size checks
256
+ if (data.length > this.maxFileSizeBytes) {
257
+ throw new Error(`file_too_large: ${data.length} bytes exceeds ${this.maxFileSizeBytes}`);
258
+ }
259
+ // Check total job size
260
+ const existingManifest = this.getManifest(agreementId);
261
+ const existingTotal = existingManifest?.total_size ?? 0;
262
+ if (existingTotal + data.length > this.maxJobSizeBytes) {
263
+ throw new Error(`job_too_large: total would exceed ${this.maxJobSizeBytes} bytes`);
264
+ }
265
+ // Write file
266
+ fs.writeFileSync(fp, data);
267
+ // Recompute manifest
268
+ const manifest = this.recomputeManifest(agreementId);
269
+ const entry = manifest.files.find(f => f.name === safe);
270
+ if (!entry)
271
+ throw new Error("manifest_inconsistent");
272
+ return { entry, manifest, alreadyExisted: false };
273
+ }
274
+ /**
275
+ * Scan a directory for output files and store all of them.
276
+ * Returns the final manifest with root_hash.
277
+ */
278
+ storeDirectory(agreementId, sourceDir, excludes = []) {
279
+ const excludeSet = new Set([...excludes, MANIFEST_FILENAME, "job.log", ".claude"]);
280
+ const files = fs.readdirSync(sourceDir).filter(f => {
281
+ if (excludeSet.has(f))
282
+ return false;
283
+ const stat = fs.statSync(path.join(sourceDir, f));
284
+ return stat.isFile();
285
+ });
286
+ for (const filename of files) {
287
+ const data = fs.readFileSync(path.join(sourceDir, filename));
288
+ try {
289
+ this.storeFile(agreementId, filename, data);
290
+ }
291
+ catch (err) {
292
+ // Log and skip files that are too large, etc.
293
+ process.stderr.write(`[file-delivery] skip ${filename}: ${err}\n`);
294
+ }
295
+ }
296
+ return this.recomputeManifest(agreementId);
297
+ }
298
+ // ── HTTP handlers ─────────────────────────────────────────────────────────
299
+ /**
300
+ * POST /job/:id/upload
301
+ * Auth required. Accepts raw binary body with X-Filename header.
302
+ * Also accepts Content-Disposition: attachment; filename="..."
303
+ */
304
+ async handleUpload(req, res, agreementId, log) {
305
+ // Determine filename from headers
306
+ const xFilename = req.headers["x-filename"];
307
+ const contentDisp = req.headers["content-disposition"];
308
+ let filename = xFilename ?? "";
309
+ if (!filename && contentDisp) {
310
+ const m = contentDisp.match(/filename="?([^";]+)"?/);
311
+ if (m)
312
+ filename = m[1];
313
+ }
314
+ if (!filename) {
315
+ res.writeHead(400, { "Content-Type": "application/json" });
316
+ res.end(JSON.stringify({ error: "missing_filename", hint: "Set X-Filename header" }));
317
+ return;
318
+ }
319
+ // Stream body with size cap
320
+ const data = await this.readUploadBody(req, res);
321
+ if (data === null)
322
+ return; // already responded
323
+ try {
324
+ const { entry, manifest, alreadyExisted } = this.storeFile(agreementId, filename, data);
325
+ log({ event: "file_uploaded", agreement_id: agreementId, filename: entry.name, size: entry.size, already_existed: alreadyExisted });
326
+ res.writeHead(alreadyExisted ? 200 : 201, { "Content-Type": "application/json" });
327
+ res.end(JSON.stringify({
328
+ ok: true,
329
+ already_existed: alreadyExisted,
330
+ file: entry,
331
+ root_hash: manifest.root_hash,
332
+ total_files: manifest.files.length,
333
+ }));
334
+ }
335
+ catch (err) {
336
+ const msg = String(err instanceof Error ? err.message : err);
337
+ if (msg.startsWith("file_too_large") || msg.startsWith("job_too_large")) {
338
+ res.writeHead(413, { "Content-Type": "application/json" });
339
+ res.end(JSON.stringify({ error: msg }));
340
+ }
341
+ else if (msg.startsWith("invalid_filename")) {
342
+ res.writeHead(400, { "Content-Type": "application/json" });
343
+ res.end(JSON.stringify({ error: "invalid_filename" }));
344
+ }
345
+ else {
346
+ log({ event: "upload_error", agreement_id: agreementId, error: msg });
347
+ res.writeHead(500, { "Content-Type": "application/json" });
348
+ res.end(JSON.stringify({ error: "upload_failed" }));
349
+ }
350
+ }
351
+ }
352
+ /**
353
+ * GET /job/:id/files
354
+ * Party-gated. Returns list of files (same as manifest but concise).
355
+ * Requires valid party auth (signature, daemon token, or arbitrator token).
356
+ */
357
+ handleListFiles(req, res, agreementId, daemonToken, log) {
358
+ const access = this.verifyPartyAccess(req, agreementId, daemonToken);
359
+ if (!access.allowed) {
360
+ log({ event: "file_list_denied", agreement_id: agreementId, reason: access.reason });
361
+ res.writeHead(403, { "Content-Type": "application/json" });
362
+ res.end(JSON.stringify({ error: "access_denied", reason: access.reason }));
363
+ return;
364
+ }
365
+ const manifest = this.getManifest(agreementId);
366
+ if (!manifest) {
367
+ res.writeHead(404, { "Content-Type": "application/json" });
368
+ res.end(JSON.stringify({ error: "no_files_for_agreement" }));
369
+ return;
370
+ }
371
+ log({ event: "file_list_served", agreement_id: agreementId, party: access.party });
372
+ res.writeHead(200, { "Content-Type": "application/json" });
373
+ res.end(JSON.stringify({
374
+ agreement_id: agreementId,
375
+ files: manifest.files.map(f => ({ name: f.name, size: f.size })),
376
+ root_hash: manifest.root_hash,
377
+ total_files: manifest.files.length,
378
+ total_size: manifest.total_size,
379
+ }));
380
+ }
381
+ /**
382
+ * GET /job/:id/files/:filename
383
+ * Party-gated. Streams the file content to authenticated agreement parties.
384
+ */
385
+ handleDownloadFile(req, res, agreementId, filename, daemonToken, log) {
386
+ const access = this.verifyPartyAccess(req, agreementId, daemonToken);
387
+ if (!access.allowed) {
388
+ log({ event: "file_download_denied", agreement_id: agreementId, filename, reason: access.reason });
389
+ res.writeHead(403, { "Content-Type": "application/json" });
390
+ res.end(JSON.stringify({ error: "access_denied", reason: access.reason }));
391
+ return;
392
+ }
393
+ const safe = path.basename(filename);
394
+ if (!safe || safe === MANIFEST_FILENAME) {
395
+ res.writeHead(400, { "Content-Type": "application/json" });
396
+ res.end(JSON.stringify({ error: "invalid_filename" }));
397
+ return;
398
+ }
399
+ const fp = this.filePath(agreementId, safe);
400
+ if (!fs.existsSync(fp)) {
401
+ res.writeHead(404, { "Content-Type": "application/json" });
402
+ res.end(JSON.stringify({ error: "file_not_found" }));
403
+ return;
404
+ }
405
+ const stat = fs.statSync(fp);
406
+ log({ event: "file_download_served", agreement_id: agreementId, filename: safe, size: stat.size, party: access.party });
407
+ res.writeHead(200, {
408
+ "Content-Type": "application/octet-stream",
409
+ "Content-Length": String(stat.size),
410
+ "Content-Disposition": `attachment; filename="${safe}"`,
411
+ "Cache-Control": "private, no-store",
412
+ });
413
+ const stream = fs.createReadStream(fp);
414
+ stream.on("error", (err) => {
415
+ log({ event: "download_error", agreement_id: agreementId, filename: safe, error: String(err) });
416
+ });
417
+ stream.pipe(res);
418
+ }
419
+ /**
420
+ * GET /job/:id/manifest
421
+ * Party-gated. Returns full manifest with hashes for verification.
422
+ */
423
+ handleManifest(req, res, agreementId, daemonToken, log) {
424
+ const access = this.verifyPartyAccess(req, agreementId, daemonToken);
425
+ if (!access.allowed) {
426
+ log({ event: "manifest_denied", agreement_id: agreementId, reason: access.reason });
427
+ res.writeHead(403, { "Content-Type": "application/json" });
428
+ res.end(JSON.stringify({ error: "access_denied", reason: access.reason }));
429
+ return;
430
+ }
431
+ const manifest = this.getManifest(agreementId);
432
+ if (!manifest) {
433
+ res.writeHead(404, { "Content-Type": "application/json" });
434
+ res.end(JSON.stringify({ error: "no_manifest_for_agreement" }));
435
+ return;
436
+ }
437
+ log({ event: "manifest_served", agreement_id: agreementId, party: access.party });
438
+ res.writeHead(200, { "Content-Type": "application/json" });
439
+ res.end(JSON.stringify(manifest, null, 2));
440
+ }
441
+ // ── Private helpers ───────────────────────────────────────────────────────
442
+ readUploadBody(req, res) {
443
+ return new Promise((resolve) => {
444
+ const chunks = [];
445
+ let size = 0;
446
+ let aborted = false;
447
+ req.on("data", (chunk) => {
448
+ if (aborted)
449
+ return;
450
+ size += chunk.length;
451
+ if (size > this.maxFileSizeBytes) {
452
+ aborted = true;
453
+ req.destroy();
454
+ res.writeHead(413, { "Content-Type": "application/json" });
455
+ res.end(JSON.stringify({ error: "file_too_large" }));
456
+ resolve(null);
457
+ return;
458
+ }
459
+ chunks.push(chunk);
460
+ });
461
+ req.on("end", () => {
462
+ if (!aborted)
463
+ resolve(Buffer.concat(chunks));
464
+ });
465
+ req.on("error", () => {
466
+ if (!aborted)
467
+ resolve(null);
468
+ });
469
+ });
470
+ }
471
+ }
472
+ exports.FileDeliveryManager = FileDeliveryManager;
473
+ //# sourceMappingURL=file-delivery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-delivery.js","sourceRoot":"","sources":["../src/file-delivery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import { ethers } from "ethers";
2
+ export interface HandshakeEvent {
3
+ handshakeId: string;
4
+ from: string;
5
+ to: string;
6
+ hsType: number;
7
+ token: string;
8
+ amount: bigint;
9
+ note: string;
10
+ timestamp: number;
11
+ blockNumber: number;
12
+ txHash: string;
13
+ }
14
+ export declare class HandshakeWatcher {
15
+ private provider;
16
+ private contract;
17
+ private myAddress;
18
+ private onHandshake;
19
+ private processedIdsPath;
20
+ private processedIds;
21
+ private liveListener;
22
+ constructor(provider: ethers.Provider, handshakeAddress: string, myAddress: string, onHandshake: (event: HandshakeEvent) => Promise<void>, processedIdsPath: string);
23
+ start(): Promise<void>;
24
+ stop(): Promise<void>;
25
+ private loadProcessedIds;
26
+ private saveProcessedIds;
27
+ private catchupScan;
28
+ private subscribeLive;
29
+ private handleLog;
30
+ }
31
+ //# sourceMappingURL=handshake-watcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handshake-watcher.d.ts","sourceRoot":"","sources":["../src/handshake-watcher.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAQhC,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAA2C;IAC9D,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,YAAY,CAA0B;IAC9C,OAAO,CAAC,YAAY,CAA+C;gBAGjE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EACzB,gBAAgB,EAAE,MAAM,EACxB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,EACrD,gBAAgB,EAAE,MAAM;IASpB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAMtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAS3B,OAAO,CAAC,gBAAgB;IAexB,OAAO,CAAC,gBAAgB;YAYV,WAAW;IAiBzB,OAAO,CAAC,aAAa;YAaP,SAAS;CAiCxB"}