@getpara/web-sdk 3.0.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,15 +196,15 @@ 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
  }
193
204
  function signMessage(ctx, share, walletId, userId, message, cosmosSignDoc) {
194
205
  return __async(this, null, function* () {
195
206
  const protocolId = uuid.v4();
196
- const preSignMessageRes = ctx.client.preSignMessage(userId, walletId, message, null, cosmosSignDoc, protocolId);
207
+ const preSignMessageRes = ctx.client.preSignMessage(userId, walletId, message, null, cosmosSignDoc, protocolId, true);
197
208
  if (ctx.offloadMPCComputationURL && !ctx.useDKLS) {
198
209
  return signMessageRequest(ctx, userId, walletId, protocolId, message, share);
199
210
  }
@@ -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;
@@ -232,7 +243,12 @@ function signMessage(ctx, share, walletId, userId, message, cosmosSignDoc) {
232
243
  function signTransaction(ctx, share, walletId, userId, tx, chainId) {
233
244
  return __async(this, null, function* () {
234
245
  const protocolId = uuid.v4();
235
- const signTransactionRes = ctx.client.signTransaction(userId, walletId, { transaction: tx, chainId, protocolId });
246
+ const signTransactionRes = ctx.client.signTransaction(userId, walletId, {
247
+ transaction: tx,
248
+ chainId,
249
+ protocolId,
250
+ useNewOT: true
251
+ });
236
252
  if (ctx.offloadMPCComputationURL && !ctx.useDKLS) {
237
253
  return sendTransactionRequest(ctx, userId, walletId, protocolId, tx, share, chainId);
238
254
  }
@@ -254,17 +270,19 @@ function signTransaction(ctx, share, walletId, userId, tx, chainId) {
254
270
  resolve({ signature: result });
255
271
  })
256
272
  );
257
- } catch (e) {
258
- 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
+ });
259
277
  }
260
278
  });
261
279
  }();
280
+ signTxRes.catch(() => {
281
+ });
262
282
  const {
263
283
  data: { pendingTransactionId }
264
284
  } = yield signTransactionRes;
265
285
  if (pendingTransactionId) {
266
- signTxRes.catch(() => {
267
- });
268
286
  return { pendingTransactionId };
269
287
  }
270
288
  return yield signTxRes;
@@ -273,7 +291,12 @@ function signTransaction(ctx, share, walletId, userId, tx, chainId) {
273
291
  function sendTransaction(ctx, share, walletId, userId, tx, chainId) {
274
292
  return __async(this, null, function* () {
275
293
  const protocolId = uuid.v4();
276
- const sendTransactionRes = ctx.client.sendTransaction(userId, walletId, { transaction: tx, chainId, protocolId });
294
+ const sendTransactionRes = ctx.client.sendTransaction(userId, walletId, {
295
+ transaction: tx,
296
+ chainId,
297
+ protocolId,
298
+ useNewOT: true
299
+ });
277
300
  if (ctx.offloadMPCComputationURL && !ctx.useDKLS) {
278
301
  return sendTransactionRequest(ctx, userId, walletId, protocolId, tx, share, chainId);
279
302
  }
@@ -295,17 +318,21 @@ function sendTransaction(ctx, share, walletId, userId, tx, chainId) {
295
318
  resolve({ signature: result });
296
319
  })
297
320
  );
298
- } catch (e) {
299
- 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
+ );
300
327
  }
301
328
  });
302
329
  }();
330
+ sendTxRes.catch(() => {
331
+ });
303
332
  const {
304
333
  data: { pendingTransactionId }
305
334
  } = yield sendTransactionRes;
306
335
  if (pendingTransactionId) {
307
- sendTxRes.catch(() => {
308
- });
309
336
  return { pendingTransactionId };
310
337
  }
311
338
  return yield sendTxRes;
@@ -315,7 +342,7 @@ function refresh(ctx, share, walletId, userId, oldPartnerId, newPartnerId, keySh
315
342
  return __async(this, null, function* () {
316
343
  const {
317
344
  data: { protocolId }
318
- } = yield ctx.client.refreshKeys(userId, walletId, oldPartnerId, newPartnerId, keyShareProtocolId);
345
+ } = yield ctx.client.refreshKeys(userId, walletId, oldPartnerId, newPartnerId, keyShareProtocolId, true);
319
346
  const serverUrl = getBaseMPCNetworkUrl(ctx.env, !ctx.disableWebSockets);
320
347
  const refreshFn = ctx.useDKLS ? globalThis.dklsRefresh : globalThis.refresh;
321
348
  const parsedShare = JSON.parse(share);
@@ -332,8 +359,8 @@ function refresh(ctx, share, walletId, userId, oldPartnerId, newPartnerId, keySh
332
359
  resolve({ protocolId, signer: result });
333
360
  })
334
361
  );
335
- } catch (e) {
336
- 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);
337
364
  }
338
365
  });
339
366
  }
@@ -352,8 +379,8 @@ function getPrivateKey(ctx, share, walletId, userId) {
352
379
  resolve(result);
353
380
  })
354
381
  );
355
- } catch (e) {
356
- 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);
357
384
  }
358
385
  });
359
386
  }
@@ -372,8 +399,11 @@ function getED25519PrivateKey(ctx, share, walletId, userId) {
372
399
  resolve(result);
373
400
  })
374
401
  );
375
- } catch (e) {
376
- 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
+ );
377
407
  }
378
408
  });
379
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.0.0",
3
+ "version": "3.2.0",
4
4
  "dependencies": {
5
- "@getpara/core-sdk": "3.0.0",
6
- "@getpara/user-management-client": "3.0.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": "e6c42e42adfcfadb0114b1ac65ba5203e6274712",
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",