space-data-module-sdk 0.8.1 → 0.8.2
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
CHANGED
|
@@ -410,11 +410,22 @@ for resolved protocol installations and producer input bindings.
|
|
|
410
410
|
## Publication Protection Extensions
|
|
411
411
|
|
|
412
412
|
Digital signature and encrypted-delivery metadata are publication-layer
|
|
413
|
-
extensions
|
|
413
|
+
extensions. The canonical runtime module is still:
|
|
414
414
|
|
|
415
415
|
- valid `.wasm`
|
|
416
416
|
- optionally carrying one appended SDS `REC` trailer after the wasm bytes
|
|
417
417
|
|
|
418
|
+
The same-file protected delivery layout is:
|
|
419
|
+
|
|
420
|
+
```text
|
|
421
|
+
protected-payload-bytes || REC-flatbuffer-bytes || uint32le(REC length) || "$REC"
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
For signed-only delivery, the protected payload bytes are the wasm bytes. For
|
|
425
|
+
encrypted binary delivery, the protected payload bytes are ciphertext and the
|
|
426
|
+
appended `REC` trailer carries `ENC` so a loader can decrypt them back to the
|
|
427
|
+
canonical wasm before runtime startup.
|
|
428
|
+
|
|
418
429
|
That trailing `REC` FlatBuffer is the standards-backed container for
|
|
419
430
|
publication records:
|
|
420
431
|
|
|
@@ -435,7 +446,7 @@ The loader contract is always:
|
|
|
435
446
|
FlatBuffers from `spacedatastandards.org`.
|
|
436
447
|
4. Resolve `PNM` for signature/publication metadata.
|
|
437
448
|
5. Resolve `ENC` if the delivery was encrypted.
|
|
438
|
-
6. Strip the trailer or decrypt the protected payload.
|
|
449
|
+
6. Strip the trailer or decrypt the protected payload bytes.
|
|
439
450
|
7. Hand the remaining raw wasm bytes to the runtime.
|
|
440
451
|
|
|
441
452
|
Aligned-binary payloads are a separate invoke-ABI optimization. They do not
|
|
@@ -547,9 +558,12 @@ npx space-data-module check --manifest ./manifest.json --wasm ./dist/isomorphic/
|
|
|
547
558
|
# Compile C/C++ source and embed the manifest
|
|
548
559
|
npx space-data-module compile --manifest ./manifest.json --source ./src/module.c --out ./dist/isomorphic/module.wasm
|
|
549
560
|
|
|
550
|
-
# Sign
|
|
561
|
+
# Sign a deployment payload and print JSON metadata
|
|
551
562
|
npx space-data-module protect --manifest ./manifest.json --wasm ./dist/isomorphic/module.wasm --json
|
|
552
563
|
|
|
564
|
+
# Emit an encrypted binary with an appended REC trailer
|
|
565
|
+
npx space-data-module protect --manifest ./manifest.json --wasm ./dist/isomorphic/module.wasm --recipient-public-key <hex> --out ./dist/module.wasm.enc
|
|
566
|
+
|
|
553
567
|
# Emit a single-file bundled wasm
|
|
554
568
|
npx space-data-module protect --manifest ./manifest.json --wasm ./dist/isomorphic/module.wasm --single-file-bundle --out ./dist/module.bundle.wasm
|
|
555
569
|
```
|
package/bin/space-data-module.js
CHANGED
|
@@ -106,6 +106,7 @@ function printUsage() {
|
|
|
106
106
|
space-data-module check --manifest ./manifest.json --wasm ./dist/module.wasm
|
|
107
107
|
space-data-module compile --manifest ./manifest.json --source ./src/module.c --out ./dist/module.wasm
|
|
108
108
|
space-data-module protect --manifest ./manifest.json --wasm ./dist/module.wasm --json
|
|
109
|
+
space-data-module protect --manifest ./manifest.json --wasm ./dist/module.wasm --recipient-public-key <hex> --out ./dist/module.wasm.enc
|
|
109
110
|
space-data-module protect --manifest ./manifest.json --wasm ./dist/module.wasm --single-file-bundle --out ./dist/module.bundle.wasm
|
|
110
111
|
`);
|
|
111
112
|
}
|
|
@@ -213,9 +214,6 @@ async function runProtect(argv) {
|
|
|
213
214
|
if (!options.manifestPath || !options.wasmPath) {
|
|
214
215
|
throw new Error("protect requires --manifest and --wasm.");
|
|
215
216
|
}
|
|
216
|
-
if (options.outputPath && options.singleFileBundle !== true) {
|
|
217
|
-
throw new Error("protect only supports --out together with --single-file-bundle.");
|
|
218
|
-
}
|
|
219
217
|
const manifest = await loadManifestFromFile(options.manifestPath);
|
|
220
218
|
const wasmBytes = new Uint8Array(await readFile(options.wasmPath));
|
|
221
219
|
const result = await protectModuleArtifact({
|
|
@@ -225,8 +223,11 @@ async function runProtect(argv) {
|
|
|
225
223
|
mnemonic: options.mnemonic,
|
|
226
224
|
singleFileBundle: options.singleFileBundle,
|
|
227
225
|
});
|
|
228
|
-
if (options.
|
|
229
|
-
await writeFile(
|
|
226
|
+
if (options.outputPath) {
|
|
227
|
+
await writeFile(
|
|
228
|
+
options.outputPath,
|
|
229
|
+
result.bundledWasmBytes ?? result.protectedArtifactBytes,
|
|
230
|
+
);
|
|
230
231
|
}
|
|
231
232
|
if (options.json) {
|
|
232
233
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -235,7 +236,8 @@ async function runProtect(argv) {
|
|
|
235
236
|
console.log(`signingPublicKeyHex=${result.signingPublicKeyHex}`);
|
|
236
237
|
console.log(`encrypted=${result.encrypted}`);
|
|
237
238
|
console.log(`wasmBase64Length=${bytesToBase64(wasmBytes).length}`);
|
|
238
|
-
|
|
239
|
+
console.log(`protectedArtifactBytes=${result.protectedArtifactBytes.length}`);
|
|
240
|
+
if (options.singleFileBundle && result.bundledWasmBytes) {
|
|
239
241
|
console.log(`singleFileBundle=true`);
|
|
240
242
|
console.log(`bundledWasmBytes=${result.bundledWasmBytes.length}`);
|
|
241
243
|
}
|
package/package.json
CHANGED
package/src/manifest/codec.js
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
import { normalizeInvokeSurfaceName } from "../invoke/codec.js";
|
|
12
12
|
import { toUint8Array } from "../runtime/bufferLike.js";
|
|
13
13
|
import { toEmbeddedPluginManifest } from "./normalize.js";
|
|
14
|
+
import { decodePlgManifest, isPlgManifestBuffer } from "./plgCodec.js";
|
|
14
15
|
|
|
15
16
|
function toByteBuffer(data) {
|
|
16
17
|
if (data instanceof flatbuffers.ByteBuffer) {
|
|
@@ -107,7 +108,79 @@ function normalizeDecodedMethod(method = {}) {
|
|
|
107
108
|
};
|
|
108
109
|
}
|
|
109
110
|
|
|
111
|
+
function typeRefFromSchemaName(schemaName) {
|
|
112
|
+
return typeof schemaName === "string" && schemaName.length > 0
|
|
113
|
+
? { schemaName }
|
|
114
|
+
: null;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function portFromSchemaName(schemaName, index, direction) {
|
|
118
|
+
const typeRef = typeRefFromSchemaName(schemaName);
|
|
119
|
+
if (!typeRef) {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
portId: `${direction}-${index + 1}`,
|
|
124
|
+
acceptedTypeSets: [
|
|
125
|
+
{
|
|
126
|
+
setId: schemaName,
|
|
127
|
+
allowedTypes: [typeRef],
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
minStreams: 0,
|
|
131
|
+
maxStreams: 1,
|
|
132
|
+
required: false,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function methodFromPlgEntry(entry = {}) {
|
|
137
|
+
const methodId = entry.name;
|
|
138
|
+
if (typeof methodId !== "string" || methodId.length === 0) {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
const inputPorts = Array.isArray(entry.inputSchemas)
|
|
142
|
+
? entry.inputSchemas
|
|
143
|
+
.map((schemaName, index) => portFromSchemaName(schemaName, index, "input"))
|
|
144
|
+
.filter(Boolean)
|
|
145
|
+
: [];
|
|
146
|
+
const outputPort = portFromSchemaName(entry.outputSchema, 0, "output");
|
|
147
|
+
return {
|
|
148
|
+
methodId,
|
|
149
|
+
displayName: methodId,
|
|
150
|
+
description: entry.description,
|
|
151
|
+
inputPorts,
|
|
152
|
+
outputPorts: outputPort ? [outputPort] : [],
|
|
153
|
+
maxBatch: 1,
|
|
154
|
+
drainPolicy: "single-shot",
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function normalizeDecodedPlgManifest(manifest = {}) {
|
|
159
|
+
const methods = Array.isArray(manifest.entryFunctions)
|
|
160
|
+
? manifest.entryFunctions.map((entry) => methodFromPlgEntry(entry)).filter(Boolean)
|
|
161
|
+
: [];
|
|
162
|
+
return {
|
|
163
|
+
...manifest,
|
|
164
|
+
methods,
|
|
165
|
+
capabilities: Array.isArray(manifest.capabilities)
|
|
166
|
+
? manifest.capabilities
|
|
167
|
+
: [],
|
|
168
|
+
invokeSurfaces: Array.isArray(manifest.invokeSurfaces)
|
|
169
|
+
? manifest.invokeSurfaces
|
|
170
|
+
.map((value) => normalizeInvokeSurfaceName(value))
|
|
171
|
+
.filter(Boolean)
|
|
172
|
+
: [],
|
|
173
|
+
runtimeTargets: Array.isArray(manifest.runtimeTargets)
|
|
174
|
+
? manifest.runtimeTargets
|
|
175
|
+
: [],
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
110
179
|
export function decodePluginManifest(data) {
|
|
180
|
+
const bytes = toUint8Array(data);
|
|
181
|
+
if (bytes && isPlgManifestBuffer(bytes)) {
|
|
182
|
+
return normalizeDecodedPlgManifest(decodePlgManifest(bytes));
|
|
183
|
+
}
|
|
111
184
|
const bb = toByteBuffer(data);
|
|
112
185
|
if (!PluginManifest.bufferHasIdentifier(bb)) {
|
|
113
186
|
throw new Error("Plugin manifest buffer identifier mismatch.");
|
|
@@ -682,6 +682,14 @@ static void register_env_host_functions(
|
|
|
682
682
|
WasmEdge_ValTypeGenI32(),
|
|
683
683
|
WasmEdge_ValTypeGenI32(),
|
|
684
684
|
WasmEdge_ValTypeGenI32()};
|
|
685
|
+
const WasmEdge_ValType seven_i32_params[7] = {
|
|
686
|
+
WasmEdge_ValTypeGenI32(),
|
|
687
|
+
WasmEdge_ValTypeGenI32(),
|
|
688
|
+
WasmEdge_ValTypeGenI32(),
|
|
689
|
+
WasmEdge_ValTypeGenI32(),
|
|
690
|
+
WasmEdge_ValTypeGenI32(),
|
|
691
|
+
WasmEdge_ValTypeGenI32(),
|
|
692
|
+
WasmEdge_ValTypeGenI32()};
|
|
685
693
|
const WasmEdge_ValType f64_return[1] = {WasmEdge_ValTypeGenF64()};
|
|
686
694
|
const WasmEdge_ValType i32_return[1] = {WasmEdge_ValTypeGenI32()};
|
|
687
695
|
|
|
@@ -735,8 +743,14 @@ static void register_env_host_functions(
|
|
|
735
743
|
"_emscripten_receive_on_main_thread_js",
|
|
736
744
|
stub_receive_on_main_thread,
|
|
737
745
|
runner,
|
|
738
|
-
receive_on_main_thread_param_len == 4
|
|
739
|
-
|
|
746
|
+
receive_on_main_thread_param_len == 4
|
|
747
|
+
? four_i32_params
|
|
748
|
+
: receive_on_main_thread_param_len == 7
|
|
749
|
+
? seven_i32_params
|
|
750
|
+
: five_i32_params,
|
|
751
|
+
receive_on_main_thread_param_len == 4
|
|
752
|
+
? 4
|
|
753
|
+
: receive_on_main_thread_param_len == 7 ? 7 : 5,
|
|
740
754
|
f64_return,
|
|
741
755
|
1);
|
|
742
756
|
add_host_func(
|
|
@@ -3072,7 +3086,7 @@ int main(int argc, char **argv) {
|
|
|
3072
3086
|
&runner,
|
|
3073
3087
|
import_config.receive_on_main_thread_param_len == 4
|
|
3074
3088
|
? 4
|
|
3075
|
-
: 5,
|
|
3089
|
+
: import_config.receive_on_main_thread_param_len == 7 ? 7 : 5,
|
|
3076
3090
|
import_config.notify_mailbox_postmessage_param_len == 3
|
|
3077
3091
|
? 3
|
|
3078
3092
|
: 2);
|