@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,80 @@
|
|
|
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.CREDENTIALS_PATH = void 0;
|
|
37
|
+
exports.loadCredentials = loadCredentials;
|
|
38
|
+
exports.getEnabledProviders = getEnabledProviders;
|
|
39
|
+
exports.getDockerEnvFlags = getDockerEnvFlags;
|
|
40
|
+
exports.getProviderHosts = getProviderHosts;
|
|
41
|
+
const fs = __importStar(require("fs"));
|
|
42
|
+
const path = __importStar(require("path"));
|
|
43
|
+
const os = __importStar(require("os"));
|
|
44
|
+
exports.CREDENTIALS_PATH = path.join(os.homedir(), ".arc402", "worker", "credentials.toml");
|
|
45
|
+
async function loadCredentials() {
|
|
46
|
+
if (!fs.existsSync(exports.CREDENTIALS_PATH))
|
|
47
|
+
return null;
|
|
48
|
+
const { parse } = await Promise.resolve().then(() => __importStar(require("smol-toml")));
|
|
49
|
+
const raw = fs.readFileSync(exports.CREDENTIALS_PATH, "utf-8");
|
|
50
|
+
return parse(raw);
|
|
51
|
+
}
|
|
52
|
+
async function getEnabledProviders() {
|
|
53
|
+
const creds = await loadCredentials();
|
|
54
|
+
if (!creds?.providers)
|
|
55
|
+
return [];
|
|
56
|
+
return Object.entries(creds.providers)
|
|
57
|
+
.filter(([_name, p]) => p.enabled)
|
|
58
|
+
.map(([name, p]) => ({
|
|
59
|
+
name,
|
|
60
|
+
env: p.env,
|
|
61
|
+
hosts: p.hosts || [],
|
|
62
|
+
auth: p.auth || "api_key",
|
|
63
|
+
hasKey: p.env ? !!process.env[p.env] : false,
|
|
64
|
+
}));
|
|
65
|
+
}
|
|
66
|
+
async function getDockerEnvFlags() {
|
|
67
|
+
const providers = await getEnabledProviders();
|
|
68
|
+
const flags = [];
|
|
69
|
+
for (const p of providers) {
|
|
70
|
+
if (p.env && process.env[p.env]) {
|
|
71
|
+
flags.push("-e", `${p.env}=${process.env[p.env]}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return flags;
|
|
75
|
+
}
|
|
76
|
+
async function getProviderHosts() {
|
|
77
|
+
const providers = await getEnabledProviders();
|
|
78
|
+
return providers.flatMap(p => p.hosts);
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmBA,0CAKC;AAED,kDAmBC;AAED,8CASC;AAED,4CAGC;AA7DD,uCAAyB;AACzB,2CAA6B;AAC7B,uCAAyB;AAeZ,QAAA,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,kBAAkB,CAAC,CAAC;AAE1F,KAAK,UAAU,eAAe;IACnC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,wBAAgB,CAAC;QAAE,OAAO,IAAI,CAAC;IAClD,MAAM,EAAE,KAAK,EAAE,GAAG,wDAAa,WAAW,GAAC,CAAC;IAC5C,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,wBAAgB,EAAE,OAAO,CAAC,CAAC;IACvD,OAAO,KAAK,CAAC,GAAG,CAAiC,CAAC;AACpD,CAAC;AAEM,KAAK,UAAU,mBAAmB;IAOvC,MAAM,KAAK,GAAG,MAAM,eAAe,EAAE,CAAC;IACtC,IAAI,CAAC,KAAK,EAAE,SAAS;QAAE,OAAO,EAAE,CAAC;IAEjC,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC;SACnC,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;SACjC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACnB,IAAI;QACJ,GAAG,EAAE,CAAC,CAAC,GAAG;QACV,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE;QACpB,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,SAAS;QACzB,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK;KAC7C,CAAC,CAAC,CAAC;AACR,CAAC;AAEM,KAAK,UAAU,iBAAiB;IACrC,MAAM,SAAS,GAAG,MAAM,mBAAmB,EAAE,CAAC;IAC9C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,IAAI,CAAC,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;YAChC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAEM,KAAK,UAAU,gBAAgB;IACpC,MAAM,SAAS,GAAG,MAAM,mBAAmB,EAAE,CAAC;IAC9C,OAAO,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export interface VerificationResult {
|
|
2
|
+
ok: boolean;
|
|
3
|
+
agreementId: string;
|
|
4
|
+
rootHashMatch: boolean;
|
|
5
|
+
fileResults: Array<{
|
|
6
|
+
name: string;
|
|
7
|
+
hashMatch: boolean;
|
|
8
|
+
expected: string;
|
|
9
|
+
actual: string;
|
|
10
|
+
}>;
|
|
11
|
+
error?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare class DeliveryClient {
|
|
14
|
+
private readonly autoDownload;
|
|
15
|
+
log: (entry: Record<string, unknown>) => void;
|
|
16
|
+
constructor(opts?: {
|
|
17
|
+
autoDownload?: boolean;
|
|
18
|
+
});
|
|
19
|
+
/**
|
|
20
|
+
* Handle an incoming delivery notification.
|
|
21
|
+
* If auto_download is true, downloads and verifies the files.
|
|
22
|
+
* Returns a VerificationResult.
|
|
23
|
+
*/
|
|
24
|
+
handleDeliveryNotification(params: {
|
|
25
|
+
agreementId: string;
|
|
26
|
+
deliverableHash: string;
|
|
27
|
+
filesUrl?: string;
|
|
28
|
+
}): Promise<VerificationResult | null>;
|
|
29
|
+
private deriveManifestUrl;
|
|
30
|
+
private downloadAndVerify;
|
|
31
|
+
private computeRootHash;
|
|
32
|
+
private fetchJson;
|
|
33
|
+
private fetchBytes;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=delivery-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delivery-client.d.ts","sourceRoot":"","sources":["../src/delivery-client.ts"],"names":[],"mappings":"AAyBA,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,OAAO,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,KAAK,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,OAAO,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC,CAAC;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAID,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAU;IACvC,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAY;gBAE7C,IAAI,GAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAA;KAAO;IAIjD;;;;OAIG;IACG,0BAA0B,CAAC,MAAM,EAAE;QACvC,WAAW,EAAE,MAAM,CAAC;QACpB,eAAe,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IA8EtC,OAAO,CAAC,iBAAiB;YAiBX,iBAAiB;IAuB/B,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,SAAS;IA6BjB,OAAO,CAAC,UAAU;CAiCnB"}
|
|
@@ -0,0 +1,231 @@
|
|
|
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.DeliveryClient = void 0;
|
|
37
|
+
/**
|
|
38
|
+
* ARC-402 Delivery Client
|
|
39
|
+
*
|
|
40
|
+
* When this agent receives a /delivery notification with a files_url, this
|
|
41
|
+
* module fetches the manifest, downloads each file, verifies all keccak256
|
|
42
|
+
* hashes, and verifies the root hash against the on-chain delivery hash.
|
|
43
|
+
*
|
|
44
|
+
* Flow:
|
|
45
|
+
* 1. Receive POST /delivery { agreementId, deliverableHash, files_url }
|
|
46
|
+
* 2. Fetch manifest from <files_url base>/manifest
|
|
47
|
+
* 3. Download each file to local job dir
|
|
48
|
+
* 4. Verify keccak256 of each file matches manifest
|
|
49
|
+
* 5. Verify root hash matches on-chain deliverableHash
|
|
50
|
+
* 6. Return verification result
|
|
51
|
+
*/
|
|
52
|
+
const fs = __importStar(require("fs"));
|
|
53
|
+
const path = __importStar(require("path"));
|
|
54
|
+
const http = __importStar(require("http"));
|
|
55
|
+
const https = __importStar(require("https"));
|
|
56
|
+
const ethers_1 = require("ethers");
|
|
57
|
+
const job_lifecycle_js_1 = require("./job-lifecycle.js");
|
|
58
|
+
// ─── DeliveryClient ───────────────────────────────────────────────────────────
|
|
59
|
+
class DeliveryClient {
|
|
60
|
+
constructor(opts = {}) {
|
|
61
|
+
this.log = () => { };
|
|
62
|
+
this.autoDownload = opts.autoDownload ?? true;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Handle an incoming delivery notification.
|
|
66
|
+
* If auto_download is true, downloads and verifies the files.
|
|
67
|
+
* Returns a VerificationResult.
|
|
68
|
+
*/
|
|
69
|
+
async handleDeliveryNotification(params) {
|
|
70
|
+
const { agreementId, deliverableHash, filesUrl } = params;
|
|
71
|
+
if (!this.autoDownload) {
|
|
72
|
+
this.log({ event: "delivery_client_skipped", agreement_id: agreementId, reason: "auto_download_disabled" });
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
if (!filesUrl) {
|
|
76
|
+
this.log({ event: "delivery_client_skipped", agreement_id: agreementId, reason: "no_files_url" });
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
this.log({ event: "delivery_download_start", agreement_id: agreementId, files_url: filesUrl });
|
|
80
|
+
try {
|
|
81
|
+
// Derive manifest URL from files_url
|
|
82
|
+
// files_url = https://host/job/abc/files → manifest = https://host/job/abc/manifest
|
|
83
|
+
const manifestUrl = this.deriveManifestUrl(filesUrl);
|
|
84
|
+
// Fetch manifest
|
|
85
|
+
const manifest = await this.fetchJson(manifestUrl);
|
|
86
|
+
this.log({ event: "manifest_fetched", agreement_id: agreementId, file_count: manifest.files.length, root_hash: manifest.root_hash });
|
|
87
|
+
// Create local job directory for client
|
|
88
|
+
const jobDir = (0, job_lifecycle_js_1.createJobDirectory)(agreementId);
|
|
89
|
+
// Download and verify each file
|
|
90
|
+
const fileResults = [];
|
|
91
|
+
let allFilesMatch = true;
|
|
92
|
+
for (const fileEntry of manifest.files) {
|
|
93
|
+
const fileUrl = `${filesUrl.replace(/\/$/, "")}/${encodeURIComponent(fileEntry.name)}`;
|
|
94
|
+
const result = await this.downloadAndVerify(fileUrl, fileEntry, jobDir);
|
|
95
|
+
fileResults.push(result);
|
|
96
|
+
if (!result.hashMatch)
|
|
97
|
+
allFilesMatch = false;
|
|
98
|
+
}
|
|
99
|
+
// Verify root hash
|
|
100
|
+
const actualRootHash = this.computeRootHash(manifest.files.map(f => f.hash));
|
|
101
|
+
const rootHashMatch = actualRootHash.toLowerCase() === deliverableHash.toLowerCase() &&
|
|
102
|
+
actualRootHash.toLowerCase() === manifest.root_hash.toLowerCase();
|
|
103
|
+
const ok = allFilesMatch && rootHashMatch;
|
|
104
|
+
const result = {
|
|
105
|
+
ok,
|
|
106
|
+
agreementId,
|
|
107
|
+
rootHashMatch,
|
|
108
|
+
fileResults,
|
|
109
|
+
};
|
|
110
|
+
this.log({
|
|
111
|
+
event: "delivery_verified",
|
|
112
|
+
agreement_id: agreementId,
|
|
113
|
+
ok,
|
|
114
|
+
root_hash_match: rootHashMatch,
|
|
115
|
+
files_verified: fileResults.length,
|
|
116
|
+
files_ok: fileResults.filter(f => f.hashMatch).length,
|
|
117
|
+
});
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
120
|
+
catch (err) {
|
|
121
|
+
const error = String(err instanceof Error ? err.message : err);
|
|
122
|
+
this.log({ event: "delivery_verify_error", agreement_id: agreementId, error });
|
|
123
|
+
return {
|
|
124
|
+
ok: false,
|
|
125
|
+
agreementId,
|
|
126
|
+
rootHashMatch: false,
|
|
127
|
+
fileResults: [],
|
|
128
|
+
error,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// ── Private helpers ───────────────────────────────────────────────────────
|
|
133
|
+
deriveManifestUrl(filesUrl) {
|
|
134
|
+
// Strip trailing slash
|
|
135
|
+
const base = filesUrl.replace(/\/$/, "");
|
|
136
|
+
// Replace /files at end with /manifest, or append /manifest
|
|
137
|
+
if (base.endsWith("/files")) {
|
|
138
|
+
return base.slice(0, -6) + "/manifest";
|
|
139
|
+
}
|
|
140
|
+
// Fallback: try stripping /files/ prefix from last segment
|
|
141
|
+
const parts = base.split("/");
|
|
142
|
+
const lastPart = parts[parts.length - 1];
|
|
143
|
+
if (lastPart === "files") {
|
|
144
|
+
parts[parts.length - 1] = "manifest";
|
|
145
|
+
return parts.join("/");
|
|
146
|
+
}
|
|
147
|
+
return base + "/manifest";
|
|
148
|
+
}
|
|
149
|
+
async downloadAndVerify(url, expected, destDir) {
|
|
150
|
+
const data = await this.fetchBytes(url);
|
|
151
|
+
const actual = ethers_1.ethers.keccak256(data);
|
|
152
|
+
const hashMatch = actual.toLowerCase() === expected.hash.toLowerCase();
|
|
153
|
+
if (hashMatch) {
|
|
154
|
+
// Write to job dir
|
|
155
|
+
const destPath = path.join(destDir, path.basename(expected.name));
|
|
156
|
+
fs.writeFileSync(destPath, data);
|
|
157
|
+
}
|
|
158
|
+
return {
|
|
159
|
+
name: expected.name,
|
|
160
|
+
hashMatch,
|
|
161
|
+
expected: expected.hash,
|
|
162
|
+
actual,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
computeRootHash(fileHashes) {
|
|
166
|
+
if (fileHashes.length === 0) {
|
|
167
|
+
return ethers_1.ethers.keccak256(new Uint8Array(0));
|
|
168
|
+
}
|
|
169
|
+
const sorted = [...fileHashes].sort();
|
|
170
|
+
const allBytes = Buffer.concat(sorted.map(h => Buffer.from(ethers_1.ethers.getBytes(h))));
|
|
171
|
+
return ethers_1.ethers.keccak256(allBytes);
|
|
172
|
+
}
|
|
173
|
+
fetchJson(url) {
|
|
174
|
+
return new Promise((resolve, reject) => {
|
|
175
|
+
const parsed = new URL(url);
|
|
176
|
+
const mod = parsed.protocol === "https:" ? https : http;
|
|
177
|
+
const req = mod.get(url, { headers: { "Accept": "application/json" } }, (res) => {
|
|
178
|
+
if (res.statusCode !== 200) {
|
|
179
|
+
reject(new Error(`fetch_manifest_failed: HTTP ${res.statusCode} for ${url}`));
|
|
180
|
+
res.resume();
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
let raw = "";
|
|
184
|
+
res.on("data", (c) => { raw += c.toString(); });
|
|
185
|
+
res.on("end", () => {
|
|
186
|
+
try {
|
|
187
|
+
resolve(JSON.parse(raw));
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
reject(new Error(`invalid_manifest_json from ${url}`));
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
req.on("error", (err) => reject(new Error(`network_error: ${err.message}`)));
|
|
195
|
+
req.setTimeout(30000, () => {
|
|
196
|
+
req.destroy(new Error("fetch_timeout"));
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
fetchBytes(url) {
|
|
201
|
+
return new Promise((resolve, reject) => {
|
|
202
|
+
const parsed = new URL(url);
|
|
203
|
+
const mod = parsed.protocol === "https:" ? https : http;
|
|
204
|
+
const MAX_FILE_BYTES = 200 * 1024 * 1024; // 200MB hard cap for downloads
|
|
205
|
+
const req = mod.get(url, (res) => {
|
|
206
|
+
if (res.statusCode !== 200) {
|
|
207
|
+
reject(new Error(`fetch_file_failed: HTTP ${res.statusCode} for ${url}`));
|
|
208
|
+
res.resume();
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
const chunks = [];
|
|
212
|
+
let total = 0;
|
|
213
|
+
res.on("data", (chunk) => {
|
|
214
|
+
total += chunk.length;
|
|
215
|
+
if (total > MAX_FILE_BYTES) {
|
|
216
|
+
req.destroy(new Error("file_too_large"));
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
chunks.push(chunk);
|
|
220
|
+
});
|
|
221
|
+
res.on("end", () => resolve(Buffer.concat(chunks)));
|
|
222
|
+
});
|
|
223
|
+
req.on("error", (err) => reject(new Error(`network_error: ${err.message}`)));
|
|
224
|
+
req.setTimeout(120000, () => {
|
|
225
|
+
req.destroy(new Error("download_timeout"));
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
exports.DeliveryClient = DeliveryClient;
|
|
231
|
+
//# sourceMappingURL=delivery-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delivery-client.js","sourceRoot":"","sources":["../src/delivery-client.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;;GAcG;AACH,uCAAyB;AACzB,2CAA6B;AAC7B,2CAA6B;AAC7B,6CAA+B;AAC/B,mCAAgC;AAChC,yDAAwD;AAkBxD,iFAAiF;AAEjF,MAAa,cAAc;IAIzB,YAAY,OAAmC,EAAE;QAFjD,QAAG,GAA6C,GAAG,EAAE,GAAE,CAAC,CAAC;QAGvD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC;IAChD,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,0BAA0B,CAAC,MAIhC;QACC,MAAM,EAAE,WAAW,EAAE,eAAe,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC;QAE1D,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YACvB,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,yBAAyB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE,wBAAwB,EAAE,CAAC,CAAC;YAC5G,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,yBAAyB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC;YAClG,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,yBAAyB,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;QAE/F,IAAI,CAAC;YACH,qCAAqC;YACrC,qFAAqF;YACrF,MAAM,WAAW,GAAG,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;YAErD,iBAAiB;YACjB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAmB,WAAW,CAAC,CAAC;YACrE,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC;YAErI,wCAAwC;YACxC,MAAM,MAAM,GAAG,IAAA,qCAAkB,EAAC,WAAW,CAAC,CAAC;YAE/C,gCAAgC;YAChC,MAAM,WAAW,GAAsC,EAAE,CAAC;YAC1D,IAAI,aAAa,GAAG,IAAI,CAAC;YAEzB,KAAK,MAAM,SAAS,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;gBACvC,MAAM,OAAO,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,kBAAkB,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;gBACvF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;gBACxE,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACzB,IAAI,CAAC,MAAM,CAAC,SAAS;oBAAE,aAAa,GAAG,KAAK,CAAC;YAC/C,CAAC;YAED,mBAAmB;YACnB,MAAM,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YAC7E,MAAM,aAAa,GAAG,cAAc,CAAC,WAAW,EAAE,KAAK,eAAe,CAAC,WAAW,EAAE;gBAC/D,cAAc,CAAC,WAAW,EAAE,KAAK,QAAQ,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;YAEvF,MAAM,EAAE,GAAG,aAAa,IAAI,aAAa,CAAC;YAE1C,MAAM,MAAM,GAAuB;gBACjC,EAAE;gBACF,WAAW;gBACX,aAAa;gBACb,WAAW;aACZ,CAAC;YAEF,IAAI,CAAC,GAAG,CAAC;gBACP,KAAK,EAAE,mBAAmB;gBAC1B,YAAY,EAAE,WAAW;gBACzB,EAAE;gBACF,eAAe,EAAE,aAAa;gBAC9B,cAAc,EAAE,WAAW,CAAC,MAAM;gBAClC,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM;aACtD,CAAC,CAAC;YAEH,OAAO,MAAM,CAAC;QAEhB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YAC/D,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,uBAAuB,EAAE,YAAY,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC;YAC/E,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,WAAW;gBACX,aAAa,EAAE,KAAK;gBACpB,WAAW,EAAE,EAAE;gBACf,KAAK;aACN,CAAC;QACJ,CAAC;IACH,CAAC;IAED,6EAA6E;IAErE,iBAAiB,CAAC,QAAgB;QACxC,uBAAuB;QACvB,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACzC,4DAA4D;QAC5D,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC;QACzC,CAAC;QACD,2DAA2D;QAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACzC,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YACzB,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC;YACrC,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC;QACD,OAAO,IAAI,GAAG,WAAW,CAAC;IAC5B,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAC7B,GAAW,EACX,QAA2B,EAC3B,OAAe;QAEf,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,eAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACtC,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,EAAE,KAAK,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QAEvE,IAAI,SAAS,EAAE,CAAC;YACd,mBAAmB;YACnB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;YAClE,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACnC,CAAC;QAED,OAAO;YACL,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,SAAS;YACT,QAAQ,EAAE,QAAQ,CAAC,IAAI;YACvB,MAAM;SACP,CAAC;IACJ,CAAC;IAEO,eAAe,CAAC,UAAoB;QAC1C,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,OAAO,eAAM,CAAC,SAAS,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC;QACD,MAAM,MAAM,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC;QACtC,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,eAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACjF,OAAO,eAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IACpC,CAAC;IAEO,SAAS,CAAI,GAAW;QAC9B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;YAC5B,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;YAExD,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,kBAAkB,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE;gBAC9E,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;oBAC3B,MAAM,CAAC,IAAI,KAAK,CAAC,+BAA+B,GAAG,CAAC,UAAU,QAAQ,GAAG,EAAE,CAAC,CAAC,CAAC;oBAC9E,GAAG,CAAC,MAAM,EAAE,CAAC;oBACb,OAAO;gBACT,CAAC;gBACD,IAAI,GAAG,GAAG,EAAE,CAAC;gBACb,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,GAAG,GAAG,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;gBACxD,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;oBACjB,IAAI,CAAC;wBACH,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAM,CAAC,CAAC;oBAChC,CAAC;oBAAC,MAAM,CAAC;wBACP,MAAM,CAAC,IAAI,KAAK,CAAC,8BAA8B,GAAG,EAAE,CAAC,CAAC,CAAC;oBACzD,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,kBAAkB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;YAC7E,GAAG,CAAC,UAAU,CAAC,KAAM,EAAE,GAAG,EAAE;gBAC1B,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;YAC1C,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,UAAU,CAAC,GAAW;QAC5B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;YAC5B,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;YACxD,MAAM,cAAc,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,+BAA+B;YAEzE,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE;gBAC/B,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;oBAC3B,MAAM,CAAC,IAAI,KAAK,CAAC,2BAA2B,GAAG,CAAC,UAAU,QAAQ,GAAG,EAAE,CAAC,CAAC,CAAC;oBAC1E,GAAG,CAAC,MAAM,EAAE,CAAC;oBACb,OAAO;gBACT,CAAC;gBACD,MAAM,MAAM,GAAa,EAAE,CAAC;gBAC5B,IAAI,KAAK,GAAG,CAAC,CAAC;gBAEd,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;oBAC/B,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC;oBACtB,IAAI,KAAK,GAAG,cAAc,EAAE,CAAC;wBAC3B,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC;wBACzC,OAAO;oBACT,CAAC;oBACD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACrB,CAAC,CAAC,CAAC;gBAEH,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACtD,CAAC,CAAC,CAAC;YAEH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,kBAAkB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;YAC7E,GAAG,CAAC,UAAU,CAAC,MAAO,EAAE,GAAG,EAAE;gBAC3B,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC;YAC7C,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AA9MD,wCA8MC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { IncomingHttpHeaders } from "http";
|
|
2
|
+
export declare function resolveJobId(headers: IncomingHttpHeaders): string | null;
|
|
3
|
+
export declare function hasExplicitCommerceDelegation(payload: unknown, endpoint: string): boolean;
|
|
4
|
+
export declare class EndpointPolicy {
|
|
5
|
+
private readonly activeJobLocks;
|
|
6
|
+
lockForJob(jobId: string): void;
|
|
7
|
+
grantCommerceDelegate(jobId: string): void;
|
|
8
|
+
releaseJob(jobId: string): void;
|
|
9
|
+
isAllowed(jobId: string | null, endpoint: string): boolean;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=endpoint-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"endpoint-policy.d.ts","sourceRoot":"","sources":["../src/endpoint-policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,MAAM,CAAC;AAkChD,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,GAAG,IAAI,CAKxE;AAED,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAkCzF;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAkC;IAEjE,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI/B,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI1C,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI/B,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;CAU3D"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EndpointPolicy = void 0;
|
|
4
|
+
exports.resolveJobId = resolveJobId;
|
|
5
|
+
exports.hasExplicitCommerceDelegation = hasExplicitCommerceDelegation;
|
|
6
|
+
const LOCKED_COMMERCE_ENDPOINTS = new Set([
|
|
7
|
+
"/hire",
|
|
8
|
+
"/subscribe",
|
|
9
|
+
"/compute/propose",
|
|
10
|
+
"/compute/hire",
|
|
11
|
+
]);
|
|
12
|
+
function isTruthy(value) {
|
|
13
|
+
if (typeof value === "boolean") {
|
|
14
|
+
return value;
|
|
15
|
+
}
|
|
16
|
+
if (typeof value === "number") {
|
|
17
|
+
return value !== 0;
|
|
18
|
+
}
|
|
19
|
+
if (typeof value === "string") {
|
|
20
|
+
return ["1", "true", "yes", "allow", "granted", "*"].includes(value.trim().toLowerCase());
|
|
21
|
+
}
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
function objectHasEndpointDelegate(value, endpoint) {
|
|
25
|
+
if (isTruthy(value.commerce))
|
|
26
|
+
return true;
|
|
27
|
+
if (isTruthy(value.allowCommerce))
|
|
28
|
+
return true;
|
|
29
|
+
if (isTruthy(value.allow_commerce))
|
|
30
|
+
return true;
|
|
31
|
+
if (isTruthy(value.allowed))
|
|
32
|
+
return true;
|
|
33
|
+
if (isTruthy(value.all))
|
|
34
|
+
return true;
|
|
35
|
+
if (Array.isArray(value.endpoints)) {
|
|
36
|
+
return value.endpoints.some((entry) => typeof entry === "string" && (entry === endpoint || entry === "*"));
|
|
37
|
+
}
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
function resolveJobId(headers) {
|
|
41
|
+
const raw = headers["x-arc402-job-id"];
|
|
42
|
+
if (typeof raw === "string" && raw.trim())
|
|
43
|
+
return raw.trim();
|
|
44
|
+
if (Array.isArray(raw) && raw[0]?.trim())
|
|
45
|
+
return raw[0].trim();
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
function hasExplicitCommerceDelegation(payload, endpoint) {
|
|
49
|
+
if (!payload || typeof payload !== "object") {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
const record = payload;
|
|
53
|
+
const directKeys = [
|
|
54
|
+
"commerceDelegation",
|
|
55
|
+
"grantCommerceDelegation",
|
|
56
|
+
"allowCommerceDelegation",
|
|
57
|
+
"allow_commerce_delegation",
|
|
58
|
+
"commerceDelegate",
|
|
59
|
+
];
|
|
60
|
+
for (const key of directKeys) {
|
|
61
|
+
if (isTruthy(record[key])) {
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
const value = record[key];
|
|
65
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
66
|
+
if (objectHasEndpointDelegate(value, endpoint)) {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (Array.isArray(record.delegatedEndpoints)) {
|
|
72
|
+
return record.delegatedEndpoints.some((value) => typeof value === "string" && (value === endpoint || value === "*"));
|
|
73
|
+
}
|
|
74
|
+
if (Array.isArray(record.allowedEndpoints)) {
|
|
75
|
+
return record.allowedEndpoints.some((value) => typeof value === "string" && (value === endpoint || value === "*"));
|
|
76
|
+
}
|
|
77
|
+
if (record.delegation && typeof record.delegation === "object" && !Array.isArray(record.delegation)) {
|
|
78
|
+
return objectHasEndpointDelegate(record.delegation, endpoint);
|
|
79
|
+
}
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
class EndpointPolicy {
|
|
83
|
+
constructor() {
|
|
84
|
+
this.activeJobLocks = new Map();
|
|
85
|
+
}
|
|
86
|
+
lockForJob(jobId) {
|
|
87
|
+
this.activeJobLocks.set(jobId, new Set(LOCKED_COMMERCE_ENDPOINTS));
|
|
88
|
+
}
|
|
89
|
+
grantCommerceDelegate(jobId) {
|
|
90
|
+
this.activeJobLocks.get(jobId)?.clear();
|
|
91
|
+
}
|
|
92
|
+
releaseJob(jobId) {
|
|
93
|
+
this.activeJobLocks.delete(jobId);
|
|
94
|
+
}
|
|
95
|
+
isAllowed(jobId, endpoint) {
|
|
96
|
+
if (!jobId) {
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
const locks = this.activeJobLocks.get(jobId);
|
|
100
|
+
if (!locks) {
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
return !locks.has(endpoint);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
exports.EndpointPolicy = EndpointPolicy;
|
|
107
|
+
//# sourceMappingURL=endpoint-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"endpoint-policy.js","sourceRoot":"","sources":["../src/endpoint-policy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface WatcherConfig {
|
|
2
|
+
rpcUrl: string;
|
|
3
|
+
wallet: `0x${string}`;
|
|
4
|
+
chainId: number;
|
|
5
|
+
}
|
|
6
|
+
export declare class ProtocolEventWatcher {
|
|
7
|
+
constructor(_config: WatcherConfig);
|
|
8
|
+
start(): void;
|
|
9
|
+
stop(): void;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=event-watchers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-watchers.d.ts","sourceRoot":"","sources":["../src/event-watchers.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,KAAK,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,oBAAoB;gBACnB,OAAO,EAAE,aAAa;IAUlC,KAAK,IAAI,IAAI;IAIb,IAAI,IAAI,IAAI;CAGb"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ProtocolEventWatcher — on-chain event subscriptions (Spec 46 §10)
|
|
3
|
+
// TODO: implement ServiceAgreement, IntelligenceRegistry, ArenaPool event watchers
|
|
4
|
+
// TODO: emit SSE events: exec.simulated, exec.signed, exec.submitted, exec.finalized, wallet.frozen
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ProtocolEventWatcher = void 0;
|
|
7
|
+
class ProtocolEventWatcher {
|
|
8
|
+
constructor(_config) {
|
|
9
|
+
// TODO: initialize ethers provider + event subscriptions
|
|
10
|
+
}
|
|
11
|
+
// TODO: watch ServiceAgreement: ProposalCreated, ProposalAccepted, WorkDelivered, PaymentReleased
|
|
12
|
+
// TODO: watch IntelligenceRegistry: AgentRegistered, AgentUpdated
|
|
13
|
+
// TODO: watch ArenaPool: PoolDeposit, PoolWithdrawal, HandshakeSent
|
|
14
|
+
// TODO: watch wallet: frozen state via guardian on-chain event (emit wallet.frozen SSE)
|
|
15
|
+
// TODO: watch verify window expiry for dispute evidence collection
|
|
16
|
+
start() {
|
|
17
|
+
// TODO: begin polling / websocket subscription
|
|
18
|
+
}
|
|
19
|
+
stop() {
|
|
20
|
+
// TODO: clean up subscriptions
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.ProtocolEventWatcher = ProtocolEventWatcher;
|
|
24
|
+
//# sourceMappingURL=event-watchers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-watchers.js","sourceRoot":"","sources":["../src/event-watchers.ts"],"names":[],"mappings":";AAAA,oEAAoE;AACpE,mFAAmF;AACnF,oGAAoG;;;AAQpG,MAAa,oBAAoB;IAC/B,YAAY,OAAsB;QAChC,yDAAyD;IAC3D,CAAC;IAED,kGAAkG;IAClG,kEAAkE;IAClE,oEAAoE;IACpE,wFAAwF;IACxF,mEAAmE;IAEnE,KAAK;QACH,+CAA+C;IACjD,CAAC;IAED,IAAI;QACF,+BAA+B;IACjC,CAAC;CACF;AAlBD,oDAkBC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ExecState machine — UserOp execution lifecycle tracking.
|
|
3
|
+
* Spec 46 §16 Pattern 4.
|
|
4
|
+
* Persisted to SQLite per-transition.
|
|
5
|
+
*/
|
|
6
|
+
export declare enum ExecState {
|
|
7
|
+
RECEIVED = "received",
|
|
8
|
+
SESSION_OK = "session_ok",
|
|
9
|
+
POLICY_OK = "policy_ok",
|
|
10
|
+
BUILT = "built",
|
|
11
|
+
SIMULATED = "simulated",
|
|
12
|
+
SIGNED = "signed",
|
|
13
|
+
SUBMITTED = "submitted",
|
|
14
|
+
INCLUDED = "included",
|
|
15
|
+
FINALIZED = "finalized",
|
|
16
|
+
REJECTED = "rejected"
|
|
17
|
+
}
|
|
18
|
+
export declare const ALLOWED_TRANSITIONS: Record<ExecState, ExecState[]>;
|
|
19
|
+
export interface ExecRecord {
|
|
20
|
+
requestId: string;
|
|
21
|
+
sessionId: string;
|
|
22
|
+
wallet: string;
|
|
23
|
+
target: string;
|
|
24
|
+
calldataHash: string;
|
|
25
|
+
state: ExecState;
|
|
26
|
+
reason?: string;
|
|
27
|
+
timestamp: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Validate a state transition. Throws if the transition is not allowed.
|
|
31
|
+
*/
|
|
32
|
+
export declare function validateTransition(from: ExecState, to: ExecState): void;
|
|
33
|
+
/**
|
|
34
|
+
* Returns true if the given state is a terminal state (no further transitions).
|
|
35
|
+
*/
|
|
36
|
+
export declare function isTerminal(state: ExecState): boolean;
|
|
37
|
+
//# sourceMappingURL=exec-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec-state.d.ts","sourceRoot":"","sources":["../src/exec-state.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,oBAAY,SAAS;IACnB,QAAQ,aAAc;IACtB,UAAU,eAAe;IACzB,SAAS,cAAe;IACxB,KAAK,UAAe;IACpB,SAAS,cAAe;IACxB,MAAM,WAAe;IACrB,SAAS,cAAe;IACxB,QAAQ,aAAe;IACvB,SAAS,cAAe;IACxB,QAAQ,aAAe;CACxB;AAGD,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,SAAS,EAAE,SAAS,EAAE,CAW9D,CAAC;AAGF,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,SAAS,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,SAAS,GAAG,IAAI,CAQvE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAEpD"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ExecState machine — UserOp execution lifecycle tracking.
|
|
4
|
+
* Spec 46 §16 Pattern 4.
|
|
5
|
+
* Persisted to SQLite per-transition.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.ALLOWED_TRANSITIONS = exports.ExecState = void 0;
|
|
9
|
+
exports.validateTransition = validateTransition;
|
|
10
|
+
exports.isTerminal = isTerminal;
|
|
11
|
+
var ExecState;
|
|
12
|
+
(function (ExecState) {
|
|
13
|
+
ExecState["RECEIVED"] = "received";
|
|
14
|
+
ExecState["SESSION_OK"] = "session_ok";
|
|
15
|
+
ExecState["POLICY_OK"] = "policy_ok";
|
|
16
|
+
ExecState["BUILT"] = "built";
|
|
17
|
+
ExecState["SIMULATED"] = "simulated";
|
|
18
|
+
ExecState["SIGNED"] = "signed";
|
|
19
|
+
ExecState["SUBMITTED"] = "submitted";
|
|
20
|
+
ExecState["INCLUDED"] = "included";
|
|
21
|
+
ExecState["FINALIZED"] = "finalized";
|
|
22
|
+
ExecState["REJECTED"] = "rejected";
|
|
23
|
+
})(ExecState || (exports.ExecState = ExecState = {}));
|
|
24
|
+
// Allowed transitions only — any other transition throws
|
|
25
|
+
exports.ALLOWED_TRANSITIONS = {
|
|
26
|
+
[ExecState.RECEIVED]: [ExecState.SESSION_OK, ExecState.REJECTED],
|
|
27
|
+
[ExecState.SESSION_OK]: [ExecState.POLICY_OK, ExecState.REJECTED],
|
|
28
|
+
[ExecState.POLICY_OK]: [ExecState.BUILT, ExecState.REJECTED],
|
|
29
|
+
[ExecState.BUILT]: [ExecState.SIMULATED, ExecState.REJECTED],
|
|
30
|
+
[ExecState.SIMULATED]: [ExecState.SIGNED, ExecState.REJECTED], // ← only state that may call signer
|
|
31
|
+
[ExecState.SIGNED]: [ExecState.SUBMITTED, ExecState.REJECTED],
|
|
32
|
+
[ExecState.SUBMITTED]: [ExecState.INCLUDED, ExecState.REJECTED],
|
|
33
|
+
[ExecState.INCLUDED]: [ExecState.FINALIZED, ExecState.REJECTED],
|
|
34
|
+
[ExecState.FINALIZED]: [],
|
|
35
|
+
[ExecState.REJECTED]: [],
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Validate a state transition. Throws if the transition is not allowed.
|
|
39
|
+
*/
|
|
40
|
+
function validateTransition(from, to) {
|
|
41
|
+
const allowed = exports.ALLOWED_TRANSITIONS[from];
|
|
42
|
+
if (!allowed.includes(to)) {
|
|
43
|
+
throw new Error(`Invalid ExecState transition: ${from} → ${to}. ` +
|
|
44
|
+
`Allowed from ${from}: [${allowed.join(", ") || "none"}]`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Returns true if the given state is a terminal state (no further transitions).
|
|
49
|
+
*/
|
|
50
|
+
function isTerminal(state) {
|
|
51
|
+
return exports.ALLOWED_TRANSITIONS[state].length === 0;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=exec-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec-state.js","sourceRoot":"","sources":["../src/exec-state.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AA4CH,gDAQC;AAKD,gCAEC;AAzDD,IAAY,SAWX;AAXD,WAAY,SAAS;IACnB,kCAAsB,CAAA;IACtB,sCAAyB,CAAA;IACzB,oCAAwB,CAAA;IACxB,4BAAoB,CAAA;IACpB,oCAAwB,CAAA;IACxB,8BAAqB,CAAA;IACrB,oCAAwB,CAAA;IACxB,kCAAuB,CAAA;IACvB,oCAAwB,CAAA;IACxB,kCAAuB,CAAA;AACzB,CAAC,EAXW,SAAS,yBAAT,SAAS,QAWpB;AAED,yDAAyD;AAC5C,QAAA,mBAAmB,GAAmC;IACjE,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAI,CAAC,SAAS,CAAC,UAAU,EAAE,SAAS,CAAC,QAAQ,CAAC;IAClE,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,EAAG,SAAS,CAAC,QAAQ,CAAC;IAClE,CAAC,SAAS,CAAC,SAAS,CAAC,EAAG,CAAC,SAAS,CAAC,KAAK,EAAO,SAAS,CAAC,QAAQ,CAAC;IAClE,CAAC,SAAS,CAAC,KAAK,CAAC,EAAO,CAAC,SAAS,CAAC,SAAS,EAAG,SAAS,CAAC,QAAQ,CAAC;IAClE,CAAC,SAAS,CAAC,SAAS,CAAC,EAAG,CAAC,SAAS,CAAC,MAAM,EAAM,SAAS,CAAC,QAAQ,CAAC,EAAG,oCAAoC;IACzG,CAAC,SAAS,CAAC,MAAM,CAAC,EAAM,CAAC,SAAS,CAAC,SAAS,EAAG,SAAS,CAAC,QAAQ,CAAC;IAClE,CAAC,SAAS,CAAC,SAAS,CAAC,EAAG,CAAC,SAAS,CAAC,QAAQ,EAAI,SAAS,CAAC,QAAQ,CAAC;IAClE,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAI,CAAC,SAAS,CAAC,SAAS,EAAG,SAAS,CAAC,QAAQ,CAAC;IAClE,CAAC,SAAS,CAAC,SAAS,CAAC,EAAG,EAAE;IAC1B,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAI,EAAE;CAC3B,CAAC;AAcF;;GAEG;AACH,SAAgB,kBAAkB,CAAC,IAAe,EAAE,EAAa;IAC/D,MAAM,OAAO,GAAG,2BAAmB,CAAC,IAAI,CAAC,CAAC;IAC1C,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CACb,iCAAiC,IAAI,MAAM,EAAE,IAAI;YACjD,gBAAgB,IAAI,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,GAAG,CAC1D,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAgB,UAAU,CAAC,KAAgB;IACzC,OAAO,2BAAmB,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;AACjD,CAAC"}
|