@getpara/web-sdk 3.1.0 → 3.2.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.
@@ -0,0 +1,14 @@
1
+ export interface MpcErrorContext {
2
+ protocolId?: string;
3
+ walletId?: string;
4
+ userId?: string;
5
+ chainId?: string;
6
+ functionType?: string;
7
+ [key: string]: unknown;
8
+ }
9
+ export declare function wrapMpcError(summary: string, cause: unknown, context?: MpcErrorContext): Error;
10
+ export declare function unwrapMpcError(err: unknown): {
11
+ cause: Error;
12
+ context: MpcErrorContext;
13
+ };
14
+ export declare function classifyMpcError(message: string | undefined): string;
@@ -0,0 +1,38 @@
1
+ "use client";
2
+ import "../chunk-YJOFEY2L.js";
3
+ function toError(value) {
4
+ return value instanceof Error ? value : new Error(String(value));
5
+ }
6
+ function wrapMpcError(summary, cause, context) {
7
+ const err = new Error(summary);
8
+ err.cause = toError(cause);
9
+ if (context) {
10
+ err.mpcContext = context;
11
+ }
12
+ return err;
13
+ }
14
+ function unwrapMpcError(err) {
15
+ var _a;
16
+ const top = err;
17
+ const cause = (top == null ? void 0 : top.cause) !== void 0 ? toError(top.cause) : toError(err);
18
+ const context = (_a = top == null ? void 0 : top.mpcContext) != null ? _a : {};
19
+ return { cause, context };
20
+ }
21
+ function classifyMpcError(message) {
22
+ const m = (message != null ? message : "").toLowerCase();
23
+ if (m.includes("panic")) return "MpcPanicError";
24
+ if (/\bwasm\b|webassembly/.test(m)) return "MpcWasmError";
25
+ if (/connection|websocket|\bdial\b|getconnection|econnrefused|network|broken pipe/.test(m)) {
26
+ return "MpcConnectionError";
27
+ }
28
+ if (/timed out|timeout|deadline/.test(m)) return "MpcTimeoutError";
29
+ if (/deserialize|unmarshal|invalid share|config from (sender|receiver)|reconstruct|magic bytes/.test(m)) {
30
+ return "MpcShareError";
31
+ }
32
+ return "MpcProtocolError";
33
+ }
34
+ export {
35
+ classifyMpcError,
36
+ unwrapMpcError,
37
+ wrapMpcError
38
+ };
@@ -4,6 +4,7 @@ import {
4
4
  } from "../chunk-YJOFEY2L.js";
5
5
  import { getBaseMPCNetworkUrl } from "@getpara/core-sdk";
6
6
  import * as uuid from "uuid";
7
+ import { wrapMpcError } from "./mpcWorkerError.js";
7
8
  const configCGGMPBase = (serverUrl, walletId, id) => `{"ServerUrl":"${serverUrl}", "WalletId": "${walletId}", "Id":"${id}", "Ids":["USER","CAPSULE"], "Threshold":1}`;
8
9
  const configDKLSBase = (walletId, id, disableWebSockets) => `{"walletId": "${walletId}", "id":"${id}", "otherId":"CAPSULE", "isReceiver": false, "disableWebSockets": ${disableWebSockets}}`;
9
10
  function keygenRequest(ctx, userId, walletId, protocolId) {
@@ -56,8 +57,11 @@ function ed25519Keygen(ctx, userId, _sessionCookie, _emailProps, type = "SOLANA"
56
57
  })
57
58
  );
58
59
  return { signer: newSigner, walletId };
59
- } catch (e) {
60
- throw new Error(`error creating ED25519 account with userId ${userId} and walletId ${walletId}`);
60
+ } catch (mpcErr) {
61
+ throw wrapMpcError(`error creating ED25519 account with userId ${userId} and walletId ${walletId}`, mpcErr, {
62
+ walletId,
63
+ protocolId
64
+ });
61
65
  }
62
66
  });
63
67
  }
@@ -80,8 +84,8 @@ function ed25519PreKeygen(ctx, pregenIdentifier, pregenIdentifierType, _sessionC
80
84
  })
81
85
  );
82
86
  return { signer: newSigner, walletId };
83
- } catch (e) {
84
- throw new Error(`error creating ED25519 account with walletId ${walletId}`);
87
+ } catch (mpcErr) {
88
+ throw wrapMpcError(`error creating ED25519 account with walletId ${walletId}`, mpcErr, { walletId, protocolId });
85
89
  }
86
90
  });
87
91
  }
@@ -101,11 +105,15 @@ function ed25519Sign(ctx, share, userId, walletId, base64Bytes) {
101
105
  })
102
106
  );
103
107
  return { signature: base64Sig };
104
- } catch (e) {
105
- throw new Error(`error signing for account of type SOLANA with userId ${userId} and walletId ${walletId}`);
108
+ } catch (mpcErr) {
109
+ throw wrapMpcError(`error signing for account of type SOLANA with userId ${userId} and walletId ${walletId}`, mpcErr, {
110
+ protocolId
111
+ });
106
112
  }
107
113
  });
108
114
  }();
115
+ signRes.catch(() => {
116
+ });
109
117
  const { pendingTransactionId } = yield preSignMessageRes;
110
118
  if (pendingTransactionId) {
111
119
  signRes.catch(() => {
@@ -151,8 +159,11 @@ function keygen(ctx, userId, type, secretKey) {
151
159
  )
152
160
  );
153
161
  return { signer: newSigner, walletId };
154
- } catch (e) {
155
- throw new Error(`error creating account of type ${type} with userId ${userId} and walletId ${walletId}`);
162
+ } catch (mpcErr) {
163
+ throw wrapMpcError(`error creating account of type ${type} with userId ${userId} and walletId ${walletId}`, mpcErr, {
164
+ walletId,
165
+ protocolId
166
+ });
156
167
  }
157
168
  });
158
169
  }
@@ -185,8 +196,8 @@ function preKeygen(ctx, _partnerId, pregenIdentifier, pregenIdentifierType, type
185
196
  )
186
197
  );
187
198
  return { signer: newSigner, walletId };
188
- } catch (e) {
189
- throw new Error(`error creating account of type ${type} with walletId ${walletId}`);
199
+ } catch (mpcErr) {
200
+ throw wrapMpcError(`error creating account of type ${type} with walletId ${walletId}`, mpcErr, { walletId, protocolId });
190
201
  }
191
202
  });
192
203
  }
@@ -215,15 +226,15 @@ function signMessage(ctx, share, walletId, userId, message, cosmosSignDoc) {
215
226
  resolve({ signature: result });
216
227
  })
217
228
  );
218
- } catch (e) {
219
- throw new Error(`error signing for account with userId ${userId} and walletId ${walletId}`);
229
+ } catch (mpcErr) {
230
+ throw wrapMpcError(`error signing for account with userId ${userId} and walletId ${walletId}`, mpcErr, { protocolId });
220
231
  }
221
232
  });
222
233
  }();
234
+ signMessageRes.catch(() => {
235
+ });
223
236
  const { pendingTransactionId } = yield preSignMessageRes;
224
237
  if (pendingTransactionId) {
225
- signMessageRes.catch(() => {
226
- });
227
238
  return { pendingTransactionId };
228
239
  }
229
240
  return yield signMessageRes;
@@ -259,17 +270,19 @@ function signTransaction(ctx, share, walletId, userId, tx, chainId) {
259
270
  resolve({ signature: result });
260
271
  })
261
272
  );
262
- } catch (e) {
263
- throw new Error(`error signing transaction for account with userId ${userId} and walletId ${walletId}`);
273
+ } catch (mpcErr) {
274
+ throw wrapMpcError(`error signing transaction for account with userId ${userId} and walletId ${walletId}`, mpcErr, {
275
+ protocolId
276
+ });
264
277
  }
265
278
  });
266
279
  }();
280
+ signTxRes.catch(() => {
281
+ });
267
282
  const {
268
283
  data: { pendingTransactionId }
269
284
  } = yield signTransactionRes;
270
285
  if (pendingTransactionId) {
271
- signTxRes.catch(() => {
272
- });
273
286
  return { pendingTransactionId };
274
287
  }
275
288
  return yield signTxRes;
@@ -305,17 +318,21 @@ function sendTransaction(ctx, share, walletId, userId, tx, chainId) {
305
318
  resolve({ signature: result });
306
319
  })
307
320
  );
308
- } catch (e) {
309
- throw new Error(`error signing transaction to send for account with userId ${userId} and walletId ${walletId}`);
321
+ } catch (mpcErr) {
322
+ throw wrapMpcError(
323
+ `error signing transaction to send for account with userId ${userId} and walletId ${walletId}`,
324
+ mpcErr,
325
+ { protocolId }
326
+ );
310
327
  }
311
328
  });
312
329
  }();
330
+ sendTxRes.catch(() => {
331
+ });
313
332
  const {
314
333
  data: { pendingTransactionId }
315
334
  } = yield sendTransactionRes;
316
335
  if (pendingTransactionId) {
317
- sendTxRes.catch(() => {
318
- });
319
336
  return { pendingTransactionId };
320
337
  }
321
338
  return yield sendTxRes;
@@ -342,8 +359,8 @@ function refresh(ctx, share, walletId, userId, oldPartnerId, newPartnerId, keySh
342
359
  resolve({ protocolId, signer: result });
343
360
  })
344
361
  );
345
- } catch (e) {
346
- throw new Error(`error refreshing keys for account with userId ${userId} and walletId ${walletId}`);
362
+ } catch (mpcErr) {
363
+ throw wrapMpcError(`error refreshing keys for account with userId ${userId} and walletId ${walletId}`, mpcErr);
347
364
  }
348
365
  });
349
366
  }
@@ -362,8 +379,8 @@ function getPrivateKey(ctx, share, walletId, userId) {
362
379
  resolve(result);
363
380
  })
364
381
  );
365
- } catch (e) {
366
- throw new Error(`error getting private key for account with userId ${userId} and walletId ${walletId}`);
382
+ } catch (mpcErr) {
383
+ throw wrapMpcError(`error getting private key for account with userId ${userId} and walletId ${walletId}`, mpcErr);
367
384
  }
368
385
  });
369
386
  }
@@ -382,8 +399,11 @@ function getED25519PrivateKey(ctx, share, walletId, userId) {
382
399
  resolve(result);
383
400
  })
384
401
  );
385
- } catch (e) {
386
- throw new Error(`error getting ed25519 private key for account with userId ${userId} and walletId ${walletId}`);
402
+ } catch (mpcErr) {
403
+ throw wrapMpcError(
404
+ `error getting ed25519 private key for account with userId ${userId} and walletId ${walletId}`,
405
+ mpcErr
406
+ );
387
407
  }
388
408
  });
389
409
  }
@@ -1,4 +1,20 @@
1
1
  "use client";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
6
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
+ var __spreadValues = (a, b) => {
8
+ for (var prop in b || (b = {}))
9
+ if (__hasOwnProp.call(b, prop))
10
+ __defNormalProp(a, prop, b[prop]);
11
+ if (__getOwnPropSymbols)
12
+ for (var prop of __getOwnPropSymbols(b)) {
13
+ if (__propIsEnum.call(b, prop))
14
+ __defNormalProp(a, prop, b[prop]);
15
+ }
16
+ return a;
17
+ };
2
18
  var __async = (__this, __arguments, generator) => {
3
19
  return new Promise((resolve, reject) => {
4
20
  var fulfilled = (value) => {
@@ -27,6 +43,7 @@ import {
27
43
  mpcComputationClient,
28
44
  paraVersion
29
45
  } from "@getpara/core-sdk";
46
+ import { classifyMpcError, unwrapMpcError } from "./mpcWorkerError.js";
30
47
  let wasmLoaded = false;
31
48
  function tryFetchWasm(url) {
32
49
  return __async(this, null, function* () {
@@ -144,13 +161,17 @@ function withRetry(operation, maxRetries = 2, timeoutMs = 1e4) {
144
161
  while (true) {
145
162
  try {
146
163
  const operationPromise = operation();
164
+ let timeoutId;
147
165
  const timeoutPromise = new Promise((_, reject) => {
148
- const timeoutId = setTimeout(() => {
166
+ timeoutId = setTimeout(() => {
149
167
  reject(new Error(`Operation timed out after ${timeoutMs}ms`));
150
168
  }, timeoutMs);
151
- operationPromise.finally(() => clearTimeout(timeoutId));
152
169
  });
153
- return yield Promise.race([operationPromise, timeoutPromise]);
170
+ try {
171
+ return yield Promise.race([operationPromise, timeoutPromise]);
172
+ } finally {
173
+ clearTimeout(timeoutId);
174
+ }
154
175
  } catch (error) {
155
176
  retries++;
156
177
  if (retries > maxRetries) {
@@ -161,6 +182,31 @@ function withRetry(operation, maxRetries = 2, timeoutMs = 1e4) {
161
182
  }
162
183
  });
163
184
  }
185
+ function reportWorkerError(ctx, sdkType, data, err) {
186
+ return __async(this, null, function* () {
187
+ var _a;
188
+ try {
189
+ const { cause, context } = unwrapMpcError(err);
190
+ yield ctx.client.trackError({
191
+ methodName: `mpcWorker.${data.functionType}`,
192
+ sdkType,
193
+ userId: (_a = data.params.userId) != null ? _a : "",
194
+ sdkVersion: paraVersion,
195
+ error: { name: classifyMpcError(cause.message), message: cause.message },
196
+ context: __spreadValues({
197
+ functionType: data.functionType,
198
+ // worker-level identifiers (present for most signing ops); the wrapped
199
+ // context (spread last) supplies walletId/protocolId for keygen flows
200
+ // where params don't carry them.
201
+ userId: data.params.userId,
202
+ walletId: data.params.walletId,
203
+ chainId: data.params.chainId
204
+ }, context)
205
+ });
206
+ } catch (e) {
207
+ }
208
+ });
209
+ }
164
210
  function handleMessage(e, postMessage, useFetchAdapter) {
165
211
  return __async(this, null, function* () {
166
212
  const {
@@ -201,25 +247,31 @@ function handleMessage(e, postMessage, useFetchAdapter) {
201
247
  disableWebSockets: !!disableWebSockets,
202
248
  wasmOverride
203
249
  };
204
- if (!wasmLoaded && (!ctx.offloadMPCComputationURL || ctx.useDKLS)) {
205
- yield loadWasm(ctx, wasmOverride);
206
- const serverUrl = getBaseMPCNetworkUrl(ctx.env, !ctx.disableWebSockets);
207
- if (globalThis.initWasm) {
208
- yield new Promise(
209
- (resolve, reject) => {
210
- var _a;
211
- return (_a = globalThis.initWasm) == null ? void 0 : _a.call(globalThis, (err, result2) => {
212
- if (err) {
213
- reject(err);
214
- }
215
- resolve(result2);
216
- }, serverUrl);
217
- }
218
- );
250
+ let result;
251
+ try {
252
+ if (!wasmLoaded && (!ctx.offloadMPCComputationURL || ctx.useDKLS)) {
253
+ yield loadWasm(ctx, wasmOverride);
254
+ const serverUrl = getBaseMPCNetworkUrl(ctx.env, !ctx.disableWebSockets);
255
+ if (globalThis.initWasm) {
256
+ yield new Promise(
257
+ (resolve, reject) => {
258
+ var _a;
259
+ return (_a = globalThis.initWasm) == null ? void 0 : _a.call(globalThis, (err, initResult) => {
260
+ if (err) {
261
+ reject(err);
262
+ }
263
+ resolve(initResult);
264
+ }, serverUrl);
265
+ }
266
+ );
267
+ }
268
+ wasmLoaded = true;
219
269
  }
220
- wasmLoaded = true;
270
+ result = yield executeMessage(ctx, e.data);
271
+ } catch (err) {
272
+ yield reportWorkerError(ctx, "WEB", e.data, err);
273
+ throw err;
221
274
  }
222
- const result = yield executeMessage(ctx, e.data);
223
275
  if (workId) {
224
276
  result.workId = workId;
225
277
  }
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@getpara/web-sdk",
3
- "version": "3.1.0",
3
+ "version": "3.2.0",
4
4
  "dependencies": {
5
- "@getpara/core-sdk": "3.1.0",
6
- "@getpara/user-management-client": "3.1.0",
5
+ "@getpara/core-sdk": "3.2.0",
6
+ "@getpara/user-management-client": "3.2.0",
7
7
  "@opentelemetry/api": "^1.9.1",
8
8
  "base64url": "^3.0.1",
9
9
  "buffer": "6.0.3",
@@ -30,7 +30,7 @@
30
30
  "dist",
31
31
  "package.json"
32
32
  ],
33
- "gitHead": "e73f17cd7960fdfe62ff68a972b3461e47b21eb0",
33
+ "gitHead": "096152f48e9d9a64fdb192588315c64d33d15a1b",
34
34
  "main": "dist/index.js",
35
35
  "scripts": {
36
36
  "build": "rm -rf dist && yarn typegen && node ./scripts/build.mjs && yarn post-build",