@getpara/web-sdk 3.0.0-alpha.1 → 3.0.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.
@@ -8,6 +8,7 @@ export declare class WebUtils implements PlatformUtils {
8
8
  private eventHandlers;
9
9
  private nativeHandlers;
10
10
  getPrivateKey(ctx: Ctx, userId: string, walletId: string, share: string, sessionCookie: string): Promise<string>;
11
+ getED25519PrivateKey(ctx: Ctx, userId: string, walletId: string, share: string, sessionCookie: string): Promise<string>;
11
12
  keygen(ctx: Ctx, userId: string, type: Exclude<TWalletType, 'SOLANA'>, secretKey: string | null, // should be acceptable as null in RN as we don't pre-gen them
12
13
  sessionCookie: string, emailProps?: BackupKitEmailProps): Promise<{
13
14
  signer: string;
package/dist/WebUtils.js CHANGED
@@ -7,7 +7,7 @@ import { LocalStorage } from "./LocalStorage.js";
7
7
  import { SessionStorage } from "./SessionStorage.js";
8
8
  import { keygen, preKeygen, ed25519Keygen, ed25519PreKeygen, refresh, initializeWorker } from "./wallet/keygen.js";
9
9
  import { signMessage, sendTransaction, signTransaction, ed25519Sign } from "./wallet/signing.js";
10
- import { getPrivateKey } from "./wallet/privateKey.js";
10
+ import { getPrivateKey, getED25519PrivateKey } from "./wallet/privateKey.js";
11
11
  import { validatePortalOrigin } from "./utils/validatePortalOrigin.js";
12
12
  class WebUtils {
13
13
  constructor() {
@@ -24,6 +24,9 @@ class WebUtils {
24
24
  getPrivateKey(ctx, userId, walletId, share, sessionCookie) {
25
25
  return getPrivateKey(ctx, userId, walletId, share, sessionCookie);
26
26
  }
27
+ getED25519PrivateKey(ctx, userId, walletId, share, sessionCookie) {
28
+ return getED25519PrivateKey(ctx, userId, walletId, share, sessionCookie);
29
+ }
27
30
  keygen(ctx, userId, type, secretKey, sessionCookie, emailProps = {}) {
28
31
  return keygen(ctx, userId, type, secretKey, true, sessionCookie, emailProps);
29
32
  }
@@ -78,7 +81,7 @@ class WebUtils {
78
81
  break;
79
82
  }
80
83
  case PopupType.EXPORT_PRIVATE_KEY: {
81
- popUpHeight = 585;
84
+ popUpHeight = 820;
82
85
  break;
83
86
  }
84
87
  // TODO: adjust this width when we change the UI for cosmos signing
@@ -4,6 +4,7 @@ export declare function isLargeIOS(): boolean;
4
4
  export declare function isTablet(): boolean;
5
5
  export declare function isIOS(): boolean;
6
6
  export declare function isMobile(): boolean;
7
+ export declare function isAndroidChrome(): boolean;
7
8
  export declare function isSafari(): boolean;
8
9
  export declare function isIOSWebview(): boolean;
9
10
  export declare function isMobileSafari(): boolean;
@@ -28,6 +28,24 @@ function isIOS() {
28
28
  function isMobile() {
29
29
  return isAndroid() || isIOS();
30
30
  }
31
+ let cachedAndroidChromeUa;
32
+ let cachedAndroidChromeResult = false;
33
+ function isAndroidChrome() {
34
+ if (typeof navigator === "undefined") return false;
35
+ const ua = navigator.userAgent;
36
+ if (cachedAndroidChromeUa === ua) return cachedAndroidChromeResult;
37
+ const compute = () => {
38
+ if (!isAndroid()) return false;
39
+ if (/EdgA\/|SamsungBrowser\/|OPR\/|UCBrowser\/|MiuiBrowser\//.test(ua)) return false;
40
+ if (/Firefox\//.test(ua)) return false;
41
+ if (navigator.brave) return false;
42
+ return /Chrome\//.test(ua);
43
+ };
44
+ const result = compute();
45
+ cachedAndroidChromeUa = ua;
46
+ cachedAndroidChromeResult = result;
47
+ return result;
48
+ }
31
49
  function isSafari() {
32
50
  return typeof navigator !== "undefined" && /AppleWebKit/i.test(navigator.userAgent) && !/CriOS/i.test(navigator.userAgent) && !/Chrome/i.test(navigator.userAgent);
33
51
  }
@@ -71,6 +89,7 @@ const openMobileUrl = (url) => {
71
89
  };
72
90
  export {
73
91
  isAndroid,
92
+ isAndroidChrome,
74
93
  isIOS,
75
94
  isIOSWebview,
76
95
  isLargeIOS,
@@ -3,8 +3,22 @@ import {
3
3
  __async
4
4
  } from "../chunk-YJOFEY2L.js";
5
5
  import { setupWorker } from "../workers/workerWrapper.js";
6
- import { distributeNewShare, waitUntilTrue, isPortal } from "@getpara/core-sdk";
6
+ import { distributeNewShare, waitUntilTrue, isPortal, wrapWithSpan } from "@getpara/core-sdk";
7
+ import { context, propagation } from "@opentelemetry/api";
7
8
  import * as uuid from "uuid";
9
+ function captureTraceCarrier() {
10
+ const carrier = {};
11
+ propagation.inject(context.active(), carrier, {
12
+ set: (c, k, v) => {
13
+ c[k] = v;
14
+ }
15
+ });
16
+ return Object.keys(carrier).length > 0 ? carrier : void 0;
17
+ }
18
+ function bindCallbackToActiveContext(fn) {
19
+ const captured = context.active();
20
+ return (...args) => context.with(captured, () => fn(...args));
21
+ }
8
22
  function isKeygenComplete(ctx, userId, walletId) {
9
23
  return __async(this, null, function* () {
10
24
  const wallets = yield (isPortal(ctx) ? ctx.client.getAllWallets : ctx.client.getWallets)(userId);
@@ -31,10 +45,13 @@ function keygen(ctx, userId, type, secretKey, skipDistribute = false, sessionCoo
31
45
  let worker = null;
32
46
  worker = yield setupWorker(
33
47
  ctx,
34
- (res) => __async(this, null, function* () {
35
- yield waitUntilTrue(() => __async(this, null, function* () {
36
- return isKeygenComplete(ctx, userId, res.walletId);
37
- }), 15e3, 1e3);
48
+ bindCallbackToActiveContext((res) => __async(this, null, function* () {
49
+ yield wrapWithSpan(
50
+ "mpc.keygen.poll_for_address",
51
+ () => waitUntilTrue(() => __async(this, null, function* () {
52
+ return isKeygenComplete(ctx, userId, res.walletId);
53
+ }), 15e3, 1e3)
54
+ );
38
55
  if (skipDistribute) {
39
56
  resolve({
40
57
  signer: res.signer,
@@ -43,22 +60,25 @@ function keygen(ctx, userId, type, secretKey, skipDistribute = false, sessionCoo
43
60
  });
44
61
  return;
45
62
  }
46
- const recoveryShare = yield distributeNewShare({
47
- ctx,
48
- userId,
49
- walletId: res.walletId,
50
- userShare: res.signer,
51
- emailProps,
52
- isEnclaveUser: false,
53
- walletScheme: "DKLS"
54
- // since `isEnclaveUser` is false, we can use `DKLS` here as it won't be used
55
- });
63
+ const recoveryShare = yield wrapWithSpan(
64
+ "wallet.distribute_recovery_share",
65
+ () => distributeNewShare({
66
+ ctx,
67
+ userId,
68
+ walletId: res.walletId,
69
+ userShare: res.signer,
70
+ emailProps,
71
+ isEnclaveUser: false,
72
+ walletScheme: "DKLS"
73
+ // since `isEnclaveUser` is false, we can use `DKLS` here as it won't be used
74
+ })
75
+ );
56
76
  resolve({
57
77
  signer: res.signer,
58
78
  walletId: res.walletId,
59
79
  recoveryShare
60
80
  });
61
- }),
81
+ })),
62
82
  (error) => {
63
83
  reject(error);
64
84
  },
@@ -76,7 +96,8 @@ function keygen(ctx, userId, type, secretKey, skipDistribute = false, sessionCoo
76
96
  useDKLS: ctx.useDKLS,
77
97
  disableWebSockets: ctx.disableWebSockets,
78
98
  wasmOverride: ctx.wasmOverride,
79
- workId
99
+ workId,
100
+ __otel: captureTraceCarrier()
80
101
  });
81
102
  }));
82
103
  }
@@ -86,20 +107,23 @@ function preKeygen(ctx, pregenIdentifier, pregenIdentifierType, type, secretKey,
86
107
  let worker = null;
87
108
  worker = yield setupWorker(
88
109
  ctx,
89
- (res) => __async(this, null, function* () {
90
- yield waitUntilTrue(
91
- () => __async(this, null, function* () {
92
- return isPreKeygenComplete(ctx, pregenIdentifier, pregenIdentifierType, res.walletId);
93
- }),
94
- 15e3,
95
- 1e3
110
+ bindCallbackToActiveContext((res) => __async(this, null, function* () {
111
+ yield wrapWithSpan(
112
+ "mpc.prekeygen.poll_for_address",
113
+ () => waitUntilTrue(
114
+ () => __async(this, null, function* () {
115
+ return isPreKeygenComplete(ctx, pregenIdentifier, pregenIdentifierType, res.walletId);
116
+ }),
117
+ 15e3,
118
+ 1e3
119
+ )
96
120
  );
97
121
  resolve({
98
122
  signer: res.signer,
99
123
  walletId: res.walletId,
100
124
  recoveryShare: null
101
125
  });
102
- }),
126
+ })),
103
127
  (error) => {
104
128
  reject(error);
105
129
  },
@@ -122,7 +146,8 @@ function preKeygen(ctx, pregenIdentifier, pregenIdentifierType, type, secretKey,
122
146
  useDKLS: ctx.useDKLS,
123
147
  disableWebSockets: ctx.disableWebSockets,
124
148
  wasmOverride: ctx.wasmOverride,
125
- workId
149
+ workId,
150
+ __otel: captureTraceCarrier()
126
151
  });
127
152
  }));
128
153
  }
@@ -132,10 +157,14 @@ function refresh(ctx, sessionCookie, userId, walletId, share, oldPartnerId, newP
132
157
  let worker = null;
133
158
  worker = yield setupWorker(
134
159
  ctx,
135
- (res) => __async(this, null, function* () {
136
- if (!(yield waitUntilTrue(() => __async(this, null, function* () {
137
- return isRefreshComplete(ctx, userId, walletId, newPartnerId);
138
- }), 15e3, 1e3))) {
160
+ bindCallbackToActiveContext((res) => __async(this, null, function* () {
161
+ const refreshDone = yield wrapWithSpan(
162
+ "mpc.refresh.poll_for_done",
163
+ () => waitUntilTrue(() => __async(this, null, function* () {
164
+ return isRefreshComplete(ctx, userId, walletId, newPartnerId);
165
+ }), 15e3, 1e3)
166
+ );
167
+ if (!refreshDone) {
139
168
  reject(new Error("refresh failed"));
140
169
  return;
141
170
  }
@@ -144,7 +173,7 @@ function refresh(ctx, sessionCookie, userId, walletId, share, oldPartnerId, newP
144
173
  signer,
145
174
  protocolId
146
175
  });
147
- }),
176
+ })),
148
177
  (error) => {
149
178
  reject(error);
150
179
  },
@@ -171,16 +200,19 @@ function ed25519Keygen(ctx, userId, sessionCookie, _emailProps = {}, type) {
171
200
  let worker = null;
172
201
  worker = yield setupWorker(
173
202
  ctx,
174
- (res) => __async(this, null, function* () {
175
- yield waitUntilTrue(() => __async(this, null, function* () {
176
- return isKeygenComplete(ctx, userId, res.walletId);
177
- }), 15e3, 1e3);
203
+ bindCallbackToActiveContext((res) => __async(this, null, function* () {
204
+ yield wrapWithSpan(
205
+ "mpc.ed25519_keygen.poll_for_address",
206
+ () => waitUntilTrue(() => __async(this, null, function* () {
207
+ return isKeygenComplete(ctx, userId, res.walletId);
208
+ }), 15e3, 1e3)
209
+ );
178
210
  resolve({
179
211
  signer: res.signer,
180
212
  walletId: res.walletId,
181
213
  recoveryShare: null
182
214
  });
183
- }),
215
+ })),
184
216
  (error) => {
185
217
  reject(error);
186
218
  },
@@ -196,7 +228,8 @@ function ed25519Keygen(ctx, userId, sessionCookie, _emailProps = {}, type) {
196
228
  sessionCookie,
197
229
  disableWebSockets: ctx.disableWebSockets,
198
230
  wasmOverride: ctx.wasmOverride,
199
- workId
231
+ workId,
232
+ __otel: captureTraceCarrier()
200
233
  });
201
234
  }));
202
235
  }
@@ -206,20 +239,23 @@ function ed25519PreKeygen(ctx, pregenIdentifier, pregenIdentifierType, sessionCo
206
239
  let worker = null;
207
240
  worker = yield setupWorker(
208
241
  ctx,
209
- (res) => __async(this, null, function* () {
210
- yield waitUntilTrue(
211
- () => __async(this, null, function* () {
212
- return isPreKeygenComplete(ctx, pregenIdentifier, pregenIdentifierType, res.walletId);
213
- }),
214
- 15e3,
215
- 1e3
242
+ bindCallbackToActiveContext((res) => __async(this, null, function* () {
243
+ yield wrapWithSpan(
244
+ "mpc.ed25519_prekeygen.poll_for_address",
245
+ () => waitUntilTrue(
246
+ () => __async(this, null, function* () {
247
+ return isPreKeygenComplete(ctx, pregenIdentifier, pregenIdentifierType, res.walletId);
248
+ }),
249
+ 15e3,
250
+ 1e3
251
+ )
216
252
  );
217
253
  resolve({
218
254
  signer: res.signer,
219
255
  walletId: res.walletId,
220
256
  recoveryShare: null
221
257
  });
222
- }),
258
+ })),
223
259
  (error) => {
224
260
  reject(error);
225
261
  },
@@ -240,7 +276,8 @@ function ed25519PreKeygen(ctx, pregenIdentifier, pregenIdentifierType, sessionCo
240
276
  sessionCookie,
241
277
  disableWebSockets: ctx.disableWebSockets,
242
278
  wasmOverride: ctx.wasmOverride,
243
- workId
279
+ workId,
280
+ __otel: captureTraceCarrier()
244
281
  });
245
282
  }));
246
283
  }
@@ -263,7 +300,8 @@ function initializeWorker(ctx) {
263
300
  env: ctx.env,
264
301
  apiKey: ctx.apiKey,
265
302
  functionType: "INIT",
266
- workId
303
+ workId,
304
+ __otel: captureTraceCarrier()
267
305
  });
268
306
  } catch (error) {
269
307
  reject(error);
@@ -1,2 +1,3 @@
1
1
  import { Ctx } from '@getpara/core-sdk';
2
2
  export declare function getPrivateKey(ctx: Ctx, userId: string, walletId: string, share: string, sessionCookie?: string): Promise<string>;
3
+ export declare function getED25519PrivateKey(ctx: Ctx, userId: string, walletId: string, share: string, sessionCookie?: string): Promise<string>;
@@ -36,6 +36,39 @@ function getPrivateKey(ctx, userId, walletId, share, sessionCookie) {
36
36
  }));
37
37
  });
38
38
  }
39
+ function getED25519PrivateKey(ctx, userId, walletId, share, sessionCookie) {
40
+ return __async(this, null, function* () {
41
+ return new Promise((resolve, reject) => __async(this, null, function* () {
42
+ const workId = uuid.v4();
43
+ let worker = null;
44
+ worker = yield setupWorker(
45
+ ctx,
46
+ (res) => __async(this, null, function* () {
47
+ resolve((res == null ? void 0 : res.privateKey) || res);
48
+ }),
49
+ (error) => {
50
+ reject(error);
51
+ },
52
+ workId
53
+ );
54
+ worker.postMessage({
55
+ env: ctx.env,
56
+ apiKey: ctx.apiKey,
57
+ cosmosPrefix: ctx.cosmosPrefix,
58
+ params: { share, walletId, userId },
59
+ functionType: "ED25519_GET_PRIVATE_KEY",
60
+ offloadMPCComputationURL: ctx.offloadMPCComputationURL,
61
+ disableWorkers: ctx.disableWorkers,
62
+ sessionCookie,
63
+ useDKLS: ctx.useDKLS,
64
+ disableWebSockets: ctx.disableWebSockets,
65
+ wasmOverride: ctx.wasmOverride,
66
+ workId
67
+ });
68
+ }));
69
+ });
70
+ }
39
71
  export {
72
+ getED25519PrivateKey,
40
73
  getPrivateKey
41
74
  };
@@ -3,7 +3,17 @@ import {
3
3
  __async
4
4
  } from "../chunk-YJOFEY2L.js";
5
5
  import { setupWorker } from "../workers/workerWrapper.js";
6
+ import { context, propagation } from "@opentelemetry/api";
6
7
  import * as uuid from "uuid";
8
+ function captureTraceCarrier() {
9
+ const carrier = {};
10
+ propagation.inject(context.active(), carrier, {
11
+ set: (c, k, v) => {
12
+ c[k] = v;
13
+ }
14
+ });
15
+ return Object.keys(carrier).length > 0 ? carrier : void 0;
16
+ }
7
17
  function signTransaction(ctx, userId, walletId, share, tx, chainId, sessionCookie, isDKLS) {
8
18
  return __async(this, null, function* () {
9
19
  return new Promise((resolve, reject) => __async(this, null, function* () {
@@ -31,7 +41,8 @@ function signTransaction(ctx, userId, walletId, share, tx, chainId, sessionCooki
31
41
  useDKLS: isDKLS,
32
42
  disableWebSockets: ctx.disableWebSockets,
33
43
  wasmOverride: ctx.wasmOverride,
34
- workId
44
+ workId,
45
+ __otel: captureTraceCarrier()
35
46
  });
36
47
  }));
37
48
  });
@@ -63,7 +74,8 @@ function sendTransaction(ctx, userId, walletId, share, tx, chainId, sessionCooki
63
74
  useDKLS: isDKLS,
64
75
  disableWebSockets: ctx.disableWebSockets,
65
76
  wasmOverride: ctx.wasmOverride,
66
- workId
77
+ workId,
78
+ __otel: captureTraceCarrier()
67
79
  });
68
80
  }));
69
81
  });
@@ -96,7 +108,8 @@ function signMessage(ctx, userId, walletId, share, message, sessionCookie, isDKL
96
108
  useDKLS: isDKLS,
97
109
  disableWebSockets: ctx.disableWebSockets,
98
110
  wasmOverride: ctx.wasmOverride,
99
- workId
111
+ workId,
112
+ __otel: captureTraceCarrier()
100
113
  });
101
114
  }));
102
115
  });
@@ -127,7 +140,8 @@ function ed25519Sign(ctx, userId, walletId, share, base64Bytes, sessionCookie) {
127
140
  sessionCookie,
128
141
  disableWebSockets: ctx.disableWebSockets,
129
142
  wasmOverride: ctx.wasmOverride,
130
- workId
143
+ workId,
144
+ __otel: captureTraceCarrier()
131
145
  });
132
146
  }));
133
147
  });
@@ -24,3 +24,4 @@ export declare function refresh(ctx: Ctx, share: string, walletId: string, userI
24
24
  signer: string;
25
25
  }>;
26
26
  export declare function getPrivateKey(ctx: Ctx, share: string, walletId: string, userId: string): Promise<string>;
27
+ export declare function getED25519PrivateKey(ctx: Ctx, share: string, walletId: string, userId: string): Promise<string>;
@@ -357,10 +357,31 @@ function getPrivateKey(ctx, share, walletId, userId) {
357
357
  }
358
358
  });
359
359
  }
360
+ function getED25519PrivateKey(ctx, share, walletId, userId) {
361
+ return __async(this, null, function* () {
362
+ const paraShare = yield ctx.client.getParaShare(userId, walletId);
363
+ if (!paraShare) {
364
+ return "";
365
+ }
366
+ try {
367
+ return yield new Promise(
368
+ (resolve, reject) => globalThis.ed25519GetPrivateKey(share, paraShare, (err, result) => {
369
+ if (err) {
370
+ reject(err);
371
+ }
372
+ resolve(result);
373
+ })
374
+ );
375
+ } catch (e) {
376
+ throw new Error(`error getting ed25519 private key for account with userId ${userId} and walletId ${walletId}`);
377
+ }
378
+ });
379
+ }
360
380
  export {
361
381
  ed25519Keygen,
362
382
  ed25519PreKeygen,
363
383
  ed25519Sign,
384
+ getED25519PrivateKey,
364
385
  getPrivateKey,
365
386
  keygen,
366
387
  preKeygen,
@@ -13,6 +13,7 @@ export interface Message {
13
13
  wasmOverride?: ArrayBuffer;
14
14
  returnObject?: boolean;
15
15
  workId?: string;
16
+ __otel?: Record<string, string>;
16
17
  }
17
18
  /**
18
19
  * Executes an operation with retry capabilities
@@ -110,6 +110,11 @@ function executeMessage(ctx, message) {
110
110
  const privateKey = yield walletUtils.getPrivateKey(ctx, share, walletId, userId);
111
111
  return { privateKey };
112
112
  }
113
+ case "ED25519_GET_PRIVATE_KEY": {
114
+ const { share, walletId, userId } = params;
115
+ const privateKey = yield walletUtils.getED25519PrivateKey(ctx, share, walletId, userId);
116
+ return { privateKey };
117
+ }
113
118
  case "ED25519_KEYGEN": {
114
119
  const { userId, type } = params;
115
120
  return walletUtils.ed25519Keygen(ctx, userId, void 0, void 0, type);
@@ -168,7 +173,8 @@ function handleMessage(e, postMessage, useFetchAdapter) {
168
173
  useDKLS,
169
174
  disableWebSockets,
170
175
  wasmOverride,
171
- workId
176
+ workId,
177
+ __otel
172
178
  } = e.data;
173
179
  if (!env) {
174
180
  return true;
@@ -182,7 +188,12 @@ function handleMessage(e, postMessage, useFetchAdapter) {
182
188
  version: paraVersion,
183
189
  apiKey,
184
190
  useFetchAdapter,
185
- retrieveSessionCookie: () => sessionCookie
191
+ retrieveSessionCookie: () => sessionCookie,
192
+ // Threading the parent's W3C trace context through so the worker's UMC
193
+ // requests carry the same traceparent the FE's mpc.* span would generate
194
+ // if it were making the call directly. BE spans then parent under the FE
195
+ // mpc.* span, completing the FE → worker → BE waterfall.
196
+ staticTraceContext: __otel
186
197
  }),
187
198
  offloadMPCComputationURL,
188
199
  mpcComputationClient: offloadMPCComputationURL ? mpcComputationClient.initClient(offloadMPCComputationURL, !!disableWorkers) : void 0,
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "@getpara/web-sdk",
3
- "version": "3.0.0-alpha.1",
3
+ "version": "3.0.0",
4
4
  "dependencies": {
5
- "@getpara/core-sdk": "3.0.0-alpha.1",
6
- "@getpara/user-management-client": "3.0.0-alpha.1",
5
+ "@getpara/core-sdk": "3.0.0",
6
+ "@getpara/user-management-client": "3.0.0",
7
+ "@opentelemetry/api": "^1.9.1",
7
8
  "base64url": "^3.0.1",
8
9
  "buffer": "6.0.3",
9
10
  "cbor-web": "^9.0.2",
@@ -29,7 +30,7 @@
29
30
  "dist",
30
31
  "package.json"
31
32
  ],
32
- "gitHead": "839d225579de67feb5be4da225d232290b2a2a04",
33
+ "gitHead": "e6c42e42adfcfadb0114b1ac65ba5203e6274712",
33
34
  "main": "dist/index.js",
34
35
  "scripts": {
35
36
  "build": "rm -rf dist && yarn typegen && node ./scripts/build.mjs && yarn post-build",