@waaskey/sdk 0.3.2 → 0.4.1

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/node.d.ts CHANGED
@@ -105,8 +105,50 @@ interface DeviceReshareAssembleParams {
105
105
  wallet: unknown;
106
106
  /** One Feldman-commitments object per dealer (the broadcast set), opaque JSON. */
107
107
  commitments: unknown[];
108
- /** This device's private sub-share from each dealer, one per dealer, opaque JSON. */
108
+ /**
109
+ * This device's SEALED sub-share from each dealer, one per dealer — hex ciphertext, opened with
110
+ * {@link encryptionSecret} before the core verifies and assembles it.
111
+ */
109
112
  subShares: unknown[];
113
+ /**
114
+ * This holder's X25519 SECRET key (32-byte hex) — the counterpart of the public key the dealers
115
+ * sealed to, and the only thing that can open {@link subShares}.
116
+ *
117
+ * Required: dealers seal every sub-share (waas-core #365 M-A), so an assemble without it cannot
118
+ * even parse its inputs. SECRET — never log it.
119
+ */
120
+ encryptionSecret: string;
121
+ }
122
+ /**
123
+ * Parameters for the device's reshare **deal** stage ({@link MpcCore.runReshareDeal}) — the OLD
124
+ * holder's half, computed locally from its current share. Pure: no relay, no rounds.
125
+ */
126
+ interface DeviceReshareDealParams {
127
+ curve: MpcCurve;
128
+ /** This holder's CURRENT (old-epoch) key share JSON. Secret — never log it. */
129
+ share: string;
130
+ /** Keygen indices of the authorising old quorum, from the ceremony plan. */
131
+ quorumIndices: number[];
132
+ /** New share preimages `I'` (32-byte big-endian hex scalars), new-holder order. */
133
+ newPreimages: string[];
134
+ /** The new signing threshold `t'`. */
135
+ newThreshold: number;
136
+ /**
137
+ * Each NEW holder's X25519 PUBLIC key (32-byte hex), in new-holder order. The dealer seals
138
+ * sub-share `k` to `recipientPubkeys[k]`, so only ciphertext leaves the device.
139
+ */
140
+ recipientPubkeys: string[];
141
+ }
142
+ /**
143
+ * Result of the device reshare **deal** — what the ceremony expects back: the PUBLIC commitments
144
+ * to broadcast and one SEALED sub-share per new holder. No plaintext sub-share is ever produced
145
+ * outside the core.
146
+ */
147
+ interface DeviceReshareDealResult {
148
+ /** The dealer's public Feldman commitments (opaque JSON) — broadcast to every new holder. */
149
+ commitments: unknown;
150
+ /** One sealed sub-share (hex ciphertext) per NEW holder, in new-holder order. */
151
+ sealedSubShares: string[];
110
152
  }
111
153
  /**
112
154
  * Result of the device reshare **assemble** — the bare NEW-epoch core. It cannot sign yet
@@ -276,6 +318,12 @@ interface MpcCore {
276
318
  * it (the web wasm needs a `--features reshare` build).
277
319
  */
278
320
  runReshareAssemble?(params: DeviceReshareAssembleParams): Promise<DeviceReshareAssembleResult>;
321
+ /**
322
+ * Deal this holder's contribution to a reshare (#488) — the OLD-holder stage, pure and local.
323
+ * Optional: only a core built with the reshare capability implements it (the web wasm needs a
324
+ * `--features reshare` build).
325
+ */
326
+ runReshareDeal?(params: DeviceReshareDealParams): Promise<DeviceReshareDealResult>;
279
327
  /**
280
328
  * Complete a reshared bare core into a signable share by running the aux-info ceremony over the
281
329
  * NEW committee (#318 / #95). Relay-driven, mirroring keygen's aux phase. Optional: only a core
@@ -324,6 +372,11 @@ interface ClientWasmModule {
324
372
  * Synchronous in the core (no relay); the SDK awaits it uniformly.
325
373
  */
326
374
  reshareAssemble?(paramsJson: string): unknown | Promise<unknown>;
375
+ /**
376
+ * Device reshare **deal** — the old holder's local contribution; returns
377
+ * `{ commitments_json, sealed_sub_shares_hex }`. Present only in a `--features reshare` build.
378
+ */
379
+ reshareDeal?(paramsJson: string): unknown | Promise<unknown>;
327
380
  /**
328
381
  * Device **complete-reshare** — run the aux ceremony over the new committee and return the
329
382
  * signable share as `{ keyshare_json, shared_public_key_json }`. Present only in a
@@ -372,6 +425,7 @@ declare class WasmMpcCore implements MpcCore {
372
425
  runSign(params: DeviceSignParams): Promise<DeviceSignResult>;
373
426
  pregeneratePrimes(curve: MpcCurve): Promise<string>;
374
427
  runReshareAssemble(params: DeviceReshareAssembleParams): Promise<DeviceReshareAssembleResult>;
428
+ runReshareDeal(params: DeviceReshareDealParams): Promise<DeviceReshareDealResult>;
375
429
  runCompleteReshare(params: DeviceCompleteReshareParams): Promise<DeviceCompleteReshareResult>;
376
430
  runMemberKeygen(params: MemberKeygenParams): Promise<DeviceKeygenResult>;
377
431
  runMemberSign(params: MemberSignParams): Promise<DeviceSignResult>;
package/dist/node.js CHANGED
@@ -68,7 +68,10 @@ var WasmMpcCore = class {
68
68
  new_threshold: params.newThreshold,
69
69
  wallet: params.wallet,
70
70
  commitments: params.commitments,
71
- sub_shares: params.subShares
71
+ sub_shares: params.subShares,
72
+ // The core opens the SEALED sub-shares with this before it can verify or assemble anything;
73
+ // omitting it (as this did until #488) makes the call fail on its own parameter parse.
74
+ encryption_secret: params.encryptionSecret
72
75
  })
73
76
  );
74
77
  if (!raw || typeof raw.core_json !== "string") {
@@ -76,6 +79,26 @@ var WasmMpcCore = class {
76
79
  }
77
80
  return { core: raw.core_json, sharedPublicKey: decodePublicKey(raw.shared_public_key_json) };
78
81
  }
82
+ async runReshareDeal(params) {
83
+ const wasm = await this.init();
84
+ if (!wasm.reshareDeal) {
85
+ throw new Error(reshareFeatureHint("reshareDeal"));
86
+ }
87
+ const raw = await wasm.reshareDeal(
88
+ JSON.stringify({
89
+ curve: params.curve,
90
+ share: JSON.parse(params.share),
91
+ quorum_indices: params.quorumIndices,
92
+ new_preimages: params.newPreimages,
93
+ new_threshold: params.newThreshold,
94
+ recipient_pubkeys: params.recipientPubkeys
95
+ })
96
+ );
97
+ if (!raw || !Array.isArray(raw.sealed_sub_shares_hex)) {
98
+ throw new Error("client-wasm returned an unexpected reshareDeal result");
99
+ }
100
+ return { commitments: raw.commitments_json, sealedSubShares: raw.sealed_sub_shares_hex };
101
+ }
79
102
  async runCompleteReshare(params) {
80
103
  const wasm = await this.init();
81
104
  if (!wasm.completeReshare) {
package/dist/node.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/mpc/wasm-core.ts","../src/mpc/node/worker-core.ts"],"names":["RealWebSocket"],"mappings":"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","file":"node.js","sourcesContent":["import type {\n DeviceCompleteReshareParams,\n DeviceCompleteReshareResult,\n DeviceKeygenParams,\n DeviceKeygenResult,\n DeviceReshareAssembleParams,\n DeviceReshareAssembleResult,\n DeviceSignParams,\n DeviceSignResult,\n CeremonyParams,\n EddsaCeremonyParams,\n EddsaKeygenParams,\n EddsaKeygenResult,\n EddsaSignParams,\n EddsaSignResult,\n MemberCeremonyParams,\n MemberKeygenParams,\n MemberSignParams,\n MpcCurve,\n MpcCore,\n} from './types';\n\n/** The subset of the client-wasm module the SDK drives. Each export takes one JSON string. */\nexport interface ClientWasmModule {\n /** Device half of keygen; resolves with `{ aux_info_json, keyshare_json, shared_public_key_json }`. */\n keygen(paramsJson: string): Promise<unknown>;\n /** Device half of sign; resolves with `{ signature_json }`. */\n sign(paramsJson: string): Promise<unknown>;\n /** Pre-generate Paillier safe-primes off the hot path; resolves with `{ primes_json }`. Optional. */\n pregeneratePrimes?(paramsJson: string): Promise<unknown>;\n /**\n * Device reshare **assemble** — compute the NEW-epoch bare core locally; returns\n * `{ core_json, shared_public_key_json }`. Present only in a `--features reshare` wasm build.\n * Synchronous in the core (no relay); the SDK awaits it uniformly.\n */\n reshareAssemble?(paramsJson: string): unknown | Promise<unknown>;\n /**\n * Device **complete-reshare** — run the aux ceremony over the new committee and return the\n * signable share as `{ keyshare_json, shared_public_key_json }`. Present only in a\n * `--features reshare` wasm build.\n */\n completeReshare?(paramsJson: string): Promise<unknown>;\n /**\n * This party's half of an n-party (member-bound wallet) keygen ceremony (#349); resolves with\n * `{ aux_info_json, keyshare_json, shared_public_key_json }`. Present only in a client-wasm\n * build with n-party (member-ceremony) support.\n */\n keygenMember?(paramsJson: string): Promise<unknown>;\n /**\n * This party's half of an n-party (member-bound wallet) sign ceremony over a fixed t-of-n\n * quorum (#349); resolves with `{ signature_json }`. Present only in a client-wasm build with\n * n-party (member-ceremony) support.\n */\n signMember?(paramsJson: string): Promise<unknown>;\n /**\n * This device's half of an ed25519 (FROST) DKG keygen ceremony (#110); resolves with\n * `{ key_package, public_key_package }` (JSON objects). Present only in a client-wasm build with\n * the ed25519 (FROST) exports.\n */\n keygenEddsa?(paramsJson: string): Promise<unknown>;\n /**\n * This device's half of an ed25519 (FROST) two-round sign ceremony (#110); resolves with\n * `{ signature }` (64-byte hex). Present only in a client-wasm build with the ed25519 (FROST) exports.\n */\n signEddsa?(paramsJson: string): Promise<unknown>;\n}\n\n/** Lazily loads + initializes the client-wasm module (e.g. dynamic `import()` of the wasm-pack pkg). */\nexport type ClientWasmLoader = () => Promise<ClientWasmModule>;\n\ninterface RawKeygenResult {\n aux_info_json: string;\n keyshare_json: string;\n shared_public_key_json?: string;\n}\n\ninterface RawSignResult {\n signature_json: string;\n}\n\ninterface RawPrimesResult {\n primes_json: string;\n}\n\ninterface RawReshareAssembleResult {\n core_json: string;\n shared_public_key_json: string;\n}\n\ninterface RawCompleteReshareResult {\n keyshare_json: string;\n shared_public_key_json: string;\n}\n\ninterface RawEddsaKeygenResult {\n key_package: unknown;\n public_key_package: unknown;\n}\n\ninterface RawEddsaSignResult {\n signature: string;\n}\n\n/**\n * {@link MpcCore} backed by the waas-core `client-wasm` module (`keygen` / `sign`).\n *\n * The wasm engine is injected via a loader so the SDK stays runtime-agnostic and\n * the core is unit-testable without a real ceremony. The device key share returned\n * by keygen must be sealed and stored on the device — it is never sent to the server.\n */\nexport class WasmMpcCore implements MpcCore {\n private modulePromise?: Promise<ClientWasmModule>;\n\n constructor(private readonly load: ClientWasmLoader) {}\n\n private init(): Promise<ClientWasmModule> {\n return (this.modulePromise ??= this.load());\n }\n\n async runKeygen(params: DeviceKeygenParams): Promise<DeviceKeygenResult> {\n const wasm = await this.init();\n const raw = (await wasm.keygen(\n this.encode(params, { parties: params.parties, threshold: params.threshold, pregenerated_primes_json: params.pregeneratedPrimes }),\n )) as RawKeygenResult;\n\n if (!raw || typeof raw.keyshare_json !== 'string') {\n throw new Error('client-wasm returned an unexpected keygen result');\n }\n return {\n keyShare: raw.keyshare_json,\n auxInfo: raw.aux_info_json,\n sharedPublicKey: extractSharedPublicKey(raw.keyshare_json),\n };\n }\n\n async runSign(params: DeviceSignParams): Promise<DeviceSignResult> {\n const wasm = await this.init();\n const raw = (await wasm.sign(\n this.encode(params, {\n // The wasm deserializes `share` with `serde_json::from_value::<KeyShare>`, so it must ride\n // the wire as the KeyShare OBJECT — not a JSON string, and not the storage blob.\n share: toShareObject(params.share),\n participants: params.participants,\n signer_position: params.signerPosition,\n digest: params.digest,\n }),\n )) as RawSignResult;\n\n if (!raw || typeof raw.signature_json !== 'string') {\n throw new Error('client-wasm returned an unexpected sign result');\n }\n return { signature: raw.signature_json };\n }\n\n async pregeneratePrimes(curve: MpcCurve): Promise<string> {\n const wasm = await this.init();\n if (!wasm.pregeneratePrimes) {\n throw new Error('client-wasm does not expose pregeneratePrimes');\n }\n const raw = (await wasm.pregeneratePrimes(JSON.stringify({ curve }))) as RawPrimesResult;\n if (!raw || typeof raw.primes_json !== 'string') {\n throw new Error('client-wasm returned an unexpected pregeneratePrimes result');\n }\n return raw.primes_json;\n }\n\n async runReshareAssemble(params: DeviceReshareAssembleParams): Promise<DeviceReshareAssembleResult> {\n const wasm = await this.init();\n if (!wasm.reshareAssemble) {\n throw new Error(reshareFeatureHint('reshareAssemble'));\n }\n // Pure + local (no relay), so no relay-URL allowlist here. `reshare_assemble` is synchronous\n // in the core; awaiting a non-promise is a no-op, so this works whether the export is sync or async.\n const raw = (await wasm.reshareAssemble(\n JSON.stringify({\n curve: params.curve,\n new_position: params.newPosition,\n new_preimages: params.newPreimages,\n new_threshold: params.newThreshold,\n wallet: params.wallet,\n commitments: params.commitments,\n sub_shares: params.subShares,\n }),\n )) as RawReshareAssembleResult;\n\n if (!raw || typeof raw.core_json !== 'string') {\n throw new Error('client-wasm returned an unexpected reshareAssemble result');\n }\n return { core: raw.core_json, sharedPublicKey: decodePublicKey(raw.shared_public_key_json) };\n }\n\n async runCompleteReshare(params: DeviceCompleteReshareParams): Promise<DeviceCompleteReshareResult> {\n const wasm = await this.init();\n if (!wasm.completeReshare) {\n throw new Error(reshareFeatureHint('completeReshare'));\n }\n const raw = (await wasm.completeReshare(\n this.encode(params, {\n // The wasm expects the bare core as an inline JSON object (serde_json::Value), not a string.\n core: JSON.parse(params.core),\n parties: params.parties,\n // The device's OWN primes for the aux ceremony — never server-provided. Absent ⇒ generated inline.\n ...(params.pregeneratedPrimes === undefined ? {} : { pregenerated_primes_json: params.pregeneratedPrimes }),\n }),\n )) as RawCompleteReshareResult;\n\n if (!raw || typeof raw.keyshare_json !== 'string') {\n throw new Error('client-wasm returned an unexpected completeReshare result');\n }\n // Derive the public key from the completed share itself (as keygen does), so the invariant\n // check downstream compares the share's own key, not a separately-serialized value.\n return { keyShare: raw.keyshare_json, sharedPublicKey: extractSharedPublicKey(raw.keyshare_json) };\n }\n\n async runMemberKeygen(params: MemberKeygenParams): Promise<DeviceKeygenResult> {\n const wasm = await this.init();\n if (!wasm.keygenMember) {\n throw new Error(memberCeremonyFeatureHint('keygenMember'));\n }\n const raw = (await wasm.keygenMember(\n this.encodeMember(params, {\n roles: params.roles,\n party_index: params.partyIndex,\n threshold: params.threshold,\n ...(params.pregeneratedPrimes === undefined ? {} : { pregenerated_primes_json: params.pregeneratedPrimes }),\n }),\n )) as RawKeygenResult;\n\n if (!raw || typeof raw.keyshare_json !== 'string') {\n throw new Error('client-wasm returned an unexpected keygenMember result');\n }\n return {\n keyShare: raw.keyshare_json,\n auxInfo: raw.aux_info_json,\n sharedPublicKey: extractSharedPublicKey(raw.keyshare_json),\n };\n }\n\n async runMemberSign(params: MemberSignParams): Promise<DeviceSignResult> {\n const wasm = await this.init();\n if (!wasm.signMember) {\n throw new Error(memberCeremonyFeatureHint('signMember'));\n }\n const raw = (await wasm.signMember(\n this.encodeMember(params, {\n roles: params.roles,\n // Mirrors runSign: the wasm deserializes `share` with `serde_json::from_value::<KeyShare>`,\n // so the KeyShare rides the wire as an OBJECT, not a JSON string (and not the storage blob).\n share: toShareObject(params.share),\n participants: params.participants,\n // This device's protocol index into `roles` (the value the SDK calls `signerPosition`).\n // The wire key is `party_index` — the same field keygen sends — NOT `signer_position`.\n party_index: params.signerPosition,\n digest: params.digest,\n }),\n )) as RawSignResult;\n\n if (!raw || typeof raw.signature_json !== 'string') {\n throw new Error('client-wasm returned an unexpected signMember result');\n }\n return { signature: raw.signature_json };\n }\n\n async runEddsaKeygen(params: EddsaKeygenParams): Promise<EddsaKeygenResult> {\n const wasm = await this.init();\n if (!wasm.keygenEddsa) {\n throw new Error(eddsaFeatureHint('keygenEddsa'));\n }\n const raw = (await wasm.keygenEddsa(\n this.encodeEddsa(params, {\n threshold: params.threshold,\n // The FROST DKG round-2 encryption roster (#114): every party's X25519 enc PUBLIC key in `roles`\n // order (`enc_pubkeys[i]` ↔ FROST id i+1) + THIS device's own X25519 enc SECRET. `enc_secret` is\n // secret and MUST NOT be logged; the wasm seals/opens the round-2 packages with these.\n enc_pubkeys: params.encPubkeys,\n enc_secret: params.encSecret,\n }),\n )) as RawEddsaKeygenResult;\n\n if (!raw || raw.key_package === undefined || raw.public_key_package === undefined) {\n throw new Error('client-wasm returned an unexpected keygenEddsa result');\n }\n return { keyPackage: raw.key_package, publicKeyPackage: raw.public_key_package };\n }\n\n async runEddsaSign(params: EddsaSignParams): Promise<EddsaSignResult> {\n const wasm = await this.init();\n if (!wasm.signEddsa) {\n throw new Error(eddsaFeatureHint('signEddsa'));\n }\n const raw = (await wasm.signEddsa(\n this.encodeEddsa(params, {\n // The wasm re-serializes these with `serde_json::to_vec` + `import_*_package`, so each MUST\n // ride the wire as the FROST JSON OBJECT — not a JSON string (and not a storage wrapper).\n key_package: toFrostPackage(params.keyPackage, 'key_package'),\n public_key_package: toFrostPackage(params.publicKeyPackage, 'public_key_package'),\n participants: params.participants,\n message: params.message,\n }),\n )) as RawEddsaSignResult;\n\n if (!raw || typeof raw.signature !== 'string') {\n throw new Error('client-wasm returned an unexpected signEddsa result');\n }\n return { signature: raw.signature };\n }\n\n /** Build the snake_case params JSON the wasm exports expect from the common routing + extras. */\n private encode(p: CeremonyParams, extra: Record<string, unknown>): string {\n // The relay URL is server-supplied and fed straight into the MPC core (issue #41);\n // allowlist its scheme/host so a compromised control-plane can't point the device party\n // at an attacker relay over an unencrypted transport.\n assertAllowedRelayUrl(p.relayUrl);\n return JSON.stringify({\n curve: p.curve,\n relay_url: p.relayUrl,\n session_id: p.sessionId,\n role: p.role ?? 'device',\n peer_role: p.peerRole ?? 'server',\n party_index: p.partyIndex,\n peer_party_index: p.peerPartyIndex,\n // Only present the relay token when set, so an auth-disabled ceremony's wire payload\n // is byte-identical to before (the client-wasm treats absent as an unauthenticated join).\n ...(p.relayToken === undefined ? {} : { relay_token: p.relayToken }),\n ...extra,\n });\n }\n\n /**\n * Build the snake_case params JSON for an n-party (member-bound, #349) member ceremony — the\n * roster-based routing shape (`roles` + `party_index`), not the 2-party `role`/`peer_role` shape\n * {@link encode} builds. The `roles` roster and `party_index` are passed through in `extra` by\n * the caller and land on the wire under those exact keys — what `keygenMember` / `signMember`\n * deserialize.\n */\n private encodeMember(p: MemberCeremonyParams, extra: Record<string, unknown>): string {\n assertAllowedRelayUrl(p.relayUrl);\n return JSON.stringify({\n curve: p.curve,\n relay_url: p.relayUrl,\n session_id: p.sessionId,\n ...(p.relayToken === undefined ? {} : { relay_token: p.relayToken }),\n ...extra,\n });\n }\n\n /**\n * Build the snake_case params JSON for an ed25519 (FROST, #110) ceremony — the roster-based routing\n * shape (`roles` + `party_index`) the `keygenEddsa` / `signEddsa` exports deserialize. Unlike\n * {@link encodeMember} there is NO `curve` (ed25519-only) and no Paillier primes; the caller passes\n * the ceremony-specific extras (keygen: `threshold`; sign: the FROST packages + participants + message).\n */\n private encodeEddsa(p: EddsaCeremonyParams, extra: Record<string, unknown>): string {\n assertAllowedRelayUrl(p.relayUrl);\n return JSON.stringify({\n relay_url: p.relayUrl,\n session_id: p.sessionId,\n roles: p.roles,\n party_index: p.partyIndex,\n ...(p.relayToken === undefined ? {} : { relay_token: p.relayToken }),\n ...extra,\n });\n }\n}\n\n/** Actionable error when a wasm build lacks the reshare exports (built without `--features reshare`). */\nfunction reshareFeatureHint(fn: string): string {\n return `client-wasm does not expose ${fn} — rebuild @waaskey/client-wasm with the \\`reshare\\` feature enabled (wasm-pack build … -- --features reshare).`;\n}\n\n/**\n * Actionable error when a wasm build lacks the n-party (member-bound wallet, #349) member-ceremony\n * exports (`keygenMember` / `signMember`). These drive the roster-based (`roles` + `party_index`)\n * transport — every member device + the platform on one relay session — that the native\n * `party-runner` already uses (mirroring `waas-mpc-transport::PartyRouting`).\n */\nfunction memberCeremonyFeatureHint(fn: string): string {\n return `client-wasm does not expose ${fn} — rebuild @waaskey/client-wasm with n-party (member-ceremony) support (the keygenMember/signMember exports).`;\n}\n\n/**\n * Actionable error when a wasm build lacks the ed25519 (FROST, #110) exports (`keygenEddsa` /\n * `signEddsa`). These drive the threshold-EdDSA choreography the server `party-runner-eddsa` runs,\n * so a device build without them cannot create or sign an ed25519 (Solana/NEAR/Aptos/Sui) wallet.\n */\nfunction eddsaFeatureHint(fn: string): string {\n return `client-wasm does not expose ${fn} — rebuild @waaskey/client-wasm with the ed25519 (FROST) exports (keygenEddsa/signEddsa).`;\n}\n\n/**\n * Allowlist a server-supplied relay URL (issue #41): only encrypted WebSocket\n * transports are accepted — `wss://` to a **public** host, and plaintext `ws://`\n * solely for loopback (local dev). Anything else is refused before it reaches the\n * wasm core.\n *\n * Beyond the scheme, the **host** is allowlisted too: a compromised control-plane\n * must not be able to point the device party at an internal/private endpoint\n * (loopback, RFC1918, link-local incl. cloud metadata `169.254.169.254`, IPv6\n * unique-/link-local, `.internal`/`.local`) — an SSRF-style redirect of the MPC\n * transport. Loopback is the one exception, and only over plaintext `ws://` for dev.\n */\nfunction assertAllowedRelayUrl(relayUrl: string): void {\n let url: URL;\n try {\n url = new URL(relayUrl);\n } catch (cause) {\n throw new Error(`Invalid relay URL \"${relayUrl}\".`, { cause });\n }\n // Dev: plaintext ws:// is tolerated, but only to loopback.\n if (url.protocol === 'ws:' && isLoopbackHost(url.hostname)) return;\n if (url.protocol !== 'wss:') {\n throw new Error(`Refusing server-supplied relay URL \"${relayUrl}\" — only wss:// (or ws:// on localhost) is allowed for the MPC transport.`);\n }\n // wss:// — reject internal/private hosts (loopback included: prod relays are public).\n if (isInternalHost(url.hostname)) {\n throw new Error(`Refusing server-supplied relay URL \"${relayUrl}\" — the relay host is internal/private; only a public wss:// endpoint is allowed.`);\n }\n}\n\n/** Loopback host literals (used to permit ws:// only for local dev). */\nfunction isLoopbackHost(hostname: string): boolean {\n const host = hostname.replace(/^\\[|\\]$/g, '').toLowerCase();\n return host === 'localhost' || host === '::1' || /^127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/.test(host);\n}\n\n/**\n * Is `hostname` an internal/private address a server must never send a client to?\n * Covers loopback, RFC1918 private v4, link-local v4 (incl. cloud metadata),\n * IPv6 unique-local (`fc00::/7`) + link-local (`fe80::/10`), and internal name\n * suffixes (`.internal`, `.local`). Public DNS names pass.\n */\nfunction isInternalHost(hostname: string): boolean {\n const host = hostname.replace(/^\\[|\\]$/g, '').toLowerCase();\n if (isLoopbackHost(hostname)) return true;\n if (host.endsWith('.internal') || host.endsWith('.local')) return true;\n\n const v4 = host.match(/^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/);\n if (v4) {\n const [a, b] = [Number(v4[1]), Number(v4[2])];\n if (a === 10) return true; // 10.0.0.0/8\n if (a === 172 && b >= 16 && b <= 31) return true; // 172.16.0.0/12\n if (a === 192 && b === 168) return true; // 192.168.0.0/16\n if (a === 169 && b === 254) return true; // 169.254.0.0/16 link-local (cloud metadata)\n return false;\n }\n\n if (host.includes(':')) {\n // IPv6 unique-local (fc00::/7 → fc/fd) and link-local (fe80::/10).\n if (/^f[cd][0-9a-f]{0,2}:/.test(host)) return true;\n if (/^fe[89ab][0-9a-f]:/.test(host)) return true;\n }\n return false;\n}\n\n/**\n * Coerce a device KeyShare into the inline JSON OBJECT the wasm sign exports expect. Both the\n * 2-party `sign` and the n-party `signMember` exports deserialize the wire `share` with\n * `serde_json::from_value::<KeyShare>`, so it MUST be a JSON object — a `share` sent as a JSON\n * string fails Rust deserialization (\"invalid type: string, expected struct\"). The KeyShare normally\n * arrives as its JSON string ({@link DeviceSignParams.share}); accept an already-parsed object too so\n * a caller can never double-encode it. The storage-blob wrapper is unpacked upstream — the core only\n * ever sees the bare KeyShare.\n */\nfunction toShareObject(share: unknown): Record<string, unknown> {\n const value: unknown = typeof share === 'string' ? JSON.parse(share) : share;\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error('KeyShare must be a JSON object (or its JSON string), not a scalar or array.');\n }\n return value as Record<string, unknown>;\n}\n\n/**\n * Coerce a FROST package (`key_package` / `public_key_package`) into the inline JSON OBJECT the wasm\n * `signEddsa` export expects. The wasm re-serializes each with `serde_json::to_vec` + `import_*_package`,\n * so it MUST be a JSON object — the ed25519 analogue of {@link toShareObject}. The package normally\n * arrives as its JSON object (from {@link EddsaKeygenResult}); accept its JSON string too (a\n * storage round-trip) so a caller can never double-encode it.\n */\nfunction toFrostPackage(pkg: unknown, which: string): Record<string, unknown> {\n const value: unknown = typeof pkg === 'string' ? JSON.parse(pkg) : pkg;\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error(`FROST ${which} must be a JSON object (or its JSON string), not a scalar or array.`);\n }\n return value as Record<string, unknown>;\n}\n\n/** Pull the shared public key out of a KeyShare JSON (`core.shared_public_key`). */\nfunction extractSharedPublicKey(keyShareJson: string): string {\n const parsed = JSON.parse(keyShareJson) as { core?: { shared_public_key?: unknown } };\n const pk = parsed.core?.shared_public_key;\n if (typeof pk !== 'string') {\n throw new Error('KeyShare is missing core.shared_public_key');\n }\n return pk;\n}\n\n/**\n * Decode the wasm's separately-surfaced `shared_public_key_json` (a JSON-encoded compressed-hex\n * point, e.g. `\"03ab…\"`) into the bare hex string. Used for the reshare **assemble** result, whose\n * bare core does not expose `core.shared_public_key` in the keygen shape.\n */\nfunction decodePublicKey(sharedPublicKeyJson: string): string {\n const pk = JSON.parse(sharedPublicKeyJson) as unknown;\n if (typeof pk !== 'string') {\n throw new Error('reshare assemble result is missing a shared_public_key');\n }\n return pk;\n}\n","/**\n * {@link NodeWorkerMpcCore} — the Node fix for waas-sdk#82.\n *\n * In-process (the plain {@link WasmMpcCore} with a Node loader) the wasm ceremony and its\n * relay WebSocket share one thread: the minutes-long zk-proof computation in\n * `aux_info_gen` blocks the loop, the socket can neither read nor answer pings, and an\n * intermediary (Cloudflare / ingress idle timeouts) kills the \"dead\" connection\n * mid-ceremony. This core splits them: the wasm runs in a `worker_threads` Worker behind\n * a bridged `WebSocket` shim, while the REAL socket lives here on the main thread — which\n * stays responsive and sends protocol-level pings (via `ws`) for the whole ceremony.\n *\n * The worker also holds a ref on the event loop, so a pending create/sign can no longer\n * silently exit the process (waas-sdk#84's symptom). Call {@link NodeWorkerMpcCore.terminate}\n * when done — the worker (and the process) stays alive until you do.\n */\nimport { Worker } from 'node:worker_threads';\n\nimport { WebSocket as RealWebSocket } from 'ws';\n\nimport { WasmMpcCore } from '../wasm-core';\n\nimport type { CallResult, FatalMessage, ReadyMessage, WorkerToMain, WsCloseRequest, WsOpenRequest, WsSendRequest } from './bridge-protocol';\nimport type { ClientWasmModule } from '../wasm-core';\n\nexport interface NodeWorkerMpcOptions {\n /**\n * The wasm engine package the worker imports (a bare specifier or file URL).\n * Defaults to `@waaskey/client-wasm`.\n */\n wasmPackage?: string;\n /**\n * Protocol-level ping cadence on each open relay socket, keeping the connection alive\n * through proxies while the worker computes. Default 15s; `0` disables.\n */\n pingIntervalMs?: number;\n}\n\ninterface PendingCall {\n resolve: (resultJson: string) => void;\n reject: (err: Error) => void;\n}\n\ninterface BridgedSocket {\n socket: RealWebSocket;\n pingTimer?: NodeJS.Timeout;\n}\n\n/** Owns the worker + the real sockets; exposes the worker as a {@link ClientWasmModule}. */\nclass WorkerBridge {\n private readonly wasmPackage: string;\n private readonly pingIntervalMs: number;\n private worker?: Worker;\n private modulePromise?: Promise<ClientWasmModule>;\n private nextCallId = 1;\n private readonly pending = new Map<number, PendingCall>();\n private readonly sockets = new Map<number, BridgedSocket>();\n\n constructor(options: NodeWorkerMpcOptions) {\n this.wasmPackage = options.wasmPackage ?? '@waaskey/client-wasm';\n this.pingIntervalMs = options.pingIntervalMs ?? 15_000;\n }\n\n module(): Promise<ClientWasmModule> {\n return (this.modulePromise ??= this.spawn());\n }\n\n async terminate(): Promise<void> {\n for (const [wsId] of this.sockets) this.dropSocket(wsId);\n this.failAllPending(new Error('NodeWorkerMpcCore terminated'));\n const { worker } = this;\n this.worker = undefined;\n this.modulePromise = undefined;\n if (worker) await worker.terminate();\n }\n\n private spawn(): Promise<ClientWasmModule> {\n // In dist the worker is the sibling `node-mpc-worker.js` bundle; when running from\n // source (vitest) it is the sibling `worker.ts`, loaded via Node's type stripping —\n // passed explicitly, since it is only on by default from Node 22.18.\n const fromSource = import.meta.url.endsWith('.ts');\n const workerUrl = new URL(fromSource ? './worker.ts' : './node-mpc-worker.js', import.meta.url);\n const worker = new Worker(workerUrl, { workerData: { wasmPackage: this.wasmPackage }, ...(fromSource ? { execArgv: ['--experimental-strip-types'] } : {}) });\n this.worker = worker;\n\n return new Promise<ClientWasmModule>((resolve, reject) => {\n let settled = false;\n worker.on('message', (message: WorkerToMain) => {\n switch (message.type) {\n case 'ready':\n settled = true;\n resolve(this.buildProxy(message));\n break;\n case 'fatal':\n settled = true;\n reject(new Error(`waaskey mpc worker failed to load ${this.wasmPackage}: ${(message as FatalMessage).error}`));\n break;\n case 'call-result':\n this.settleCall(message);\n break;\n case 'ws-open':\n this.openSocket(message);\n break;\n case 'ws-send':\n this.sendOnSocket(message);\n break;\n case 'ws-close':\n this.closeSocket(message);\n break;\n }\n });\n worker.on('error', (err: Error) => {\n if (!settled) {\n settled = true;\n reject(err);\n }\n this.failAllPending(err);\n });\n worker.on('exit', (code) => {\n const err = new Error(`waaskey mpc worker exited unexpectedly (code ${code})`);\n if (!settled) {\n settled = true;\n reject(err);\n }\n this.failAllPending(err);\n });\n });\n }\n\n private buildProxy(ready: ReadyMessage): ClientWasmModule {\n const proxy: Record<string, (paramsJson: string) => Promise<unknown>> = {};\n for (const name of ready.exports) {\n proxy[name] = async (paramsJson: string) => JSON.parse(await this.call(name, paramsJson)) as unknown;\n }\n return proxy as unknown as ClientWasmModule;\n }\n\n private call(method: string, paramsJson: string): Promise<string> {\n const { worker } = this;\n if (!worker) return Promise.reject(new Error('NodeWorkerMpcCore is terminated'));\n const id = this.nextCallId++;\n return new Promise<string>((resolve, reject) => {\n this.pending.set(id, { resolve, reject });\n worker.postMessage({ type: 'call', id, method, paramsJson });\n });\n }\n\n private settleCall(result: CallResult): void {\n const pending = this.pending.get(result.id);\n if (!pending) return;\n this.pending.delete(result.id);\n if (result.ok) pending.resolve(result.resultJson ?? 'null');\n else pending.reject(new Error(result.error ?? 'mpc worker call failed'));\n }\n\n private failAllPending(err: Error): void {\n for (const pending of this.pending.values()) pending.reject(err);\n this.pending.clear();\n }\n\n private openSocket(request: WsOpenRequest): void {\n const socket = new RealWebSocket(request.url, request.protocols);\n const entry: BridgedSocket = { socket };\n this.sockets.set(request.wsId, entry);\n\n socket.on('open', () => {\n if (this.pingIntervalMs > 0) {\n entry.pingTimer = setInterval(() => {\n if (socket.readyState === RealWebSocket.OPEN) socket.ping();\n }, this.pingIntervalMs);\n }\n this.worker?.postMessage({ type: 'ws-event', wsId: request.wsId, event: 'open', protocol: socket.protocol });\n });\n socket.on('message', (data: Buffer | ArrayBuffer | Buffer[], isBinary: boolean) => {\n const buf = Array.isArray(data) ? Buffer.concat(data) : Buffer.from(data as ArrayBuffer);\n const payload = isBinary ? new Uint8Array(buf) : buf.toString('utf8');\n this.worker?.postMessage({ type: 'ws-event', wsId: request.wsId, event: 'message', data: payload });\n });\n socket.on('close', (code: number, reason: Buffer) => {\n this.dropSocket(request.wsId);\n this.worker?.postMessage({ type: 'ws-event', wsId: request.wsId, event: 'close', code, reason: reason.toString('utf8'), wasClean: code === 1000 });\n });\n socket.on('error', (err: Error) => {\n this.worker?.postMessage({ type: 'ws-event', wsId: request.wsId, event: 'error', message: err.message });\n });\n }\n\n private sendOnSocket(request: WsSendRequest): void {\n this.sockets.get(request.wsId)?.socket.send(request.data);\n }\n\n private closeSocket(request: WsCloseRequest): void {\n const entry = this.sockets.get(request.wsId);\n entry?.socket.close(request.code, request.reason);\n }\n\n private dropSocket(wsId: number): void {\n const entry = this.sockets.get(wsId);\n if (!entry) return;\n this.sockets.delete(wsId);\n if (entry.pingTimer) clearInterval(entry.pingTimer);\n if (entry.socket.readyState === RealWebSocket.OPEN || entry.socket.readyState === RealWebSocket.CONNECTING) entry.socket.close();\n }\n}\n\n/**\n * A drop-in {@link WasmMpcCore} for Node ≥ 22 that runs the wasm ceremony in a worker\n * thread and keeps the relay WebSocket responsive on the main thread (waas-sdk#82).\n *\n * ```ts\n * import { NodeWorkerMpcCore } from '@waaskey/sdk/node';\n * const mpc = new NodeWorkerMpcCore();\n * const waaskey = new Waaskey({ apiKey, mpc, ... });\n * // …create / sign…\n * await mpc.terminate(); // the worker keeps the process alive until terminated\n * ```\n */\nexport class NodeWorkerMpcCore extends WasmMpcCore {\n private readonly bridge: WorkerBridge;\n\n constructor(options: NodeWorkerMpcOptions = {}) {\n const bridge = new WorkerBridge(options);\n super(() => bridge.module());\n this.bridge = bridge;\n }\n\n /** Close every bridged socket and terminate the worker; the core is unusable afterwards. */\n terminate(): Promise<void> {\n return this.bridge.terminate();\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/mpc/wasm-core.ts","../src/mpc/node/worker-core.ts"],"names":["RealWebSocket"],"mappings":"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","file":"node.js","sourcesContent":["import type {\n DeviceCompleteReshareParams,\n DeviceCompleteReshareResult,\n DeviceKeygenParams,\n DeviceKeygenResult,\n DeviceReshareAssembleParams,\n DeviceReshareAssembleResult,\n DeviceReshareDealParams,\n DeviceReshareDealResult,\n DeviceSignParams,\n DeviceSignResult,\n CeremonyParams,\n EddsaCeremonyParams,\n EddsaKeygenParams,\n EddsaKeygenResult,\n EddsaSignParams,\n EddsaSignResult,\n MemberCeremonyParams,\n MemberKeygenParams,\n MemberSignParams,\n MpcCurve,\n MpcCore,\n} from './types';\n\n/** The subset of the client-wasm module the SDK drives. Each export takes one JSON string. */\nexport interface ClientWasmModule {\n /** Device half of keygen; resolves with `{ aux_info_json, keyshare_json, shared_public_key_json }`. */\n keygen(paramsJson: string): Promise<unknown>;\n /** Device half of sign; resolves with `{ signature_json }`. */\n sign(paramsJson: string): Promise<unknown>;\n /** Pre-generate Paillier safe-primes off the hot path; resolves with `{ primes_json }`. Optional. */\n pregeneratePrimes?(paramsJson: string): Promise<unknown>;\n /**\n * Device reshare **assemble** — compute the NEW-epoch bare core locally; returns\n * `{ core_json, shared_public_key_json }`. Present only in a `--features reshare` wasm build.\n * Synchronous in the core (no relay); the SDK awaits it uniformly.\n */\n reshareAssemble?(paramsJson: string): unknown | Promise<unknown>;\n /**\n * Device reshare **deal** — the old holder's local contribution; returns\n * `{ commitments_json, sealed_sub_shares_hex }`. Present only in a `--features reshare` build.\n */\n reshareDeal?(paramsJson: string): unknown | Promise<unknown>;\n /**\n * Device **complete-reshare** — run the aux ceremony over the new committee and return the\n * signable share as `{ keyshare_json, shared_public_key_json }`. Present only in a\n * `--features reshare` wasm build.\n */\n completeReshare?(paramsJson: string): Promise<unknown>;\n /**\n * This party's half of an n-party (member-bound wallet) keygen ceremony (#349); resolves with\n * `{ aux_info_json, keyshare_json, shared_public_key_json }`. Present only in a client-wasm\n * build with n-party (member-ceremony) support.\n */\n keygenMember?(paramsJson: string): Promise<unknown>;\n /**\n * This party's half of an n-party (member-bound wallet) sign ceremony over a fixed t-of-n\n * quorum (#349); resolves with `{ signature_json }`. Present only in a client-wasm build with\n * n-party (member-ceremony) support.\n */\n signMember?(paramsJson: string): Promise<unknown>;\n /**\n * This device's half of an ed25519 (FROST) DKG keygen ceremony (#110); resolves with\n * `{ key_package, public_key_package }` (JSON objects). Present only in a client-wasm build with\n * the ed25519 (FROST) exports.\n */\n keygenEddsa?(paramsJson: string): Promise<unknown>;\n /**\n * This device's half of an ed25519 (FROST) two-round sign ceremony (#110); resolves with\n * `{ signature }` (64-byte hex). Present only in a client-wasm build with the ed25519 (FROST) exports.\n */\n signEddsa?(paramsJson: string): Promise<unknown>;\n}\n\n/** Lazily loads + initializes the client-wasm module (e.g. dynamic `import()` of the wasm-pack pkg). */\nexport type ClientWasmLoader = () => Promise<ClientWasmModule>;\n\ninterface RawKeygenResult {\n aux_info_json: string;\n keyshare_json: string;\n shared_public_key_json?: string;\n}\n\ninterface RawSignResult {\n signature_json: string;\n}\n\ninterface RawPrimesResult {\n primes_json: string;\n}\n\ninterface RawReshareAssembleResult {\n core_json: string;\n shared_public_key_json: string;\n}\n\ninterface RawReshareDealResult {\n commitments_json: unknown;\n sealed_sub_shares_hex: string[];\n}\n\ninterface RawCompleteReshareResult {\n keyshare_json: string;\n shared_public_key_json: string;\n}\n\ninterface RawEddsaKeygenResult {\n key_package: unknown;\n public_key_package: unknown;\n}\n\ninterface RawEddsaSignResult {\n signature: string;\n}\n\n/**\n * {@link MpcCore} backed by the waas-core `client-wasm` module (`keygen` / `sign`).\n *\n * The wasm engine is injected via a loader so the SDK stays runtime-agnostic and\n * the core is unit-testable without a real ceremony. The device key share returned\n * by keygen must be sealed and stored on the device — it is never sent to the server.\n */\nexport class WasmMpcCore implements MpcCore {\n private modulePromise?: Promise<ClientWasmModule>;\n\n constructor(private readonly load: ClientWasmLoader) {}\n\n private init(): Promise<ClientWasmModule> {\n return (this.modulePromise ??= this.load());\n }\n\n async runKeygen(params: DeviceKeygenParams): Promise<DeviceKeygenResult> {\n const wasm = await this.init();\n const raw = (await wasm.keygen(\n this.encode(params, { parties: params.parties, threshold: params.threshold, pregenerated_primes_json: params.pregeneratedPrimes }),\n )) as RawKeygenResult;\n\n if (!raw || typeof raw.keyshare_json !== 'string') {\n throw new Error('client-wasm returned an unexpected keygen result');\n }\n return {\n keyShare: raw.keyshare_json,\n auxInfo: raw.aux_info_json,\n sharedPublicKey: extractSharedPublicKey(raw.keyshare_json),\n };\n }\n\n async runSign(params: DeviceSignParams): Promise<DeviceSignResult> {\n const wasm = await this.init();\n const raw = (await wasm.sign(\n this.encode(params, {\n // The wasm deserializes `share` with `serde_json::from_value::<KeyShare>`, so it must ride\n // the wire as the KeyShare OBJECT — not a JSON string, and not the storage blob.\n share: toShareObject(params.share),\n participants: params.participants,\n signer_position: params.signerPosition,\n digest: params.digest,\n }),\n )) as RawSignResult;\n\n if (!raw || typeof raw.signature_json !== 'string') {\n throw new Error('client-wasm returned an unexpected sign result');\n }\n return { signature: raw.signature_json };\n }\n\n async pregeneratePrimes(curve: MpcCurve): Promise<string> {\n const wasm = await this.init();\n if (!wasm.pregeneratePrimes) {\n throw new Error('client-wasm does not expose pregeneratePrimes');\n }\n const raw = (await wasm.pregeneratePrimes(JSON.stringify({ curve }))) as RawPrimesResult;\n if (!raw || typeof raw.primes_json !== 'string') {\n throw new Error('client-wasm returned an unexpected pregeneratePrimes result');\n }\n return raw.primes_json;\n }\n\n async runReshareAssemble(params: DeviceReshareAssembleParams): Promise<DeviceReshareAssembleResult> {\n const wasm = await this.init();\n if (!wasm.reshareAssemble) {\n throw new Error(reshareFeatureHint('reshareAssemble'));\n }\n // Pure + local (no relay), so no relay-URL allowlist here. `reshare_assemble` is synchronous\n // in the core; awaiting a non-promise is a no-op, so this works whether the export is sync or async.\n const raw = (await wasm.reshareAssemble(\n JSON.stringify({\n curve: params.curve,\n new_position: params.newPosition,\n new_preimages: params.newPreimages,\n new_threshold: params.newThreshold,\n wallet: params.wallet,\n commitments: params.commitments,\n sub_shares: params.subShares,\n // The core opens the SEALED sub-shares with this before it can verify or assemble anything;\n // omitting it (as this did until #488) makes the call fail on its own parameter parse.\n encryption_secret: params.encryptionSecret,\n }),\n )) as RawReshareAssembleResult;\n\n if (!raw || typeof raw.core_json !== 'string') {\n throw new Error('client-wasm returned an unexpected reshareAssemble result');\n }\n return { core: raw.core_json, sharedPublicKey: decodePublicKey(raw.shared_public_key_json) };\n }\n\n async runReshareDeal(params: DeviceReshareDealParams): Promise<DeviceReshareDealResult> {\n const wasm = await this.init();\n if (!wasm.reshareDeal) {\n throw new Error(reshareFeatureHint('reshareDeal'));\n }\n // Pure + local like the assemble: the dealer reads its own share, seals a sub-share to each new\n // holder's key, and returns ciphertext. No relay, so no relay-URL allowlist here.\n const raw = (await wasm.reshareDeal(\n JSON.stringify({\n curve: params.curve,\n share: JSON.parse(params.share),\n quorum_indices: params.quorumIndices,\n new_preimages: params.newPreimages,\n new_threshold: params.newThreshold,\n recipient_pubkeys: params.recipientPubkeys,\n }),\n )) as RawReshareDealResult;\n\n if (!raw || !Array.isArray(raw.sealed_sub_shares_hex)) {\n throw new Error('client-wasm returned an unexpected reshareDeal result');\n }\n return { commitments: raw.commitments_json, sealedSubShares: raw.sealed_sub_shares_hex };\n }\n\n async runCompleteReshare(params: DeviceCompleteReshareParams): Promise<DeviceCompleteReshareResult> {\n const wasm = await this.init();\n if (!wasm.completeReshare) {\n throw new Error(reshareFeatureHint('completeReshare'));\n }\n const raw = (await wasm.completeReshare(\n this.encode(params, {\n // The wasm expects the bare core as an inline JSON object (serde_json::Value), not a string.\n core: JSON.parse(params.core),\n parties: params.parties,\n // The device's OWN primes for the aux ceremony — never server-provided. Absent ⇒ generated inline.\n ...(params.pregeneratedPrimes === undefined ? {} : { pregenerated_primes_json: params.pregeneratedPrimes }),\n }),\n )) as RawCompleteReshareResult;\n\n if (!raw || typeof raw.keyshare_json !== 'string') {\n throw new Error('client-wasm returned an unexpected completeReshare result');\n }\n // Derive the public key from the completed share itself (as keygen does), so the invariant\n // check downstream compares the share's own key, not a separately-serialized value.\n return { keyShare: raw.keyshare_json, sharedPublicKey: extractSharedPublicKey(raw.keyshare_json) };\n }\n\n async runMemberKeygen(params: MemberKeygenParams): Promise<DeviceKeygenResult> {\n const wasm = await this.init();\n if (!wasm.keygenMember) {\n throw new Error(memberCeremonyFeatureHint('keygenMember'));\n }\n const raw = (await wasm.keygenMember(\n this.encodeMember(params, {\n roles: params.roles,\n party_index: params.partyIndex,\n threshold: params.threshold,\n ...(params.pregeneratedPrimes === undefined ? {} : { pregenerated_primes_json: params.pregeneratedPrimes }),\n }),\n )) as RawKeygenResult;\n\n if (!raw || typeof raw.keyshare_json !== 'string') {\n throw new Error('client-wasm returned an unexpected keygenMember result');\n }\n return {\n keyShare: raw.keyshare_json,\n auxInfo: raw.aux_info_json,\n sharedPublicKey: extractSharedPublicKey(raw.keyshare_json),\n };\n }\n\n async runMemberSign(params: MemberSignParams): Promise<DeviceSignResult> {\n const wasm = await this.init();\n if (!wasm.signMember) {\n throw new Error(memberCeremonyFeatureHint('signMember'));\n }\n const raw = (await wasm.signMember(\n this.encodeMember(params, {\n roles: params.roles,\n // Mirrors runSign: the wasm deserializes `share` with `serde_json::from_value::<KeyShare>`,\n // so the KeyShare rides the wire as an OBJECT, not a JSON string (and not the storage blob).\n share: toShareObject(params.share),\n participants: params.participants,\n // This device's protocol index into `roles` (the value the SDK calls `signerPosition`).\n // The wire key is `party_index` — the same field keygen sends — NOT `signer_position`.\n party_index: params.signerPosition,\n digest: params.digest,\n }),\n )) as RawSignResult;\n\n if (!raw || typeof raw.signature_json !== 'string') {\n throw new Error('client-wasm returned an unexpected signMember result');\n }\n return { signature: raw.signature_json };\n }\n\n async runEddsaKeygen(params: EddsaKeygenParams): Promise<EddsaKeygenResult> {\n const wasm = await this.init();\n if (!wasm.keygenEddsa) {\n throw new Error(eddsaFeatureHint('keygenEddsa'));\n }\n const raw = (await wasm.keygenEddsa(\n this.encodeEddsa(params, {\n threshold: params.threshold,\n // The FROST DKG round-2 encryption roster (#114): every party's X25519 enc PUBLIC key in `roles`\n // order (`enc_pubkeys[i]` ↔ FROST id i+1) + THIS device's own X25519 enc SECRET. `enc_secret` is\n // secret and MUST NOT be logged; the wasm seals/opens the round-2 packages with these.\n enc_pubkeys: params.encPubkeys,\n enc_secret: params.encSecret,\n }),\n )) as RawEddsaKeygenResult;\n\n if (!raw || raw.key_package === undefined || raw.public_key_package === undefined) {\n throw new Error('client-wasm returned an unexpected keygenEddsa result');\n }\n return { keyPackage: raw.key_package, publicKeyPackage: raw.public_key_package };\n }\n\n async runEddsaSign(params: EddsaSignParams): Promise<EddsaSignResult> {\n const wasm = await this.init();\n if (!wasm.signEddsa) {\n throw new Error(eddsaFeatureHint('signEddsa'));\n }\n const raw = (await wasm.signEddsa(\n this.encodeEddsa(params, {\n // The wasm re-serializes these with `serde_json::to_vec` + `import_*_package`, so each MUST\n // ride the wire as the FROST JSON OBJECT — not a JSON string (and not a storage wrapper).\n key_package: toFrostPackage(params.keyPackage, 'key_package'),\n public_key_package: toFrostPackage(params.publicKeyPackage, 'public_key_package'),\n participants: params.participants,\n message: params.message,\n }),\n )) as RawEddsaSignResult;\n\n if (!raw || typeof raw.signature !== 'string') {\n throw new Error('client-wasm returned an unexpected signEddsa result');\n }\n return { signature: raw.signature };\n }\n\n /** Build the snake_case params JSON the wasm exports expect from the common routing + extras. */\n private encode(p: CeremonyParams, extra: Record<string, unknown>): string {\n // The relay URL is server-supplied and fed straight into the MPC core (issue #41);\n // allowlist its scheme/host so a compromised control-plane can't point the device party\n // at an attacker relay over an unencrypted transport.\n assertAllowedRelayUrl(p.relayUrl);\n return JSON.stringify({\n curve: p.curve,\n relay_url: p.relayUrl,\n session_id: p.sessionId,\n role: p.role ?? 'device',\n peer_role: p.peerRole ?? 'server',\n party_index: p.partyIndex,\n peer_party_index: p.peerPartyIndex,\n // Only present the relay token when set, so an auth-disabled ceremony's wire payload\n // is byte-identical to before (the client-wasm treats absent as an unauthenticated join).\n ...(p.relayToken === undefined ? {} : { relay_token: p.relayToken }),\n ...extra,\n });\n }\n\n /**\n * Build the snake_case params JSON for an n-party (member-bound, #349) member ceremony — the\n * roster-based routing shape (`roles` + `party_index`), not the 2-party `role`/`peer_role` shape\n * {@link encode} builds. The `roles` roster and `party_index` are passed through in `extra` by\n * the caller and land on the wire under those exact keys — what `keygenMember` / `signMember`\n * deserialize.\n */\n private encodeMember(p: MemberCeremonyParams, extra: Record<string, unknown>): string {\n assertAllowedRelayUrl(p.relayUrl);\n return JSON.stringify({\n curve: p.curve,\n relay_url: p.relayUrl,\n session_id: p.sessionId,\n ...(p.relayToken === undefined ? {} : { relay_token: p.relayToken }),\n ...extra,\n });\n }\n\n /**\n * Build the snake_case params JSON for an ed25519 (FROST, #110) ceremony — the roster-based routing\n * shape (`roles` + `party_index`) the `keygenEddsa` / `signEddsa` exports deserialize. Unlike\n * {@link encodeMember} there is NO `curve` (ed25519-only) and no Paillier primes; the caller passes\n * the ceremony-specific extras (keygen: `threshold`; sign: the FROST packages + participants + message).\n */\n private encodeEddsa(p: EddsaCeremonyParams, extra: Record<string, unknown>): string {\n assertAllowedRelayUrl(p.relayUrl);\n return JSON.stringify({\n relay_url: p.relayUrl,\n session_id: p.sessionId,\n roles: p.roles,\n party_index: p.partyIndex,\n ...(p.relayToken === undefined ? {} : { relay_token: p.relayToken }),\n ...extra,\n });\n }\n}\n\n/** Actionable error when a wasm build lacks the reshare exports (built without `--features reshare`). */\nfunction reshareFeatureHint(fn: string): string {\n return `client-wasm does not expose ${fn} — rebuild @waaskey/client-wasm with the \\`reshare\\` feature enabled (wasm-pack build … -- --features reshare).`;\n}\n\n/**\n * Actionable error when a wasm build lacks the n-party (member-bound wallet, #349) member-ceremony\n * exports (`keygenMember` / `signMember`). These drive the roster-based (`roles` + `party_index`)\n * transport — every member device + the platform on one relay session — that the native\n * `party-runner` already uses (mirroring `waas-mpc-transport::PartyRouting`).\n */\nfunction memberCeremonyFeatureHint(fn: string): string {\n return `client-wasm does not expose ${fn} — rebuild @waaskey/client-wasm with n-party (member-ceremony) support (the keygenMember/signMember exports).`;\n}\n\n/**\n * Actionable error when a wasm build lacks the ed25519 (FROST, #110) exports (`keygenEddsa` /\n * `signEddsa`). These drive the threshold-EdDSA choreography the server `party-runner-eddsa` runs,\n * so a device build without them cannot create or sign an ed25519 (Solana/NEAR/Aptos/Sui) wallet.\n */\nfunction eddsaFeatureHint(fn: string): string {\n return `client-wasm does not expose ${fn} — rebuild @waaskey/client-wasm with the ed25519 (FROST) exports (keygenEddsa/signEddsa).`;\n}\n\n/**\n * Allowlist a server-supplied relay URL (issue #41): only encrypted WebSocket\n * transports are accepted — `wss://` to a **public** host, and plaintext `ws://`\n * solely for loopback (local dev). Anything else is refused before it reaches the\n * wasm core.\n *\n * Beyond the scheme, the **host** is allowlisted too: a compromised control-plane\n * must not be able to point the device party at an internal/private endpoint\n * (loopback, RFC1918, link-local incl. cloud metadata `169.254.169.254`, IPv6\n * unique-/link-local, `.internal`/`.local`) — an SSRF-style redirect of the MPC\n * transport. Loopback is the one exception, and only over plaintext `ws://` for dev.\n */\nfunction assertAllowedRelayUrl(relayUrl: string): void {\n let url: URL;\n try {\n url = new URL(relayUrl);\n } catch (cause) {\n throw new Error(`Invalid relay URL \"${relayUrl}\".`, { cause });\n }\n // Dev: plaintext ws:// is tolerated, but only to loopback.\n if (url.protocol === 'ws:' && isLoopbackHost(url.hostname)) return;\n if (url.protocol !== 'wss:') {\n throw new Error(`Refusing server-supplied relay URL \"${relayUrl}\" — only wss:// (or ws:// on localhost) is allowed for the MPC transport.`);\n }\n // wss:// — reject internal/private hosts (loopback included: prod relays are public).\n if (isInternalHost(url.hostname)) {\n throw new Error(`Refusing server-supplied relay URL \"${relayUrl}\" — the relay host is internal/private; only a public wss:// endpoint is allowed.`);\n }\n}\n\n/** Loopback host literals (used to permit ws:// only for local dev). */\nfunction isLoopbackHost(hostname: string): boolean {\n const host = hostname.replace(/^\\[|\\]$/g, '').toLowerCase();\n return host === 'localhost' || host === '::1' || /^127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/.test(host);\n}\n\n/**\n * Is `hostname` an internal/private address a server must never send a client to?\n * Covers loopback, RFC1918 private v4, link-local v4 (incl. cloud metadata),\n * IPv6 unique-local (`fc00::/7`) + link-local (`fe80::/10`), and internal name\n * suffixes (`.internal`, `.local`). Public DNS names pass.\n */\nfunction isInternalHost(hostname: string): boolean {\n const host = hostname.replace(/^\\[|\\]$/g, '').toLowerCase();\n if (isLoopbackHost(hostname)) return true;\n if (host.endsWith('.internal') || host.endsWith('.local')) return true;\n\n const v4 = host.match(/^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/);\n if (v4) {\n const [a, b] = [Number(v4[1]), Number(v4[2])];\n if (a === 10) return true; // 10.0.0.0/8\n if (a === 172 && b >= 16 && b <= 31) return true; // 172.16.0.0/12\n if (a === 192 && b === 168) return true; // 192.168.0.0/16\n if (a === 169 && b === 254) return true; // 169.254.0.0/16 link-local (cloud metadata)\n return false;\n }\n\n if (host.includes(':')) {\n // IPv6 unique-local (fc00::/7 → fc/fd) and link-local (fe80::/10).\n if (/^f[cd][0-9a-f]{0,2}:/.test(host)) return true;\n if (/^fe[89ab][0-9a-f]:/.test(host)) return true;\n }\n return false;\n}\n\n/**\n * Coerce a device KeyShare into the inline JSON OBJECT the wasm sign exports expect. Both the\n * 2-party `sign` and the n-party `signMember` exports deserialize the wire `share` with\n * `serde_json::from_value::<KeyShare>`, so it MUST be a JSON object — a `share` sent as a JSON\n * string fails Rust deserialization (\"invalid type: string, expected struct\"). The KeyShare normally\n * arrives as its JSON string ({@link DeviceSignParams.share}); accept an already-parsed object too so\n * a caller can never double-encode it. The storage-blob wrapper is unpacked upstream — the core only\n * ever sees the bare KeyShare.\n */\nfunction toShareObject(share: unknown): Record<string, unknown> {\n const value: unknown = typeof share === 'string' ? JSON.parse(share) : share;\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error('KeyShare must be a JSON object (or its JSON string), not a scalar or array.');\n }\n return value as Record<string, unknown>;\n}\n\n/**\n * Coerce a FROST package (`key_package` / `public_key_package`) into the inline JSON OBJECT the wasm\n * `signEddsa` export expects. The wasm re-serializes each with `serde_json::to_vec` + `import_*_package`,\n * so it MUST be a JSON object — the ed25519 analogue of {@link toShareObject}. The package normally\n * arrives as its JSON object (from {@link EddsaKeygenResult}); accept its JSON string too (a\n * storage round-trip) so a caller can never double-encode it.\n */\nfunction toFrostPackage(pkg: unknown, which: string): Record<string, unknown> {\n const value: unknown = typeof pkg === 'string' ? JSON.parse(pkg) : pkg;\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error(`FROST ${which} must be a JSON object (or its JSON string), not a scalar or array.`);\n }\n return value as Record<string, unknown>;\n}\n\n/** Pull the shared public key out of a KeyShare JSON (`core.shared_public_key`). */\nfunction extractSharedPublicKey(keyShareJson: string): string {\n const parsed = JSON.parse(keyShareJson) as { core?: { shared_public_key?: unknown } };\n const pk = parsed.core?.shared_public_key;\n if (typeof pk !== 'string') {\n throw new Error('KeyShare is missing core.shared_public_key');\n }\n return pk;\n}\n\n/**\n * Decode the wasm's separately-surfaced `shared_public_key_json` (a JSON-encoded compressed-hex\n * point, e.g. `\"03ab…\"`) into the bare hex string. Used for the reshare **assemble** result, whose\n * bare core does not expose `core.shared_public_key` in the keygen shape.\n */\nfunction decodePublicKey(sharedPublicKeyJson: string): string {\n const pk = JSON.parse(sharedPublicKeyJson) as unknown;\n if (typeof pk !== 'string') {\n throw new Error('reshare assemble result is missing a shared_public_key');\n }\n return pk;\n}\n","/**\n * {@link NodeWorkerMpcCore} — the Node fix for waas-sdk#82.\n *\n * In-process (the plain {@link WasmMpcCore} with a Node loader) the wasm ceremony and its\n * relay WebSocket share one thread: the minutes-long zk-proof computation in\n * `aux_info_gen` blocks the loop, the socket can neither read nor answer pings, and an\n * intermediary (Cloudflare / ingress idle timeouts) kills the \"dead\" connection\n * mid-ceremony. This core splits them: the wasm runs in a `worker_threads` Worker behind\n * a bridged `WebSocket` shim, while the REAL socket lives here on the main thread — which\n * stays responsive and sends protocol-level pings (via `ws`) for the whole ceremony.\n *\n * The worker also holds a ref on the event loop, so a pending create/sign can no longer\n * silently exit the process (waas-sdk#84's symptom). Call {@link NodeWorkerMpcCore.terminate}\n * when done — the worker (and the process) stays alive until you do.\n */\nimport { Worker } from 'node:worker_threads';\n\nimport { WebSocket as RealWebSocket } from 'ws';\n\nimport { WasmMpcCore } from '../wasm-core';\n\nimport type { CallResult, FatalMessage, ReadyMessage, WorkerToMain, WsCloseRequest, WsOpenRequest, WsSendRequest } from './bridge-protocol';\nimport type { ClientWasmModule } from '../wasm-core';\n\nexport interface NodeWorkerMpcOptions {\n /**\n * The wasm engine package the worker imports (a bare specifier or file URL).\n * Defaults to `@waaskey/client-wasm`.\n */\n wasmPackage?: string;\n /**\n * Protocol-level ping cadence on each open relay socket, keeping the connection alive\n * through proxies while the worker computes. Default 15s; `0` disables.\n */\n pingIntervalMs?: number;\n}\n\ninterface PendingCall {\n resolve: (resultJson: string) => void;\n reject: (err: Error) => void;\n}\n\ninterface BridgedSocket {\n socket: RealWebSocket;\n pingTimer?: NodeJS.Timeout;\n}\n\n/** Owns the worker + the real sockets; exposes the worker as a {@link ClientWasmModule}. */\nclass WorkerBridge {\n private readonly wasmPackage: string;\n private readonly pingIntervalMs: number;\n private worker?: Worker;\n private modulePromise?: Promise<ClientWasmModule>;\n private nextCallId = 1;\n private readonly pending = new Map<number, PendingCall>();\n private readonly sockets = new Map<number, BridgedSocket>();\n\n constructor(options: NodeWorkerMpcOptions) {\n this.wasmPackage = options.wasmPackage ?? '@waaskey/client-wasm';\n this.pingIntervalMs = options.pingIntervalMs ?? 15_000;\n }\n\n module(): Promise<ClientWasmModule> {\n return (this.modulePromise ??= this.spawn());\n }\n\n async terminate(): Promise<void> {\n for (const [wsId] of this.sockets) this.dropSocket(wsId);\n this.failAllPending(new Error('NodeWorkerMpcCore terminated'));\n const { worker } = this;\n this.worker = undefined;\n this.modulePromise = undefined;\n if (worker) await worker.terminate();\n }\n\n private spawn(): Promise<ClientWasmModule> {\n // In dist the worker is the sibling `node-mpc-worker.js` bundle; when running from\n // source (vitest) it is the sibling `worker.ts`, loaded via Node's type stripping —\n // passed explicitly, since it is only on by default from Node 22.18.\n const fromSource = import.meta.url.endsWith('.ts');\n const workerUrl = new URL(fromSource ? './worker.ts' : './node-mpc-worker.js', import.meta.url);\n const worker = new Worker(workerUrl, { workerData: { wasmPackage: this.wasmPackage }, ...(fromSource ? { execArgv: ['--experimental-strip-types'] } : {}) });\n this.worker = worker;\n\n return new Promise<ClientWasmModule>((resolve, reject) => {\n let settled = false;\n worker.on('message', (message: WorkerToMain) => {\n switch (message.type) {\n case 'ready':\n settled = true;\n resolve(this.buildProxy(message));\n break;\n case 'fatal':\n settled = true;\n reject(new Error(`waaskey mpc worker failed to load ${this.wasmPackage}: ${(message as FatalMessage).error}`));\n break;\n case 'call-result':\n this.settleCall(message);\n break;\n case 'ws-open':\n this.openSocket(message);\n break;\n case 'ws-send':\n this.sendOnSocket(message);\n break;\n case 'ws-close':\n this.closeSocket(message);\n break;\n }\n });\n worker.on('error', (err: Error) => {\n if (!settled) {\n settled = true;\n reject(err);\n }\n this.failAllPending(err);\n });\n worker.on('exit', (code) => {\n const err = new Error(`waaskey mpc worker exited unexpectedly (code ${code})`);\n if (!settled) {\n settled = true;\n reject(err);\n }\n this.failAllPending(err);\n });\n });\n }\n\n private buildProxy(ready: ReadyMessage): ClientWasmModule {\n const proxy: Record<string, (paramsJson: string) => Promise<unknown>> = {};\n for (const name of ready.exports) {\n proxy[name] = async (paramsJson: string) => JSON.parse(await this.call(name, paramsJson)) as unknown;\n }\n return proxy as unknown as ClientWasmModule;\n }\n\n private call(method: string, paramsJson: string): Promise<string> {\n const { worker } = this;\n if (!worker) return Promise.reject(new Error('NodeWorkerMpcCore is terminated'));\n const id = this.nextCallId++;\n return new Promise<string>((resolve, reject) => {\n this.pending.set(id, { resolve, reject });\n worker.postMessage({ type: 'call', id, method, paramsJson });\n });\n }\n\n private settleCall(result: CallResult): void {\n const pending = this.pending.get(result.id);\n if (!pending) return;\n this.pending.delete(result.id);\n if (result.ok) pending.resolve(result.resultJson ?? 'null');\n else pending.reject(new Error(result.error ?? 'mpc worker call failed'));\n }\n\n private failAllPending(err: Error): void {\n for (const pending of this.pending.values()) pending.reject(err);\n this.pending.clear();\n }\n\n private openSocket(request: WsOpenRequest): void {\n const socket = new RealWebSocket(request.url, request.protocols);\n const entry: BridgedSocket = { socket };\n this.sockets.set(request.wsId, entry);\n\n socket.on('open', () => {\n if (this.pingIntervalMs > 0) {\n entry.pingTimer = setInterval(() => {\n if (socket.readyState === RealWebSocket.OPEN) socket.ping();\n }, this.pingIntervalMs);\n }\n this.worker?.postMessage({ type: 'ws-event', wsId: request.wsId, event: 'open', protocol: socket.protocol });\n });\n socket.on('message', (data: Buffer | ArrayBuffer | Buffer[], isBinary: boolean) => {\n const buf = Array.isArray(data) ? Buffer.concat(data) : Buffer.from(data as ArrayBuffer);\n const payload = isBinary ? new Uint8Array(buf) : buf.toString('utf8');\n this.worker?.postMessage({ type: 'ws-event', wsId: request.wsId, event: 'message', data: payload });\n });\n socket.on('close', (code: number, reason: Buffer) => {\n this.dropSocket(request.wsId);\n this.worker?.postMessage({ type: 'ws-event', wsId: request.wsId, event: 'close', code, reason: reason.toString('utf8'), wasClean: code === 1000 });\n });\n socket.on('error', (err: Error) => {\n this.worker?.postMessage({ type: 'ws-event', wsId: request.wsId, event: 'error', message: err.message });\n });\n }\n\n private sendOnSocket(request: WsSendRequest): void {\n this.sockets.get(request.wsId)?.socket.send(request.data);\n }\n\n private closeSocket(request: WsCloseRequest): void {\n const entry = this.sockets.get(request.wsId);\n entry?.socket.close(request.code, request.reason);\n }\n\n private dropSocket(wsId: number): void {\n const entry = this.sockets.get(wsId);\n if (!entry) return;\n this.sockets.delete(wsId);\n if (entry.pingTimer) clearInterval(entry.pingTimer);\n if (entry.socket.readyState === RealWebSocket.OPEN || entry.socket.readyState === RealWebSocket.CONNECTING) entry.socket.close();\n }\n}\n\n/**\n * A drop-in {@link WasmMpcCore} for Node ≥ 22 that runs the wasm ceremony in a worker\n * thread and keeps the relay WebSocket responsive on the main thread (waas-sdk#82).\n *\n * ```ts\n * import { NodeWorkerMpcCore } from '@waaskey/sdk/node';\n * const mpc = new NodeWorkerMpcCore();\n * const waaskey = new Waaskey({ apiKey, mpc, ... });\n * // …create / sign…\n * await mpc.terminate(); // the worker keeps the process alive until terminated\n * ```\n */\nexport class NodeWorkerMpcCore extends WasmMpcCore {\n private readonly bridge: WorkerBridge;\n\n constructor(options: NodeWorkerMpcOptions = {}) {\n const bridge = new WorkerBridge(options);\n super(() => bridge.module());\n this.bridge = bridge;\n }\n\n /** Close every bridged socket and terminate the worker; the core is unusable afterwards. */\n terminate(): Promise<void> {\n return this.bridge.terminate();\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@waaskey/sdk",
3
- "version": "0.3.2",
3
+ "version": "0.4.1",
4
4
  "description": "WAASKey — embedded, non-custodial MPC wallets for your app. Official TypeScript SDK.",
5
5
  "license": "MIT",
6
6
  "author": "Waaskey",
@@ -56,7 +56,7 @@
56
56
  "devDependencies": {
57
57
  "@simplewebauthn/browser": "^13.3.0",
58
58
  "@types/ws": "^8.18.0",
59
- "@types/node": "^26.1.1",
59
+ "@types/node": "^26.1.2",
60
60
  "tsup": "^8.5.1",
61
61
  "typescript": "^6.0.3",
62
62
  "vitest": "^4.1.10"