xoonya 2.5.0 → 2.7.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/README.md +119 -7
- package/RELEASE_NOTES.md +29 -7
- package/SERVICE_CONTRACT.md +22 -0
- package/START_HERE.md +12 -0
- package/XOONYA_NATIVE_ATOM_SPEC.md +184 -0
- package/XOONYA_NATIVE_PROOF_FORMAT.md +502 -0
- package/XOONYA_NATIVE_STANDARD_GOVERNANCE.md +116 -0
- package/bin/xoonya-first-run.js +184 -0
- package/bin/xoonya.js +31 -5
- package/lib/release_history.js +29 -0
- package/package.json +11 -15
- package/proof_sdk.js +2391 -44
- package/scripts/registry_cli.js +157 -0
- package/scripts/verify_all.js +558 -0
- package/scripts/verify_examples.js +19 -0
- package/scripts/verify_integrations.js +170 -0
- package/scripts/verify_release_candidate.js +87 -0
- package/scripts/verify_service.js +2825 -0
- package/scripts/verify_tooling.js +1228 -0
- package/scripts/verify_vectors.js +164 -0
- package/server.js +125 -2
- package/vectors/adversarial-vectors.json +373 -2
- package/vectors/conformance-vectors.json +342 -1
- package/vectors/native-atom-vectors.json +101 -0
- package/vectors/native-payload-profile-vectors.json +50 -0
- package/OPERATIONS_RUNBOOK.md +0 -50
- package/OPERATOR_START_HERE.md +0 -67
- package/PROGRAM_COMPLETE_RELEASE.md +0 -52
- package/PROGRAM_STATUS.md +0 -57
- package/PUBLISH_PLAN.md +0 -14
- package/RELEASE_CHECKLIST.md +0 -16
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const assert = require("assert");
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
const sdk = require("..");
|
|
7
|
+
|
|
8
|
+
const conformanceVectors = JSON.parse(
|
|
9
|
+
fs.readFileSync(path.resolve(__dirname, "..", "vectors", "conformance-vectors.json"), "utf8")
|
|
10
|
+
);
|
|
11
|
+
const adversarialVectors = JSON.parse(
|
|
12
|
+
fs.readFileSync(path.resolve(__dirname, "..", "vectors", "adversarial-vectors.json"), "utf8")
|
|
13
|
+
);
|
|
14
|
+
const nativeAtomVectors = JSON.parse(
|
|
15
|
+
fs.readFileSync(path.resolve(__dirname, "..", "vectors", "native-atom-vectors.json"), "utf8")
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
function unique(values) {
|
|
19
|
+
return Array.from(new Set(values.filter(Boolean))).sort();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function runVectorVerification() {
|
|
23
|
+
assert.strictEqual(conformanceVectors.version, "proof-conformance-v1", "conformance vector version mismatch");
|
|
24
|
+
assert.strictEqual(adversarialVectors.version, "proof-adversarial-v1", "adversarial vector version mismatch");
|
|
25
|
+
assert.strictEqual(nativeAtomVectors.version, "xoonya-native-atom-vectors-v1", "native atom vector version mismatch");
|
|
26
|
+
|
|
27
|
+
const conformanceResults = [];
|
|
28
|
+
for (const vector of conformanceVectors.vectors) {
|
|
29
|
+
const eventCommitment = sdk.hashEvent(vector.event);
|
|
30
|
+
assert.strictEqual(eventCommitment, vector.expected.event_commitment, `${vector.id} event commitment mismatch`);
|
|
31
|
+
|
|
32
|
+
const receipt = sdk.emitReceipt(vector.event, vector.receipt_options || {});
|
|
33
|
+
assert.deepStrictEqual(receipt, vector.expected.receipt, `${vector.id} receipt mismatch`);
|
|
34
|
+
|
|
35
|
+
const bundle = sdk.buildProofBundle({
|
|
36
|
+
ceb: vector.event,
|
|
37
|
+
receipt,
|
|
38
|
+
anchors: Array.isArray(vector.anchors) ? vector.anchors : undefined
|
|
39
|
+
});
|
|
40
|
+
assert.strictEqual(bundle.version, vector.expected.proof_bundle_version, `${vector.id} proof bundle version mismatch`);
|
|
41
|
+
const verification = sdk.verifyProofBundle(bundle);
|
|
42
|
+
assert.strictEqual(verification.valid, true, `${vector.id} proof bundle should verify`);
|
|
43
|
+
conformanceResults.push({
|
|
44
|
+
id: vector.id,
|
|
45
|
+
verification_method: verification.verification_method,
|
|
46
|
+
verification_state: verification.verification_state
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const adversarialResults = [];
|
|
51
|
+
for (const vector of adversarialVectors.vectors) {
|
|
52
|
+
if (vector.kind === "canonicalize_event_error") {
|
|
53
|
+
assert.throws(
|
|
54
|
+
() => sdk.canonicalizeEvent(vector.event),
|
|
55
|
+
(error) => error && error.message === vector.expected_reason,
|
|
56
|
+
`${vector.id} should throw expected reason`
|
|
57
|
+
);
|
|
58
|
+
adversarialResults.push({
|
|
59
|
+
id: vector.id,
|
|
60
|
+
kind: vector.kind,
|
|
61
|
+
reason: vector.expected_reason
|
|
62
|
+
});
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (vector.kind === "verify_bundle_reason") {
|
|
66
|
+
const result = sdk.verifyProofBundle(vector.bundle);
|
|
67
|
+
assert.strictEqual(result.valid, false, `${vector.id} should fail`);
|
|
68
|
+
assert.strictEqual(result.reason, vector.expected_reason, `${vector.id} failure reason mismatch`);
|
|
69
|
+
adversarialResults.push({
|
|
70
|
+
id: vector.id,
|
|
71
|
+
kind: vector.kind,
|
|
72
|
+
reason: result.reason
|
|
73
|
+
});
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
throw new Error(`${vector.id} has unsupported vector kind`);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const nativeAtomResults = [];
|
|
80
|
+
const nativeAtomPayload = Buffer.from(nativeAtomVectors.payload_ascii, "utf8");
|
|
81
|
+
for (const vector of nativeAtomVectors.vectors) {
|
|
82
|
+
const parsed = sdk.parseXoonyaNativeAtom(vector.atom_hex);
|
|
83
|
+
assert.strictEqual(parsed.atom_version, vector.atom_version, `${vector.id} atom version mismatch`);
|
|
84
|
+
assert.strictEqual(parsed.byte_length, vector.byte_length, `${vector.id} byte length mismatch`);
|
|
85
|
+
assert.strictEqual(parsed.agent_id, vector.agent_id, `${vector.id} agent id mismatch`);
|
|
86
|
+
assert.strictEqual(parsed.payload_hash_sha256, vector.payload_hash_sha256, `${vector.id} payload hash mismatch`);
|
|
87
|
+
const hasPayload = vector.payload_hash_sha256 !== "00".repeat(32);
|
|
88
|
+
const verification = sdk.verifyXoonyaNativeAtom(vector.atom_hex, {
|
|
89
|
+
identity_material_hex: nativeAtomVectors.identity_material_hex,
|
|
90
|
+
...(hasPayload ? { payload_bytes: nativeAtomPayload } : {})
|
|
91
|
+
});
|
|
92
|
+
assert.strictEqual(verification.valid, true, `${vector.id} should verify`);
|
|
93
|
+
assert.strictEqual(verification.error_code, null, `${vector.id} should not have error code`);
|
|
94
|
+
nativeAtomResults.push({
|
|
95
|
+
id: vector.id,
|
|
96
|
+
atom_version: vector.atom_version,
|
|
97
|
+
byte_length: vector.byte_length
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const nativeAtomAdversarialResults = [];
|
|
102
|
+
for (const vector of nativeAtomVectors.adversarial) {
|
|
103
|
+
const verification = sdk.verifyXoonyaNativeAtom(vector.atom_hex, {
|
|
104
|
+
identity_material_hex: vector.identity_material_hex || nativeAtomVectors.identity_material_hex,
|
|
105
|
+
...(vector.payload_ascii ? { payload_bytes: Buffer.from(vector.payload_ascii, "utf8") } : {})
|
|
106
|
+
});
|
|
107
|
+
assert.strictEqual(verification.valid, false, `${vector.id} should fail`);
|
|
108
|
+
assert.strictEqual(verification.reason, vector.expected_reason, `${vector.id} failure reason mismatch`);
|
|
109
|
+
assert.strictEqual(verification.error_code, vector.expected_error_code, `${vector.id} error code mismatch`);
|
|
110
|
+
nativeAtomAdversarialResults.push({
|
|
111
|
+
id: vector.id,
|
|
112
|
+
reason: verification.reason,
|
|
113
|
+
error_code: verification.error_code
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return {
|
|
118
|
+
ok: true,
|
|
119
|
+
product: "xoonya",
|
|
120
|
+
suite: "proof-conformance-and-adversarial-vectors",
|
|
121
|
+
conformance_version: conformanceVectors.version,
|
|
122
|
+
adversarial_version: adversarialVectors.version,
|
|
123
|
+
conformance_count: conformanceResults.length,
|
|
124
|
+
adversarial_count: adversarialResults.length,
|
|
125
|
+
native_atom_vector_count: nativeAtomResults.length,
|
|
126
|
+
native_atom_adversarial_count: nativeAtomAdversarialResults.length,
|
|
127
|
+
verification_methods: unique(conformanceResults.map((result) => result.verification_method)),
|
|
128
|
+
adversarial_reasons: unique(adversarialResults.map((result) => result.reason)),
|
|
129
|
+
native_atom_error_codes: unique(nativeAtomAdversarialResults.map((result) => result.error_code)),
|
|
130
|
+
conformance_results: conformanceResults,
|
|
131
|
+
adversarial_results: adversarialResults,
|
|
132
|
+
native_atom_results: nativeAtomResults,
|
|
133
|
+
native_atom_adversarial_results: nativeAtomAdversarialResults
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function main() {
|
|
138
|
+
const json = process.argv.includes("--json");
|
|
139
|
+
const summary = runVectorVerification();
|
|
140
|
+
if (json) {
|
|
141
|
+
process.stdout.write(`${JSON.stringify(summary, null, 2)}\n`);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
process.stdout.write(
|
|
145
|
+
[
|
|
146
|
+
"xoonya verify:vectors passed",
|
|
147
|
+
`conformance vectors: ${summary.conformance_count}`,
|
|
148
|
+
`adversarial vectors: ${summary.adversarial_count}`,
|
|
149
|
+
`native atom vectors: ${summary.native_atom_vector_count}`,
|
|
150
|
+
`native atom adversarial vectors: ${summary.native_atom_adversarial_count}`,
|
|
151
|
+
`verification methods: ${summary.verification_methods.join(", ")}`,
|
|
152
|
+
`adversarial reasons: ${summary.adversarial_reasons.join(", ")}`,
|
|
153
|
+
`native atom error codes: ${summary.native_atom_error_codes.join(", ")}`
|
|
154
|
+
].join("\n") + "\n"
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (require.main === module) {
|
|
159
|
+
main();
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
module.exports = {
|
|
163
|
+
runVectorVerification
|
|
164
|
+
};
|
package/server.js
CHANGED
|
@@ -2356,6 +2356,96 @@ async function routeRequest(req, res) {
|
|
|
2356
2356
|
return;
|
|
2357
2357
|
}
|
|
2358
2358
|
|
|
2359
|
+
if (req.method === 'GET' && url.pathname === '/v1/proof-center/native-standard') {
|
|
2360
|
+
sendJson(res, 200, proofSdk.buildXoonyaNativeProofStandard());
|
|
2361
|
+
return;
|
|
2362
|
+
}
|
|
2363
|
+
|
|
2364
|
+
if (req.method === 'GET' && url.pathname === '/v1/proof-center/native-standard/summary') {
|
|
2365
|
+
sendJson(res, 200, proofSdk.summarizeXoonyaNativeProofStandard());
|
|
2366
|
+
return;
|
|
2367
|
+
}
|
|
2368
|
+
|
|
2369
|
+
if (req.method === 'GET' && url.pathname === '/v1/proof-center/native-hybrid-readiness') {
|
|
2370
|
+
sendJson(res, 200, proofSdk.buildXoonyaNativeHybridReadinessPack());
|
|
2371
|
+
return;
|
|
2372
|
+
}
|
|
2373
|
+
|
|
2374
|
+
if (req.method === 'GET' && url.pathname === '/v1/proof-center/native-hybrid-readiness/summary') {
|
|
2375
|
+
sendJson(res, 200, proofSdk.summarizeXoonyaNativeHybridReadinessPack());
|
|
2376
|
+
return;
|
|
2377
|
+
}
|
|
2378
|
+
|
|
2379
|
+
if (req.method === 'GET' && url.pathname === '/v1/proof-center/native-standardization') {
|
|
2380
|
+
sendJson(res, 200, proofSdk.buildXoonyaNativeStandardizationPack());
|
|
2381
|
+
return;
|
|
2382
|
+
}
|
|
2383
|
+
|
|
2384
|
+
if (req.method === 'GET' && url.pathname === '/v1/proof-center/native-standardization/summary') {
|
|
2385
|
+
sendJson(res, 200, proofSdk.summarizeXoonyaNativeStandardizationPack());
|
|
2386
|
+
return;
|
|
2387
|
+
}
|
|
2388
|
+
|
|
2389
|
+
if (req.method === 'GET' && url.pathname === '/v1/proof-center/native-payload-profile') {
|
|
2390
|
+
sendJson(res, 200, proofSdk.buildXoonyaNativePayloadProfilePack());
|
|
2391
|
+
return;
|
|
2392
|
+
}
|
|
2393
|
+
|
|
2394
|
+
if (req.method === 'GET' && url.pathname === '/v1/proof-center/native-payload-profile/summary') {
|
|
2395
|
+
sendJson(res, 200, proofSdk.summarizeXoonyaNativePayloadProfilePack());
|
|
2396
|
+
return;
|
|
2397
|
+
}
|
|
2398
|
+
|
|
2399
|
+
if (req.method === 'GET' && url.pathname === '/v1/proof-center/native-line-rate-frame') {
|
|
2400
|
+
sendJson(res, 200, proofSdk.buildXoonyaNativeLineRateFramePack());
|
|
2401
|
+
return;
|
|
2402
|
+
}
|
|
2403
|
+
|
|
2404
|
+
if (req.method === 'GET' && url.pathname === '/v1/proof-center/native-line-rate-frame/summary') {
|
|
2405
|
+
sendJson(res, 200, proofSdk.summarizeXoonyaNativeLineRateFramePack());
|
|
2406
|
+
return;
|
|
2407
|
+
}
|
|
2408
|
+
|
|
2409
|
+
if (req.method === 'GET' && url.pathname === '/v1/proof-center/native-atom-spec') {
|
|
2410
|
+
sendJson(res, 200, proofSdk.buildXoonyaNativeAtomSpec());
|
|
2411
|
+
return;
|
|
2412
|
+
}
|
|
2413
|
+
|
|
2414
|
+
if (req.method === 'GET' && url.pathname === '/v1/proof-center/native-atom-spec/summary') {
|
|
2415
|
+
sendJson(res, 200, proofSdk.summarizeXoonyaNativeAtomSpec());
|
|
2416
|
+
return;
|
|
2417
|
+
}
|
|
2418
|
+
|
|
2419
|
+
if (req.method === 'GET' && url.pathname === '/v1/proof-center/native-atom-conformance') {
|
|
2420
|
+
sendJson(res, 200, proofSdk.buildXoonyaNativeAtomConformancePack());
|
|
2421
|
+
return;
|
|
2422
|
+
}
|
|
2423
|
+
|
|
2424
|
+
if (req.method === 'GET' && url.pathname === '/v1/proof-center/native-atom-conformance/summary') {
|
|
2425
|
+
sendJson(res, 200, proofSdk.summarizeXoonyaNativeAtomConformancePack());
|
|
2426
|
+
return;
|
|
2427
|
+
}
|
|
2428
|
+
|
|
2429
|
+
if (req.method === 'GET' && url.pathname === '/v1/proof-center/native-anchor-profile') {
|
|
2430
|
+
sendJson(res, 200, proofSdk.buildXoonyaNativeAnchorProfile());
|
|
2431
|
+
return;
|
|
2432
|
+
}
|
|
2433
|
+
|
|
2434
|
+
if (req.method === 'GET' && url.pathname === '/v1/proof-center/native-anchor-profile/summary') {
|
|
2435
|
+
sendJson(res, 200, proofSdk.summarizeXoonyaNativeAnchorProfile());
|
|
2436
|
+
return;
|
|
2437
|
+
}
|
|
2438
|
+
|
|
2439
|
+
if (req.method === 'GET' && url.pathname === '/v1/proof-center/import-adapter') {
|
|
2440
|
+
sendJson(res, 200, proofSdk.buildExternalProofImportAdapterPack());
|
|
2441
|
+
return;
|
|
2442
|
+
}
|
|
2443
|
+
|
|
2444
|
+
if (req.method === 'GET' && url.pathname === '/v1/proof-center/import-adapter/summary') {
|
|
2445
|
+
sendJson(res, 200, proofSdk.summarizeExternalProofImportAdapterPack());
|
|
2446
|
+
return;
|
|
2447
|
+
}
|
|
2448
|
+
|
|
2359
2449
|
if (req.method === 'GET' && url.pathname === '/v1/proof-center/default-loops') {
|
|
2360
2450
|
sendJson(res, 200, proofSdk.buildDefaultProofLoopCatalog());
|
|
2361
2451
|
return;
|
|
@@ -2443,6 +2533,39 @@ async function routeRequest(req, res) {
|
|
|
2443
2533
|
return;
|
|
2444
2534
|
}
|
|
2445
2535
|
|
|
2536
|
+
if (req.method === 'POST' && url.pathname === '/v1/proof-center/import-adapter/review') {
|
|
2537
|
+
try {
|
|
2538
|
+
const body = await readJsonBody(req);
|
|
2539
|
+
const result = proofSdk.reviewExternalProofImport(body);
|
|
2540
|
+
sendJson(res, 200, result);
|
|
2541
|
+
} catch (error) {
|
|
2542
|
+
sendJson(res, 400, { ok: false, reason: error.message });
|
|
2543
|
+
}
|
|
2544
|
+
return;
|
|
2545
|
+
}
|
|
2546
|
+
|
|
2547
|
+
if (req.method === 'POST' && url.pathname === '/v1/proof-center/import-adapter/review/summary') {
|
|
2548
|
+
try {
|
|
2549
|
+
const body = await readJsonBody(req);
|
|
2550
|
+
const result = proofSdk.summarizeExternalProofImportReview(body);
|
|
2551
|
+
sendJson(res, 200, result);
|
|
2552
|
+
} catch (error) {
|
|
2553
|
+
sendJson(res, 400, { ok: false, reason: error.message });
|
|
2554
|
+
}
|
|
2555
|
+
return;
|
|
2556
|
+
}
|
|
2557
|
+
|
|
2558
|
+
if (req.method === 'POST' && url.pathname === '/v1/proof-center/import-adapter/run') {
|
|
2559
|
+
try {
|
|
2560
|
+
const body = await readJsonBody(req);
|
|
2561
|
+
const result = proofSdk.runExternalProofImport(body);
|
|
2562
|
+
sendJson(res, 200, result);
|
|
2563
|
+
} catch (error) {
|
|
2564
|
+
sendJson(res, 400, { ok: false, reason: error.message });
|
|
2565
|
+
}
|
|
2566
|
+
return;
|
|
2567
|
+
}
|
|
2568
|
+
|
|
2446
2569
|
if (req.method === 'POST' && url.pathname === '/v1/proof-center/transaction-handoff/run') {
|
|
2447
2570
|
try {
|
|
2448
2571
|
const body = await readJsonBody(req);
|
|
@@ -3687,8 +3810,8 @@ function createServer() {
|
|
|
3687
3810
|
}
|
|
3688
3811
|
|
|
3689
3812
|
if (require.main === module) {
|
|
3690
|
-
const port = Number(process.env.XOONYA_PORT || 4310);
|
|
3691
|
-
const host = process.env.XOONYA_HOST || '127.0.0.1';
|
|
3813
|
+
const port = Number(process.env.PORT || process.env.XOONYA_PORT || 4310);
|
|
3814
|
+
const host = process.env.XOONYA_HOST || (process.env.RENDER ? '0.0.0.0' : '127.0.0.1');
|
|
3692
3815
|
const server = createServer();
|
|
3693
3816
|
server.listen(port, host, () => {
|
|
3694
3817
|
console.log(`xoonya listening on http://${host}:${port}`);
|