@nexart/codemode-sdk 1.8.3 → 1.9.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/CHANGELOG.md +89 -0
- package/README.md +121 -2
- package/dist/cjs/browser.cjs +3077 -0
- package/dist/cjs/browser.js +3042 -0
- package/dist/cjs/core.cjs +1998 -0
- package/dist/cjs/core.js +1966 -0
- package/dist/cjs/node.cjs +3245 -0
- package/dist/cjs/node.js +3208 -0
- package/dist/esm/browser.cjs +3077 -0
- package/dist/esm/browser.js +3042 -0
- package/dist/esm/core.cjs +1998 -0
- package/dist/esm/core.js +1966 -0
- package/dist/esm/node.cjs +3245 -0
- package/dist/esm/node.js +3208 -0
- package/dist/types/sdk/codemode/attestation.d.ts +24 -0
- package/dist/types/sdk/codemode/attestation.d.ts.map +1 -0
- package/dist/types/sdk/codemode/builder-manifest.d.ts.map +1 -0
- package/dist/types/sdk/codemode/canonicalJson.d.ts +16 -0
- package/dist/types/sdk/codemode/canonicalJson.d.ts.map +1 -0
- package/dist/{sdk → types/sdk}/codemode/core-index.d.ts +5 -1
- package/dist/types/sdk/codemode/core-index.d.ts.map +1 -0
- package/dist/types/sdk/codemode/engine.d.ts.map +1 -0
- package/dist/{sdk → types/sdk}/codemode/entry/browser.d.ts +1 -1
- package/dist/types/sdk/codemode/entry/browser.d.ts.map +1 -0
- package/dist/types/sdk/codemode/entry/node.d.ts.map +1 -0
- package/dist/types/sdk/codemode/execute.d.ts.map +1 -0
- package/dist/types/sdk/codemode/execution-sandbox.d.ts.map +1 -0
- package/dist/types/sdk/codemode/loop-engine.d.ts.map +1 -0
- package/dist/types/sdk/codemode/nodeReceipt.d.ts +65 -0
- package/dist/types/sdk/codemode/nodeReceipt.d.ts.map +1 -0
- package/dist/types/sdk/codemode/p5-runtime.d.ts.map +1 -0
- package/dist/{sdk → types/sdk}/codemode/runtime.d.ts +1 -1
- package/dist/types/sdk/codemode/runtime.d.ts.map +1 -0
- package/dist/types/sdk/codemode/snapshot.d.ts +72 -0
- package/dist/types/sdk/codemode/snapshot.d.ts.map +1 -0
- package/dist/types/sdk/codemode/sound-bridge.d.ts.map +1 -0
- package/dist/types/sdk/codemode/soundart-engine.d.ts.map +1 -0
- package/dist/types/sdk/codemode/soundart-sketches/chladniBloom.d.ts.map +1 -0
- package/dist/types/sdk/codemode/soundart-sketches/dualVortex.d.ts.map +1 -0
- package/dist/types/sdk/codemode/soundart-sketches/geometryIllusion.d.ts.map +1 -0
- package/dist/types/sdk/codemode/soundart-sketches/index.d.ts.map +1 -0
- package/dist/types/sdk/codemode/soundart-sketches/isoflow.d.ts.map +1 -0
- package/dist/types/sdk/codemode/soundart-sketches/loomWeave.d.ts.map +1 -0
- package/dist/types/sdk/codemode/soundart-sketches/noiseTerraces.d.ts.map +1 -0
- package/dist/types/sdk/codemode/soundart-sketches/orb.d.ts.map +1 -0
- package/dist/types/sdk/codemode/soundart-sketches/pixelGlyphs.d.ts.map +1 -0
- package/dist/types/sdk/codemode/soundart-sketches/prismFlowFields.d.ts.map +1 -0
- package/dist/types/sdk/codemode/soundart-sketches/radialBurst.d.ts.map +1 -0
- package/dist/types/sdk/codemode/soundart-sketches/resonantSoundBodies.d.ts.map +1 -0
- package/dist/types/sdk/codemode/soundart-sketches/rings.d.ts.map +1 -0
- package/dist/types/sdk/codemode/soundart-sketches/squares.d.ts.map +1 -0
- package/dist/types/sdk/codemode/soundart-sketches/waveStripes.d.ts.map +1 -0
- package/dist/types/sdk/codemode/static-engine.d.ts.map +1 -0
- package/dist/{sdk → types/sdk}/codemode/types.d.ts +96 -0
- package/dist/types/sdk/codemode/types.d.ts.map +1 -0
- package/dist/{sdk → types/sdk}/codemode/version.d.ts +2 -2
- package/dist/types/sdk/codemode/version.d.ts.map +1 -0
- package/dist/types/shared/soundSnapshot.d.ts.map +1 -0
- package/examples/sketch-minimal.js +27 -0
- package/examples/sketch-vars.js +59 -0
- package/examples/sketch.js +24 -0
- package/package.json +29 -23
- package/dist/sdk/codemode/builder-manifest.d.ts.map +0 -1
- package/dist/sdk/codemode/builder-manifest.js +0 -97
- package/dist/sdk/codemode/core-index.d.ts.map +0 -1
- package/dist/sdk/codemode/core-index.js +0 -28
- package/dist/sdk/codemode/engine.d.ts.map +0 -1
- package/dist/sdk/codemode/engine.js +0 -67
- package/dist/sdk/codemode/entry/browser.d.ts.map +0 -1
- package/dist/sdk/codemode/entry/browser.js +0 -69
- package/dist/sdk/codemode/entry/node.d.ts.map +0 -1
- package/dist/sdk/codemode/entry/node.js +0 -35
- package/dist/sdk/codemode/execute.d.ts.map +0 -1
- package/dist/sdk/codemode/execute.js +0 -283
- package/dist/sdk/codemode/execution-sandbox.d.ts.map +0 -1
- package/dist/sdk/codemode/execution-sandbox.js +0 -207
- package/dist/sdk/codemode/loop-engine.d.ts.map +0 -1
- package/dist/sdk/codemode/loop-engine.js +0 -229
- package/dist/sdk/codemode/p5-runtime.d.ts.map +0 -1
- package/dist/sdk/codemode/p5-runtime.js +0 -1033
- package/dist/sdk/codemode/runtime.d.ts.map +0 -1
- package/dist/sdk/codemode/runtime.js +0 -220
- package/dist/sdk/codemode/sound-bridge.d.ts.map +0 -1
- package/dist/sdk/codemode/sound-bridge.js +0 -128
- package/dist/sdk/codemode/soundart-engine.d.ts.map +0 -1
- package/dist/sdk/codemode/soundart-engine.js +0 -173
- package/dist/sdk/codemode/soundart-sketches/chladniBloom.d.ts.map +0 -1
- package/dist/sdk/codemode/soundart-sketches/chladniBloom.js +0 -53
- package/dist/sdk/codemode/soundart-sketches/dualVortex.d.ts.map +0 -1
- package/dist/sdk/codemode/soundart-sketches/dualVortex.js +0 -67
- package/dist/sdk/codemode/soundart-sketches/geometryIllusion.d.ts.map +0 -1
- package/dist/sdk/codemode/soundart-sketches/geometryIllusion.js +0 -89
- package/dist/sdk/codemode/soundart-sketches/index.d.ts.map +0 -1
- package/dist/sdk/codemode/soundart-sketches/index.js +0 -72
- package/dist/sdk/codemode/soundart-sketches/isoflow.d.ts.map +0 -1
- package/dist/sdk/codemode/soundart-sketches/isoflow.js +0 -60
- package/dist/sdk/codemode/soundart-sketches/loomWeave.d.ts.map +0 -1
- package/dist/sdk/codemode/soundart-sketches/loomWeave.js +0 -59
- package/dist/sdk/codemode/soundart-sketches/noiseTerraces.d.ts.map +0 -1
- package/dist/sdk/codemode/soundart-sketches/noiseTerraces.js +0 -53
- package/dist/sdk/codemode/soundart-sketches/orb.d.ts.map +0 -1
- package/dist/sdk/codemode/soundart-sketches/orb.js +0 -50
- package/dist/sdk/codemode/soundart-sketches/pixelGlyphs.d.ts.map +0 -1
- package/dist/sdk/codemode/soundart-sketches/pixelGlyphs.js +0 -72
- package/dist/sdk/codemode/soundart-sketches/prismFlowFields.d.ts.map +0 -1
- package/dist/sdk/codemode/soundart-sketches/prismFlowFields.js +0 -51
- package/dist/sdk/codemode/soundart-sketches/radialBurst.d.ts.map +0 -1
- package/dist/sdk/codemode/soundart-sketches/radialBurst.js +0 -60
- package/dist/sdk/codemode/soundart-sketches/resonantSoundBodies.d.ts.map +0 -1
- package/dist/sdk/codemode/soundart-sketches/resonantSoundBodies.js +0 -89
- package/dist/sdk/codemode/soundart-sketches/rings.d.ts.map +0 -1
- package/dist/sdk/codemode/soundart-sketches/rings.js +0 -89
- package/dist/sdk/codemode/soundart-sketches/squares.d.ts.map +0 -1
- package/dist/sdk/codemode/soundart-sketches/squares.js +0 -52
- package/dist/sdk/codemode/soundart-sketches/waveStripes.d.ts.map +0 -1
- package/dist/sdk/codemode/soundart-sketches/waveStripes.js +0 -44
- package/dist/sdk/codemode/static-engine.d.ts.map +0 -1
- package/dist/sdk/codemode/static-engine.js +0 -157
- package/dist/sdk/codemode/types.d.ts.map +0 -1
- package/dist/sdk/codemode/types.js +0 -34
- package/dist/sdk/codemode/version.d.ts.map +0 -1
- package/dist/sdk/codemode/version.js +0 -17
- package/dist/shared/soundSnapshot.d.ts.map +0 -1
- package/dist/shared/soundSnapshot.js +0 -128
- /package/dist/{sdk → types/sdk}/codemode/builder-manifest.d.ts +0 -0
- /package/dist/{sdk → types/sdk}/codemode/engine.d.ts +0 -0
- /package/dist/{sdk → types/sdk}/codemode/entry/node.d.ts +0 -0
- /package/dist/{sdk → types/sdk}/codemode/execute.d.ts +0 -0
- /package/dist/{sdk → types/sdk}/codemode/execution-sandbox.d.ts +0 -0
- /package/dist/{sdk → types/sdk}/codemode/loop-engine.d.ts +0 -0
- /package/dist/{sdk → types/sdk}/codemode/p5-runtime.d.ts +0 -0
- /package/dist/{sdk → types/sdk}/codemode/sound-bridge.d.ts +0 -0
- /package/dist/{sdk → types/sdk}/codemode/soundart-engine.d.ts +0 -0
- /package/dist/{sdk → types/sdk}/codemode/soundart-sketches/chladniBloom.d.ts +0 -0
- /package/dist/{sdk → types/sdk}/codemode/soundart-sketches/dualVortex.d.ts +0 -0
- /package/dist/{sdk → types/sdk}/codemode/soundart-sketches/geometryIllusion.d.ts +0 -0
- /package/dist/{sdk → types/sdk}/codemode/soundart-sketches/index.d.ts +0 -0
- /package/dist/{sdk → types/sdk}/codemode/soundart-sketches/isoflow.d.ts +0 -0
- /package/dist/{sdk → types/sdk}/codemode/soundart-sketches/loomWeave.d.ts +0 -0
- /package/dist/{sdk → types/sdk}/codemode/soundart-sketches/noiseTerraces.d.ts +0 -0
- /package/dist/{sdk → types/sdk}/codemode/soundart-sketches/orb.d.ts +0 -0
- /package/dist/{sdk → types/sdk}/codemode/soundart-sketches/pixelGlyphs.d.ts +0 -0
- /package/dist/{sdk → types/sdk}/codemode/soundart-sketches/prismFlowFields.d.ts +0 -0
- /package/dist/{sdk → types/sdk}/codemode/soundart-sketches/radialBurst.d.ts +0 -0
- /package/dist/{sdk → types/sdk}/codemode/soundart-sketches/resonantSoundBodies.d.ts +0 -0
- /package/dist/{sdk → types/sdk}/codemode/soundart-sketches/rings.d.ts +0 -0
- /package/dist/{sdk → types/sdk}/codemode/soundart-sketches/squares.d.ts +0 -0
- /package/dist/{sdk → types/sdk}/codemode/soundart-sketches/waveStripes.d.ts +0 -0
- /package/dist/{sdk → types/sdk}/codemode/static-engine.d.ts +0 -0
- /package/dist/{shared → types/shared}/soundSnapshot.d.ts +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,95 @@ All notable changes to @nexart/codemode-sdk will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## [1.9.0] — 2026-02-25
|
|
8
|
+
|
|
9
|
+
### Added — Attestation Parity (Reason Codes + Signed Receipt Verification)
|
|
10
|
+
|
|
11
|
+
**Feature Release — Additive only. No existing APIs changed.**
|
|
12
|
+
|
|
13
|
+
Brings the Code Mode SDK attestation layer to parity with `@nexart/ai-execution` v0.5.0.
|
|
14
|
+
|
|
15
|
+
#### New Types (`types.ts`)
|
|
16
|
+
- `CodeVerifyCode` — stable string-valued reason code enum (12 codes)
|
|
17
|
+
- `CodeVerificationResult` — `{ ok, code, details? }` returned by all verification functions
|
|
18
|
+
- `NodeReceiptVerifyResult` — alias of `CodeVerificationResult` for receipt-specific call sites
|
|
19
|
+
- `NodeKeysDocument` — shape of `/.well-known/nexart-node.json`
|
|
20
|
+
- `SignedAttestationReceipt` — payload signed by the attestation node
|
|
21
|
+
- `CodeAttestationReceipt` — normalised receipt extracted from any bundle layout
|
|
22
|
+
|
|
23
|
+
#### New Module — `nodeReceipt.ts`
|
|
24
|
+
- `verifyNodeReceiptSignature({ receipt, signatureB64Url, key })` — offline Ed25519 verification (browser + Node, @noble/ed25519)
|
|
25
|
+
- `fetchNodeKeys(nodeUrl)` — fetch `NodeKeysDocument` from attestation node
|
|
26
|
+
- `selectNodeKey(doc, kid?)` — select key by explicit kid → activeKid → first
|
|
27
|
+
- `verifyBundleAttestation(bundle, { nodeUrl, kid? })` — full offline attestation check with certificateHash cross-check (receipt-swap prevention), all three bundle layouts supported
|
|
28
|
+
|
|
29
|
+
#### New Module — `attestation.ts`
|
|
30
|
+
- `getAttestationReceipt(bundle)` — normalised receipt or null; recognises Layout A (top-level), Layout B (nested envelope), Layout C (legacy flat fields)
|
|
31
|
+
- `hasAttestation(bundle)` — boolean shorthand
|
|
32
|
+
|
|
33
|
+
#### New Module — `canonicalJson.ts`
|
|
34
|
+
- `toCanonicalJson(value)` — deterministic sorted-key JSON serialisation used for signing/verifying receipt bytes
|
|
35
|
+
|
|
36
|
+
#### New Dependencies
|
|
37
|
+
- `@noble/ed25519` ^3.0.0 (browser-compatible Ed25519) — declared in `dependencies` (installed per-package, no hoisting required)
|
|
38
|
+
- `@noble/hashes` ^1.7.0 (sha512 for noble ed25519) — same
|
|
39
|
+
- `@types/node` ^20.0.0 (dev) — added to `devDependencies` so `Buffer`/`process`/`require` resolve correctly under TypeScript strict mode; prevents "works only when hoisted" failures
|
|
40
|
+
|
|
41
|
+
#### TypeScript Config
|
|
42
|
+
- `"types": ["node"]` added to both `tsconfig.json` and `tsconfig.types.json` `compilerOptions`
|
|
43
|
+
- `nodeReceipt.ts`, `attestation.ts`, `canonicalJson.ts` added explicitly to both `files` arrays
|
|
44
|
+
|
|
45
|
+
#### Tests
|
|
46
|
+
- `tests/attestation.test.ts` — 25 tests covering all code paths, error cases, and all three bundle layouts; `npm run test:attestation`
|
|
47
|
+
|
|
48
|
+
#### Fixtures
|
|
49
|
+
- `fixtures/attestation/keys-v1.json`
|
|
50
|
+
- `fixtures/attestation/receipt-v1.json`
|
|
51
|
+
- `fixtures/attestation/receipt-v1.sig`
|
|
52
|
+
- `fixtures/attestation/receipt-v1.pub`
|
|
53
|
+
|
|
54
|
+
#### Docs
|
|
55
|
+
- README: new Attestation & Verification section with reason codes, `verifyBundleAttestation` usage, node keys endpoint, and receipt extraction helpers
|
|
56
|
+
|
|
57
|
+
#### Unchanged
|
|
58
|
+
- No protocol changes (v1.2.0)
|
|
59
|
+
- No changes to existing hashing or canonicalisation semantics
|
|
60
|
+
- All existing `executeCodeMode`, `createRuntime`, `validateSnapshot` APIs unchanged
|
|
61
|
+
- All existing smoke tests and execution boundary tests pass
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## [1.8.4] — 2026-01-25
|
|
66
|
+
|
|
67
|
+
### Fixed — Node ESM Compatibility
|
|
68
|
+
|
|
69
|
+
**Patch Release — Packaging Fix Only**
|
|
70
|
+
|
|
71
|
+
This release fixes Node.js ESM compatibility by switching to dual build output (ESM + CJS) via tsup.
|
|
72
|
+
|
|
73
|
+
#### Breaking Change (Internal Only)
|
|
74
|
+
- Dist structure changed from `dist/entry/*.js` to `dist/esm/*.js` and `dist/cjs/*.js`
|
|
75
|
+
- Types now in `dist/types/`
|
|
76
|
+
- Exports map updated to support both `import` and `require`
|
|
77
|
+
|
|
78
|
+
#### Fixes
|
|
79
|
+
- Node ESM: Imports now resolve correctly (no more missing .js extension errors)
|
|
80
|
+
- Node CJS: `require('@nexart/codemode-sdk')` now works
|
|
81
|
+
- Bundlers: Continue to work via exports map
|
|
82
|
+
|
|
83
|
+
#### Build Changes
|
|
84
|
+
- Added tsup for dual ESM/CJS bundling
|
|
85
|
+
- Types emitted separately via tsc
|
|
86
|
+
- New smoke tests: `scripts/smoke-node.mjs` and `scripts/smoke-node.cjs`
|
|
87
|
+
|
|
88
|
+
#### Unchanged
|
|
89
|
+
- No protocol changes (v1.2.0)
|
|
90
|
+
- No runtime API changes
|
|
91
|
+
- No behavior changes
|
|
92
|
+
- Full backward compatibility with v1.8.3 API
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
7
96
|
## [1.8.3] — 2026-01-25
|
|
8
97
|
|
|
9
98
|
### Changed — CLI v0.2 Remote Renderer + Version Bump
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @nexart/codemode-sdk
|
|
2
2
|
|
|
3
|
-
**Version: 1.
|
|
3
|
+
**Version: 1.9.0 (Protocol v1.2.0)**
|
|
4
4
|
|
|
5
5
|
A deterministic execution runtime for reproducible, verifiable computation.
|
|
6
6
|
|
|
@@ -33,6 +33,43 @@ A deterministic execution runtime for reproducible, verifiable computation.
|
|
|
33
33
|
|
|
34
34
|
---
|
|
35
35
|
|
|
36
|
+
## Quickstart: CLI Examples
|
|
37
|
+
|
|
38
|
+
The SDK includes ready-to-run example sketches. Use the `@nexart/cli` to render them via the canonical renderer.
|
|
39
|
+
|
|
40
|
+
### Setup
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# Set up authentication for remote rendering
|
|
44
|
+
export NEXART_RENDERER_ENDPOINT=https://nexart-canonical-renderer-production.up.railway.app
|
|
45
|
+
export NEXART_API_KEY=nx_live_your_key_here
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Run Examples
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# Run the main example sketch
|
|
52
|
+
npx @nexart/cli run ./examples/sketch.js --seed 12345 --include-code --out ./out.png
|
|
53
|
+
|
|
54
|
+
# Verify the output is deterministic
|
|
55
|
+
npx @nexart/cli verify ./out.snapshot.json
|
|
56
|
+
# Output: [nexart] Result: PASS
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Example Sketches
|
|
60
|
+
|
|
61
|
+
| File | Description |
|
|
62
|
+
|------|-------------|
|
|
63
|
+
| `examples/sketch.js` | Main example — VAR controls + random palette, protocol-safe |
|
|
64
|
+
| `examples/sketch-minimal.js` | Simple shapes, no randomness — identical every run |
|
|
65
|
+
| `examples/sketch-vars.js` | Uses VAR + random() — demonstrates determinism |
|
|
66
|
+
|
|
67
|
+
### Canonical Size
|
|
68
|
+
|
|
69
|
+
The canonical renderer enforces a fixed canvas size of **1950x2400**. Do not pass custom `--width` or `--height` to the canonical endpoint — the size is enforced server-side for consistent, verifiable output.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
36
73
|
## What This SDK Does
|
|
37
74
|
|
|
38
75
|
This SDK provides a **deterministic runtime layer** for executing code that must produce identical output given identical inputs — across environments, over time, and under verification.
|
|
@@ -236,7 +273,7 @@ These are examples — the SDK is designed for any system requiring deterministi
|
|
|
236
273
|
|----------|-------|
|
|
237
274
|
| Protocol Version | v1.2.0 |
|
|
238
275
|
| Status | **STABLE** |
|
|
239
|
-
| SDK Version | 1.8.
|
|
276
|
+
| SDK Version | 1.8.4 |
|
|
240
277
|
|
|
241
278
|
**Core protocol surface is frozen. Breaking changes require v2.0.0.**
|
|
242
279
|
|
|
@@ -434,6 +471,88 @@ The following are rejected with `[Code Mode Protocol Error]`:
|
|
|
434
471
|
|
|
435
472
|
---
|
|
436
473
|
|
|
474
|
+
## Attestation & Verification (v1.9.0)
|
|
475
|
+
|
|
476
|
+
### Verification Reason Codes
|
|
477
|
+
|
|
478
|
+
Every verification function returns a `CodeVerificationResult` with a stable, machine-readable `code`:
|
|
479
|
+
|
|
480
|
+
```typescript
|
|
481
|
+
import { CodeVerifyCode } from '@nexart/codemode-sdk';
|
|
482
|
+
|
|
483
|
+
// Stable string codes — safe to switch on, persist to storage, or compare:
|
|
484
|
+
// CodeVerifyCode.OK
|
|
485
|
+
// CodeVerifyCode.CERTIFICATE_HASH_MISMATCH
|
|
486
|
+
// CodeVerifyCode.SNAPSHOT_HASH_MISMATCH
|
|
487
|
+
// CodeVerifyCode.RENDER_HASH_MISMATCH
|
|
488
|
+
// CodeVerifyCode.INVALID_SHA256_FORMAT
|
|
489
|
+
// CodeVerifyCode.CANONICALIZATION_ERROR
|
|
490
|
+
// CodeVerifyCode.SCHEMA_ERROR
|
|
491
|
+
// CodeVerifyCode.NODE_RECEIPT_MISSING
|
|
492
|
+
// CodeVerifyCode.NODE_RECEIPT_KEY_NOT_FOUND
|
|
493
|
+
// CodeVerifyCode.NODE_RECEIPT_INVALID_SIGNATURE
|
|
494
|
+
// CodeVerifyCode.NODE_RECEIPT_KEY_FORMAT_UNSUPPORTED
|
|
495
|
+
// CodeVerifyCode.UNKNOWN_ERROR
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
### Signed Node Receipt Verification (offline)
|
|
499
|
+
|
|
500
|
+
Verify that a Code Mode snapshot bundle was attested by an authorised NexArt attestation node — entirely offline, browser and Node.js compatible:
|
|
501
|
+
|
|
502
|
+
```typescript
|
|
503
|
+
import { verifyBundleAttestation } from '@nexart/codemode-sdk';
|
|
504
|
+
|
|
505
|
+
const res = await verifyBundleAttestation(bundle, { nodeUrl: 'https://node.nexart.dev' });
|
|
506
|
+
console.log(res.ok, res.code);
|
|
507
|
+
// true "OK"
|
|
508
|
+
// false "CERTIFICATE_HASH_MISMATCH" (receipt doesn't match bundle)
|
|
509
|
+
// false "NODE_RECEIPT_INVALID_SIGNATURE" (tampered receipt)
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
`verifyBundleAttestation` performs these steps automatically:
|
|
513
|
+
1. Extracts the signed receipt and signature from the bundle (top-level or nested layout).
|
|
514
|
+
2. Cross-checks `receipt.certificateHash === bundle.certificateHash` to prevent receipt-swapping attacks.
|
|
515
|
+
3. Fetches the node's public keys from `/.well-known/nexart-node.json`.
|
|
516
|
+
4. Selects the appropriate key (by `kid`, `activeKid`, or first available).
|
|
517
|
+
5. Verifies the Ed25519 signature over the canonical JSON bytes of the receipt.
|
|
518
|
+
|
|
519
|
+
### Node Keys Endpoint
|
|
520
|
+
|
|
521
|
+
Public keys are discovered automatically from:
|
|
522
|
+
|
|
523
|
+
```
|
|
524
|
+
GET {nodeUrl}/.well-known/nexart-node.json
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
You can also fetch or inspect keys directly:
|
|
528
|
+
|
|
529
|
+
```typescript
|
|
530
|
+
import { fetchNodeKeys, selectNodeKey } from '@nexart/codemode-sdk';
|
|
531
|
+
|
|
532
|
+
const doc = await fetchNodeKeys('https://node.nexart.dev');
|
|
533
|
+
const { key } = selectNodeKey(doc, 'kid-optional');
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
### Receipt Extraction Helpers
|
|
537
|
+
|
|
538
|
+
Inspect bundles without performing full verification:
|
|
539
|
+
|
|
540
|
+
```typescript
|
|
541
|
+
import { getAttestationReceipt, hasAttestation } from '@nexart/codemode-sdk';
|
|
542
|
+
|
|
543
|
+
if (hasAttestation(bundle)) {
|
|
544
|
+
const receipt = getAttestationReceipt(bundle);
|
|
545
|
+
console.log(receipt?.attestationId, receipt?.nodeId);
|
|
546
|
+
}
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
Both helpers recognise:
|
|
550
|
+
- **Layout A** — `bundle.receipt` + `bundle.signature` (signed envelope)
|
|
551
|
+
- **Layout B** — `bundle.attestation.receipt` + `bundle.attestation.signature` (nested envelope)
|
|
552
|
+
- **Layout C** — legacy flat fields (`bundle.attestationId`, `bundle.nodeRuntimeHash`, …)
|
|
553
|
+
|
|
554
|
+
---
|
|
555
|
+
|
|
437
556
|
## Examples
|
|
438
557
|
|
|
439
558
|
```bash
|