@qntx/nostr-wasm 0.10.1 → 0.11.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/dist/browser.mjs +2 -2
- package/dist/browser.mjs.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/dist/{instance-DS92CCrA.mjs → instance-CFwzTT0p.mjs} +71 -94
- package/dist/instance-CFwzTT0p.mjs.map +1 -0
- package/dist/nk_wasm-BbbBKBiH.mjs +4 -0
- package/dist/nk_wasm.wasm +0 -0
- package/package.json +3 -3
- package/dist/instance-DS92CCrA.mjs.map +0 -1
- package/dist/nk_wasm_bg-BjJ0ckB7.mjs +0 -4
- package/dist/nk_wasm_bg.wasm +0 -0
package/dist/browser.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as WasmPoisonedError, n as fetchWasmUrl, r as isWasmBytes, t as createNostrWasmLoader } from "./instance-
|
|
1
|
+
import { i as WasmPoisonedError, n as fetchWasmUrl, r as isWasmBytes, t as createNostrWasmLoader } from "./instance-CFwzTT0p.mjs";
|
|
2
2
|
import { CryptoError } from "@qntx/nostr/core";
|
|
3
3
|
//#region src/load.browser.ts
|
|
4
4
|
async function wasmBytes(opts) {
|
|
@@ -6,7 +6,7 @@ async function wasmBytes(opts) {
|
|
|
6
6
|
if (source !== void 0 && isWasmBytes(source)) return source;
|
|
7
7
|
if (source instanceof URL && source.protocol !== "file:") return fetchWasmUrl(source);
|
|
8
8
|
if (source instanceof URL) throw new CryptoError(`cannot fetch wasm from ${source.href}`);
|
|
9
|
-
return fetchWasmUrl(new URL("
|
|
9
|
+
return fetchWasmUrl(new URL("nk_wasm.wasm", import.meta.url));
|
|
10
10
|
}
|
|
11
11
|
const loader = createNostrWasmLoader(wasmBytes);
|
|
12
12
|
/** Instantiate once. Repeats reuse the same module. Failure throws; no noble fallback. */
|
package/dist/browser.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.mjs","names":[],"sources":["../src/load.browser.ts"],"sourcesContent":["import { CryptoError } from \"@qntx/nostr/core\";\n\nimport { createNostrWasmLoader, fetchWasmUrl, isWasmBytes } from \"./instance.ts\";\nimport type { LoadNostrWasmOptions, NostrWasm } from \"./instance.ts\";\n\nexport type { LoadNostrWasmOptions, NostrWasm } from \"./instance.ts\";\n\nasync function wasmBytes(opts?: LoadNostrWasmOptions): Promise<ArrayBuffer | ArrayBufferView> {\n const source = opts?.module;\n if (source !== undefined && isWasmBytes(source)) {\n return source;\n }\n if (source instanceof URL && source.protocol !== \"file:\") {\n return fetchWasmUrl(source);\n }\n if (source instanceof URL) {\n throw new CryptoError(`cannot fetch wasm from ${source.href}`);\n }\n return fetchWasmUrl(new URL(\"
|
|
1
|
+
{"version":3,"file":"browser.mjs","names":[],"sources":["../src/load.browser.ts"],"sourcesContent":["import { CryptoError } from \"@qntx/nostr/core\";\n\nimport { createNostrWasmLoader, fetchWasmUrl, isWasmBytes } from \"./instance.ts\";\nimport type { LoadNostrWasmOptions, NostrWasm } from \"./instance.ts\";\n\nexport type { LoadNostrWasmOptions, NostrWasm } from \"./instance.ts\";\n\nasync function wasmBytes(opts?: LoadNostrWasmOptions): Promise<ArrayBuffer | ArrayBufferView> {\n const source = opts?.module;\n if (source !== undefined && isWasmBytes(source)) {\n return source;\n }\n if (source instanceof URL && source.protocol !== \"file:\") {\n return fetchWasmUrl(source);\n }\n if (source instanceof URL) {\n throw new CryptoError(`cannot fetch wasm from ${source.href}`);\n }\n return fetchWasmUrl(new URL(\"nk_wasm.wasm\", import.meta.url));\n}\n\nconst loader = createNostrWasmLoader(wasmBytes);\n\n/** Instantiate once. Repeats reuse the same module. Failure throws; no noble fallback. */\nexport async function loadNostrWasm(opts?: LoadNostrWasmOptions): Promise<NostrWasm> {\n return loader.loadNostrWasm(opts);\n}\n"],"mappings":";;;AAOA,eAAe,UAAU,MAAqE;CAC5F,MAAM,SAAS,MAAM;CACrB,IAAI,WAAW,KAAA,KAAa,YAAY,MAAM,GAC5C,OAAO;CAET,IAAI,kBAAkB,OAAO,OAAO,aAAa,SAC/C,OAAO,aAAa,MAAM;CAE5B,IAAI,kBAAkB,KACpB,MAAM,IAAI,YAAY,0BAA0B,OAAO,MAAM;CAE/D,OAAO,aAAa,IAAI,IAAI,gBAAgB,YAAY,GAAG,CAAC;AAC9D;AAEA,MAAM,SAAS,sBAAsB,SAAS;;AAG9C,eAAsB,cAAc,MAAiD;CACnF,OAAO,OAAO,cAAc,IAAI;AAClC"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { i as WasmPoisonedError, n as fetchWasmUrl, r as isWasmBytes, t as createNostrWasmLoader } from "./instance-
|
|
1
|
+
import { i as WasmPoisonedError, n as fetchWasmUrl, r as isWasmBytes, t as createNostrWasmLoader } from "./instance-CFwzTT0p.mjs";
|
|
2
2
|
//#region src/load.ts
|
|
3
3
|
async function defaultWasmHref() {
|
|
4
|
-
return (await import("./
|
|
4
|
+
return (await import("./nk_wasm-BbbBKBiH.mjs")).default;
|
|
5
5
|
}
|
|
6
6
|
async function readWasmUrl(url) {
|
|
7
7
|
if (url.protocol === "file:") {
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/load.ts"],"sourcesContent":["import { createNostrWasmLoader, fetchWasmUrl, isWasmBytes } from \"./instance.ts\";\nimport type { LoadNostrWasmOptions, NostrWasm } from \"./instance.ts\";\n\nexport { WasmPoisonedError } from \"./adapter.ts\";\nexport type { LoadNostrWasmOptions, NostrWasm } from \"./instance.ts\";\n\nasync function defaultWasmHref(): Promise<string> {\n const mod = await import(\"./
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/load.ts"],"sourcesContent":["import { createNostrWasmLoader, fetchWasmUrl, isWasmBytes } from \"./instance.ts\";\nimport type { LoadNostrWasmOptions, NostrWasm } from \"./instance.ts\";\n\nexport { WasmPoisonedError } from \"./adapter.ts\";\nexport type { LoadNostrWasmOptions, NostrWasm } from \"./instance.ts\";\n\nasync function defaultWasmHref(): Promise<string> {\n const mod = await import(\"./nk_wasm.wasm?url\");\n return mod.default;\n}\n\nasync function readWasmUrl(url: URL): Promise<Uint8Array> {\n if (url.protocol === \"file:\") {\n const { readFile } = await import(\"node:fs/promises\");\n const { fileURLToPath } = await import(\"node:url\");\n return new Uint8Array(await readFile(fileURLToPath(url)));\n }\n return fetchWasmUrl(url);\n}\n\nasync function wasmBytes(opts?: LoadNostrWasmOptions): Promise<ArrayBuffer | ArrayBufferView> {\n const source = opts?.module;\n if (source !== undefined && isWasmBytes(source)) {\n return source;\n }\n const href = source instanceof URL ? source : new URL(await defaultWasmHref(), import.meta.url);\n return readWasmUrl(href);\n}\n\nconst loader = createNostrWasmLoader(wasmBytes);\n\n/** Instantiate once. Repeats reuse the same module. Failure throws; no noble fallback. */\nexport async function loadNostrWasm(opts?: LoadNostrWasmOptions): Promise<NostrWasm> {\n return loader.loadNostrWasm(opts);\n}\n"],"mappings":";;AAMA,eAAe,kBAAmC;CAEhD,QAAO,MADW,OAAO,0BAAA,CACd;AACb;AAEA,eAAe,YAAY,KAA+B;CACxD,IAAI,IAAI,aAAa,SAAS;EAC5B,MAAM,EAAE,aAAa,MAAM,OAAO;EAClC,MAAM,EAAE,kBAAkB,MAAM,OAAO;EACvC,OAAO,IAAI,WAAW,MAAM,SAAS,cAAc,GAAG,CAAC,CAAC;CAC1D;CACA,OAAO,aAAa,GAAG;AACzB;AAEA,eAAe,UAAU,MAAqE;CAC5F,MAAM,SAAS,MAAM;CACrB,IAAI,WAAW,KAAA,KAAa,YAAY,MAAM,GAC5C,OAAO;CAGT,OAAO,YADM,kBAAkB,MAAM,SAAS,IAAI,IAAI,MAAM,gBAAgB,GAAG,YAAY,GAAG,CACvE;AACzB;AAEA,MAAM,SAAS,sBAAsB,SAAS;;AAG9C,eAAsB,cAAc,MAAiD;CACnF,OAAO,OAAO,cAAc,IAAI;AAClC"}
|
|
@@ -1,37 +1,8 @@
|
|
|
1
1
|
import { CryptoError, WasmPoisonedError, WasmPoisonedError as WasmPoisonedError$1, createEventVerifier } from "@qntx/nostr/core";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
name: "__wbindgen_throw"
|
|
7
|
-
}, {
|
|
8
|
-
module: "./nk_wasm_bg.js",
|
|
9
|
-
name: "__wbindgen_throw"
|
|
10
|
-
}];
|
|
11
|
-
const utf8 = new TextDecoder();
|
|
12
|
-
function decodeUtf8(memory, ptr, len) {
|
|
13
|
-
return utf8.decode(new Uint8Array(memory.buffer, ptr, len));
|
|
14
|
-
}
|
|
15
|
-
function makeWbgImports(holder) {
|
|
16
|
-
const throwRuntime = (ptr, len) => {
|
|
17
|
-
const mem = holder.exports?.memory;
|
|
18
|
-
const msg = mem ? decodeUtf8(mem, ptr, len) : "wasm panic";
|
|
19
|
-
throw new WebAssembly.RuntimeError(msg);
|
|
20
|
-
};
|
|
21
|
-
const wbg = { __wbindgen_throw: throwRuntime };
|
|
22
|
-
return {
|
|
23
|
-
wbg,
|
|
24
|
-
"./nk_wasm_bg.js": wbg
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
/** Fail if the module imports anything outside {@link ALLOWED_WASM_IMPORTS}. */
|
|
28
|
-
function assertAllowedWasmImports(mod) {
|
|
29
|
-
const allowed = new Set(ALLOWED_WASM_IMPORTS.map((item) => `${item.module}\0${item.name}`));
|
|
30
|
-
for (const imp of WebAssembly.Module.imports(mod)) {
|
|
31
|
-
if (imp.kind !== "function") throw new TypeError(`unexpected wasm import kind ${imp.kind}: ${imp.module}.${imp.name}`);
|
|
32
|
-
if (!allowed.has(`${imp.module}\0${imp.name}`)) throw new TypeError(`unexpected wasm import ${imp.module}.${imp.name}`);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
2
|
+
const ID_LEN = 32;
|
|
3
|
+
const PUBKEY_LEN = 32;
|
|
4
|
+
const SIG_LEN = 64;
|
|
5
|
+
const SECKEY_LEN = 32;
|
|
35
6
|
function requireMemory(value) {
|
|
36
7
|
if (!(value instanceof WebAssembly.Memory)) throw new TypeError("wasm missing memory export");
|
|
37
8
|
return value;
|
|
@@ -41,81 +12,87 @@ function requireFn(value, name) {
|
|
|
41
12
|
return value;
|
|
42
13
|
}
|
|
43
14
|
function asExports(raw) {
|
|
44
|
-
|
|
15
|
+
return {
|
|
45
16
|
memory: requireMemory(raw["memory"]),
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
__wbindgen_add_to_stack_pointer: requireFn(raw["__wbindgen_add_to_stack_pointer"], "__wbindgen_add_to_stack_pointer")
|
|
17
|
+
nk_abi_version: requireFn(raw["nk_abi_version"], "nk_abi_version"),
|
|
18
|
+
nk_buffer: requireFn(raw["nk_buffer"], "nk_buffer"),
|
|
19
|
+
nk_verify: requireFn(raw["nk_verify"], "nk_verify"),
|
|
20
|
+
nk_verify_serialized: requireFn(raw["nk_verify_serialized"], "nk_verify_serialized"),
|
|
21
|
+
nk_sign: requireFn(raw["nk_sign"], "nk_sign"),
|
|
22
|
+
nk_public_key: requireFn(raw["nk_public_key"], "nk_public_key")
|
|
53
23
|
};
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const ptr = exports.
|
|
61
|
-
new Uint8Array(exports.memory.buffer, ptr, len).set(bytes);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Reserve `total` bytes in the wasm scratch region and return a fresh view. The view is taken after
|
|
27
|
+
* `nk_buffer` ran, so a growth inside it cannot leave a detached view in the caller's hands.
|
|
28
|
+
*/
|
|
29
|
+
function scratch(exports, total) {
|
|
30
|
+
const ptr = exports.nk_buffer(total) >>> 0;
|
|
62
31
|
return {
|
|
63
32
|
ptr,
|
|
64
|
-
|
|
33
|
+
view: new Uint8Array(exports.memory.buffer, ptr, total)
|
|
65
34
|
};
|
|
66
35
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
const pkP = passBytes(exports, pubkey);
|
|
70
|
-
const sigP = passBytes(exports, sig);
|
|
71
|
-
return exports.verify(idP.ptr, idP.len, pkP.ptr, pkP.len, sigP.ptr, sigP.len) !== 0;
|
|
72
|
-
}
|
|
73
|
-
function wasmVerifySerialized(exports, serialized, id, pubkey, sig) {
|
|
74
|
-
const serP = passBytes(exports, serialized);
|
|
75
|
-
const idP = passBytes(exports, id);
|
|
76
|
-
const pkP = passBytes(exports, pubkey);
|
|
77
|
-
const sigP = passBytes(exports, sig);
|
|
78
|
-
return exports.verify_serialized(serP.ptr, serP.len, idP.ptr, idP.len, pkP.ptr, pkP.len, sigP.ptr, sigP.len) !== 0;
|
|
79
|
-
}
|
|
80
|
-
function takeBytes(exports, ptr, len) {
|
|
36
|
+
/** Copies `len` scratch bytes out; the view is re-acquired after the call. */
|
|
37
|
+
function takeOut(exports, ptr, len) {
|
|
81
38
|
const out = new Uint8Array(len);
|
|
82
|
-
|
|
83
|
-
out.set(new Uint8Array(exports.memory.buffer, ptr, len));
|
|
84
|
-
exports.__wbindgen_export2(ptr, len, 1);
|
|
85
|
-
}
|
|
39
|
+
out.set(new Uint8Array(exports.memory.buffer, ptr, len));
|
|
86
40
|
return out;
|
|
87
41
|
}
|
|
88
|
-
function
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
42
|
+
function wasmVerify(exports, id, pubkey, sig) {
|
|
43
|
+
if (id.length !== ID_LEN || pubkey.length !== PUBKEY_LEN || sig.length !== SIG_LEN) return false;
|
|
44
|
+
const { ptr, view } = scratch(exports, 128);
|
|
45
|
+
view.set(id, 0);
|
|
46
|
+
view.set(pubkey, ID_LEN);
|
|
47
|
+
view.set(sig, 64);
|
|
48
|
+
return exports.nk_verify(ptr, ptr + ID_LEN, ptr + ID_LEN + PUBKEY_LEN) === 0;
|
|
49
|
+
}
|
|
50
|
+
function wasmVerifySerialized(exports, serialized, id, pubkey, sig) {
|
|
51
|
+
if (id.length !== ID_LEN || pubkey.length !== PUBKEY_LEN || sig.length !== SIG_LEN) return false;
|
|
52
|
+
const serLen = serialized.length;
|
|
53
|
+
const { ptr, view } = scratch(exports, serLen + ID_LEN + PUBKEY_LEN + SIG_LEN);
|
|
54
|
+
view.set(serialized, 0);
|
|
55
|
+
view.set(id, serLen);
|
|
56
|
+
view.set(pubkey, serLen + ID_LEN);
|
|
57
|
+
view.set(sig, serLen + ID_LEN + PUBKEY_LEN);
|
|
58
|
+
return exports.nk_verify_serialized(ptr, serLen, ptr + serLen, ptr + serLen + ID_LEN, ptr + serLen + ID_LEN + PUBKEY_LEN) === 0;
|
|
97
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* Returns the 64-byte signature, or an empty array on failure (invalid input). The Rust side zeroes
|
|
62
|
+
* the scratch copy of `seckey` before returning.
|
|
63
|
+
*/
|
|
98
64
|
function wasmSign(exports, id, seckey, aux) {
|
|
99
|
-
const
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
65
|
+
const outOffset = 96;
|
|
66
|
+
const { ptr, view } = scratch(exports, 160);
|
|
67
|
+
view.set(id, 0);
|
|
68
|
+
view.set(seckey, ID_LEN);
|
|
69
|
+
view.set(aux, 64);
|
|
70
|
+
if (exports.nk_sign(ptr, ptr + ID_LEN, ptr + ID_LEN + SECKEY_LEN, ptr + outOffset) !== 0) return /* @__PURE__ */ new Uint8Array(0);
|
|
71
|
+
return takeOut(exports, ptr + outOffset, SIG_LEN);
|
|
105
72
|
}
|
|
73
|
+
/**
|
|
74
|
+
* Returns the 32-byte x-only public key, or an empty array on failure. The Rust side zeroes the
|
|
75
|
+
* scratch copy of `seckey` before returning.
|
|
76
|
+
*/
|
|
106
77
|
function wasmPublicKey(exports, seckey) {
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
78
|
+
const { ptr, view } = scratch(exports, 64);
|
|
79
|
+
view.set(seckey, 0);
|
|
80
|
+
if (exports.nk_public_key(ptr, ptr + SECKEY_LEN) !== 0) return /* @__PURE__ */ new Uint8Array(0);
|
|
81
|
+
return takeOut(exports, ptr + SECKEY_LEN, PUBKEY_LEN);
|
|
111
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Compile and instantiate `nk_wasm.wasm`. The module must declare no imports and must implement ABI
|
|
85
|
+
* version {@link NK_ABI_VERSION} — a mismatch means the artifact predates or postdates this loader
|
|
86
|
+
* and instantiation fails.
|
|
87
|
+
*/
|
|
112
88
|
async function instantiateCryptoWasm(bytes) {
|
|
113
|
-
const
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
89
|
+
const module = await WebAssembly.compile(bytes);
|
|
90
|
+
const imports = WebAssembly.Module.imports(module);
|
|
91
|
+
if (imports.length > 0) throw new TypeError(`nk_wasm module must not import anything, got ${imports.length} imports`);
|
|
92
|
+
const instance = await WebAssembly.instantiate(module, {});
|
|
93
|
+
const version = requireFn(instance.exports["nk_abi_version"], "nk_abi_version")();
|
|
94
|
+
if (version !== 1) throw new CryptoError(`unsupported nk_wasm ABI version ${String(version)}, expected 1`);
|
|
95
|
+
return asExports(instance.exports);
|
|
119
96
|
}
|
|
120
97
|
//#endregion
|
|
121
98
|
//#region src/adapter.ts
|
|
@@ -216,4 +193,4 @@ function createNostrWasmLoader(wasmBytes) {
|
|
|
216
193
|
//#endregion
|
|
217
194
|
export { WasmPoisonedError$1 as i, fetchWasmUrl as n, isWasmBytes as r, createNostrWasmLoader as t };
|
|
218
195
|
|
|
219
|
-
//# sourceMappingURL=instance-
|
|
196
|
+
//# sourceMappingURL=instance-CFwzTT0p.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instance-CFwzTT0p.mjs","names":[],"sources":["../src/abi.ts","../src/adapter.ts","../src/instance.ts"],"sourcesContent":["import { CryptoError } from \"@qntx/nostr/core\";\n\n/**\n * Byte-ABI version 1 surface exported by `nk_wasm.wasm` (`crates/nk-wasm/src/abi.rs`). All inputs\n * are caller-written regions of a single scratch buffer; status codes are 0 ok/verified, 1\n * verification failed, 2 invalid input.\n */\nexport type CryptoWasmExports = {\n memory: WebAssembly.Memory;\n nk_abi_version: () => number;\n nk_buffer: (len: number) => number;\n nk_verify: (id: number, pubkey: number, sig: number) => number;\n nk_verify_serialized: (\n ser: number,\n serLen: number,\n id: number,\n pubkey: number,\n sig: number,\n ) => number;\n nk_sign: (id: number, seckey: number, aux: number, outSig: number) => number;\n nk_public_key: (seckey: number, outPubkey: number) => number;\n};\n\nexport const NK_ABI_VERSION = 1;\n\nconst ID_LEN = 32;\nconst PUBKEY_LEN = 32;\nconst SIG_LEN = 64;\nconst SECKEY_LEN = 32;\nconst AUX_LEN = 32;\n\nfunction requireMemory(value: WebAssembly.ExportValue | undefined): WebAssembly.Memory {\n if (!(value instanceof WebAssembly.Memory)) {\n throw new TypeError(\"wasm missing memory export\");\n }\n return value;\n}\n\n// oxlint-disable-next-line no-unnecessary-type-parameters -- T binds the declared ABI signature at each call site\nfunction requireFn<T extends (...args: number[]) => unknown>(\n value: WebAssembly.ExportValue | undefined,\n name: string,\n): T {\n if (typeof value !== \"function\") {\n throw new TypeError(`wasm missing ${name} export`);\n }\n // oxlint-disable-next-line no-unsafe-type-assertion -- wasm exports are opaque; each name is bound to the signature the ABI contract requires\n return value as T;\n}\n\nfunction asExports(raw: WebAssembly.Exports): CryptoWasmExports {\n return {\n memory: requireMemory(raw[\"memory\"]),\n nk_abi_version: requireFn(raw[\"nk_abi_version\"], \"nk_abi_version\"),\n nk_buffer: requireFn(raw[\"nk_buffer\"], \"nk_buffer\"),\n nk_verify: requireFn(raw[\"nk_verify\"], \"nk_verify\"),\n nk_verify_serialized: requireFn(raw[\"nk_verify_serialized\"], \"nk_verify_serialized\"),\n nk_sign: requireFn(raw[\"nk_sign\"], \"nk_sign\"),\n nk_public_key: requireFn(raw[\"nk_public_key\"], \"nk_public_key\"),\n };\n}\n\n/**\n * Reserve `total` bytes in the wasm scratch region and return a fresh view. The view is taken after\n * `nk_buffer` ran, so a growth inside it cannot leave a detached view in the caller's hands.\n */\nfunction scratch(exports: CryptoWasmExports, total: number): { ptr: number; view: Uint8Array } {\n const ptr = exports.nk_buffer(total) >>> 0;\n return { ptr, view: new Uint8Array(exports.memory.buffer, ptr, total) };\n}\n\n/** Copies `len` scratch bytes out; the view is re-acquired after the call. */\nfunction takeOut(exports: CryptoWasmExports, ptr: number, len: number): Uint8Array {\n const out = new Uint8Array(len);\n out.set(new Uint8Array(exports.memory.buffer, ptr, len));\n return out;\n}\n\nexport function wasmVerify(\n exports: CryptoWasmExports,\n id: Uint8Array,\n pubkey: Uint8Array,\n sig: Uint8Array,\n): boolean {\n if (id.length !== ID_LEN || pubkey.length !== PUBKEY_LEN || sig.length !== SIG_LEN) {\n return false; // fixed-size ABI: a wrong-length input simply cannot verify\n }\n const { ptr, view } = scratch(exports, ID_LEN + PUBKEY_LEN + SIG_LEN);\n view.set(id, 0);\n view.set(pubkey, ID_LEN);\n view.set(sig, ID_LEN + PUBKEY_LEN);\n return exports.nk_verify(ptr, ptr + ID_LEN, ptr + ID_LEN + PUBKEY_LEN) === 0;\n}\n\nexport function wasmVerifySerialized(\n exports: CryptoWasmExports,\n serialized: Uint8Array,\n id: Uint8Array,\n pubkey: Uint8Array,\n sig: Uint8Array,\n): boolean {\n if (id.length !== ID_LEN || pubkey.length !== PUBKEY_LEN || sig.length !== SIG_LEN) {\n return false;\n }\n const serLen = serialized.length;\n const { ptr, view } = scratch(exports, serLen + ID_LEN + PUBKEY_LEN + SIG_LEN);\n view.set(serialized, 0);\n view.set(id, serLen);\n view.set(pubkey, serLen + ID_LEN);\n view.set(sig, serLen + ID_LEN + PUBKEY_LEN);\n return (\n exports.nk_verify_serialized(\n ptr,\n serLen,\n ptr + serLen,\n ptr + serLen + ID_LEN,\n ptr + serLen + ID_LEN + PUBKEY_LEN,\n ) === 0\n );\n}\n\n/**\n * Returns the 64-byte signature, or an empty array on failure (invalid input). The Rust side zeroes\n * the scratch copy of `seckey` before returning.\n */\nexport function wasmSign(\n exports: CryptoWasmExports,\n id: Uint8Array,\n seckey: Uint8Array,\n aux: Uint8Array,\n): Uint8Array {\n const outOffset = ID_LEN + SECKEY_LEN + AUX_LEN;\n const { ptr, view } = scratch(exports, outOffset + SIG_LEN);\n view.set(id, 0);\n view.set(seckey, ID_LEN);\n view.set(aux, ID_LEN + SECKEY_LEN);\n const status = exports.nk_sign(ptr, ptr + ID_LEN, ptr + ID_LEN + SECKEY_LEN, ptr + outOffset);\n if (status !== 0) {\n return new Uint8Array(0);\n }\n return takeOut(exports, ptr + outOffset, SIG_LEN);\n}\n\n/**\n * Returns the 32-byte x-only public key, or an empty array on failure. The Rust side zeroes the\n * scratch copy of `seckey` before returning.\n */\nexport function wasmPublicKey(exports: CryptoWasmExports, seckey: Uint8Array): Uint8Array {\n const { ptr, view } = scratch(exports, SECKEY_LEN + PUBKEY_LEN);\n view.set(seckey, 0);\n const status = exports.nk_public_key(ptr, ptr + SECKEY_LEN);\n if (status !== 0) {\n return new Uint8Array(0);\n }\n return takeOut(exports, ptr + SECKEY_LEN, PUBKEY_LEN);\n}\n\n/**\n * Compile and instantiate `nk_wasm.wasm`. The module must declare no imports and must implement ABI\n * version {@link NK_ABI_VERSION} — a mismatch means the artifact predates or postdates this loader\n * and instantiation fails.\n */\nexport async function instantiateCryptoWasm(\n bytes: ArrayBuffer | ArrayBufferView,\n): Promise<CryptoWasmExports> {\n const module = await WebAssembly.compile(bytes);\n const imports = WebAssembly.Module.imports(module);\n if (imports.length > 0) {\n throw new TypeError(`nk_wasm module must not import anything, got ${imports.length} imports`);\n }\n const instance = await WebAssembly.instantiate(module, {});\n const version = requireFn(instance.exports[\"nk_abi_version\"], \"nk_abi_version\")();\n if (version !== NK_ABI_VERSION) {\n throw new CryptoError(\n `unsupported nk_wasm ABI version ${String(version)}, expected ${NK_ABI_VERSION}`,\n );\n }\n return asExports(instance.exports);\n}\n","import { WasmPoisonedError, createEventVerifier } from \"@qntx/nostr/core\";\nimport type { EventVerifier, SerializedEventVerifier } from \"@qntx/nostr/core\";\n\nexport { WasmPoisonedError } from \"@qntx/nostr/core\";\n\n/**\n * Run `fn` unless the instance is already poisoned; a `WebAssembly.RuntimeError` aborts the\n * instance, so it is converted to {@link WasmPoisonedError} and rethrown on every later call.\n */\nexport function runPoisoned<T>(poison: { error?: Error }, fn: () => T): T {\n if (poison.error !== undefined) {\n throw poison.error;\n }\n try {\n return fn();\n } catch (error) {\n if (error instanceof WebAssembly.RuntimeError) {\n poison.error = new WasmPoisonedError(\"wasm instance aborted\", {\n cause: error,\n });\n throw poison.error;\n }\n throw error;\n }\n}\n\n/**\n * Build the WASM event verifier on {@link createEventVerifier}. A `WebAssembly.RuntimeError` from\n * the module means the instance aborted — it poisons every later call with the same\n * `WasmPoisonedError`; any other backend error verifies `false` (the event is marked failed).\n */\nexport function createWasmEventVerifier(\n verifySerialized: SerializedEventVerifier,\n poison: { error?: Error },\n): EventVerifier {\n const backend: SerializedEventVerifier = (serializedUtf8, id, pubkey, sig) => {\n try {\n return runPoisoned(poison, () => verifySerialized(serializedUtf8, id, pubkey, sig));\n } catch (error) {\n if (error instanceof WasmPoisonedError) {\n throw error;\n }\n return false;\n }\n };\n return createEventVerifier(backend);\n}\n","import { CryptoError } from \"@qntx/nostr/core\";\nimport type { SigningBackend, EventVerifier } from \"@qntx/nostr/core\";\n\nimport {\n instantiateCryptoWasm,\n wasmPublicKey,\n wasmSign,\n wasmVerify,\n wasmVerifySerialized,\n} from \"./abi.ts\";\nimport type { CryptoWasmExports } from \"./abi.ts\";\nimport { createWasmEventVerifier, runPoisoned } from \"./adapter.ts\";\n\nexport type LoadNostrWasmOptions = {\n /** Bytes, or a URL whose bytes will be read by the platform loader. */\n module?: ArrayBuffer | ArrayBufferView | URL | undefined;\n};\n\nexport type NostrWasm = SigningBackend & {\n verify: (id: Uint8Array, pubkey: Uint8Array, sig: Uint8Array) => boolean;\n verifySerialized: (\n serializedUtf8: Uint8Array,\n id: Uint8Array,\n pubkey: Uint8Array,\n sig: Uint8Array,\n ) => boolean;\n verifyEvent: EventVerifier;\n};\n\nexport function isWasmBytes(value: unknown): value is ArrayBuffer | ArrayBufferView {\n return value instanceof ArrayBuffer || ArrayBuffer.isView(value);\n}\n\nexport async function fetchWasmUrl(url: URL): Promise<Uint8Array> {\n const res = await fetch(url);\n if (!res.ok) {\n throw new CryptoError(`failed to fetch wasm: ${res.status} ${url.href}`);\n }\n return new Uint8Array(await res.arrayBuffer());\n}\n\nfunction requireByteLength(bytes: Uint8Array, expected: number, label: string): void {\n if (bytes.length !== expected) {\n throw new CryptoError(`invalid ${label} length: expected ${expected}, got ${bytes.length}`);\n }\n}\n\nfunction bindExports(exports: CryptoWasmExports): NostrWasm {\n const poison: { error?: Error } = {};\n const rawSerialized = (\n serializedUtf8: Uint8Array,\n id: Uint8Array,\n pubkey: Uint8Array,\n sig: Uint8Array,\n ): boolean => wasmVerifySerialized(exports, serializedUtf8, id, pubkey, sig);\n return {\n verify: (id, pubkey, sig) => runPoisoned(poison, () => wasmVerify(exports, id, pubkey, sig)),\n verifySerialized: (serializedUtf8, id, pubkey, sig) =>\n runPoisoned(poison, () => rawSerialized(serializedUtf8, id, pubkey, sig)),\n verifyEvent: createWasmEventVerifier(rawSerialized, poison),\n sign: (id, seckey, aux) =>\n runPoisoned(poison, () => {\n requireByteLength(id, 32, \"id\");\n requireByteLength(seckey, 32, \"secret key\");\n requireByteLength(aux, 32, \"aux\");\n const sig = wasmSign(exports, id, seckey, aux);\n if (sig.length !== 64) {\n throw new CryptoError(\"wasm sign failed\");\n }\n return sig;\n }),\n publicKey: (seckey) =>\n runPoisoned(poison, () => {\n requireByteLength(seckey, 32, \"secret key\");\n const pk = wasmPublicKey(exports, seckey);\n if (pk.length !== 32) {\n throw new CryptoError(\"wasm publicKey failed\");\n }\n return pk;\n }),\n };\n}\n\n/** Builds a loader that interns a single instance per module slot. */\nexport function createNostrWasmLoader(\n wasmBytes: (opts?: LoadNostrWasmOptions) => Promise<ArrayBuffer | ArrayBufferView>,\n): {\n loadNostrWasm: (opts?: LoadNostrWasmOptions) => Promise<NostrWasm>;\n resetNostrWasm: () => void;\n} {\n let interned: Promise<NostrWasm> | undefined;\n\n async function instantiate(opts?: LoadNostrWasmOptions): Promise<NostrWasm> {\n const bytes = await wasmBytes(opts);\n const exports = await instantiateCryptoWasm(bytes);\n return bindExports(exports);\n }\n\n /** Instantiate once. Repeats reuse the same module. Failure throws; no noble fallback. */\n async function loadNostrWasm(opts?: LoadNostrWasmOptions): Promise<NostrWasm> {\n if (interned) {\n return interned;\n }\n const pending = instantiate(opts);\n interned = pending;\n try {\n return await pending;\n } catch (error) {\n if (interned === pending) {\n interned = undefined;\n }\n throw error;\n }\n }\n\n function resetNostrWasm(): void {\n interned = undefined;\n }\n\n return { loadNostrWasm, resetNostrWasm };\n}\n"],"mappings":"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"}
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qntx/nostr-wasm",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "WebAssembly-accelerated cryptography backend for @qntx/nostr",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"nostr",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@arethetypeswrong/cli": "0.18.5",
|
|
57
57
|
"@noble/curves": "2.4.0",
|
|
58
|
-
"@qntx/nostr": "0.
|
|
58
|
+
"@qntx/nostr": "0.11.0",
|
|
59
59
|
"@qntx/tsconfig": "1.0.1",
|
|
60
60
|
"@types/node": "26.6.3",
|
|
61
61
|
"binaryen": "132.0.0",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"vite-plus": "1.0.0"
|
|
65
65
|
},
|
|
66
66
|
"peerDependencies": {
|
|
67
|
-
"@qntx/nostr": "^0.
|
|
67
|
+
"@qntx/nostr": "^0.11.0"
|
|
68
68
|
},
|
|
69
69
|
"devEngines": {
|
|
70
70
|
"packageManager": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"instance-DS92CCrA.mjs","names":[],"sources":["../src/abi.ts","../src/adapter.ts","../src/instance.ts"],"sourcesContent":["/** Wasm-bindgen 0.2.122 bundler-produced exports used by interned TS glue. */\nexport type CryptoWasmExports = {\n memory: WebAssembly.Memory;\n verify: (\n idPtr: number,\n idLen: number,\n pkPtr: number,\n pkLen: number,\n sigPtr: number,\n sigLen: number,\n ) => number;\n verify_serialized: (\n serPtr: number,\n serLen: number,\n idPtr: number,\n idLen: number,\n pkPtr: number,\n pkLen: number,\n sigPtr: number,\n sigLen: number,\n ) => number;\n sign: (\n retptr: number,\n idPtr: number,\n idLen: number,\n skPtr: number,\n skLen: number,\n auxPtr: number,\n auxLen: number,\n ) => void;\n public_key: (retptr: number, skPtr: number, skLen: number) => void;\n /** 0.2.122 name for `__wbindgen_malloc(size, align)`. */\n __wbindgen_export: (size: number, align: number) => number;\n /** 0.2.122 name for `__wbindgen_free(ptr, size, align)` after malloc claimed `__wbindgen_export`. */\n __wbindgen_export2: (ptr: number, size: number, align: number) => void;\n __wbindgen_add_to_stack_pointer: (delta: number) => number;\n __wbindgen_start?: () => void;\n};\n\n/** Imports 0.2.122 may request. Instantiation fails if anything else appears. */\nexport const ALLOWED_WASM_IMPORTS: ReadonlyArray<{ module: string; name: string }> = [\n { module: \"wbg\", name: \"__wbindgen_throw\" },\n { module: \"./nk_wasm_bg.js\", name: \"__wbindgen_throw\" },\n];\n\nconst utf8 = new TextDecoder();\n\nfunction decodeUtf8(memory: WebAssembly.Memory, ptr: number, len: number): string {\n return utf8.decode(new Uint8Array(memory.buffer, ptr, len));\n}\n\nfunction makeWbgImports(holder: { exports?: CryptoWasmExports }): WebAssembly.Imports {\n const throwRuntime = (ptr: number, len: number): never => {\n const mem = holder.exports?.memory;\n const msg = mem ? decodeUtf8(mem, ptr, len) : \"wasm panic\";\n throw new WebAssembly.RuntimeError(msg);\n };\n const wbg = {\n __wbindgen_throw: throwRuntime,\n };\n return {\n wbg,\n \"./nk_wasm_bg.js\": wbg,\n };\n}\n\n/** Fail if the module imports anything outside {@link ALLOWED_WASM_IMPORTS}. */\nexport function assertAllowedWasmImports(mod: WebAssembly.Module): void {\n const allowed = new Set(ALLOWED_WASM_IMPORTS.map((item) => `${item.module}\\0${item.name}`));\n for (const imp of WebAssembly.Module.imports(mod)) {\n if (imp.kind !== \"function\") {\n throw new TypeError(`unexpected wasm import kind ${imp.kind}: ${imp.module}.${imp.name}`);\n }\n if (!allowed.has(`${imp.module}\\0${imp.name}`)) {\n throw new TypeError(`unexpected wasm import ${imp.module}.${imp.name}`);\n }\n }\n}\n\nfunction requireMemory(value: WebAssembly.ExportValue | undefined): WebAssembly.Memory {\n if (!(value instanceof WebAssembly.Memory)) {\n throw new TypeError(\"wasm missing memory export\");\n }\n return value;\n}\n\n// oxlint-disable-next-line no-unnecessary-type-parameters -- T binds the declared ABI signature at each call site\nfunction requireFn<T extends (...args: number[]) => unknown>(\n value: WebAssembly.ExportValue | undefined,\n name: string,\n): T {\n if (typeof value !== \"function\") {\n throw new TypeError(`wasm missing ${name} export`);\n }\n // oxlint-disable-next-line no-unsafe-type-assertion -- wasm exports are opaque; each name is bound to the signature the ABI contract requires\n return value as T;\n}\n\nfunction asExports(raw: WebAssembly.Exports): CryptoWasmExports {\n const exports: CryptoWasmExports = {\n memory: requireMemory(raw[\"memory\"]),\n verify: requireFn(raw[\"verify\"], \"verify\"),\n verify_serialized: requireFn(raw[\"verify_serialized\"], \"verify_serialized\"),\n sign: requireFn(raw[\"sign\"], \"sign\"),\n public_key: requireFn(raw[\"public_key\"], \"public_key\"),\n __wbindgen_export: requireFn(raw[\"__wbindgen_export\"], \"__wbindgen_export\"),\n __wbindgen_export2: requireFn(raw[\"__wbindgen_export2\"], \"__wbindgen_export2\"),\n __wbindgen_add_to_stack_pointer: requireFn(\n raw[\"__wbindgen_add_to_stack_pointer\"],\n \"__wbindgen_add_to_stack_pointer\",\n ),\n };\n const start = raw[\"__wbindgen_start\"];\n if (typeof start === \"function\") {\n exports.__wbindgen_start = requireFn<() => void>(start, \"__wbindgen_start\");\n }\n return exports;\n}\n\nfunction passBytes(exports: CryptoWasmExports, bytes: Uint8Array): { ptr: number; len: number } {\n const len = bytes.length;\n const ptr = exports.__wbindgen_export(len, 1) >>> 0;\n new Uint8Array(exports.memory.buffer, ptr, len).set(bytes);\n return { ptr, len };\n}\n\nexport function wasmVerify(\n exports: CryptoWasmExports,\n id: Uint8Array,\n pubkey: Uint8Array,\n sig: Uint8Array,\n): boolean {\n const idP = passBytes(exports, id);\n const pkP = passBytes(exports, pubkey);\n const sigP = passBytes(exports, sig);\n return exports.verify(idP.ptr, idP.len, pkP.ptr, pkP.len, sigP.ptr, sigP.len) !== 0;\n}\n\nexport function wasmVerifySerialized(\n exports: CryptoWasmExports,\n serialized: Uint8Array,\n id: Uint8Array,\n pubkey: Uint8Array,\n sig: Uint8Array,\n): boolean {\n const serP = passBytes(exports, serialized);\n const idP = passBytes(exports, id);\n const pkP = passBytes(exports, pubkey);\n const sigP = passBytes(exports, sig);\n return (\n exports.verify_serialized(\n serP.ptr,\n serP.len,\n idP.ptr,\n idP.len,\n pkP.ptr,\n pkP.len,\n sigP.ptr,\n sigP.len,\n ) !== 0\n );\n}\n\nfunction takeBytes(exports: CryptoWasmExports, ptr: number, len: number): Uint8Array {\n const out = new Uint8Array(len);\n if (len > 0) {\n out.set(new Uint8Array(exports.memory.buffer, ptr, len));\n exports.__wbindgen_export2(ptr, len, 1);\n }\n return out;\n}\n\nfunction callReturningBytes(\n exports: CryptoWasmExports,\n invoke: (retptr: number) => void,\n): Uint8Array {\n const retptr = exports.__wbindgen_add_to_stack_pointer(-16);\n try {\n invoke(retptr);\n const view = new DataView(exports.memory.buffer);\n const ptr = view.getUint32(retptr, true);\n const len = view.getUint32(retptr + 4, true);\n return takeBytes(exports, ptr, len);\n } finally {\n exports.__wbindgen_add_to_stack_pointer(16);\n }\n}\n\nexport function wasmSign(\n exports: CryptoWasmExports,\n id: Uint8Array,\n seckey: Uint8Array,\n aux: Uint8Array,\n): Uint8Array {\n const idP = passBytes(exports, id);\n const skP = passBytes(exports, seckey);\n const auxP = passBytes(exports, aux);\n return callReturningBytes(exports, (retptr) => {\n exports.sign(retptr, idP.ptr, idP.len, skP.ptr, skP.len, auxP.ptr, auxP.len);\n });\n}\n\nexport function wasmPublicKey(exports: CryptoWasmExports, seckey: Uint8Array): Uint8Array {\n const skP = passBytes(exports, seckey);\n return callReturningBytes(exports, (retptr) => {\n exports.public_key(retptr, skP.ptr, skP.len);\n });\n}\n\nexport async function instantiateCryptoWasm(\n bytes: ArrayBuffer | ArrayBufferView,\n): Promise<CryptoWasmExports> {\n const holder: { exports?: CryptoWasmExports } = {};\n const { module, instance } = await WebAssembly.instantiate(bytes, makeWbgImports(holder));\n assertAllowedWasmImports(module);\n holder.exports = asExports(instance.exports);\n holder.exports.__wbindgen_start?.();\n return holder.exports;\n}\n","import { WasmPoisonedError, createEventVerifier } from \"@qntx/nostr/core\";\nimport type { EventVerifier, SerializedEventVerifier } from \"@qntx/nostr/core\";\n\nexport { WasmPoisonedError } from \"@qntx/nostr/core\";\n\n/**\n * Run `fn` unless the instance is already poisoned; a `WebAssembly.RuntimeError` aborts the\n * instance, so it is converted to {@link WasmPoisonedError} and rethrown on every later call.\n */\nexport function runPoisoned<T>(poison: { error?: Error }, fn: () => T): T {\n if (poison.error !== undefined) {\n throw poison.error;\n }\n try {\n return fn();\n } catch (error) {\n if (error instanceof WebAssembly.RuntimeError) {\n poison.error = new WasmPoisonedError(\"wasm instance aborted\", {\n cause: error,\n });\n throw poison.error;\n }\n throw error;\n }\n}\n\n/**\n * Build the WASM event verifier on {@link createEventVerifier}. A `WebAssembly.RuntimeError` from\n * the module means the instance aborted — it poisons every later call with the same\n * `WasmPoisonedError`; any other backend error verifies `false` (the event is marked failed).\n */\nexport function createWasmEventVerifier(\n verifySerialized: SerializedEventVerifier,\n poison: { error?: Error },\n): EventVerifier {\n const backend: SerializedEventVerifier = (serializedUtf8, id, pubkey, sig) => {\n try {\n return runPoisoned(poison, () => verifySerialized(serializedUtf8, id, pubkey, sig));\n } catch (error) {\n if (error instanceof WasmPoisonedError) {\n throw error;\n }\n return false;\n }\n };\n return createEventVerifier(backend);\n}\n","import { CryptoError } from \"@qntx/nostr/core\";\nimport type { SigningBackend, EventVerifier } from \"@qntx/nostr/core\";\n\nimport {\n instantiateCryptoWasm,\n wasmPublicKey,\n wasmSign,\n wasmVerify,\n wasmVerifySerialized,\n} from \"./abi.ts\";\nimport type { CryptoWasmExports } from \"./abi.ts\";\nimport { createWasmEventVerifier, runPoisoned } from \"./adapter.ts\";\n\nexport type LoadNostrWasmOptions = {\n /** Bytes, or a URL whose bytes will be read by the platform loader. */\n module?: ArrayBuffer | ArrayBufferView | URL | undefined;\n};\n\nexport type NostrWasm = SigningBackend & {\n verify: (id: Uint8Array, pubkey: Uint8Array, sig: Uint8Array) => boolean;\n verifySerialized: (\n serializedUtf8: Uint8Array,\n id: Uint8Array,\n pubkey: Uint8Array,\n sig: Uint8Array,\n ) => boolean;\n verifyEvent: EventVerifier;\n};\n\nexport function isWasmBytes(value: unknown): value is ArrayBuffer | ArrayBufferView {\n return value instanceof ArrayBuffer || ArrayBuffer.isView(value);\n}\n\nexport async function fetchWasmUrl(url: URL): Promise<Uint8Array> {\n const res = await fetch(url);\n if (!res.ok) {\n throw new CryptoError(`failed to fetch wasm: ${res.status} ${url.href}`);\n }\n return new Uint8Array(await res.arrayBuffer());\n}\n\nfunction requireByteLength(bytes: Uint8Array, expected: number, label: string): void {\n if (bytes.length !== expected) {\n throw new CryptoError(`invalid ${label} length: expected ${expected}, got ${bytes.length}`);\n }\n}\n\nfunction bindExports(exports: CryptoWasmExports): NostrWasm {\n const poison: { error?: Error } = {};\n const rawSerialized = (\n serializedUtf8: Uint8Array,\n id: Uint8Array,\n pubkey: Uint8Array,\n sig: Uint8Array,\n ): boolean => wasmVerifySerialized(exports, serializedUtf8, id, pubkey, sig);\n return {\n verify: (id, pubkey, sig) => runPoisoned(poison, () => wasmVerify(exports, id, pubkey, sig)),\n verifySerialized: (serializedUtf8, id, pubkey, sig) =>\n runPoisoned(poison, () => rawSerialized(serializedUtf8, id, pubkey, sig)),\n verifyEvent: createWasmEventVerifier(rawSerialized, poison),\n sign: (id, seckey, aux) =>\n runPoisoned(poison, () => {\n requireByteLength(id, 32, \"id\");\n requireByteLength(seckey, 32, \"secret key\");\n requireByteLength(aux, 32, \"aux\");\n const sig = wasmSign(exports, id, seckey, aux);\n if (sig.length !== 64) {\n throw new CryptoError(\"wasm sign failed\");\n }\n return sig;\n }),\n publicKey: (seckey) =>\n runPoisoned(poison, () => {\n requireByteLength(seckey, 32, \"secret key\");\n const pk = wasmPublicKey(exports, seckey);\n if (pk.length !== 32) {\n throw new CryptoError(\"wasm publicKey failed\");\n }\n return pk;\n }),\n };\n}\n\n/** Builds a loader that interns a single instance per module slot. */\nexport function createNostrWasmLoader(\n wasmBytes: (opts?: LoadNostrWasmOptions) => Promise<ArrayBuffer | ArrayBufferView>,\n): {\n loadNostrWasm: (opts?: LoadNostrWasmOptions) => Promise<NostrWasm>;\n resetNostrWasm: () => void;\n} {\n let interned: Promise<NostrWasm> | undefined;\n\n async function instantiate(opts?: LoadNostrWasmOptions): Promise<NostrWasm> {\n const bytes = await wasmBytes(opts);\n const exports = await instantiateCryptoWasm(bytes);\n return bindExports(exports);\n }\n\n /** Instantiate once. Repeats reuse the same module. Failure throws; no noble fallback. */\n async function loadNostrWasm(opts?: LoadNostrWasmOptions): Promise<NostrWasm> {\n if (interned) {\n return interned;\n }\n const pending = instantiate(opts);\n interned = pending;\n try {\n return await pending;\n } catch (error) {\n if (interned === pending) {\n interned = undefined;\n }\n throw error;\n }\n }\n\n function resetNostrWasm(): void {\n interned = undefined;\n }\n\n return { loadNostrWasm, resetNostrWasm };\n}\n"],"mappings":"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"}
|
package/dist/nk_wasm_bg.wasm
DELETED
|
Binary file
|