@getpara/core-sdk 2.17.0 → 2.18.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.
@@ -207,6 +207,7 @@ const _ParaCore = class _ParaCore {
207
207
  methodName,
208
208
  sdkType: this.platformUtils.sdkType,
209
209
  userId: this.userId,
210
+ sdkVersion: _ParaCore.version,
210
211
  error: {
211
212
  name: err.name,
212
213
  message: err.message
@@ -495,22 +496,20 @@ const _ParaCore = class _ParaCore {
495
496
  this.initializeFromStorage();
496
497
  import_utils2.setupListeners.bind(this)();
497
498
  (0, import_utils2.autoBind)(this);
498
- if (env !== import_types.Environment.PROD) {
499
- this.wrapMethodsWithErrorTracking([
500
- "signUpOrLogIn",
501
- "verifyNewAccount",
502
- "waitForLogin",
503
- "waitForSignup",
504
- "waitForWalletCreation",
505
- "verifyOAuth",
506
- "verifyTelegram",
507
- "verifyFarcaster",
508
- "createPregenWallet",
509
- "claimPregenWallets",
510
- "signMessage",
511
- "signTransaction"
512
- ]);
513
- }
499
+ this.wrapMethodsWithErrorTracking([
500
+ "signUpOrLogIn",
501
+ "verifyNewAccount",
502
+ "waitForLogin",
503
+ "waitForSignup",
504
+ "waitForWalletCreation",
505
+ "verifyOAuth",
506
+ "verifyTelegram",
507
+ "verifyFarcaster",
508
+ "createPregenWallet",
509
+ "claimPregenWallets",
510
+ "signMessage",
511
+ "signTransaction"
512
+ ]);
514
513
  __privateGet(this, _stateManager).start();
515
514
  }
516
515
  setModalError(_error) {
@@ -2142,7 +2141,8 @@ const _ParaCore = class _ParaCore {
2142
2141
  cosmosSignDocBase64,
2143
2142
  isCanceled = () => false,
2144
2143
  onCancel,
2145
- onPoll
2144
+ onPoll,
2145
+ onTransactionReviewUrl
2146
2146
  }) {
2147
2147
  var _a;
2148
2148
  __privateGet(this, _walletService).assertIsValidWalletId(walletId);
@@ -2155,10 +2155,17 @@ const _ParaCore = class _ParaCore {
2155
2155
  let timeStart = Date.now();
2156
2156
  const effectiveTimeoutMs = Math.max(timeoutMs, constants.TRANSACTION_REVIEW_TIMEOUT_MS);
2157
2157
  if (signRes.pendingTransactionId) {
2158
- yield this.platformUtils.openPopup(
2159
- yield this.getTransactionReviewUrl(signRes.pendingTransactionId, effectiveTimeoutMs),
2160
- { type: cosmosSignDocBase64 ? import_types.PopupType.SIGN_TRANSACTION_REVIEW : import_types.PopupType.SIGN_MESSAGE_REVIEW }
2158
+ const reviewUrl = yield this.getTransactionReviewUrl(
2159
+ signRes.pendingTransactionId,
2160
+ effectiveTimeoutMs
2161
2161
  );
2162
+ if (onTransactionReviewUrl) {
2163
+ onTransactionReviewUrl(reviewUrl);
2164
+ } else {
2165
+ yield this.platformUtils.openPopup(reviewUrl, {
2166
+ type: cosmosSignDocBase64 ? import_types.PopupType.SIGN_TRANSACTION_REVIEW : import_types.PopupType.SIGN_MESSAGE_REVIEW
2167
+ });
2168
+ }
2162
2169
  } else {
2163
2170
  (0, import_utils2.dispatchEvent)(import_types.ParaEvent.SIGN_MESSAGE_EVENT, signRes);
2164
2171
  return signRes;
@@ -2248,7 +2255,8 @@ const _ParaCore = class _ParaCore {
2248
2255
  timeoutMs = 3e4,
2249
2256
  isCanceled = () => false,
2250
2257
  onCancel,
2251
- onPoll
2258
+ onPoll,
2259
+ onTransactionReviewUrl
2252
2260
  }) {
2253
2261
  var _a;
2254
2262
  __privateGet(this, _walletService).assertIsValidWalletId(walletId);
@@ -2270,10 +2278,15 @@ const _ParaCore = class _ParaCore {
2270
2278
  let timeStart = Date.now();
2271
2279
  const effectiveTimeoutMs = Math.max(timeoutMs, constants.TRANSACTION_REVIEW_TIMEOUT_MS);
2272
2280
  if (signRes.pendingTransactionId) {
2273
- yield this.platformUtils.openPopup(
2274
- yield this.getTransactionReviewUrl(signRes.pendingTransactionId, effectiveTimeoutMs),
2275
- { type: import_types.PopupType.SIGN_TRANSACTION_REVIEW }
2281
+ const reviewUrl = yield this.getTransactionReviewUrl(
2282
+ signRes.pendingTransactionId,
2283
+ effectiveTimeoutMs
2276
2284
  );
2285
+ if (onTransactionReviewUrl) {
2286
+ onTransactionReviewUrl(reviewUrl);
2287
+ } else {
2288
+ yield this.platformUtils.openPopup(reviewUrl, { type: import_types.PopupType.SIGN_TRANSACTION_REVIEW });
2289
+ }
2277
2290
  } else {
2278
2291
  (0, import_utils2.dispatchEvent)(import_types.ParaEvent.SIGN_TRANSACTION_EVENT, signRes);
2279
2292
  return signRes;
@@ -2369,10 +2382,14 @@ const _ParaCore = class _ParaCore {
2369
2382
  }
2370
2383
  /**
2371
2384
  * Serialize the current session for import by another Para instance.
2385
+ * @deprecated Use {@link waitAndExportSession} instead, which awaits auth settlement before exporting.
2372
2386
  * @param {boolean} excludeSigners - whether or not to exclude the signer from the exported wallets.
2373
2387
  * @returns {string} the serialized session
2374
2388
  */
2375
2389
  exportSession({ excludeSigners = false } = {}) {
2390
+ if (__privateGet(this, _stateManager).getSnapshot().authStatePhase !== "authenticated") {
2391
+ throw new Error("Cannot export session: user is not authenticated.");
2392
+ }
2376
2393
  const sessionInfo = {
2377
2394
  authInfo: __privateGet(this, _authService).authInfo,
2378
2395
  userId: this.userId,
@@ -2388,6 +2405,32 @@ const _ParaCore = class _ParaCore {
2388
2405
  }
2389
2406
  return Buffer.from(JSON.stringify(sessionInfo)).toString("base64");
2390
2407
  }
2408
+ /**
2409
+ * Awaits auth settlement, then serializes the current session for import by another Para instance.
2410
+ * Unlike {@link exportSession}, this method waits for the auth state machine to reach the
2411
+ * `authenticated` phase before reading state, ensuring the exported data is up-to-date.
2412
+ * @param {boolean} excludeSigners - whether or not to exclude the signer from the exported wallets.
2413
+ * @returns {Promise<string>} the serialized session
2414
+ */
2415
+ waitAndExportSession() {
2416
+ return __async(this, arguments, function* (params = {}) {
2417
+ yield (0, import_stateListener.waitForAuthStateChange)({
2418
+ stateManager: __privateGet(this, _stateManager),
2419
+ resolvePhases: [{ phase: "authenticated", onPhase: () => void 0 }],
2420
+ rejectPhases: [
2421
+ {
2422
+ phase: "unauthenticated",
2423
+ onPhase: () => new Error("No active session to export.")
2424
+ },
2425
+ {
2426
+ phase: "guest_mode",
2427
+ onPhase: () => new Error("Cannot export session in guest mode.")
2428
+ }
2429
+ ]
2430
+ });
2431
+ return this.exportSession(params);
2432
+ });
2433
+ }
2391
2434
  /**
2392
2435
  * Imports a session serialized by another Para instance.
2393
2436
  * @param {string} serializedInstanceBase64 the serialized session
@@ -46,7 +46,7 @@ __export(constants_exports, {
46
46
  TRANSACTION_REVIEW_TIMEOUT_MS: () => TRANSACTION_REVIEW_TIMEOUT_MS
47
47
  });
48
48
  module.exports = __toCommonJS(constants_exports);
49
- const PARA_CORE_VERSION = "2.16.0";
49
+ const PARA_CORE_VERSION = "2.18.0";
50
50
  const PREFIX = "@CAPSULE/";
51
51
  const PARA_PREFIX = "@PARA/";
52
52
  const LOCAL_STORAGE_AUTH_INFO = `${PREFIX}authInfo`;
@@ -67,7 +67,7 @@ module.exports = __toCommonJS(ExternalWalletService_exports);
67
67
  var import_events = require("../types/events.js");
68
68
  var import_constants = require("../constants.js");
69
69
  var import_utils = require("../utils/index.js");
70
- var _stateManager, _authService, _walletService, _paraCoreInterface, _externalWallets, _watchedProviders, _onWalletDisconnected;
70
+ var _stateManager, _authService, _walletService, _paraCoreInterface, _externalWallets, _watchedProviders, _validateConnectionDeferred, _onWalletDisconnected;
71
71
  class ExternalWalletService {
72
72
  constructor(paraCore) {
73
73
  __privateAdd(this, _stateManager);
@@ -95,30 +95,11 @@ class ExternalWalletService {
95
95
  return true;
96
96
  }
97
97
  for (let i = 0; i < 20; i++) {
98
- const neededProviderInterfaces = Array.from(storedWalletTypes).map((type) => ({
99
- type,
100
- interface: this.externalWalletProviderInterfaces[type]
101
- })).filter(({ interface: providerInterface }) => !!providerInterface);
102
- if (neededProviderInterfaces.length !== storedWalletTypes.size) {
103
- yield new Promise((resolve) => setTimeout(resolve, 100));
104
- continue;
105
- }
106
- const loadingResults = yield Promise.all(
107
- neededProviderInterfaces.map((_0) => __async(this, [_0], function* ({ type, interface: providerInterface }) {
108
- try {
109
- const providerAddresses = yield providerInterface.getAddress();
110
- const storedAddressesForType = Object.values(this.externalWallets).filter((wallet) => wallet.type === type).map((wallet) => Object.keys(this.externalWallets).find((addr) => this.externalWallets[addr] === wallet)).filter(Boolean);
111
- const allAddressesAvailable = storedAddressesForType.every((addr) => providerAddresses.includes(addr));
112
- return allAddressesAvailable;
113
- } catch (error) {
114
- console.warn(`Error checking provider ${type}:`, error);
115
- return false;
116
- }
117
- }))
118
- );
119
- if (loadingResults.every((result) => result === true)) {
120
- neededProviderInterfaces.forEach(({ type, interface: providerInterface }) => {
121
- if (!__privateGet(this, _watchedProviders).has(type)) {
98
+ const allRegistered = Array.from(storedWalletTypes).every((type) => !!this.externalWalletProviderInterfaces[type]);
99
+ if (allRegistered) {
100
+ Array.from(storedWalletTypes).forEach((type) => {
101
+ const providerInterface = this.externalWalletProviderInterfaces[type];
102
+ if (providerInterface && !__privateGet(this, _watchedProviders).has(type)) {
122
103
  __privateGet(this, _watchedProviders).add(type);
123
104
  providerInterface.watchDisconnection(() => __async(this, null, function* () {
124
105
  yield __privateGet(this, _onWalletDisconnected).call(this);
@@ -128,6 +109,7 @@ class ExternalWalletService {
128
109
  }));
129
110
  }
130
111
  });
112
+ __privateGet(this, _validateConnectionDeferred).call(this);
131
113
  return true;
132
114
  }
133
115
  yield new Promise((resolve) => setTimeout(resolve, 100));
@@ -138,7 +120,8 @@ class ExternalWalletService {
138
120
  if (__privateGet(this, _stateManager).getSnapshot().authStatePhase === "switching_external_wallet") {
139
121
  return;
140
122
  }
141
- if (this.externalWalletConnectionType === "NONE") {
123
+ const connectionType = this.externalWalletConnectionType;
124
+ if (connectionType === "NONE") {
142
125
  return;
143
126
  }
144
127
  const connectedAddresses = (yield Promise.all(
@@ -146,6 +129,9 @@ class ExternalWalletService {
146
129
  return yield providerInterface.getAddress();
147
130
  }))
148
131
  )).filter((a) => !!a);
132
+ if (connectedAddresses.length === 0) {
133
+ return;
134
+ }
149
135
  const storedExternalWalletAddresses = Object.keys(this.externalWallets);
150
136
  const someConnectedHaveStoredWallets = connectedAddresses.some(
151
137
  (connectedAddress) => connectedAddress && this.externalWallets[connectedAddress]
@@ -214,11 +200,53 @@ class ExternalWalletService {
214
200
  }
215
201
  __privateGet(this, _stateManager).send({ type: "SWITCH_EXTERNAL_WALLET", data: params });
216
202
  });
203
+ /**
204
+ * Poll until the wallet adapter connects, then validate the address matches a stored wallet.
205
+ * If the adapter doesn't connect within the timeout, or connects with the wrong address, log out.
206
+ */
207
+ __privateAdd(this, _validateConnectionDeferred, () => {
208
+ const POLL_INTERVAL_MS = 500;
209
+ const TIMEOUT_MS = 1e4;
210
+ const startedAt = Date.now();
211
+ const poll = () => __async(this, null, function* () {
212
+ if (this.externalWalletConnectionType === "NONE") {
213
+ return;
214
+ }
215
+ const connectedAddresses = (yield Promise.all(
216
+ Object.values(this.externalWalletProviderInterfaces).map((providerInterface) => __async(this, null, function* () {
217
+ return yield providerInterface.getAddress();
218
+ }))
219
+ )).filter((a) => !!a);
220
+ if (connectedAddresses.length === 0) {
221
+ if (Date.now() - startedAt >= TIMEOUT_MS) {
222
+ yield __privateGet(this, _paraCoreInterface).logout();
223
+ return;
224
+ }
225
+ setTimeout(() => void poll(), POLL_INTERVAL_MS);
226
+ return;
227
+ }
228
+ const someMatchesStored = connectedAddresses.some((addr) => addr && this.externalWallets[addr]);
229
+ if (!someMatchesStored) {
230
+ yield __privateGet(this, _paraCoreInterface).logout();
231
+ }
232
+ });
233
+ setTimeout(() => void poll(), POLL_INTERVAL_MS);
234
+ });
217
235
  __privateAdd(this, _onWalletDisconnected, () => __async(this, null, function* () {
218
- if (this.externalWalletConnectionType === "NONE") {
236
+ const connectionType = this.externalWalletConnectionType;
237
+ if (connectionType === "NONE") {
219
238
  return;
220
239
  }
221
- yield __privateGet(this, _paraCoreInterface).logout();
240
+ yield new Promise((resolve) => setTimeout(resolve, 500));
241
+ const connectedAddresses = (yield Promise.all(
242
+ Object.values(this.externalWalletProviderInterfaces).map((providerInterface) => __async(this, null, function* () {
243
+ return yield providerInterface.getAddress();
244
+ }))
245
+ )).filter((a) => !!a);
246
+ const someStillConnected = connectedAddresses.some((addr) => addr && this.externalWallets[addr]);
247
+ if (!someStillConnected) {
248
+ yield __privateGet(this, _paraCoreInterface).logout();
249
+ }
222
250
  }));
223
251
  /**
224
252
  * Function to perform connecting an external wallet
@@ -379,6 +407,7 @@ _walletService = new WeakMap();
379
407
  _paraCoreInterface = new WeakMap();
380
408
  _externalWallets = new WeakMap();
381
409
  _watchedProviders = new WeakMap();
410
+ _validateConnectionDeferred = new WeakMap();
382
411
  _onWalletDisconnected = new WeakMap();
383
412
  // Annotate the CommonJS export names for ESM import in node:
384
413
  0 && (module.exports = {
@@ -42,11 +42,7 @@ __export(waitForExternalWalletProviders_exports, {
42
42
  module.exports = __toCommonJS(waitForExternalWalletProviders_exports);
43
43
  var import_xstate = require("xstate");
44
44
  const createWaitForExternalWalletProvidersActor = (stateMachineInterface) => (0, import_xstate.fromPromise)(() => __async(void 0, null, function* () {
45
- const resp = yield stateMachineInterface.externalWalletService.waitForProvidersLoading();
46
- if (!resp) {
47
- yield stateMachineInterface.logout();
48
- }
49
- return resp;
45
+ return yield stateMachineInterface.externalWalletService.waitForProvidersLoading();
50
46
  }));
51
47
  // Annotate the CommonJS export names for ESM import in node:
52
48
  0 && (module.exports = {
@@ -46,6 +46,7 @@ const PARA_CORE_METHODS = [
46
46
  "refreshSession",
47
47
  "keepSessionAlive",
48
48
  "exportSession",
49
+ "waitAndExportSession",
49
50
  "importSession",
50
51
  "getVerificationToken",
51
52
  "getWallets",
@@ -149,6 +149,7 @@ const _ParaCore = class _ParaCore {
149
149
  methodName,
150
150
  sdkType: this.platformUtils.sdkType,
151
151
  userId: this.userId,
152
+ sdkVersion: _ParaCore.version,
152
153
  error: {
153
154
  name: err.name,
154
155
  message: err.message
@@ -437,22 +438,20 @@ const _ParaCore = class _ParaCore {
437
438
  this.initializeFromStorage();
438
439
  setupListeners.bind(this)();
439
440
  autoBind(this);
440
- if (env !== Environment.PROD) {
441
- this.wrapMethodsWithErrorTracking([
442
- "signUpOrLogIn",
443
- "verifyNewAccount",
444
- "waitForLogin",
445
- "waitForSignup",
446
- "waitForWalletCreation",
447
- "verifyOAuth",
448
- "verifyTelegram",
449
- "verifyFarcaster",
450
- "createPregenWallet",
451
- "claimPregenWallets",
452
- "signMessage",
453
- "signTransaction"
454
- ]);
455
- }
441
+ this.wrapMethodsWithErrorTracking([
442
+ "signUpOrLogIn",
443
+ "verifyNewAccount",
444
+ "waitForLogin",
445
+ "waitForSignup",
446
+ "waitForWalletCreation",
447
+ "verifyOAuth",
448
+ "verifyTelegram",
449
+ "verifyFarcaster",
450
+ "createPregenWallet",
451
+ "claimPregenWallets",
452
+ "signMessage",
453
+ "signTransaction"
454
+ ]);
456
455
  __privateGet(this, _stateManager).start();
457
456
  }
458
457
  setModalError(_error) {
@@ -2084,7 +2083,8 @@ const _ParaCore = class _ParaCore {
2084
2083
  cosmosSignDocBase64,
2085
2084
  isCanceled = () => false,
2086
2085
  onCancel,
2087
- onPoll
2086
+ onPoll,
2087
+ onTransactionReviewUrl
2088
2088
  }) {
2089
2089
  var _a;
2090
2090
  __privateGet(this, _walletService).assertIsValidWalletId(walletId);
@@ -2097,10 +2097,17 @@ const _ParaCore = class _ParaCore {
2097
2097
  let timeStart = Date.now();
2098
2098
  const effectiveTimeoutMs = Math.max(timeoutMs, constants.TRANSACTION_REVIEW_TIMEOUT_MS);
2099
2099
  if (signRes.pendingTransactionId) {
2100
- yield this.platformUtils.openPopup(
2101
- yield this.getTransactionReviewUrl(signRes.pendingTransactionId, effectiveTimeoutMs),
2102
- { type: cosmosSignDocBase64 ? PopupType.SIGN_TRANSACTION_REVIEW : PopupType.SIGN_MESSAGE_REVIEW }
2100
+ const reviewUrl = yield this.getTransactionReviewUrl(
2101
+ signRes.pendingTransactionId,
2102
+ effectiveTimeoutMs
2103
2103
  );
2104
+ if (onTransactionReviewUrl) {
2105
+ onTransactionReviewUrl(reviewUrl);
2106
+ } else {
2107
+ yield this.platformUtils.openPopup(reviewUrl, {
2108
+ type: cosmosSignDocBase64 ? PopupType.SIGN_TRANSACTION_REVIEW : PopupType.SIGN_MESSAGE_REVIEW
2109
+ });
2110
+ }
2104
2111
  } else {
2105
2112
  dispatchEvent(ParaEvent.SIGN_MESSAGE_EVENT, signRes);
2106
2113
  return signRes;
@@ -2190,7 +2197,8 @@ const _ParaCore = class _ParaCore {
2190
2197
  timeoutMs = 3e4,
2191
2198
  isCanceled = () => false,
2192
2199
  onCancel,
2193
- onPoll
2200
+ onPoll,
2201
+ onTransactionReviewUrl
2194
2202
  }) {
2195
2203
  var _a;
2196
2204
  __privateGet(this, _walletService).assertIsValidWalletId(walletId);
@@ -2212,10 +2220,15 @@ const _ParaCore = class _ParaCore {
2212
2220
  let timeStart = Date.now();
2213
2221
  const effectiveTimeoutMs = Math.max(timeoutMs, constants.TRANSACTION_REVIEW_TIMEOUT_MS);
2214
2222
  if (signRes.pendingTransactionId) {
2215
- yield this.platformUtils.openPopup(
2216
- yield this.getTransactionReviewUrl(signRes.pendingTransactionId, effectiveTimeoutMs),
2217
- { type: PopupType.SIGN_TRANSACTION_REVIEW }
2223
+ const reviewUrl = yield this.getTransactionReviewUrl(
2224
+ signRes.pendingTransactionId,
2225
+ effectiveTimeoutMs
2218
2226
  );
2227
+ if (onTransactionReviewUrl) {
2228
+ onTransactionReviewUrl(reviewUrl);
2229
+ } else {
2230
+ yield this.platformUtils.openPopup(reviewUrl, { type: PopupType.SIGN_TRANSACTION_REVIEW });
2231
+ }
2219
2232
  } else {
2220
2233
  dispatchEvent(ParaEvent.SIGN_TRANSACTION_EVENT, signRes);
2221
2234
  return signRes;
@@ -2311,10 +2324,14 @@ const _ParaCore = class _ParaCore {
2311
2324
  }
2312
2325
  /**
2313
2326
  * Serialize the current session for import by another Para instance.
2327
+ * @deprecated Use {@link waitAndExportSession} instead, which awaits auth settlement before exporting.
2314
2328
  * @param {boolean} excludeSigners - whether or not to exclude the signer from the exported wallets.
2315
2329
  * @returns {string} the serialized session
2316
2330
  */
2317
2331
  exportSession({ excludeSigners = false } = {}) {
2332
+ if (__privateGet(this, _stateManager).getSnapshot().authStatePhase !== "authenticated") {
2333
+ throw new Error("Cannot export session: user is not authenticated.");
2334
+ }
2318
2335
  const sessionInfo = {
2319
2336
  authInfo: __privateGet(this, _authService).authInfo,
2320
2337
  userId: this.userId,
@@ -2330,6 +2347,32 @@ const _ParaCore = class _ParaCore {
2330
2347
  }
2331
2348
  return Buffer.from(JSON.stringify(sessionInfo)).toString("base64");
2332
2349
  }
2350
+ /**
2351
+ * Awaits auth settlement, then serializes the current session for import by another Para instance.
2352
+ * Unlike {@link exportSession}, this method waits for the auth state machine to reach the
2353
+ * `authenticated` phase before reading state, ensuring the exported data is up-to-date.
2354
+ * @param {boolean} excludeSigners - whether or not to exclude the signer from the exported wallets.
2355
+ * @returns {Promise<string>} the serialized session
2356
+ */
2357
+ waitAndExportSession() {
2358
+ return __async(this, arguments, function* (params = {}) {
2359
+ yield waitForAuthStateChange({
2360
+ stateManager: __privateGet(this, _stateManager),
2361
+ resolvePhases: [{ phase: "authenticated", onPhase: () => void 0 }],
2362
+ rejectPhases: [
2363
+ {
2364
+ phase: "unauthenticated",
2365
+ onPhase: () => new Error("No active session to export.")
2366
+ },
2367
+ {
2368
+ phase: "guest_mode",
2369
+ onPhase: () => new Error("Cannot export session in guest mode.")
2370
+ }
2371
+ ]
2372
+ });
2373
+ return this.exportSession(params);
2374
+ });
2375
+ }
2333
2376
  /**
2334
2377
  * Imports a session serialized by another Para instance.
2335
2378
  * @param {string} serializedInstanceBase64 the serialized session
@@ -1,5 +1,5 @@
1
1
  import "./chunk-7B52C2XE.js";
2
- const PARA_CORE_VERSION = "2.16.0";
2
+ const PARA_CORE_VERSION = "2.18.0";
3
3
  const PREFIX = "@CAPSULE/";
4
4
  const PARA_PREFIX = "@PARA/";
5
5
  const LOCAL_STORAGE_AUTH_INFO = `${PREFIX}authInfo`;
@@ -6,7 +6,7 @@ import {
6
6
  __spreadProps,
7
7
  __spreadValues
8
8
  } from "../chunk-7B52C2XE.js";
9
- var _stateManager, _authService, _walletService, _paraCoreInterface, _externalWallets, _watchedProviders, _onWalletDisconnected;
9
+ var _stateManager, _authService, _walletService, _paraCoreInterface, _externalWallets, _watchedProviders, _validateConnectionDeferred, _onWalletDisconnected;
10
10
  import { ParaEvent } from "../types/events.js";
11
11
  import { LOCAL_STORAGE_EXTERNAL_WALLETS } from "../constants.js";
12
12
  import { dispatchEvent } from "../utils/index.js";
@@ -37,30 +37,11 @@ class ExternalWalletService {
37
37
  return true;
38
38
  }
39
39
  for (let i = 0; i < 20; i++) {
40
- const neededProviderInterfaces = Array.from(storedWalletTypes).map((type) => ({
41
- type,
42
- interface: this.externalWalletProviderInterfaces[type]
43
- })).filter(({ interface: providerInterface }) => !!providerInterface);
44
- if (neededProviderInterfaces.length !== storedWalletTypes.size) {
45
- yield new Promise((resolve) => setTimeout(resolve, 100));
46
- continue;
47
- }
48
- const loadingResults = yield Promise.all(
49
- neededProviderInterfaces.map((_0) => __async(this, [_0], function* ({ type, interface: providerInterface }) {
50
- try {
51
- const providerAddresses = yield providerInterface.getAddress();
52
- const storedAddressesForType = Object.values(this.externalWallets).filter((wallet) => wallet.type === type).map((wallet) => Object.keys(this.externalWallets).find((addr) => this.externalWallets[addr] === wallet)).filter(Boolean);
53
- const allAddressesAvailable = storedAddressesForType.every((addr) => providerAddresses.includes(addr));
54
- return allAddressesAvailable;
55
- } catch (error) {
56
- console.warn(`Error checking provider ${type}:`, error);
57
- return false;
58
- }
59
- }))
60
- );
61
- if (loadingResults.every((result) => result === true)) {
62
- neededProviderInterfaces.forEach(({ type, interface: providerInterface }) => {
63
- if (!__privateGet(this, _watchedProviders).has(type)) {
40
+ const allRegistered = Array.from(storedWalletTypes).every((type) => !!this.externalWalletProviderInterfaces[type]);
41
+ if (allRegistered) {
42
+ Array.from(storedWalletTypes).forEach((type) => {
43
+ const providerInterface = this.externalWalletProviderInterfaces[type];
44
+ if (providerInterface && !__privateGet(this, _watchedProviders).has(type)) {
64
45
  __privateGet(this, _watchedProviders).add(type);
65
46
  providerInterface.watchDisconnection(() => __async(this, null, function* () {
66
47
  yield __privateGet(this, _onWalletDisconnected).call(this);
@@ -70,6 +51,7 @@ class ExternalWalletService {
70
51
  }));
71
52
  }
72
53
  });
54
+ __privateGet(this, _validateConnectionDeferred).call(this);
73
55
  return true;
74
56
  }
75
57
  yield new Promise((resolve) => setTimeout(resolve, 100));
@@ -80,7 +62,8 @@ class ExternalWalletService {
80
62
  if (__privateGet(this, _stateManager).getSnapshot().authStatePhase === "switching_external_wallet") {
81
63
  return;
82
64
  }
83
- if (this.externalWalletConnectionType === "NONE") {
65
+ const connectionType = this.externalWalletConnectionType;
66
+ if (connectionType === "NONE") {
84
67
  return;
85
68
  }
86
69
  const connectedAddresses = (yield Promise.all(
@@ -88,6 +71,9 @@ class ExternalWalletService {
88
71
  return yield providerInterface.getAddress();
89
72
  }))
90
73
  )).filter((a) => !!a);
74
+ if (connectedAddresses.length === 0) {
75
+ return;
76
+ }
91
77
  const storedExternalWalletAddresses = Object.keys(this.externalWallets);
92
78
  const someConnectedHaveStoredWallets = connectedAddresses.some(
93
79
  (connectedAddress) => connectedAddress && this.externalWallets[connectedAddress]
@@ -156,11 +142,53 @@ class ExternalWalletService {
156
142
  }
157
143
  __privateGet(this, _stateManager).send({ type: "SWITCH_EXTERNAL_WALLET", data: params });
158
144
  });
145
+ /**
146
+ * Poll until the wallet adapter connects, then validate the address matches a stored wallet.
147
+ * If the adapter doesn't connect within the timeout, or connects with the wrong address, log out.
148
+ */
149
+ __privateAdd(this, _validateConnectionDeferred, () => {
150
+ const POLL_INTERVAL_MS = 500;
151
+ const TIMEOUT_MS = 1e4;
152
+ const startedAt = Date.now();
153
+ const poll = () => __async(this, null, function* () {
154
+ if (this.externalWalletConnectionType === "NONE") {
155
+ return;
156
+ }
157
+ const connectedAddresses = (yield Promise.all(
158
+ Object.values(this.externalWalletProviderInterfaces).map((providerInterface) => __async(this, null, function* () {
159
+ return yield providerInterface.getAddress();
160
+ }))
161
+ )).filter((a) => !!a);
162
+ if (connectedAddresses.length === 0) {
163
+ if (Date.now() - startedAt >= TIMEOUT_MS) {
164
+ yield __privateGet(this, _paraCoreInterface).logout();
165
+ return;
166
+ }
167
+ setTimeout(() => void poll(), POLL_INTERVAL_MS);
168
+ return;
169
+ }
170
+ const someMatchesStored = connectedAddresses.some((addr) => addr && this.externalWallets[addr]);
171
+ if (!someMatchesStored) {
172
+ yield __privateGet(this, _paraCoreInterface).logout();
173
+ }
174
+ });
175
+ setTimeout(() => void poll(), POLL_INTERVAL_MS);
176
+ });
159
177
  __privateAdd(this, _onWalletDisconnected, () => __async(this, null, function* () {
160
- if (this.externalWalletConnectionType === "NONE") {
178
+ const connectionType = this.externalWalletConnectionType;
179
+ if (connectionType === "NONE") {
161
180
  return;
162
181
  }
163
- yield __privateGet(this, _paraCoreInterface).logout();
182
+ yield new Promise((resolve) => setTimeout(resolve, 500));
183
+ const connectedAddresses = (yield Promise.all(
184
+ Object.values(this.externalWalletProviderInterfaces).map((providerInterface) => __async(this, null, function* () {
185
+ return yield providerInterface.getAddress();
186
+ }))
187
+ )).filter((a) => !!a);
188
+ const someStillConnected = connectedAddresses.some((addr) => addr && this.externalWallets[addr]);
189
+ if (!someStillConnected) {
190
+ yield __privateGet(this, _paraCoreInterface).logout();
191
+ }
164
192
  }));
165
193
  /**
166
194
  * Function to perform connecting an external wallet
@@ -321,6 +349,7 @@ _walletService = new WeakMap();
321
349
  _paraCoreInterface = new WeakMap();
322
350
  _externalWallets = new WeakMap();
323
351
  _watchedProviders = new WeakMap();
352
+ _validateConnectionDeferred = new WeakMap();
324
353
  _onWalletDisconnected = new WeakMap();
325
354
  export {
326
355
  ExternalWalletService
@@ -3,11 +3,7 @@ import {
3
3
  } from "../../chunk-7B52C2XE.js";
4
4
  import { fromPromise } from "xstate";
5
5
  const createWaitForExternalWalletProvidersActor = (stateMachineInterface) => fromPromise(() => __async(void 0, null, function* () {
6
- const resp = yield stateMachineInterface.externalWalletService.waitForProvidersLoading();
7
- if (!resp) {
8
- yield stateMachineInterface.logout();
9
- }
10
- return resp;
6
+ return yield stateMachineInterface.externalWalletService.waitForProvidersLoading();
11
7
  }));
12
8
  export {
13
9
  createWaitForExternalWalletProvidersActor
@@ -24,6 +24,7 @@ const PARA_CORE_METHODS = [
24
24
  "refreshSession",
25
25
  "keepSessionAlive",
26
26
  "exportSession",
27
+ "waitAndExportSession",
27
28
  "importSession",
28
29
  "getVerificationToken",
29
30
  "getWallets",
@@ -735,7 +735,7 @@ export declare abstract class ParaCore implements CoreInterface {
735
735
  * @param {number} [opts.timeout] optional timeout in milliseconds. If not present, defaults to 30 seconds. Extended to a minimum of 5 minutes when the transaction requires approval.
736
736
  * @param {string} [opts.cosmosSignDocBase64] the Cosmos `SignDoc` in base64, if applicable
737
737
  **/
738
- signMessage({ walletId, messageBase64, timeoutMs, cosmosSignDocBase64, isCanceled, onCancel, onPoll, }: CoreMethodParams<'signMessage'>): CoreMethodResponse<'signMessage'>;
738
+ signMessage({ walletId, messageBase64, timeoutMs, cosmosSignDocBase64, isCanceled, onCancel, onPoll, onTransactionReviewUrl, }: CoreMethodParams<'signMessage'>): CoreMethodResponse<'signMessage'>;
739
739
  private signMessageInner;
740
740
  /**
741
741
  * Signs a transaction.
@@ -745,7 +745,7 @@ export declare abstract class ParaCore implements CoreInterface {
745
745
  * @param {string} [opts.chainId] the EVM chain id of the chain the transaction is being sent on, if applicable
746
746
  * @param {number} [opts.timeoutMs] the amount of time to wait for the user to sign the transaction, in milliseconds. Extended to a minimum of 5 minutes when the transaction requires approval.
747
747
  **/
748
- signTransaction({ walletId, rlpEncodedTxBase64, chainId, timeoutMs, isCanceled, onCancel, onPoll, }: CoreMethodParams<'signTransaction'>): CoreMethodResponse<'signTransaction'>;
748
+ signTransaction({ walletId, rlpEncodedTxBase64, chainId, timeoutMs, isCanceled, onCancel, onPoll, onTransactionReviewUrl, }: CoreMethodParams<'signTransaction'>): CoreMethodResponse<'signTransaction'>;
749
749
  protected isProviderModalDisabled(): boolean;
750
750
  /**
751
751
  * Starts a on-ramp or off-ramp transaction and returns the Para Portal link for the user to finalize and complete it.
@@ -762,10 +762,19 @@ export declare abstract class ParaCore implements CoreInterface {
762
762
  keepSessionAlive(): Promise<boolean>;
763
763
  /**
764
764
  * Serialize the current session for import by another Para instance.
765
+ * @deprecated Use {@link waitAndExportSession} instead, which awaits auth settlement before exporting.
765
766
  * @param {boolean} excludeSigners - whether or not to exclude the signer from the exported wallets.
766
767
  * @returns {string} the serialized session
767
768
  */
768
769
  exportSession({ excludeSigners }?: CoreMethodParams<'exportSession'>): CoreMethodResponse<'exportSession'>;
770
+ /**
771
+ * Awaits auth settlement, then serializes the current session for import by another Para instance.
772
+ * Unlike {@link exportSession}, this method waits for the auth state machine to reach the
773
+ * `authenticated` phase before reading state, ensuring the exported data is up-to-date.
774
+ * @param {boolean} excludeSigners - whether or not to exclude the signer from the exported wallets.
775
+ * @returns {Promise<string>} the serialized session
776
+ */
777
+ waitAndExportSession(params?: CoreMethodParams<'waitAndExportSession'>): CoreMethodResponse<'waitAndExportSession'>;
769
778
  /**
770
779
  * Imports a session serialized by another Para instance.
771
780
  * @param {string} serializedInstanceBase64 the serialized session
@@ -1,5 +1,5 @@
1
1
  import { ParaCore } from './ParaCore.js';
2
- export { type Auth, type AuthInfo, type PrimaryAuthInfo, type VerifiedAuthInfo, type VerifiedAuth, AuthMethod, type TAuthMethod, AuthMethodStatus, type AuthExtras, type CurrentWalletIds, EmailTheme, type PartnerEntity, type WalletEntity, Network, type TNetwork, WalletType, type TWalletType, WalletScheme, type TWalletScheme, OnRampAsset, type TOnRampAsset, OnRampPurchaseType, OnRampProvider, OnRampPurchaseStatus, type OnRampConfig, type OnRampAssets, type OnRampPurchase, type OnRampAssetInfo, type ProviderAssetInfo, OnRampMethod, type Theme, OAuthMethod, type TOAuthMethod, type TLinkedAccountType, type SupportedAccountLinks, type SupportedWalletTypes, type TPregenIdentifierType, type PregenIds, type LinkedAccount, type LinkedAccounts, type TExternalWallet, type ExternalWalletInfo, type PregenAuth, type Setup2faResponse, type TelegramAuthResponse, type VerifyExternalWalletParams, type AssetMetadata, type AssetMetadataIndexed, type AssetValue, type BalancesConfig, type WalletBalance, type ProfileBalance, type OfframpDepositRequest, type WalletWithMetadata, RecoveryStatus, ThemeMode, NON_ED25519, PREGEN_IDENTIFIER_TYPES, WALLET_TYPES, WALLET_SCHEMES, OAUTH_METHODS, LINKED_ACCOUNT_TYPES, EXTERNAL_WALLET_TYPES, EVM_WALLETS, SOLANA_WALLETS, COSMOS_WALLETS, formatAssetQuantity, formatCurrency, type EstimateTransactionOpts, type EstimateTransactionResult, type BroadcastTransactionOpts, type BroadcastTransactionResult, } from '@getpara/user-management-client';
2
+ export { type Auth, type AuthInfo, type PrimaryAuthInfo, type VerifiedAuthInfo, type VerifiedAuth, AuthMethod, type TAuthMethod, AuthMethodStatus, type AuthExtras, type CurrentWalletIds, EmailTheme, type PartnerEntity, type WalletEntity, Network, type TNetwork, WalletType, type TWalletType, WalletScheme, type TWalletScheme, OnRampAsset, type TOnRampAsset, OnRampPurchaseType, OnRampProvider, OnRampPurchaseStatus, type OnRampConfig, type OnRampAssets, type OnRampPurchase, type OnRampAssetInfo, type ProviderAssetInfo, OnRampMethod, type Theme, OAuthMethod, type TOAuthMethod, type TLinkedAccountType, type SupportedAccountLinks, type SupportedWalletTypes, type TPregenIdentifierType, type PregenIds, type LinkedAccount, type LinkedAccounts, type TExternalWallet, type ExternalWalletInfo, type PregenAuth, type Setup2faResponse, type TelegramAuthResponse, type VerifyExternalWalletParams, type AssetMetadata, type AssetMetadataIndexed, type AssetValue, type BalancesConfig, type WalletBalance, type ProfileBalance, type OfframpDepositRequest, type WalletWithMetadata, RecoveryStatus, ThemeMode, NON_ED25519, PREGEN_IDENTIFIER_TYPES, WALLET_TYPES, WALLET_SCHEMES, OAUTH_METHODS, LINKED_ACCOUNT_TYPES, EXTERNAL_WALLET_TYPES, EVM_WALLETS, SOLANA_WALLETS, COSMOS_WALLETS, formatAssetQuantity, formatCurrency, type EstimateTransactionOpts, type EstimateTransactionResult, type BroadcastTransactionOpts, type BroadcastTransactionResult, type PendingTransactionEntity, type SerializedDecodedTx, type SerializedTxData, type GetPendingTransactionResponse, } from '@getpara/user-management-client';
3
3
  export { PopupType, PregenIdentifierType, type AuthStateSignup, type AuthStateVerify, type AuthStateLogin, type AuthState, type OAuthResponse, type CoreAuthInfo, type SignatureRes, type FullSignatureRes, type SuccessfulSignatureRes, type DeniedSignatureRes, type DeniedSignatureResWithUrl, type Wallet, type AvailableWallet, type AccountLinkInProgress, AccountLinkError, type InternalInterface, type Verify2faParams, type Verify2faResponse, type StorageType, type TelegramParams, } from './types/index.js';
4
4
  export * from './types/coreApi.js';
5
5
  export * from './types/events.js';
@@ -17,6 +17,15 @@ export type PollingCallbacks = {
17
17
  * Signal to cancel the polling.
18
18
  */
19
19
  isCanceled?: () => boolean;
20
+ /**
21
+ * Callback fired when a transaction requires user review. Receives the portal URL
22
+ * that must be opened for the user to approve or deny the transaction.
23
+ *
24
+ * On web this is handled automatically via a popup. On React Native, provide this
25
+ * callback to open the URL in an in-app browser (e.g. `expo-web-browser`).
26
+ * If not provided, the SDK falls back to `openPopup` (which throws on React Native).
27
+ */
28
+ onTransactionReviewUrl?: (url: string) => void;
20
29
  };
21
30
  export interface PollingConfig<T> extends PollingCallbacks {
22
31
  init?: () => Promise<void>;
@@ -4,7 +4,7 @@ import { ParaCore } from '../ParaCore.js';
4
4
  import { FullSignatureRes, Wallet } from './wallet.js';
5
5
  import { AccountLinkInProgress } from './accountLinking.js';
6
6
  import type { WaitForLoginParams, WaitForLoginResponse, WaitForSignupParams, WaitForWalletCreationParams, WaitForWalletCreationResponse, GetOAuthUrlParams, AddCredentialParams, LoginExternalWalletParams, LoginExternalWalletResponse, ResendVerificationCodeParams, SignUpOrLogInParams, SignUpOrLogInResponse, VerifyOAuthProcessParams, VerifyExternalWalletParams, VerifyExternalWalletResponse, VerifyFarcasterParams, VerifyTelegramParams, ClaimPregenWalletsParams, ClaimPregenWalletsResponse, CreateGuestWalletsResponse, CreatePregenWalletParams, CreatePregenWalletPerTypeParams, CreatePregenWalletPerTypeResponse, CreatePregenWalletResponse, CreateWalletParams, CreateWalletPerTypeParams, CreateWalletPerTypeResponse, CreateWalletResponse, DistributeNewWalletShareParams, GetPregenWalletsParams, GetPregenWalletsResponse, GetWalletBalanceParams, HasPregenWalletParams, PollingCallbacks, RefreshShareParams, RefreshShareResponse, UpdatePregenWalletIdentifierParams, BaseVerifyExternalWalletParams, AuthenticateWithEmailOrPhoneParams, AuthenticateWithEmailOrPhoneResponse, AuthenticateWithOAuthParams, AuthenticateWithOAuthResponse } from '../services/types';
7
- export declare const PARA_CORE_METHODS: readonly ["getAuthInfo", "signUpOrLogIn", "verifyNewAccount", "waitForLogin", "waitForSignup", "waitForWalletCreation", "getOAuthUrl", "verifyOAuth", "getFarcasterConnectUri", "verifyFarcaster", "verifyTelegram", "resendVerificationCode", "loginExternalWallet", "verifyExternalWallet", "setup2fa", "enable2fa", "verify2fa", "logout", "clearStorage", "isSessionActive", "isFullyLoggedIn", "refreshSession", "keepSessionAlive", "exportSession", "importSession", "getVerificationToken", "getWallets", "getWalletsByType", "fetchWallets", "createWallet", "createWalletPerType", "getPregenWallets", "hasPregenWallet", "updatePregenWalletIdentifier", "createPregenWallet", "createPregenWalletPerType", "claimPregenWallets", "createGuestWallets", "distributeNewWalletShare", "getUserShare", "setUserShare", "refreshShare", "signMessage", "signTransaction", "initiateOnRampTransaction", "getWalletBalance", "issueJwt", "getLinkedAccounts", "accountLinkInProgress", "addCredential", "exportPrivateKey", "authenticateWithEmailOrPhone", "authenticateWithOAuth"];
7
+ export declare const PARA_CORE_METHODS: readonly ["getAuthInfo", "signUpOrLogIn", "verifyNewAccount", "waitForLogin", "waitForSignup", "waitForWalletCreation", "getOAuthUrl", "verifyOAuth", "getFarcasterConnectUri", "verifyFarcaster", "verifyTelegram", "resendVerificationCode", "loginExternalWallet", "verifyExternalWallet", "setup2fa", "enable2fa", "verify2fa", "logout", "clearStorage", "isSessionActive", "isFullyLoggedIn", "refreshSession", "keepSessionAlive", "exportSession", "waitAndExportSession", "importSession", "getVerificationToken", "getWallets", "getWalletsByType", "fetchWallets", "createWallet", "createWalletPerType", "getPregenWallets", "hasPregenWallet", "updatePregenWalletIdentifier", "createPregenWallet", "createPregenWalletPerType", "claimPregenWallets", "createGuestWallets", "distributeNewWalletShare", "getUserShare", "setUserShare", "refreshShare", "signMessage", "signTransaction", "initiateOnRampTransaction", "getWalletBalance", "issueJwt", "getLinkedAccounts", "accountLinkInProgress", "addCredential", "exportPrivateKey", "authenticateWithEmailOrPhone", "authenticateWithOAuth"];
8
8
  export declare const PARA_INTERNAL_METHODS: readonly ["linkAccount", "unlinkAccount", "verifyEmailOrPhoneLink", "verifyOAuthLink", "verifyFarcasterLink", "verifyTelegramLink", "verifyExternalWalletLink", "accountLinkInProgress", "prepareLogin", "sendLoginCode", "supportedUserAuthMethods"];
9
9
  export type CoreMethodName = (typeof PARA_CORE_METHODS)[number];
10
10
  export type CoreMethodParams<method extends CoreMethodName & keyof CoreMethods> = CoreMethods[method] extends {
@@ -227,6 +227,15 @@ export type CoreMethods = Record<CoreMethodName, {
227
227
  response: string;
228
228
  sync: true;
229
229
  };
230
+ waitAndExportSession: {
231
+ params: {
232
+ /**
233
+ * Whether to exclude the wallet signers from the exported session.
234
+ */
235
+ excludeSigners?: boolean;
236
+ };
237
+ response: string;
238
+ };
230
239
  importSession: {
231
240
  params: string;
232
241
  response: void;
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@getpara/core-sdk",
3
- "version": "2.17.0",
3
+ "version": "2.18.0",
4
4
  "dependencies": {
5
5
  "@celo/utils": "^8.0.2",
6
6
  "@cosmjs/encoding": "^0.32.4",
7
7
  "@ethereumjs/util": "^9.1.0",
8
- "@getpara/user-management-client": "2.17.0",
8
+ "@getpara/user-management-client": "2.18.0",
9
9
  "@noble/hashes": "^1.5.0",
10
10
  "axios": "^1.8.4",
11
11
  "base64url": "^3.0.1",
@@ -30,7 +30,7 @@
30
30
  "dist",
31
31
  "package.json"
32
32
  ],
33
- "gitHead": "3ed1f835b97ae720f1ac747611296e3b86f61138",
33
+ "gitHead": "4481f6f4e108e682d14c74d4433696141c47fc58",
34
34
  "main": "dist/cjs/index.js",
35
35
  "module": "dist/esm/index.js",
36
36
  "scripts": {