@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.
- package/bin/arc402-daemon +3 -0
- package/dist/abis.d.ts +20 -0
- package/dist/abis.d.ts.map +1 -0
- package/dist/abis.js +214 -0
- package/dist/abis.js.map +1 -0
- package/dist/api.d.ts +32 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +430 -0
- package/dist/api.js.map +1 -0
- package/dist/auth-server.d.ts +50 -0
- package/dist/auth-server.d.ts.map +1 -0
- package/dist/auth-server.js +266 -0
- package/dist/auth-server.js.map +1 -0
- package/dist/bundler.d.ts +68 -0
- package/dist/bundler.d.ts.map +1 -0
- package/dist/bundler.js +181 -0
- package/dist/bundler.js.map +1 -0
- package/dist/capabilities.d.ts +17 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/capabilities.js +57 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/compute-metering.d.ts +61 -0
- package/dist/compute-metering.d.ts.map +1 -0
- package/dist/compute-metering.js +299 -0
- package/dist/compute-metering.js.map +1 -0
- package/dist/compute-session.d.ts +100 -0
- package/dist/compute-session.d.ts.map +1 -0
- package/dist/compute-session.js +231 -0
- package/dist/compute-session.js.map +1 -0
- package/dist/config.d.ts +121 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +397 -0
- package/dist/config.js.map +1 -0
- package/dist/context-manager.d.ts +17 -0
- package/dist/context-manager.d.ts.map +1 -0
- package/dist/context-manager.js +123 -0
- package/dist/context-manager.js.map +1 -0
- package/dist/credentials.d.ts +24 -0
- package/dist/credentials.d.ts.map +1 -0
- package/dist/credentials.js +80 -0
- package/dist/credentials.js.map +1 -0
- package/dist/delivery-client.d.ts +35 -0
- package/dist/delivery-client.d.ts.map +1 -0
- package/dist/delivery-client.js +231 -0
- package/dist/delivery-client.js.map +1 -0
- package/dist/endpoint-policy.d.ts +11 -0
- package/dist/endpoint-policy.d.ts.map +1 -0
- package/dist/endpoint-policy.js +107 -0
- package/dist/endpoint-policy.js.map +1 -0
- package/dist/event-watchers.d.ts +11 -0
- package/dist/event-watchers.d.ts.map +1 -0
- package/dist/event-watchers.js +24 -0
- package/dist/event-watchers.js.map +1 -0
- package/dist/exec-state.d.ts +37 -0
- package/dist/exec-state.d.ts.map +1 -0
- package/dist/exec-state.js +53 -0
- package/dist/exec-state.js.map +1 -0
- package/dist/file-delivery.d.ts +98 -0
- package/dist/file-delivery.d.ts.map +1 -0
- package/dist/file-delivery.js +473 -0
- package/dist/file-delivery.js.map +1 -0
- package/dist/handshake-watcher.d.ts +31 -0
- package/dist/handshake-watcher.d.ts.map +1 -0
- package/dist/handshake-watcher.js +157 -0
- package/dist/handshake-watcher.js.map +1 -0
- package/dist/hire-listener.d.ts +32 -0
- package/dist/hire-listener.d.ts.map +1 -0
- package/dist/hire-listener.js +237 -0
- package/dist/hire-listener.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +182 -0
- package/dist/index.js.map +1 -0
- package/dist/job-lifecycle.d.ts +62 -0
- package/dist/job-lifecycle.d.ts.map +1 -0
- package/dist/job-lifecycle.js +201 -0
- package/dist/job-lifecycle.js.map +1 -0
- package/dist/notify.d.ts +51 -0
- package/dist/notify.d.ts.map +1 -0
- package/dist/notify.js +276 -0
- package/dist/notify.js.map +1 -0
- package/dist/permission-gate.d.ts +30 -0
- package/dist/permission-gate.d.ts.map +1 -0
- package/dist/permission-gate.js +180 -0
- package/dist/permission-gate.js.map +1 -0
- package/dist/prompt-guard.d.ts +18 -0
- package/dist/prompt-guard.d.ts.map +1 -0
- package/dist/prompt-guard.js +70 -0
- package/dist/prompt-guard.js.map +1 -0
- package/dist/server.d.ts +27 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +1956 -0
- package/dist/server.js.map +1 -0
- package/dist/session-manager.d.ts +55 -0
- package/dist/session-manager.d.ts.map +1 -0
- package/dist/session-manager.js +139 -0
- package/dist/session-manager.js.map +1 -0
- package/dist/signer.d.ts +19 -0
- package/dist/signer.d.ts.map +1 -0
- package/dist/signer.js +195 -0
- package/dist/signer.js.map +1 -0
- package/dist/token-metering.d.ts +42 -0
- package/dist/token-metering.d.ts.map +1 -0
- package/dist/token-metering.js +178 -0
- package/dist/token-metering.js.map +1 -0
- package/dist/userops.d.ts +24 -0
- package/dist/userops.d.ts.map +1 -0
- package/dist/userops.js +156 -0
- package/dist/userops.js.map +1 -0
- package/dist/wallet-monitor.d.ts +16 -0
- package/dist/wallet-monitor.d.ts.map +1 -0
- package/dist/wallet-monitor.js +57 -0
- package/dist/wallet-monitor.js.map +1 -0
- package/dist/worker-executor.d.ts +81 -0
- package/dist/worker-executor.d.ts.map +1 -0
- package/dist/worker-executor.js +527 -0
- package/dist/worker-executor.js.map +1 -0
- package/dist/worker-router.d.ts +63 -0
- package/dist/worker-router.d.ts.map +1 -0
- package/dist/worker-router.js +263 -0
- package/dist/worker-router.js.map +1 -0
- 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"}
|