@getpara/core-sdk 3.0.0-alpha.1 → 3.1.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.
Files changed (106) hide show
  1. package/dist/cjs/ParaCore.js +436 -86
  2. package/dist/cjs/constants.js +1 -1
  3. package/dist/cjs/cryptography/utils.js +5 -2
  4. package/dist/cjs/errors.js +10 -0
  5. package/dist/cjs/external/userManagementClient.js +21 -4
  6. package/dist/cjs/index.js +67 -1
  7. package/dist/cjs/services/AuthService.js +66 -47
  8. package/dist/cjs/services/LoginFlowService.js +30 -27
  9. package/dist/cjs/services/PollingService.js +100 -75
  10. package/dist/cjs/services/PortalUrlService.js +112 -19
  11. package/dist/cjs/services/PregenWalletService.js +125 -76
  12. package/dist/cjs/services/SessionManagementService.js +81 -10
  13. package/dist/cjs/services/SignupFlowService.js +52 -47
  14. package/dist/cjs/services/VerificationFlowService.js +13 -10
  15. package/dist/cjs/services/WalletService.js +51 -36
  16. package/dist/cjs/shares/enclave.js +44 -24
  17. package/dist/cjs/state/CoreStateManager.js +17 -5
  18. package/dist/cjs/state/actors/setupPara.js +4 -1
  19. package/dist/cjs/state/machines/walletStateMachine.js +22 -0
  20. package/dist/cjs/telemetry/BeaconSpanProcessor.js +99 -0
  21. package/dist/cjs/telemetry/config.js +15 -0
  22. package/dist/cjs/telemetry/init.js +193 -0
  23. package/dist/cjs/telemetry/modalSession.js +54 -0
  24. package/dist/cjs/telemetry/session.js +39 -0
  25. package/dist/cjs/telemetry/tracer.js +126 -0
  26. package/dist/cjs/telemetry/uxAction.js +30 -0
  27. package/dist/cjs/telemetry/uxBaggagePropagator.js +58 -0
  28. package/dist/cjs/telemetry/uxState.js +46 -0
  29. package/dist/cjs/telemetry/uxStateSpanProcessor.js +51 -0
  30. package/dist/cjs/utils/configEncoding.js +98 -0
  31. package/dist/cjs/utils/deprecation.js +13 -13
  32. package/dist/cjs/utils/index.js +11 -0
  33. package/dist/cjs/utils/partnerConfig.js +103 -0
  34. package/dist/cjs/utils/partnerConfigGating.js +83 -0
  35. package/dist/cjs/utils/stateErrorHelpers.js +6 -1
  36. package/dist/cjs/utils/url.js +10 -2
  37. package/dist/esm/ParaCore.js +441 -88
  38. package/dist/esm/constants.js +1 -1
  39. package/dist/esm/cryptography/utils.js +5 -2
  40. package/dist/esm/errors.js +9 -0
  41. package/dist/esm/external/userManagementClient.js +21 -4
  42. package/dist/esm/index.js +58 -4
  43. package/dist/esm/services/AuthService.js +66 -47
  44. package/dist/esm/services/LoginFlowService.js +30 -27
  45. package/dist/esm/services/PollingService.js +100 -75
  46. package/dist/esm/services/PortalUrlService.js +112 -19
  47. package/dist/esm/services/PregenWalletService.js +125 -76
  48. package/dist/esm/services/SessionManagementService.js +69 -11
  49. package/dist/esm/services/SignupFlowService.js +52 -47
  50. package/dist/esm/services/VerificationFlowService.js +13 -10
  51. package/dist/esm/services/WalletService.js +51 -36
  52. package/dist/esm/shares/enclave.js +44 -24
  53. package/dist/esm/state/CoreStateManager.js +17 -5
  54. package/dist/esm/state/actors/setupPara.js +4 -1
  55. package/dist/esm/state/machines/walletStateMachine.js +22 -0
  56. package/dist/esm/telemetry/BeaconSpanProcessor.js +74 -0
  57. package/dist/esm/telemetry/config.js +0 -0
  58. package/dist/esm/telemetry/init.js +130 -0
  59. package/dist/esm/telemetry/modalSession.js +29 -0
  60. package/dist/esm/telemetry/session.js +16 -0
  61. package/dist/esm/telemetry/tracer.js +84 -0
  62. package/dist/esm/telemetry/uxAction.js +8 -0
  63. package/dist/esm/telemetry/uxBaggagePropagator.js +35 -0
  64. package/dist/esm/telemetry/uxState.js +21 -0
  65. package/dist/esm/telemetry/uxStateSpanProcessor.js +28 -0
  66. package/dist/esm/utils/configEncoding.js +45 -0
  67. package/dist/esm/utils/deprecation.js +11 -12
  68. package/dist/esm/utils/index.js +6 -0
  69. package/dist/esm/utils/partnerConfig.js +67 -0
  70. package/dist/esm/utils/partnerConfigGating.js +61 -0
  71. package/dist/esm/utils/stateErrorHelpers.js +6 -1
  72. package/dist/esm/utils/url.js +10 -2
  73. package/dist/types/ParaCore.d.ts +101 -19
  74. package/dist/types/PlatformUtils.d.ts +1 -0
  75. package/dist/types/errors.d.ts +26 -0
  76. package/dist/types/external/userManagementClient.d.ts +2 -1
  77. package/dist/types/index.d.ts +15 -3
  78. package/dist/types/services/types/AuthServiceTypes.d.ts +10 -3
  79. package/dist/types/services/types/PortalUrlServiceTypes.d.ts +3 -3
  80. package/dist/types/services/types/WalletServiceTypes.d.ts +4 -0
  81. package/dist/types/state/actors/setupPara.d.ts +18 -0
  82. package/dist/types/state/machines/authStateMachine.d.ts +1 -1
  83. package/dist/types/state/machines/coreStateMachine.d.ts +30 -6
  84. package/dist/types/state/machines/walletStateMachine.d.ts +4 -0
  85. package/dist/types/state/types/core.d.ts +7 -1
  86. package/dist/types/telemetry/BeaconSpanProcessor.d.ts +10 -0
  87. package/dist/types/telemetry/config.d.ts +4 -0
  88. package/dist/types/telemetry/init.d.ts +17 -0
  89. package/dist/types/telemetry/modalSession.d.ts +5 -0
  90. package/dist/types/telemetry/session.d.ts +2 -0
  91. package/dist/types/telemetry/tracer.d.ts +10 -0
  92. package/dist/types/telemetry/uxAction.d.ts +3 -0
  93. package/dist/types/telemetry/uxBaggagePropagator.d.ts +7 -0
  94. package/dist/types/telemetry/uxState.d.ts +8 -0
  95. package/dist/types/telemetry/uxStateSpanProcessor.d.ts +9 -0
  96. package/dist/types/types/config.d.ts +15 -3
  97. package/dist/types/types/coreApi.d.ts +7 -9
  98. package/dist/types/types/serviceInterfaces.d.ts +5 -3
  99. package/dist/types/types/util.d.ts +2 -15
  100. package/dist/types/utils/configEncoding.d.ts +51 -0
  101. package/dist/types/utils/deprecation.d.ts +3 -1
  102. package/dist/types/utils/index.d.ts +2 -0
  103. package/dist/types/utils/partnerConfig.d.ts +28 -0
  104. package/dist/types/utils/partnerConfigGating.d.ts +48 -0
  105. package/dist/types/utils/url.d.ts +3 -2
  106. package/package.json +15 -4
@@ -28,6 +28,7 @@ import { ParaEvent } from "../types/events.js";
28
28
  import { LOCAL_STORAGE_CURRENT_WALLET_IDS, LOCAL_STORAGE_WALLETS, SHORT_POLLING_INTERVAL_MS } from "../constants.js";
29
29
  import { distributeNewShare } from "../shares/shareDistribution.js";
30
30
  import { sendRecoveryForShare } from "../shares/recovery.js";
31
+ import { wrapWithSpan } from "../telemetry/tracer.js";
31
32
  class WalletService {
32
33
  constructor(paraCore) {
33
34
  __privateAdd(this, _authService);
@@ -108,15 +109,20 @@ class WalletService {
108
109
  }
109
110
  });
110
111
  });
112
+ // wallets.populate names the GET /users/:userId/wallets call that runs to
113
+ // refresh address state after creation/refresh; without it the GET shows up
114
+ // as a bare span at the trace top level.
111
115
  this.populateWalletAddresses = () => __async(this, null, function* () {
112
- const res = yield (__privateGet(this, _paraCoreInterface).isPortal() ? __privateGet(this, _paraCoreInterface).ctx.client.getAllWallets : __privateGet(this, _paraCoreInterface).ctx.client.getWallets)(__privateGet(this, _authService).userId, true);
113
- const wallets = res.data.wallets;
114
- wallets.forEach((entity) => {
115
- if (this.wallets[entity.id]) {
116
- this.wallets[entity.id] = __spreadValues(__spreadValues({}, entityToWallet(entity)), this.wallets[entity.id]);
117
- }
118
- });
119
- yield this.setWallets(this.wallets);
116
+ return wrapWithSpan("wallets.populate", () => __async(this, null, function* () {
117
+ const res = yield (__privateGet(this, _paraCoreInterface).isPortal() ? __privateGet(this, _paraCoreInterface).ctx.client.getAllWallets : __privateGet(this, _paraCoreInterface).ctx.client.getWallets)(__privateGet(this, _authService).userId, true);
118
+ const wallets = res.data.wallets;
119
+ wallets.forEach((entity) => {
120
+ if (this.wallets[entity.id]) {
121
+ this.wallets[entity.id] = __spreadValues(__spreadValues({}, entityToWallet(entity)), this.wallets[entity.id]);
122
+ }
123
+ });
124
+ yield this.setWallets(this.wallets);
125
+ }));
120
126
  });
121
127
  this.addToCurrentWalletIds = (walletIds, options) => __async(this, null, function* () {
122
128
  const updatedWalletIds = __spreadValues({}, this.currentWalletIds);
@@ -156,31 +162,35 @@ class WalletService {
156
162
  );
157
163
  let signer;
158
164
  let wallet;
159
- let keygenRes;
160
- switch (walletType) {
161
- case "STELLAR":
162
- case "SOLANA": {
163
- keygenRes = yield __privateGet(this, _paraCoreInterface).platformUtils.ed25519Keygen(
164
- __privateGet(this, _paraCoreInterface).ctx,
165
- __privateGet(this, _authService).userId,
166
- __privateGet(this, _paraCoreInterface).retrieveSessionCookie(),
167
- __privateGet(this, _paraCoreInterface).getBackupKitEmailProps(),
168
- walletType
169
- );
170
- break;
171
- }
172
- default: {
173
- keygenRes = yield __privateGet(this, _paraCoreInterface).platformUtils.keygen(
174
- __privateGet(this, _paraCoreInterface).ctx,
175
- __privateGet(this, _authService).userId,
176
- walletType,
177
- null,
178
- __privateGet(this, _paraCoreInterface).retrieveSessionCookie(),
179
- __privateGet(this, _paraCoreInterface).getBackupKitEmailProps()
180
- );
181
- break;
165
+ const keygenRes = yield wrapWithSpan(
166
+ "mpc.keygen",
167
+ () => __async(this, null, function* () {
168
+ switch (walletType) {
169
+ case "STELLAR":
170
+ case "SOLANA":
171
+ return __privateGet(this, _paraCoreInterface).platformUtils.ed25519Keygen(
172
+ __privateGet(this, _paraCoreInterface).ctx,
173
+ __privateGet(this, _authService).userId,
174
+ __privateGet(this, _paraCoreInterface).retrieveSessionCookie(),
175
+ __privateGet(this, _paraCoreInterface).getBackupKitEmailProps(),
176
+ walletType
177
+ );
178
+ default:
179
+ return __privateGet(this, _paraCoreInterface).platformUtils.keygen(
180
+ __privateGet(this, _paraCoreInterface).ctx,
181
+ __privateGet(this, _authService).userId,
182
+ walletType,
183
+ null,
184
+ __privateGet(this, _paraCoreInterface).retrieveSessionCookie(),
185
+ __privateGet(this, _paraCoreInterface).getBackupKitEmailProps()
186
+ );
187
+ }
188
+ }),
189
+ {
190
+ "wallet.type": walletType,
191
+ "wallet.scheme": walletType === "SOLANA" || walletType === "STELLAR" ? "ED25519" : "DKLS"
182
192
  }
183
- }
193
+ );
184
194
  const walletId = keygenRes.walletId;
185
195
  const walletScheme = walletType === "SOLANA" || walletType === "STELLAR" ? "ED25519" : "DKLS";
186
196
  signer = keygenRes.signer;
@@ -388,11 +398,16 @@ class WalletService {
388
398
  }
389
399
  return type;
390
400
  });
401
+ // wallets.fetch names the post-keygen wallet list reads (the polling-style
402
+ // GETs that follow each MPC keygen). The auto-instrumented HTTP child carries
403
+ // the URL and status so this stays cheap.
391
404
  this.fetchWallets = () => __async(this, null, function* () {
392
- const res = yield __privateGet(this, _paraCoreInterface).isPortal() || __privateGet(this, _paraCoreInterface).isParaConnect() ? __privateGet(this, _paraCoreInterface).ctx.client.getAllWallets(__privateGet(this, _authService).userId) : __privateGet(this, _paraCoreInterface).ctx.client.getWallets(__privateGet(this, _authService).userId, true);
393
- return res.data.wallets.filter(
394
- (wallet) => !!wallet.address && wallet.sharesPersisted && (__privateGet(this, _paraCoreInterface).isParaConnect() || !__privateGet(this, _paraCoreInterface).isParaConnect() && this.isWalletSupported(entityToWallet(wallet)))
395
- );
405
+ return wrapWithSpan("wallets.fetch", () => __async(this, null, function* () {
406
+ const res = yield __privateGet(this, _paraCoreInterface).isPortal() || __privateGet(this, _paraCoreInterface).isParaConnect() ? __privateGet(this, _paraCoreInterface).ctx.client.getAllWallets(__privateGet(this, _authService).userId) : __privateGet(this, _paraCoreInterface).ctx.client.getWallets(__privateGet(this, _authService).userId, true);
407
+ return res.data.wallets.filter(
408
+ (wallet) => !!wallet.address && wallet.sharesPersisted && (__privateGet(this, _paraCoreInterface).isParaConnect() || !__privateGet(this, _paraCoreInterface).isParaConnect() && this.isWalletSupported(entityToWallet(wallet)))
409
+ );
410
+ }));
396
411
  });
397
412
  this.getWalletBalance = (_0) => __async(this, [_0], function* ({ walletId, rpcUrl }) {
398
413
  return (yield __privateGet(this, _paraCoreInterface).ctx.client.getWalletBalance({ walletId, rpcUrl })).balance;
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  __async
3
3
  } from "../chunk-7B52C2XE.js";
4
+ import { wrapWithSpan } from "../telemetry/tracer.js";
4
5
  class EnclaveClient {
5
6
  constructor({
6
7
  userManagementClient,
@@ -172,40 +173,59 @@ ${exportedAsBase64}
172
173
  * Persist key shares to the enclave
173
174
  * @param shares Array of share data to persist
174
175
  */
176
+ // enclave.persist_shares wraps the encrypt + POST /enclave/key-shares pair so
177
+ // both the (CPU-bound) ECIES encryption and the network call show up under a
178
+ // named parent in the trace. Encryption can dominate the wall time so it's
179
+ // worth spelling out separately from the POST itself.
175
180
  persistShares(shares) {
176
181
  return __async(this, null, function* () {
177
- const payload = {
178
- shares,
179
- jwt: this.retrieveJwt()
180
- };
181
- const encryptedPayload = yield this.encryptForEnclave(JSON.stringify(payload));
182
- const encryptedPayloadStr = JSON.stringify(encryptedPayload);
183
- return yield this.userManagementClient.persistEnclaveShares({ encryptedPayload: encryptedPayloadStr });
182
+ return wrapWithSpan(
183
+ "enclave.persist_shares",
184
+ () => __async(this, null, function* () {
185
+ const payload = {
186
+ shares,
187
+ jwt: this.retrieveJwt()
188
+ };
189
+ const encryptedPayload = yield this.encryptForEnclave(JSON.stringify(payload));
190
+ const encryptedPayloadStr = JSON.stringify(encryptedPayload);
191
+ return yield this.userManagementClient.persistEnclaveShares({ encryptedPayload: encryptedPayloadStr });
192
+ }),
193
+ { "enclave.share_count": shares.length }
194
+ );
184
195
  });
185
196
  }
186
197
  /**
187
198
  * Retrieve key shares from the enclave
188
199
  * @param query Query parameters for finding shares (single query or array of queries)
189
200
  */
201
+ // enclave.retrieve_shares wraps the JWT issue + ECDH keypair gen + GET
202
+ // /enclave/key-shares + decrypt pipeline. The decrypt step can be slow on
203
+ // many-share accounts so a named span makes that latency easy to spot.
190
204
  retrieveShares(query) {
191
205
  return __async(this, null, function* () {
192
- yield this.issueEnclaveJwt();
193
- const frontendKeyPair = yield this.generateFrontendKeyPair();
194
- const responsePublicKeyPEM = yield this.exportPublicKeyToPEM(frontendKeyPair.publicKey);
195
- const fullQuery = query.map((q) => ({
196
- userId: q.userId
197
- }));
198
- const payload = {
199
- query: fullQuery,
200
- responsePublicKey: responsePublicKeyPEM,
201
- jwt: this.retrieveJwt()
202
- };
203
- const encryptedPayload = yield this.encryptForEnclave(JSON.stringify(payload));
204
- const encryptedPayloadStr = JSON.stringify(encryptedPayload);
205
- const response = yield this.userManagementClient.retrieveEnclaveShares(encryptedPayloadStr);
206
- const encryptedResponse = JSON.parse(response.payload);
207
- const decryptedData = yield this.decryptForFrontend(encryptedResponse);
208
- return Array.isArray(decryptedData == null ? void 0 : decryptedData.shares) ? decryptedData.shares : [];
206
+ return wrapWithSpan(
207
+ "enclave.retrieve_shares",
208
+ () => __async(this, null, function* () {
209
+ yield this.issueEnclaveJwt();
210
+ const frontendKeyPair = yield this.generateFrontendKeyPair();
211
+ const responsePublicKeyPEM = yield this.exportPublicKeyToPEM(frontendKeyPair.publicKey);
212
+ const fullQuery = query.map((q) => ({
213
+ userId: q.userId
214
+ }));
215
+ const payload = {
216
+ query: fullQuery,
217
+ responsePublicKey: responsePublicKeyPEM,
218
+ jwt: this.retrieveJwt()
219
+ };
220
+ const encryptedPayload = yield this.encryptForEnclave(JSON.stringify(payload));
221
+ const encryptedPayloadStr = JSON.stringify(encryptedPayload);
222
+ const response = yield this.userManagementClient.retrieveEnclaveShares(encryptedPayloadStr);
223
+ const encryptedResponse = JSON.parse(response.payload);
224
+ const decryptedData = yield this.decryptForFrontend(encryptedResponse);
225
+ return Array.isArray(decryptedData == null ? void 0 : decryptedData.shares) ? decryptedData.shares : [];
226
+ }),
227
+ { "enclave.query_count": query.length }
228
+ );
209
229
  });
210
230
  }
211
231
  deleteShares() {
@@ -80,7 +80,7 @@ const _CoreStateManager = class _CoreStateManager {
80
80
  * Extracts all data needed by UI consumers from authStateResult.
81
81
  */
82
82
  computeAuthStateInfo(authContext, walletContext) {
83
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I;
83
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L;
84
84
  const defaultAuthStateInfo = {
85
85
  userId: null,
86
86
  isPasskeySupported: false,
@@ -98,6 +98,9 @@ const _CoreStateManager = class _CoreStateManager {
98
98
  passkeyId: null,
99
99
  verificationUrl: null,
100
100
  verificationFullUrl: null,
101
+ deliveryChannel: null,
102
+ fallbackUsed: false,
103
+ fallbackChannel: null,
101
104
  externalWalletVerification: null,
102
105
  recoverySecret: null,
103
106
  isNewUser: false
@@ -137,6 +140,9 @@ const _CoreStateManager = class _CoreStateManager {
137
140
  let verificationFullUrl = null;
138
141
  let passkeyHints = null;
139
142
  let passkeyId = null;
143
+ let deliveryChannel = null;
144
+ let fallbackUsed = false;
145
+ let fallbackChannel = null;
140
146
  if (stage === "login") {
141
147
  const loginState = authStateResult;
142
148
  const authMethods = (_j = loginState.loginAuthMethods) != null ? _j : [];
@@ -170,6 +176,9 @@ const _CoreStateManager = class _CoreStateManager {
170
176
  const verifyState = authStateResult;
171
177
  verificationUrl = (_C = verifyState.loginUrl) != null ? _C : null;
172
178
  verificationFullUrl = (_D = verifyState.loginFullUrl) != null ? _D : null;
179
+ deliveryChannel = (_E = verifyState.deliveryChannel) != null ? _E : null;
180
+ fallbackUsed = (_F = verifyState.fallbackUsed) != null ? _F : false;
181
+ fallbackChannel = (_G = verifyState.fallbackChannel) != null ? _G : null;
173
182
  }
174
183
  return {
175
184
  userId,
@@ -188,10 +197,13 @@ const _CoreStateManager = class _CoreStateManager {
188
197
  passkeyId,
189
198
  verificationUrl,
190
199
  verificationFullUrl,
200
+ deliveryChannel,
201
+ fallbackUsed,
202
+ fallbackChannel,
191
203
  externalWalletVerification: externalWalletVerification ? {
192
- signatureVerificationMessage: (_E = externalWalletVerification.signatureVerificationMessage) != null ? _E : "",
193
- walletAddress: (_G = (_F = externalWalletVerification.externalWallet) == null ? void 0 : _F.address) != null ? _G : "",
194
- walletType: (_I = (_H = externalWalletVerification.externalWallet) == null ? void 0 : _H.type) != null ? _I : ""
204
+ signatureVerificationMessage: (_H = externalWalletVerification.signatureVerificationMessage) != null ? _H : "",
205
+ walletAddress: (_J = (_I = externalWalletVerification.externalWallet) == null ? void 0 : _I.address) != null ? _J : "",
206
+ walletType: (_L = (_K = externalWalletVerification.externalWallet) == null ? void 0 : _K.type) != null ? _L : ""
195
207
  } : null,
196
208
  recoverySecret,
197
209
  isNewUser
@@ -253,7 +265,7 @@ const _CoreStateManager = class _CoreStateManager {
253
265
  }
254
266
  authStateInfoEqual(a, b) {
255
267
  var _a, _b, _c, _d, _e, _f, _g, _h, _i;
256
- return a.userId === b.userId && a.isPasskeySupported === b.isPasskeySupported && a.hasPasskey === b.hasPasskey && a.hasPassword === b.hasPassword && a.hasPin === b.hasPin && a.passkeyUrl === b.passkeyUrl && a.passkeyFullUrl === b.passkeyFullUrl && a.passkeyKnownDeviceUrl === b.passkeyKnownDeviceUrl && a.passwordUrl === b.passwordUrl && a.passwordFullUrl === b.passwordFullUrl && a.pinUrl === b.pinUrl && a.pinFullUrl === b.pinFullUrl && a.passkeyId === b.passkeyId && a.verificationUrl === b.verificationUrl && a.verificationFullUrl === b.verificationFullUrl && a.recoverySecret === b.recoverySecret && a.isNewUser === b.isNewUser && ((_a = a.externalWalletVerification) == null ? void 0 : _a.signatureVerificationMessage) === ((_b = b.externalWalletVerification) == null ? void 0 : _b.signatureVerificationMessage) && ((_c = a.externalWalletVerification) == null ? void 0 : _c.walletAddress) === ((_d = b.externalWalletVerification) == null ? void 0 : _d.walletAddress) && ((_e = a.externalWalletVerification) == null ? void 0 : _e.walletType) === ((_f = b.externalWalletVerification) == null ? void 0 : _f.walletType) && ((_g = a.passkeyHints) == null ? void 0 : _g.length) === ((_h = b.passkeyHints) == null ? void 0 : _h.length) && ((_i = a.passkeyHints) != null ? _i : []).every(
268
+ return a.userId === b.userId && a.isPasskeySupported === b.isPasskeySupported && a.hasPasskey === b.hasPasskey && a.hasPassword === b.hasPassword && a.hasPin === b.hasPin && a.passkeyUrl === b.passkeyUrl && a.passkeyFullUrl === b.passkeyFullUrl && a.passkeyKnownDeviceUrl === b.passkeyKnownDeviceUrl && a.passwordUrl === b.passwordUrl && a.passwordFullUrl === b.passwordFullUrl && a.pinUrl === b.pinUrl && a.pinFullUrl === b.pinFullUrl && a.passkeyId === b.passkeyId && a.verificationUrl === b.verificationUrl && a.verificationFullUrl === b.verificationFullUrl && a.deliveryChannel === b.deliveryChannel && a.fallbackUsed === b.fallbackUsed && a.fallbackChannel === b.fallbackChannel && a.recoverySecret === b.recoverySecret && a.isNewUser === b.isNewUser && ((_a = a.externalWalletVerification) == null ? void 0 : _a.signatureVerificationMessage) === ((_b = b.externalWalletVerification) == null ? void 0 : _b.signatureVerificationMessage) && ((_c = a.externalWalletVerification) == null ? void 0 : _c.walletAddress) === ((_d = b.externalWalletVerification) == null ? void 0 : _d.walletAddress) && ((_e = a.externalWalletVerification) == null ? void 0 : _e.walletType) === ((_f = b.externalWalletVerification) == null ? void 0 : _f.walletType) && ((_g = a.passkeyHints) == null ? void 0 : _g.length) === ((_h = b.passkeyHints) == null ? void 0 : _h.length) && ((_i = a.passkeyHints) != null ? _i : []).every(
257
269
  (hint, i) => hint.useragent === b.passkeyHints[i].useragent && hint.aaguid === b.passkeyHints[i].aaguid
258
270
  );
259
271
  }
@@ -3,7 +3,10 @@ import {
3
3
  } from "../../chunk-7B52C2XE.js";
4
4
  import { fromPromise } from "xstate";
5
5
  const createSetupParaActor = (paraCoreInterface) => fromPromise(() => __async(void 0, null, function* () {
6
- yield paraCoreInterface.setup();
6
+ const eagerPartnerLoad = paraCoreInterface.isPortal() ? Promise.resolve() : paraCoreInterface.sessionManagementService.touchSession().catch((e) => {
7
+ paraCoreInterface.devLog("setupPara: eager partner load via touchSession failed; will retry lazily", e);
8
+ });
9
+ yield Promise.all([paraCoreInterface.setup(), eagerPartnerLoad]);
7
10
  }));
8
11
  export {
9
12
  createSetupParaActor
@@ -161,6 +161,28 @@ function createWalletStateMachine(paraCoreInterface) {
161
161
  ]
162
162
  },
163
163
  needs_wallets: {
164
+ // `needs_wallets` is otherwise a passive state that waits for the consumer
165
+ // to dispatch `WAIT_FOR_WALLET_CREATION`. That contract is fine for
166
+ // `isNewUser` reaching this state without auto-create (`checking_wallet_state`
167
+ // guard at line ~127), but it traps existing users who landed here via
168
+ // `waiting_for_wallets` COMPLETE with `needsWallet=true` — i.e., an
169
+ // authenticated user whose wallets don't satisfy the partner's
170
+ // `supportedWalletTypes` (e.g. EVM-only user logging into a Solana-only
171
+ // partner). Their auth flow set `shouldAutoCreateWallets: true` via
172
+ // `authenticateWithOAuth` / `authenticateWithEmailOrPhone`, but the
173
+ // existing `claiming_wallets` guard requires `isNewUser ||
174
+ // shouldClaimGuestWallets`, neither of which is true for them, so
175
+ // auto-create silently never happens.
176
+ //
177
+ // When `shouldAutoCreate` is true, route directly to `creating_wallets`.
178
+ // `createWalletPerType` is partner-aware via `#getMissingTypes`, so it
179
+ // provisions exactly the missing required types (no duplicates).
180
+ always: [
181
+ {
182
+ target: "creating_wallets",
183
+ guard: "shouldAutoCreate"
184
+ }
185
+ ],
164
186
  on: {
165
187
  WAIT_FOR_WALLET_CREATION: {
166
188
  target: "claiming_wallets",
@@ -0,0 +1,74 @@
1
+ import {
2
+ __privateAdd,
3
+ __privateGet,
4
+ __privateMethod,
5
+ __privateSet
6
+ } from "../chunk-7B52C2XE.js";
7
+ var _spans, _pagehideListener, _visibilityListener, _url, _BeaconSpanProcessor_instances, flushViaBeacon_fn;
8
+ import { JsonTraceSerializer } from "@opentelemetry/otlp-transformer";
9
+ const MAX_BUFFER_SIZE = 200;
10
+ class BeaconSpanProcessor {
11
+ constructor(url) {
12
+ __privateAdd(this, _BeaconSpanProcessor_instances);
13
+ __privateAdd(this, _spans, []);
14
+ __privateAdd(this, _pagehideListener);
15
+ __privateAdd(this, _visibilityListener);
16
+ __privateAdd(this, _url);
17
+ __privateSet(this, _url, url);
18
+ if (typeof window !== "undefined") {
19
+ __privateSet(this, _pagehideListener, () => __privateMethod(this, _BeaconSpanProcessor_instances, flushViaBeacon_fn).call(this));
20
+ __privateSet(this, _visibilityListener, () => {
21
+ if (typeof document !== "undefined" && document.visibilityState === "hidden") {
22
+ __privateMethod(this, _BeaconSpanProcessor_instances, flushViaBeacon_fn).call(this);
23
+ }
24
+ });
25
+ window.addEventListener("pagehide", __privateGet(this, _pagehideListener));
26
+ if (typeof document !== "undefined") {
27
+ document.addEventListener("visibilitychange", __privateGet(this, _visibilityListener));
28
+ }
29
+ }
30
+ }
31
+ onStart(_span, _parentContext) {
32
+ }
33
+ onEnd(span) {
34
+ __privateGet(this, _spans).push(span);
35
+ if (__privateGet(this, _spans).length > MAX_BUFFER_SIZE) {
36
+ __privateGet(this, _spans).shift();
37
+ }
38
+ }
39
+ forceFlush() {
40
+ return Promise.resolve();
41
+ }
42
+ shutdown() {
43
+ __privateMethod(this, _BeaconSpanProcessor_instances, flushViaBeacon_fn).call(this);
44
+ if (__privateGet(this, _pagehideListener) && typeof window !== "undefined") {
45
+ window.removeEventListener("pagehide", __privateGet(this, _pagehideListener));
46
+ __privateSet(this, _pagehideListener, void 0);
47
+ }
48
+ if (__privateGet(this, _visibilityListener) && typeof document !== "undefined") {
49
+ document.removeEventListener("visibilitychange", __privateGet(this, _visibilityListener));
50
+ __privateSet(this, _visibilityListener, void 0);
51
+ }
52
+ __privateSet(this, _spans, []);
53
+ return Promise.resolve();
54
+ }
55
+ }
56
+ _spans = new WeakMap();
57
+ _pagehideListener = new WeakMap();
58
+ _visibilityListener = new WeakMap();
59
+ _url = new WeakMap();
60
+ _BeaconSpanProcessor_instances = new WeakSet();
61
+ flushViaBeacon_fn = function() {
62
+ if (__privateGet(this, _spans).length === 0) return;
63
+ if (typeof navigator === "undefined" || typeof navigator.sendBeacon !== "function") return;
64
+ try {
65
+ const body = JsonTraceSerializer.serializeRequest(__privateGet(this, _spans));
66
+ const blob = new Blob([body], { type: "application/json" });
67
+ navigator.sendBeacon(__privateGet(this, _url), blob);
68
+ __privateSet(this, _spans, []);
69
+ } catch (e) {
70
+ }
71
+ };
72
+ export {
73
+ BeaconSpanProcessor
74
+ };
File without changes
@@ -0,0 +1,130 @@
1
+ import {
2
+ __async,
3
+ __spreadValues
4
+ } from "../chunk-7B52C2XE.js";
5
+ import {
6
+ BatchSpanProcessor,
7
+ BasicTracerProvider,
8
+ TraceIdRatioBasedSampler
9
+ } from "@opentelemetry/sdk-trace-base";
10
+ import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
11
+ import { resourceFromAttributes } from "@opentelemetry/resources";
12
+ import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from "@opentelemetry/semantic-conventions";
13
+ import { context, propagation, trace } from "@opentelemetry/api";
14
+ import { CompositePropagator, W3CTraceContextPropagator } from "@opentelemetry/core";
15
+ import { UxStateSpanProcessor } from "./uxStateSpanProcessor.js";
16
+ import { UxBaggagePropagator } from "./uxBaggagePropagator.js";
17
+ let initialized = false;
18
+ let tracerProvider;
19
+ const readyCallbacks = [];
20
+ function onTelemetryReady(cb) {
21
+ if (initialized) {
22
+ cb();
23
+ return;
24
+ }
25
+ readyCallbacks.push(cb);
26
+ }
27
+ function initTelemetry(opts) {
28
+ return __async(this, null, function* () {
29
+ if (initialized) return;
30
+ initialized = true;
31
+ const isWeb = opts.sdkType === "WEB" && typeof window !== "undefined";
32
+ if (isWeb && !opts.isPortal) {
33
+ try {
34
+ const { ZoneContextManager } = yield import("@opentelemetry/context-zone");
35
+ const zoneManager = new ZoneContextManager().enable();
36
+ context.setGlobalContextManager(zoneManager);
37
+ } catch (e) {
38
+ }
39
+ }
40
+ const resource = resourceFromAttributes(__spreadValues(__spreadValues({
41
+ [ATTR_SERVICE_NAME]: opts.isPortal ? "para-portal" : "para-sdk",
42
+ [ATTR_SERVICE_VERSION]: opts.sdkVersion,
43
+ "para.platform": opts.sdkType
44
+ }, opts.partnerId ? { "para.partner_id": opts.partnerId } : {}), opts.resourceAttributes));
45
+ const exporter = new OTLPTraceExporter({
46
+ url: opts.tunnelUrl
47
+ // No auth header — the tunnel is a dumb proxy. Per-IP rate limit + body cap on the
48
+ // BE side keep abuse contained.
49
+ });
50
+ const sampler = new TraceIdRatioBasedSampler(Math.max(0, Math.min(1, opts.sampleRate)));
51
+ const spanProcessors = [new UxStateSpanProcessor(), new BatchSpanProcessor(exporter)];
52
+ if (isWeb && opts.isPortal) {
53
+ try {
54
+ const { BeaconSpanProcessor } = yield import("./BeaconSpanProcessor.js");
55
+ spanProcessors.push(new BeaconSpanProcessor(opts.tunnelUrl));
56
+ } catch (e) {
57
+ }
58
+ }
59
+ tracerProvider = new BasicTracerProvider({
60
+ resource,
61
+ sampler,
62
+ spanProcessors
63
+ });
64
+ trace.setGlobalTracerProvider(tracerProvider);
65
+ propagation.setGlobalPropagator(
66
+ new CompositePropagator({
67
+ propagators: [new W3CTraceContextPropagator(), new UxBaggagePropagator()]
68
+ })
69
+ );
70
+ if (isWeb) {
71
+ try {
72
+ const [{ registerInstrumentations }, { FetchInstrumentation }, { XMLHttpRequestInstrumentation }] = yield Promise.all([
73
+ import("@opentelemetry/instrumentation"),
74
+ import("@opentelemetry/instrumentation-fetch"),
75
+ import("@opentelemetry/instrumentation-xml-http-request")
76
+ ]);
77
+ const propagateTraceHeaderCorsUrls = [
78
+ /^https?:\/\/api\.[^/]*getpara\.com/,
79
+ /^https?:\/\/api\.[^/]*usecapsule\.com/
80
+ ];
81
+ if (opts.isDev) {
82
+ propagateTraceHeaderCorsUrls.push(/^https?:\/\/localhost/);
83
+ }
84
+ registerInstrumentations({
85
+ // Both fetch and XHR are instrumented because axios uses XHR by default in
86
+ // the browser and `window.fetch` for first-party SDK code paths that opt in.
87
+ // Without XHR instrumentation, axios calls don't produce client spans AND
88
+ // Zone-tracked traceparent injection through our manual interceptor isn't
89
+ // always reliable on native async/await — the auto-instrumentation handles
90
+ // both span creation and W3C propagation in one pass.
91
+ instrumentations: [
92
+ new FetchInstrumentation({ propagateTraceHeaderCorsUrls }),
93
+ new XMLHttpRequestInstrumentation({ propagateTraceHeaderCorsUrls })
94
+ ]
95
+ });
96
+ } catch (e) {
97
+ }
98
+ }
99
+ while (readyCallbacks.length) {
100
+ const cb = readyCallbacks.shift();
101
+ try {
102
+ cb();
103
+ } catch (e) {
104
+ }
105
+ }
106
+ });
107
+ }
108
+ function isTelemetryInitialized() {
109
+ return initialized;
110
+ }
111
+ function flushTelemetry() {
112
+ return __async(this, null, function* () {
113
+ if (!tracerProvider) return;
114
+ try {
115
+ yield tracerProvider.forceFlush();
116
+ } catch (e) {
117
+ }
118
+ });
119
+ }
120
+ function __resetTelemetryForTests() {
121
+ initialized = false;
122
+ tracerProvider = void 0;
123
+ }
124
+ export {
125
+ __resetTelemetryForTests,
126
+ flushTelemetry,
127
+ initTelemetry,
128
+ isTelemetryInitialized,
129
+ onTelemetryReady
130
+ };
@@ -0,0 +1,29 @@
1
+ import "../chunk-7B52C2XE.js";
2
+ import { context as otelContext, trace } from "@opentelemetry/api";
3
+ const TRACER_NAME = "para-sdk";
4
+ let activeSpan;
5
+ let activeCtx;
6
+ function startModalSession() {
7
+ if (activeSpan) return;
8
+ activeSpan = trace.getTracer(TRACER_NAME).startSpan("ui.modal.session");
9
+ activeCtx = trace.setSpan(otelContext.active(), activeSpan);
10
+ }
11
+ function endModalSession() {
12
+ activeSpan == null ? void 0 : activeSpan.end();
13
+ activeSpan = void 0;
14
+ activeCtx = void 0;
15
+ }
16
+ function getModalSessionContext() {
17
+ return activeCtx;
18
+ }
19
+ function __resetModalSessionForTests() {
20
+ activeSpan == null ? void 0 : activeSpan.end();
21
+ activeSpan = void 0;
22
+ activeCtx = void 0;
23
+ }
24
+ export {
25
+ __resetModalSessionForTests,
26
+ endModalSession,
27
+ getModalSessionContext,
28
+ startModalSession
29
+ };
@@ -0,0 +1,16 @@
1
+ import "../chunk-7B52C2XE.js";
2
+ import { v4 as uuidv4 } from "uuid";
3
+ let sessionId;
4
+ function getOrCreateSessionId() {
5
+ if (!sessionId) {
6
+ sessionId = uuidv4();
7
+ }
8
+ return sessionId;
9
+ }
10
+ function __resetSessionForTests() {
11
+ sessionId = void 0;
12
+ }
13
+ export {
14
+ __resetSessionForTests,
15
+ getOrCreateSessionId
16
+ };
@@ -0,0 +1,84 @@
1
+ import {
2
+ __async
3
+ } from "../chunk-7B52C2XE.js";
4
+ import {
5
+ context as otelContext,
6
+ propagation,
7
+ SpanStatusCode,
8
+ trace
9
+ } from "@opentelemetry/api";
10
+ import { getModalSessionContext } from "./modalSession.js";
11
+ const TRACER_NAME = "para-sdk";
12
+ function getTracer() {
13
+ return trace.getTracer(TRACER_NAME);
14
+ }
15
+ let defaultParentContext;
16
+ function setDefaultParentContext(ctx) {
17
+ defaultParentContext = ctx;
18
+ }
19
+ function getDefaultParentContext() {
20
+ return defaultParentContext;
21
+ }
22
+ function wrapWithSpan(name, fn, attributes) {
23
+ return __async(this, null, function* () {
24
+ var _a, _b;
25
+ const active = otelContext.active();
26
+ const activeSpan = trace.getSpan(active);
27
+ const parentCtx = activeSpan ? active : (_b = (_a = getModalSessionContext()) != null ? _a : defaultParentContext) != null ? _b : active;
28
+ return otelContext.with(
29
+ parentCtx,
30
+ () => getTracer().startActiveSpan(name, { attributes }, (span) => __async(this, null, function* () {
31
+ try {
32
+ const result = yield fn(span);
33
+ return result;
34
+ } catch (err) {
35
+ span.recordException(err);
36
+ span.setStatus({ code: SpanStatusCode.ERROR, message: err.message });
37
+ throw err;
38
+ } finally {
39
+ span.end();
40
+ }
41
+ }))
42
+ );
43
+ });
44
+ }
45
+ function extractTraceContextFromUrl(search) {
46
+ return propagation.extract(otelContext.active(), getUrlTraceCarrier(search));
47
+ }
48
+ function getUrlTraceCarrier(search) {
49
+ const url = search != null ? search : typeof window !== "undefined" ? window.location.search : "";
50
+ const params = new URLSearchParams(url);
51
+ const carrier = {};
52
+ const tp = params.get("traceparent");
53
+ const ts = params.get("tracestate");
54
+ if (tp) carrier.traceparent = tp;
55
+ if (ts) carrier.tracestate = ts;
56
+ return carrier;
57
+ }
58
+ function wrapWithSpanInContext(parentContext, name, fn) {
59
+ return __async(this, null, function* () {
60
+ return otelContext.with(
61
+ parentContext,
62
+ () => wrapWithSpan(name, (span) => {
63
+ const traceHeaders = {};
64
+ propagation.inject(otelContext.active(), traceHeaders, {
65
+ set: (carrier, key, value) => {
66
+ carrier[key] = value;
67
+ }
68
+ });
69
+ return fn(span, traceHeaders);
70
+ })
71
+ );
72
+ });
73
+ }
74
+ import { SpanStatusCode as SpanStatusCode2 } from "@opentelemetry/api";
75
+ export {
76
+ SpanStatusCode2 as SpanStatusCode,
77
+ extractTraceContextFromUrl,
78
+ getDefaultParentContext,
79
+ getTracer,
80
+ getUrlTraceCarrier,
81
+ setDefaultParentContext,
82
+ wrapWithSpan,
83
+ wrapWithSpanInContext
84
+ };