@turnkey/core 1.0.0-beta.2 → 1.0.0-beta.5

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 (89) hide show
  1. package/dist/__clients__/core.d.ts +92 -9
  2. package/dist/__clients__/core.d.ts.map +1 -1
  3. package/dist/__clients__/core.js +699 -535
  4. package/dist/__clients__/core.js.map +1 -1
  5. package/dist/__clients__/core.mjs +702 -538
  6. package/dist/__clients__/core.mjs.map +1 -1
  7. package/dist/__generated__/sdk-client-base.d.ts +1 -1
  8. package/dist/__generated__/sdk-client-base.d.ts.map +1 -1
  9. package/dist/__generated__/sdk-client-base.js +156 -253
  10. package/dist/__generated__/sdk-client-base.js.map +1 -1
  11. package/dist/__generated__/sdk-client-base.mjs +156 -253
  12. package/dist/__generated__/sdk-client-base.mjs.map +1 -1
  13. package/dist/__generated__/version.d.ts +1 -1
  14. package/dist/__generated__/version.js +1 -1
  15. package/dist/__generated__/version.mjs +1 -1
  16. package/dist/__inputs__/public_api.types.d.ts +377 -504
  17. package/dist/__inputs__/public_api.types.d.ts.map +1 -1
  18. package/dist/__types__/base.d.ts +193 -75
  19. package/dist/__types__/base.d.ts.map +1 -1
  20. package/dist/__types__/base.js +14 -13
  21. package/dist/__types__/base.js.map +1 -1
  22. package/dist/__types__/base.mjs +15 -14
  23. package/dist/__types__/base.mjs.map +1 -1
  24. package/dist/__wallet__/base.d.ts +11 -0
  25. package/dist/__wallet__/base.d.ts.map +1 -1
  26. package/dist/__wallet__/base.js +12 -1
  27. package/dist/__wallet__/base.js.map +1 -1
  28. package/dist/__wallet__/base.mjs +12 -1
  29. package/dist/__wallet__/base.mjs.map +1 -1
  30. package/dist/__wallet__/connector.d.ts +31 -4
  31. package/dist/__wallet__/connector.d.ts.map +1 -1
  32. package/dist/__wallet__/connector.js +35 -5
  33. package/dist/__wallet__/connector.js.map +1 -1
  34. package/dist/__wallet__/connector.mjs +35 -5
  35. package/dist/__wallet__/connector.mjs.map +1 -1
  36. package/dist/__wallet__/mobile/manager.d.ts +21 -5
  37. package/dist/__wallet__/mobile/manager.d.ts.map +1 -1
  38. package/dist/__wallet__/mobile/manager.js +28 -11
  39. package/dist/__wallet__/mobile/manager.js.map +1 -1
  40. package/dist/__wallet__/mobile/manager.mjs +28 -11
  41. package/dist/__wallet__/mobile/manager.mjs.map +1 -1
  42. package/dist/__wallet__/stamper.d.ts +73 -2
  43. package/dist/__wallet__/stamper.d.ts.map +1 -1
  44. package/dist/__wallet__/stamper.js +81 -15
  45. package/dist/__wallet__/stamper.js.map +1 -1
  46. package/dist/__wallet__/stamper.mjs +82 -16
  47. package/dist/__wallet__/stamper.mjs.map +1 -1
  48. package/dist/__wallet__/wallet-connect/base.d.ts +102 -19
  49. package/dist/__wallet__/wallet-connect/base.d.ts.map +1 -1
  50. package/dist/__wallet__/wallet-connect/base.js +198 -77
  51. package/dist/__wallet__/wallet-connect/base.js.map +1 -1
  52. package/dist/__wallet__/wallet-connect/base.mjs +198 -77
  53. package/dist/__wallet__/wallet-connect/base.mjs.map +1 -1
  54. package/dist/__wallet__/wallet-connect/client.d.ts +50 -17
  55. package/dist/__wallet__/wallet-connect/client.d.ts.map +1 -1
  56. package/dist/__wallet__/wallet-connect/client.js +76 -19
  57. package/dist/__wallet__/wallet-connect/client.js.map +1 -1
  58. package/dist/__wallet__/wallet-connect/client.mjs +76 -19
  59. package/dist/__wallet__/wallet-connect/client.mjs.map +1 -1
  60. package/dist/__wallet__/web/manager.d.ts +20 -12
  61. package/dist/__wallet__/web/manager.d.ts.map +1 -1
  62. package/dist/__wallet__/web/manager.js +29 -21
  63. package/dist/__wallet__/web/manager.js.map +1 -1
  64. package/dist/__wallet__/web/manager.mjs +29 -21
  65. package/dist/__wallet__/web/manager.mjs.map +1 -1
  66. package/dist/__wallet__/web/native/ethereum.d.ts +45 -11
  67. package/dist/__wallet__/web/native/ethereum.d.ts.map +1 -1
  68. package/dist/__wallet__/web/native/ethereum.js +58 -17
  69. package/dist/__wallet__/web/native/ethereum.js.map +1 -1
  70. package/dist/__wallet__/web/native/ethereum.mjs +58 -17
  71. package/dist/__wallet__/web/native/ethereum.mjs.map +1 -1
  72. package/dist/__wallet__/web/native/solana.d.ts +56 -3
  73. package/dist/__wallet__/web/native/solana.d.ts.map +1 -1
  74. package/dist/__wallet__/web/native/solana.js +95 -36
  75. package/dist/__wallet__/web/native/solana.js.map +1 -1
  76. package/dist/__wallet__/web/native/solana.mjs +95 -36
  77. package/dist/__wallet__/web/native/solana.mjs.map +1 -1
  78. package/dist/index.d.ts +2 -1
  79. package/dist/index.d.ts.map +1 -1
  80. package/dist/index.js +2 -10
  81. package/dist/index.js.map +1 -1
  82. package/dist/index.mjs +2 -2
  83. package/dist/utils.d.ts +59 -13
  84. package/dist/utils.d.ts.map +1 -1
  85. package/dist/utils.js +105 -30
  86. package/dist/utils.js.map +1 -1
  87. package/dist/utils.mjs +103 -29
  88. package/dist/utils.mjs.map +1 -1
  89. package/package.json +8 -8
@@ -1,7 +1,7 @@
1
1
  import { TurnkeySDKClientBase } from '../__generated__/sdk-client-base.mjs';
2
- import { TurnkeyError, TurnkeyErrorCodes, TurnkeyNetworkError } from '@turnkey/sdk-types';
3
- import { SessionKey, DEFAULT_SESSION_EXPIRATION_IN_SECONDS, StamperType, Chain, FilterType, OtpTypeToFilterTypeMap, TurnkeyRequestError, OtpType, WalletSource, Curve } from '../__types__/base.mjs';
4
- import { isWeb, isReactNative, buildSignUpBody, isEthereumWallet, getPublicKeyFromStampHeader, toExternalTimestamp, isSolanaWallet, getWalletAccountMethods, getHashFunction, getEncodingType, getEncodedMessage, splitSignature, broadcastTransaction, googleISS, isWalletAccountArray, generateWalletAccountsFromAddressFormat } from '../utils.mjs';
2
+ import { TurnkeyErrorCodes, TurnkeyError, TurnkeyNetworkError } from '@turnkey/sdk-types';
3
+ import { SessionKey, DEFAULT_SESSION_EXPIRATION_IN_SECONDS, StamperType, WalletSource, Chain, FilterType, OtpTypeToFilterTypeMap, OtpType, Curve, SignIntent } from '../__types__/base.mjs';
4
+ import { withTurnkeyErrorHandling, isWeb, isReactNative, buildSignUpBody, findWalletProviderFromAddress, isEthereumProvider, getPublicKeyFromStampHeader, toExternalTimestamp, isSolanaProvider, getHashFunction, getEncodingType, getEncodedMessage, splitSignature, broadcastTransaction, googleISS, isWalletAccountArray, generateWalletAccountsFromAddressFormat } from '../utils.mjs';
5
5
  import { createStorageManager } from '../__storage__/base.mjs';
6
6
  import { CrossPlatformApiKeyStamper } from '../__stampers__/api/base.mjs';
7
7
  import { CrossPlatformPasskeyStamper } from '../__stampers__/passkey/base.mjs';
@@ -30,7 +30,7 @@ class TurnkeyClient {
30
30
  * @throws {TurnkeyError} If there is an error during passkey creation, or if the platform is unsupported.
31
31
  */
32
32
  this.createPasskey = async (params) => {
33
- try {
33
+ return withTurnkeyErrorHandling(async () => {
34
34
  const name = params?.name || "A Passkey";
35
35
  const displayName = params?.displayName || "A Passkey";
36
36
  let passkey;
@@ -68,16 +68,16 @@ class TurnkeyClient {
68
68
  throw new TurnkeyError("Unsupported platform for passkey creation", TurnkeyErrorCodes.INVALID_REQUEST);
69
69
  }
70
70
  return passkey;
71
- }
72
- catch (error) {
73
- if (error?.message?.includes("timed out or was not allowed")) {
74
- throw new TurnkeyError("Passkey creation was cancelled by the user.", TurnkeyErrorCodes.SELECT_PASSKEY_CANCELLED, error);
75
- }
76
- else if (error instanceof TurnkeyError) {
77
- throw error;
78
- }
79
- throw new TurnkeyError(`Failed to create passkey`, TurnkeyErrorCodes.CREATE_PASSKEY_ERROR, error);
80
- }
71
+ }, {
72
+ errorMessage: "Failed to create passkey",
73
+ errorCode: TurnkeyErrorCodes.CREATE_PASSKEY_ERROR,
74
+ customMessageByMessages: {
75
+ "timed out or was not allowed": {
76
+ message: "Passkey creation was cancelled by the user.",
77
+ code: TurnkeyErrorCodes.SELECT_PASSKEY_CANCELLED,
78
+ },
79
+ },
80
+ });
81
81
  };
82
82
  /**
83
83
  * Logs out the current client session.
@@ -91,7 +91,7 @@ class TurnkeyClient {
91
91
  * @throws {TurnkeyError} If there is no active session or if there is an error during the logout process.
92
92
  */
93
93
  this.logout = async (params) => {
94
- try {
94
+ withTurnkeyErrorHandling(async () => {
95
95
  if (params?.sessionKey) {
96
96
  const session = await this.storageManager.getSession(params.sessionKey);
97
97
  this.storageManager.clearSession(params.sessionKey);
@@ -108,12 +108,10 @@ class TurnkeyClient {
108
108
  throw new TurnkeyError("No active session found to log out from.", TurnkeyErrorCodes.NO_SESSION_FOUND);
109
109
  }
110
110
  }
111
- }
112
- catch (error) {
113
- if (error instanceof TurnkeyError)
114
- throw error;
115
- throw new TurnkeyError(`Failed to log out`, TurnkeyErrorCodes.LOGOUT_ERROR, error);
116
- }
111
+ }, {
112
+ errorMessage: "Failed to log out",
113
+ errorCode: TurnkeyErrorCodes.LOGOUT_ERROR,
114
+ });
117
115
  };
118
116
  /**
119
117
  * Logs in a user using a passkey, optionally specifying the public key, session key, and session expiration.
@@ -131,16 +129,17 @@ class TurnkeyClient {
131
129
  * @throws {TurnkeyError} If there is an error during the passkey login process or if the user cancels the passkey prompt.
132
130
  */
133
131
  this.loginWithPasskey = async (params) => {
134
- let generatedKeyPair = null;
135
- try {
136
- const publicKey = params?.publicKey || (await this.apiKeyStamper?.createKeyPair());
132
+ let generatedKeyPair = undefined;
133
+ return await withTurnkeyErrorHandling(async () => {
134
+ generatedKeyPair =
135
+ params?.publicKey || (await this.apiKeyStamper?.createKeyPair());
137
136
  const sessionKey = params?.sessionKey || SessionKey.DefaultSessionkey;
138
137
  const expirationSeconds = params?.expirationSeconds || DEFAULT_SESSION_EXPIRATION_IN_SECONDS;
139
- if (!publicKey) {
138
+ if (!generatedKeyPair) {
140
139
  throw new TurnkeyError("A publickey could not be found or generated.", TurnkeyErrorCodes.INTERNAL_ERROR);
141
140
  }
142
141
  const sessionResponse = await this.httpClient.stampLogin({
143
- publicKey,
142
+ publicKey: generatedKeyPair,
144
143
  organizationId: this.config.organizationId,
145
144
  expirationSeconds,
146
145
  }, StamperType.Passkey);
@@ -148,28 +147,29 @@ class TurnkeyClient {
148
147
  sessionToken: sessionResponse.session,
149
148
  sessionKey,
150
149
  });
151
- // Key pair was successfully used, set to null to prevent cleanup
152
- generatedKeyPair = null;
150
+ generatedKeyPair = undefined; // Key pair was successfully used, set to null to prevent cleanup
153
151
  return sessionResponse.session;
154
- }
155
- catch (error) {
156
- if (error?.message?.includes("timed out or was not allowed"))
157
- throw new TurnkeyError("Passkey login was cancelled by the user.", TurnkeyErrorCodes.SELECT_PASSKEY_CANCELLED, error);
158
- if (error instanceof TurnkeyError)
159
- throw error;
160
- throw new TurnkeyError(`Unable to log in with the provided passkey`, TurnkeyErrorCodes.PASSKEY_LOGIN_AUTH_ERROR, error);
161
- }
162
- finally {
163
- // Clean up the generated key pair if it wasn't successfully used
164
- if (generatedKeyPair) {
165
- try {
166
- await this.apiKeyStamper?.deleteKeyPair(generatedKeyPair);
167
- }
168
- catch (cleanupError) {
169
- throw new TurnkeyError(`Failed to clean up generated key pair`, TurnkeyErrorCodes.KEY_PAIR_CLEANUP_ERROR, cleanupError);
152
+ }, {
153
+ errorMessage: "Unable to log in with the provided passkey",
154
+ errorCode: TurnkeyErrorCodes.PASSKEY_LOGIN_AUTH_ERROR,
155
+ customMessageByMessages: {
156
+ "timed out or was not allowed": {
157
+ message: "Passkey login was cancelled by the user.",
158
+ code: TurnkeyErrorCodes.SELECT_PASSKEY_CANCELLED,
159
+ },
160
+ },
161
+ }, {
162
+ finallyFn: async () => {
163
+ if (generatedKeyPair) {
164
+ try {
165
+ await this.apiKeyStamper?.deleteKeyPair(generatedKeyPair);
166
+ }
167
+ catch (cleanupError) {
168
+ throw new TurnkeyError(`Failed to clean up generated key pair`, TurnkeyErrorCodes.KEY_PAIR_CLEANUP_ERROR, cleanupError);
169
+ }
170
170
  }
171
- }
172
- }
171
+ },
172
+ });
173
173
  };
174
174
  /**
175
175
  * Signs up a user using a passkey, creating a new sub-organization and session.
@@ -189,8 +189,8 @@ class TurnkeyClient {
189
189
  */
190
190
  this.signUpWithPasskey = async (params) => {
191
191
  const { createSubOrgParams, passkeyDisplayName, sessionKey = SessionKey.DefaultSessionkey, expirationSeconds = DEFAULT_SESSION_EXPIRATION_IN_SECONDS, } = params || {};
192
- let generatedKeyPair = null;
193
- try {
192
+ let generatedKeyPair = undefined;
193
+ return withTurnkeyErrorHandling(async () => {
194
194
  generatedKeyPair = await this.apiKeyStamper?.createKeyPair();
195
195
  const passkeyName = passkeyDisplayName || `passkey-${Date.now()}`;
196
196
  // A passkey will be created automatically when you call this function. The name is passed in
@@ -239,26 +239,24 @@ class TurnkeyClient {
239
239
  sessionToken: sessionResponse.session,
240
240
  sessionKey,
241
241
  });
242
- generatedKeyPair = null; // Key pair was successfully used, set to null to prevent cleanup
242
+ generatedKeyPair = undefined; // Key pair was successfully used, set to null to prevent cleanup
243
243
  return sessionResponse.session;
244
- }
245
- catch (error) {
246
- if (error instanceof TurnkeyError)
247
- throw error;
248
- throw new TurnkeyError(`Failed to sign up with passkey`, TurnkeyErrorCodes.PASSKEY_SIGNUP_AUTH_ERROR, error);
249
- }
250
- finally {
251
- // Clean up the generated key pair if it wasn't successfully used
252
- this.apiKeyStamper?.clearPublicKeyOverride();
253
- if (generatedKeyPair) {
254
- try {
255
- await this.apiKeyStamper?.deleteKeyPair(generatedKeyPair);
256
- }
257
- catch (cleanupError) {
258
- throw new TurnkeyError(`Failed to clean up generated key pair`, TurnkeyErrorCodes.KEY_PAIR_CLEANUP_ERROR, cleanupError);
244
+ }, {
245
+ errorCode: TurnkeyErrorCodes.PASSKEY_SIGNUP_AUTH_ERROR,
246
+ errorMessage: "Failed to sign up with passkey",
247
+ }, {
248
+ finallyFn: async () => {
249
+ this.apiKeyStamper?.clearPublicKeyOverride();
250
+ if (generatedKeyPair) {
251
+ try {
252
+ await this.apiKeyStamper?.deleteKeyPair(generatedKeyPair);
253
+ }
254
+ catch (cleanupError) {
255
+ throw new TurnkeyError(`Failed to clean up generated key pair`, TurnkeyErrorCodes.KEY_PAIR_CLEANUP_ERROR, cleanupError);
256
+ }
259
257
  }
260
- }
261
- }
258
+ },
259
+ });
262
260
  };
263
261
  /**
264
262
  * Retrieves wallet providers from the initialized wallet manager.
@@ -271,15 +269,15 @@ class TurnkeyClient {
271
269
  * @throws {TurnkeyError} If the wallet manager is uninitialized or provider retrieval fails.
272
270
  */
273
271
  this.getWalletProviders = async (chain) => {
274
- try {
272
+ return withTurnkeyErrorHandling(async () => {
275
273
  if (!this.walletManager) {
276
274
  throw new TurnkeyError("Wallet manager is not initialized", TurnkeyErrorCodes.WALLET_MANAGER_COMPONENT_NOT_INITIALIZED);
277
275
  }
278
276
  return await this.walletManager.getProviders(chain);
279
- }
280
- catch (error) {
281
- throw new TurnkeyError(`Unable to get wallet providers`, TurnkeyErrorCodes.FETCH_WALLETS_ERROR, error);
282
- }
277
+ }, {
278
+ errorMessage: "Unable to get wallet providers",
279
+ errorCode: TurnkeyErrorCodes.FETCH_WALLETS_ERROR,
280
+ });
283
281
  };
284
282
  /**
285
283
  * Connects the specified wallet account.
@@ -291,15 +289,15 @@ class TurnkeyClient {
291
289
  * @throws {TurnkeyError} If the wallet manager is uninitialized or the connection fails.
292
290
  */
293
291
  this.connectWalletAccount = async (walletProvider) => {
294
- if (!this.walletManager?.connector) {
295
- throw new TurnkeyError("Wallet connector is not initialized", TurnkeyErrorCodes.WALLET_MANAGER_COMPONENT_NOT_INITIALIZED);
296
- }
297
- try {
292
+ return withTurnkeyErrorHandling(async () => {
293
+ if (!this.walletManager?.connector) {
294
+ throw new TurnkeyError("Wallet connector is not initialized", TurnkeyErrorCodes.WALLET_MANAGER_COMPONENT_NOT_INITIALIZED);
295
+ }
298
296
  await this.walletManager.connector.connectWalletAccount(walletProvider);
299
- }
300
- catch (error) {
301
- throw new TurnkeyError("Unable to connect wallet account", TurnkeyErrorCodes.CONNECT_WALLET_ACCOUNT_ERROR, error);
302
- }
297
+ }, {
298
+ errorMessage: "Unable to connect wallet account",
299
+ errorCode: TurnkeyErrorCodes.CONNECT_WALLET_ACCOUNT_ERROR,
300
+ });
303
301
  };
304
302
  /**
305
303
  * Disconnects the specified wallet account.
@@ -311,45 +309,55 @@ class TurnkeyClient {
311
309
  * @throws {TurnkeyError} If the wallet manager is uninitialized or the disconnection fails.
312
310
  */
313
311
  this.disconnectWalletAccount = async (walletProvider) => {
314
- if (!this.walletManager?.connector) {
315
- throw new TurnkeyError("Wallet connector is not initialized", TurnkeyErrorCodes.WALLET_MANAGER_COMPONENT_NOT_INITIALIZED);
316
- }
317
- try {
312
+ return withTurnkeyErrorHandling(async () => {
313
+ if (!this.walletManager?.connector) {
314
+ throw new TurnkeyError("Wallet connector is not initialized", TurnkeyErrorCodes.WALLET_MANAGER_COMPONENT_NOT_INITIALIZED);
315
+ }
318
316
  await this.walletManager.connector.disconnectWalletAccount(walletProvider);
319
- }
320
- catch (error) {
321
- throw new TurnkeyError("Unable to disconnect wallet account", TurnkeyErrorCodes.DISCONNECT_WALLET_ACCOUNT_ERROR, error);
322
- }
317
+ }, {
318
+ errorMessage: "Unable to disconnect wallet account",
319
+ errorCode: TurnkeyErrorCodes.DISCONNECT_WALLET_ACCOUNT_ERROR,
320
+ });
323
321
  };
324
322
  /**
325
- * Switches the specified wallet provider to a different blockchain chain.
323
+ * Switches the wallet provider associated with a given wallet account
324
+ * to a different chain.
326
325
  *
327
- * - Requires the wallet manager and its connector to be initialized.
328
- * - The wallet provider must have at least one connected address.
329
- * - Does nothing if the wallet provider is already on the desired chain.
326
+ * - Requires the wallet manager and its connector to be initialized
327
+ * - Only works for connected wallet accounts
328
+ * - Looks up the provider for the given account address
329
+ * - Does nothing if the provider is already on the desired chain.
330
330
  *
331
- * @param walletProvider - wallet provider to switch.
332
- * @param chainOrId - target chain as a chain ID string or SwitchableChain object.
331
+ * @param params.walletAccount - The wallet account whose provider should be switched.
332
+ * @param params.chainOrId - The target chain, specified as a chain ID string or a SwitchableChain object.
333
+ * @param params.walletProviders - Optional list of wallet providers to search; falls back to `getWalletProviders()` if omitted.
333
334
  * @returns A promise that resolves once the chain switch is complete.
335
+ *
334
336
  * @throws {TurnkeyError} If the wallet manager is uninitialized, the provider is not connected, or the switch fails.
335
337
  */
336
- this.switchWalletProviderChain = async (walletProvider, chainOrId) => {
337
- if (!this.walletManager?.connector) {
338
- throw new TurnkeyError("Wallet connector is not initialized", TurnkeyErrorCodes.WALLET_MANAGER_COMPONENT_NOT_INITIALIZED);
339
- }
340
- if (walletProvider.connectedAddresses.length === 0) {
341
- throw new TurnkeyError("You can not switch chains for a provider that is not connected", TurnkeyErrorCodes.INVALID_REQUEST);
342
- }
343
- // if the wallet provider is already on the desired chain, do nothing
344
- if (walletProvider.chainInfo.namespace === chainOrId) {
345
- return;
346
- }
347
- try {
338
+ this.switchWalletAccountChain = async (params) => {
339
+ const { walletAccount, chainOrId, walletProviders } = params;
340
+ return withTurnkeyErrorHandling(async () => {
341
+ if (!this.walletManager?.connector) {
342
+ throw new TurnkeyError("Wallet connector is not initialized", TurnkeyErrorCodes.WALLET_MANAGER_COMPONENT_NOT_INITIALIZED);
343
+ }
344
+ if (walletAccount.source === WalletSource.Embedded) {
345
+ throw new TurnkeyError("You can only switch chains for connected wallet accounts", TurnkeyErrorCodes.NOT_FOUND);
346
+ }
347
+ const providers = walletProviders ?? (await this.getWalletProviders());
348
+ const walletProvider = findWalletProviderFromAddress(walletAccount.address, providers);
349
+ if (!walletProvider) {
350
+ throw new TurnkeyError("Wallet provider not found", TurnkeyErrorCodes.SWITCH_WALLET_CHAIN_ERROR);
351
+ }
352
+ // if the wallet provider is already on the desired chain, do nothing
353
+ if (walletProvider.chainInfo.namespace === chainOrId) {
354
+ return;
355
+ }
348
356
  await this.walletManager.connector.switchChain(walletProvider, chainOrId);
349
- }
350
- catch (error) {
351
- throw new TurnkeyError("Unable to switch wallet account chain", TurnkeyErrorCodes.SWITCH_WALLET_CHAIN_ERROR, error);
352
- }
357
+ }, {
358
+ errorMessage: "Unable to switch wallet account chain",
359
+ errorCode: TurnkeyErrorCodes.SWITCH_WALLET_CHAIN_ERROR,
360
+ });
353
361
  };
354
362
  /**
355
363
  * Logs in a user using the specified wallet provider.
@@ -368,11 +376,11 @@ class TurnkeyClient {
368
376
  * @throws {TurnkeyError} If the wallet stamper is uninitialized, a public key cannot be found or generated, or login fails.
369
377
  */
370
378
  this.loginWithWallet = async (params) => {
371
- if (!this.walletManager?.stamper) {
372
- throw new TurnkeyError("Wallet stamper is not initialized", TurnkeyErrorCodes.WALLET_MANAGER_COMPONENT_NOT_INITIALIZED);
373
- }
374
- try {
375
- const publicKey = params.publicKey || (await this.apiKeyStamper?.createKeyPair());
379
+ let publicKey = params.publicKey || (await this.apiKeyStamper?.createKeyPair());
380
+ return withTurnkeyErrorHandling(async () => {
381
+ if (!this.walletManager?.stamper) {
382
+ throw new TurnkeyError("Wallet stamper is not initialized", TurnkeyErrorCodes.WALLET_MANAGER_COMPONENT_NOT_INITIALIZED);
383
+ }
376
384
  const sessionKey = params.sessionKey || SessionKey.DefaultSessionkey;
377
385
  const walletProvider = params.walletProvider;
378
386
  const expirationSeconds = params?.expirationSeconds || DEFAULT_SESSION_EXPIRATION_IN_SECONDS;
@@ -390,12 +398,23 @@ class TurnkeyClient {
390
398
  sessionKey,
391
399
  });
392
400
  return sessionResponse.session;
393
- }
394
- catch (error) {
395
- if (error instanceof TurnkeyError)
396
- throw error;
397
- throw new TurnkeyError(`Unable to log in with the provided wallet`, TurnkeyErrorCodes.WALLET_LOGIN_AUTH_ERROR, error);
398
- }
401
+ }, {
402
+ errorMessage: "Unable to log in with the provided wallet",
403
+ errorCode: TurnkeyErrorCodes.WALLET_LOGIN_AUTH_ERROR,
404
+ }, {
405
+ finallyFn: async () => {
406
+ // Clean up the generated key pair if it wasn't successfully used
407
+ this.apiKeyStamper?.clearPublicKeyOverride();
408
+ if (publicKey) {
409
+ try {
410
+ await this.apiKeyStamper?.deleteKeyPair(publicKey);
411
+ }
412
+ catch (cleanupError) {
413
+ throw new TurnkeyError("Failed to clean up generated key pair", TurnkeyErrorCodes.KEY_PAIR_CLEANUP_ERROR, cleanupError);
414
+ }
415
+ }
416
+ },
417
+ });
399
418
  };
400
419
  /**
401
420
  * Signs up a user using a wallet, creating a new sub-organization and session.
@@ -415,11 +434,11 @@ class TurnkeyClient {
415
434
  */
416
435
  this.signUpWithWallet = async (params) => {
417
436
  const { walletProvider, createSubOrgParams, sessionKey = SessionKey.DefaultSessionkey, expirationSeconds = DEFAULT_SESSION_EXPIRATION_IN_SECONDS, } = params;
418
- if (!this.walletManager?.stamper) {
419
- throw new TurnkeyError("Wallet stamper is not initialized", TurnkeyErrorCodes.WALLET_MANAGER_COMPONENT_NOT_INITIALIZED);
420
- }
421
- let generatedKeyPair = null;
422
- try {
437
+ let generatedKeyPair = undefined;
438
+ return withTurnkeyErrorHandling(async () => {
439
+ if (!this.walletManager?.stamper) {
440
+ throw new TurnkeyError("Wallet stamper is not initialized", TurnkeyErrorCodes.WALLET_MANAGER_COMPONENT_NOT_INITIALIZED);
441
+ }
423
442
  generatedKeyPair = await this.apiKeyStamper?.createKeyPair();
424
443
  this.walletManager.stamper.setProvider(walletProvider.interfaceType, walletProvider);
425
444
  const publicKey = await this.walletManager.stamper.getPublicKey(walletProvider.interfaceType, walletProvider);
@@ -433,7 +452,7 @@ class TurnkeyClient {
433
452
  {
434
453
  apiKeyName: `wallet-auth:${publicKey}`,
435
454
  publicKey: publicKey,
436
- curveType: isEthereumWallet(walletProvider)
455
+ curveType: isEthereumProvider(walletProvider)
437
456
  ? "API_KEY_CURVE_SECP256K1"
438
457
  : "API_KEY_CURVE_ED25519",
439
458
  },
@@ -462,24 +481,25 @@ class TurnkeyClient {
462
481
  sessionToken: sessionResponse.session,
463
482
  sessionKey,
464
483
  });
465
- generatedKeyPair = null; // Key pair was successfully used, set to null to prevent cleanup
484
+ generatedKeyPair = undefined; // Key pair was successfully used, set to null to prevent cleanup
466
485
  return sessionResponse.session;
467
- }
468
- catch (error) {
469
- throw new TurnkeyError("Failed to sign up with wallet", TurnkeyErrorCodes.WALLET_SIGNUP_AUTH_ERROR, error);
470
- }
471
- finally {
472
- // Clean up the generated key pair if it wasn't successfully used
473
- this.apiKeyStamper?.clearPublicKeyOverride();
474
- if (generatedKeyPair) {
475
- try {
476
- await this.apiKeyStamper?.deleteKeyPair(generatedKeyPair);
477
- }
478
- catch (cleanupError) {
479
- throw new TurnkeyError("Failed to clean up generated key pair", TurnkeyErrorCodes.KEY_PAIR_CLEANUP_ERROR, cleanupError);
486
+ }, {
487
+ errorMessage: "Failed to sign up with wallet",
488
+ errorCode: TurnkeyErrorCodes.WALLET_SIGNUP_AUTH_ERROR,
489
+ }, {
490
+ finallyFn: async () => {
491
+ // Clean up the generated key pair if it wasn't successfully used
492
+ this.apiKeyStamper?.clearPublicKeyOverride();
493
+ if (generatedKeyPair) {
494
+ try {
495
+ await this.apiKeyStamper?.deleteKeyPair(generatedKeyPair);
496
+ }
497
+ catch (cleanupError) {
498
+ throw new TurnkeyError("Failed to clean up generated key pair", TurnkeyErrorCodes.KEY_PAIR_CLEANUP_ERROR, cleanupError);
499
+ }
480
500
  }
481
- }
482
- }
501
+ },
502
+ });
483
503
  };
484
504
  /**
485
505
  * Logs in an existing user or signs up a new user using a wallet, creating a new sub-organization if needed.
@@ -499,25 +519,36 @@ class TurnkeyClient {
499
519
  * @throws {TurnkeyError} If there is an error during wallet authentication, sub-organization creation, or session storage.
500
520
  */
501
521
  this.loginOrSignupWithWallet = async (params) => {
502
- if (!this.walletManager?.stamper) {
503
- throw new TurnkeyError("Wallet stamper is not initialized", TurnkeyErrorCodes.WALLET_MANAGER_COMPONENT_NOT_INITIALIZED);
504
- }
505
522
  const createSubOrgParams = params.createSubOrgParams;
506
523
  const sessionKey = params.sessionKey || SessionKey.DefaultSessionkey;
507
524
  const walletProvider = params.walletProvider;
508
525
  const expirationSeconds = params.expirationSeconds || DEFAULT_SESSION_EXPIRATION_IN_SECONDS;
509
- let generatedKeyPair = null;
510
- try {
526
+ let generatedKeyPair = undefined;
527
+ return withTurnkeyErrorHandling(async () => {
528
+ if (!this.walletManager?.stamper) {
529
+ throw new TurnkeyError("Wallet stamper is not initialized", TurnkeyErrorCodes.WALLET_MANAGER_COMPONENT_NOT_INITIALIZED);
530
+ }
511
531
  generatedKeyPair = await this.apiKeyStamper?.createKeyPair();
512
532
  this.walletManager.stamper.setProvider(walletProvider.interfaceType, walletProvider);
513
533
  // here we sign the request with the wallet, but we don't send it to the Turnkey yet
514
534
  // this is because we need to check if the subOrg exists first, and create one if it doesn't
515
535
  // once we have the subOrg for the publicKey, we then can send the request to the Turnkey
516
- const signedRequest = await this.httpClient.stampStampLogin({
517
- publicKey: generatedKeyPair,
518
- organizationId: this.config.organizationId,
519
- expirationSeconds,
520
- }, StamperType.Wallet);
536
+ const signedRequest = await withTurnkeyErrorHandling(async () => {
537
+ return this.httpClient.stampStampLogin({
538
+ publicKey: generatedKeyPair,
539
+ organizationId: this.config.organizationId,
540
+ expirationSeconds,
541
+ }, StamperType.Wallet);
542
+ }, {
543
+ errorMessage: "Failed to create stamped request for wallet login",
544
+ errorCode: TurnkeyErrorCodes.WALLET_LOGIN_OR_SIGNUP_ERROR,
545
+ customMessageByMessages: {
546
+ "Failed to sign the message": {
547
+ message: "Wallet auth was cancelled by the user.",
548
+ code: TurnkeyErrorCodes.CONNECT_WALLET_CANCELLED,
549
+ },
550
+ },
551
+ });
521
552
  if (!signedRequest) {
522
553
  throw new TurnkeyError("Failed to create stamped request for wallet login", TurnkeyErrorCodes.BAD_RESPONSE);
523
554
  }
@@ -559,7 +590,7 @@ class TurnkeyClient {
559
590
  {
560
591
  apiKeyName: `wallet-auth:${publicKey}`,
561
592
  publicKey: publicKey,
562
- curveType: isEthereumWallet(walletProvider)
593
+ curveType: isEthereumProvider(walletProvider)
563
594
  ? "API_KEY_CURVE_SECP256K1"
564
595
  : "API_KEY_CURVE_ED25519",
565
596
  },
@@ -595,10 +626,20 @@ class TurnkeyClient {
595
626
  sessionKey,
596
627
  });
597
628
  return sessionToken;
598
- }
599
- catch (error) {
600
- throw new TurnkeyError(`Unable to log in or signup with the provided wallet`, TurnkeyErrorCodes.WALLET_LOGIN_OR_SIGNUP_ERROR, error);
601
- }
629
+ }, {
630
+ errorCode: TurnkeyErrorCodes.WALLET_LOGIN_OR_SIGNUP_ERROR,
631
+ errorMessage: "Failed to log in or sign up with wallet",
632
+ catchFn: async () => {
633
+ if (generatedKeyPair) {
634
+ try {
635
+ await this.apiKeyStamper?.deleteKeyPair(generatedKeyPair);
636
+ }
637
+ catch (cleanupError) {
638
+ throw new TurnkeyError(`Failed to clean up generated key pair`, TurnkeyErrorCodes.KEY_PAIR_CLEANUP_ERROR, cleanupError);
639
+ }
640
+ }
641
+ },
642
+ });
602
643
  };
603
644
  /**
604
645
  * Initializes the OTP process by sending an OTP code to the provided contact.
@@ -613,23 +654,22 @@ class TurnkeyClient {
613
654
  * @throws {TurnkeyError} If there is an error during the OTP initialization process or if the maximum number of OTPs has been reached.
614
655
  */
615
656
  this.initOtp = async (params) => {
616
- try {
657
+ return withTurnkeyErrorHandling(async () => {
617
658
  const initOtpRes = await this.httpClient.proxyInitOtp(params);
618
659
  if (!initOtpRes || !initOtpRes.otpId) {
619
660
  throw new TurnkeyError("Failed to initialize OTP: otpId is missing", TurnkeyErrorCodes.INIT_OTP_ERROR);
620
661
  }
621
662
  return initOtpRes.otpId;
622
- }
623
- catch (error) {
624
- if (error instanceof TurnkeyNetworkError) {
625
- if (error.message.includes("Max number of OTPs have been initiated")) {
626
- throw new TurnkeyError("Max number of OTPs have been initiated", TurnkeyErrorCodes.MAX_OTP_INITIATED_ERROR);
627
- }
628
- }
629
- if (error instanceof TurnkeyError)
630
- throw error;
631
- throw new TurnkeyError(`Failed to initialize OTP`, TurnkeyErrorCodes.INIT_OTP_ERROR, error);
632
- }
663
+ }, {
664
+ errorMessage: "Failed to initialize OTP",
665
+ errorCode: TurnkeyErrorCodes.INIT_OTP_ERROR,
666
+ customMessageByMessages: {
667
+ "Max number of OTPs have been initiated": {
668
+ message: "Maximum number of OTPs has been reached for this contact.",
669
+ code: TurnkeyErrorCodes.MAX_OTP_INITIATED_ERROR,
670
+ },
671
+ },
672
+ });
633
673
  };
634
674
  /**
635
675
  * Verifies the OTP code sent to the user.
@@ -650,7 +690,7 @@ class TurnkeyClient {
650
690
  */
651
691
  this.verifyOtp = async (params) => {
652
692
  const { otpId, otpCode, contact, otpType } = params;
653
- try {
693
+ return withTurnkeyErrorHandling(async () => {
654
694
  const verifyOtpRes = await this.httpClient.proxyVerifyOtp({
655
695
  otpId: otpId,
656
696
  otpCode: otpCode,
@@ -670,16 +710,16 @@ class TurnkeyClient {
670
710
  subOrganizationId: subOrganizationId,
671
711
  verificationToken: verifyOtpRes.verificationToken,
672
712
  };
673
- }
674
- catch (error) {
675
- if (error instanceof TurnkeyRequestError &&
676
- error.message.includes("Invalid OTP code")) {
677
- throw new TurnkeyError("Invalid OTP code provided", TurnkeyErrorCodes.INVALID_OTP_CODE, error.message);
678
- }
679
- else if (error instanceof TurnkeyError)
680
- throw error;
681
- throw new TurnkeyError(`Failed to verify OTP`, TurnkeyErrorCodes.VERIFY_OTP_ERROR, error);
682
- }
713
+ }, {
714
+ errorMessage: "Failed to verify OTP",
715
+ errorCode: TurnkeyErrorCodes.VERIFY_OTP_ERROR,
716
+ customMessageByMessages: {
717
+ "Invalid OTP code": {
718
+ message: "The provided OTP code is invalid.",
719
+ code: TurnkeyErrorCodes.INVALID_OTP_CODE,
720
+ },
721
+ },
722
+ });
683
723
  };
684
724
  /**
685
725
  * Logs in a user using an OTP verification token.
@@ -699,7 +739,7 @@ class TurnkeyClient {
699
739
  */
700
740
  this.loginWithOtp = async (params) => {
701
741
  const { verificationToken, invalidateExisting = false, publicKey = await this.apiKeyStamper?.createKeyPair(), sessionKey = SessionKey.DefaultSessionkey, } = params;
702
- try {
742
+ return withTurnkeyErrorHandling(async () => {
703
743
  const res = await this.httpClient.proxyOtpLogin({
704
744
  verificationToken,
705
745
  publicKey: publicKey,
@@ -717,21 +757,21 @@ class TurnkeyClient {
717
757
  sessionKey,
718
758
  });
719
759
  return loginRes.session;
720
- }
721
- catch (error) {
722
- if (error instanceof TurnkeyError)
723
- throw error;
724
- // Clean up the generated key pair if it wasn't successfully used
725
- if (publicKey) {
726
- try {
727
- await this.apiKeyStamper?.deleteKeyPair(publicKey);
728
- }
729
- catch (cleanupError) {
730
- throw new TurnkeyError(`Failed to clean up generated key pair`, TurnkeyErrorCodes.KEY_PAIR_CLEANUP_ERROR, cleanupError);
760
+ }, {
761
+ errorMessage: "Failed to log in with OTP",
762
+ errorCode: TurnkeyErrorCodes.OTP_LOGIN_ERROR,
763
+ catchFn: async () => {
764
+ // Clean up the generated key pair if it wasn't successfully used
765
+ if (publicKey) {
766
+ try {
767
+ await this.apiKeyStamper?.deleteKeyPair(publicKey);
768
+ }
769
+ catch (cleanupError) {
770
+ throw new TurnkeyError(`Failed to clean up generated key pair`, TurnkeyErrorCodes.KEY_PAIR_CLEANUP_ERROR, cleanupError);
771
+ }
731
772
  }
732
- }
733
- throw new TurnkeyError(`Failed to log in with OTP`, TurnkeyErrorCodes.OTP_LOGIN_ERROR, error);
734
- }
773
+ },
774
+ });
735
775
  };
736
776
  /**
737
777
  * Signs up a user using an OTP verification token.
@@ -762,8 +802,8 @@ class TurnkeyClient {
762
802
  verificationToken,
763
803
  },
764
804
  });
765
- const generatedKeyPair = await this.apiKeyStamper?.createKeyPair();
766
- try {
805
+ return withTurnkeyErrorHandling(async () => {
806
+ const generatedKeyPair = await this.apiKeyStamper?.createKeyPair();
767
807
  const res = await this.httpClient.proxySignup(signUpBody);
768
808
  if (!res) {
769
809
  throw new TurnkeyError(`Auth proxy OTP sign up failed`, TurnkeyErrorCodes.OTP_SIGNUP_ERROR);
@@ -774,12 +814,10 @@ class TurnkeyClient {
774
814
  ...(invalidateExisting && { invalidateExisting }),
775
815
  ...(sessionKey && { sessionKey }),
776
816
  });
777
- }
778
- catch (error) {
779
- if (error instanceof TurnkeyError)
780
- throw error;
781
- throw new TurnkeyError(`Failed to sign up with OTP`, TurnkeyErrorCodes.OTP_SIGNUP_ERROR, error);
782
- }
817
+ }, {
818
+ errorCode: TurnkeyErrorCodes.OTP_SIGNUP_ERROR,
819
+ errorMessage: "Failed to sign up with OTP",
820
+ });
783
821
  };
784
822
  /**
785
823
  * Completes the OTP authentication flow by verifying the OTP code and then either signing up or logging in the user.
@@ -803,7 +841,7 @@ class TurnkeyClient {
803
841
  */
804
842
  this.completeOtp = async (params) => {
805
843
  const { otpId, otpCode, contact, otpType, publicKey, invalidateExisting = false, sessionKey, createSubOrgParams, } = params;
806
- try {
844
+ return withTurnkeyErrorHandling(async () => {
807
845
  const { subOrganizationId, verificationToken } = await this.verifyOtp({
808
846
  otpId: otpId,
809
847
  otpCode: otpCode,
@@ -833,12 +871,10 @@ class TurnkeyClient {
833
871
  ...(sessionKey && { sessionKey }),
834
872
  });
835
873
  }
836
- }
837
- catch (error) {
838
- if (error instanceof TurnkeyError)
839
- throw error;
840
- throw new TurnkeyError(`Failed to complete OTP process`, TurnkeyErrorCodes.OTP_COMPLETION_ERROR, error);
841
- }
874
+ }, {
875
+ errorMessage: "Failed to complete OTP process",
876
+ errorCode: TurnkeyErrorCodes.OTP_COMPLETION_ERROR,
877
+ });
842
878
  };
843
879
  /**
844
880
  * Completes the OAuth authentication flow by either signing up or logging in the user, depending on whether a sub-organization already exists for the provided OIDC token.
@@ -860,7 +896,7 @@ class TurnkeyClient {
860
896
  */
861
897
  this.completeOauth = async (params) => {
862
898
  const { oidcToken, publicKey, createSubOrgParams, providerName = "OpenID Connect Provider" + Date.now(), sessionKey = SessionKey.DefaultSessionkey, invalidateExisting = false, } = params;
863
- try {
899
+ return withTurnkeyErrorHandling(async () => {
864
900
  const accountRes = await this.httpClient.proxyGetAccount({
865
901
  filterType: "OIDC_TOKEN",
866
902
  filterValue: oidcToken,
@@ -887,12 +923,10 @@ class TurnkeyClient {
887
923
  }),
888
924
  });
889
925
  }
890
- }
891
- catch (error) {
892
- if (error instanceof TurnkeyError)
893
- throw error;
894
- throw new TurnkeyError(`Failed to handle Google OAuth login`, TurnkeyErrorCodes.OAUTH_LOGIN_ERROR, error);
895
- }
926
+ }, {
927
+ errorMessage: "Failed to complete OAuth process",
928
+ errorCode: TurnkeyErrorCodes.OAUTH_LOGIN_ERROR,
929
+ });
896
930
  };
897
931
  /**
898
932
  * Logs in a user using OAuth authentication.
@@ -911,10 +945,10 @@ class TurnkeyClient {
911
945
  */
912
946
  this.loginWithOauth = async (params) => {
913
947
  const { oidcToken, invalidateExisting = false, publicKey, sessionKey = SessionKey.DefaultSessionkey, } = params;
914
- if (!publicKey) {
915
- throw new TurnkeyError("Public key must be provided to log in with OAuth. Please create a key pair first.", TurnkeyErrorCodes.MISSING_PARAMS);
916
- }
917
- try {
948
+ return withTurnkeyErrorHandling(async () => {
949
+ if (!publicKey) {
950
+ throw new TurnkeyError("Public key must be provided to log in with OAuth. Please create a key pair first.", TurnkeyErrorCodes.MISSING_PARAMS);
951
+ }
918
952
  const loginRes = await this.httpClient.proxyOAuthLogin({
919
953
  oidcToken,
920
954
  publicKey,
@@ -931,21 +965,27 @@ class TurnkeyClient {
931
965
  sessionKey,
932
966
  });
933
967
  return loginRes.session;
934
- }
935
- catch (error) {
936
- if (error instanceof TurnkeyError)
937
- throw error;
938
- // Clean up the generated key pair if it wasn't successfully used
939
- if (publicKey) {
940
- try {
941
- await this.apiKeyStamper?.deleteKeyPair(publicKey);
942
- }
943
- catch (cleanupError) {
944
- throw new TurnkeyError(`Failed to clean up generated key pair`, TurnkeyErrorCodes.KEY_PAIR_CLEANUP_ERROR, cleanupError);
968
+ }, {
969
+ errorMessage: "Failed to complete OAuth login",
970
+ errorCode: TurnkeyErrorCodes.OAUTH_LOGIN_ERROR,
971
+ customMessageByMessages: {
972
+ "OAUTH disallowed": {
973
+ message: "OAuth is disabled on the dashboard for this organization.",
974
+ code: TurnkeyErrorCodes.AUTH_METHOD_NOT_ENABLED,
975
+ },
976
+ },
977
+ catchFn: async () => {
978
+ // Clean up the generated key pair if it wasn't successfully used
979
+ if (publicKey) {
980
+ try {
981
+ await this.apiKeyStamper?.deleteKeyPair(publicKey);
982
+ }
983
+ catch (cleanupError) {
984
+ throw new TurnkeyError(`Failed to clean up generated key pair`, TurnkeyErrorCodes.KEY_PAIR_CLEANUP_ERROR, cleanupError);
985
+ }
945
986
  }
946
- }
947
- throw new TurnkeyError(`Failed to log in with oauth`, TurnkeyErrorCodes.OAUTH_LOGIN_ERROR, error);
948
- }
987
+ },
988
+ });
949
989
  };
950
990
  /**
951
991
  * Signs up a user using OAuth authentication.
@@ -965,7 +1005,7 @@ class TurnkeyClient {
965
1005
  */
966
1006
  this.signUpWithOauth = async (params) => {
967
1007
  const { oidcToken, publicKey, providerName, createSubOrgParams } = params;
968
- try {
1008
+ return withTurnkeyErrorHandling(async () => {
969
1009
  const signUpBody = buildSignUpBody({
970
1010
  createSubOrgParams: {
971
1011
  ...createSubOrgParams,
@@ -985,12 +1025,10 @@ class TurnkeyClient {
985
1025
  oidcToken,
986
1026
  publicKey: publicKey,
987
1027
  });
988
- }
989
- catch (error) {
990
- if (error instanceof TurnkeyError)
991
- throw error;
992
- throw new TurnkeyError(`Failed to sign up with OAuth`, TurnkeyErrorCodes.OAUTH_SIGNUP_ERROR, error);
993
- }
1028
+ }, {
1029
+ errorMessage: "Failed to sign up with OAuth",
1030
+ errorCode: TurnkeyErrorCodes.OAUTH_SIGNUP_ERROR,
1031
+ });
994
1032
  };
995
1033
  /**
996
1034
  * Fetches all wallets for the current user, including both embedded and connected wallets.
@@ -1006,12 +1044,12 @@ class TurnkeyClient {
1006
1044
  * @throws {TurnkeyError} If no active session is found or if there is an error fetching wallets.
1007
1045
  */
1008
1046
  this.fetchWallets = async (params) => {
1009
- const { stampWith } = params || {};
1047
+ const { stampWith, walletProviders } = params || {};
1010
1048
  const session = await this.storageManager.getActiveSession();
1011
1049
  if (!session) {
1012
1050
  throw new TurnkeyError("No active session found. Please log in first.", TurnkeyErrorCodes.NO_SESSION_FOUND);
1013
1051
  }
1014
- try {
1052
+ return withTurnkeyErrorHandling(async () => {
1015
1053
  const res = await this.httpClient.getWallets({ organizationId: session.organizationId }, stampWith);
1016
1054
  if (!res || !res.wallets) {
1017
1055
  throw new TurnkeyError("No wallets found in the response", TurnkeyErrorCodes.BAD_RESPONSE);
@@ -1032,10 +1070,11 @@ class TurnkeyClient {
1032
1070
  // if wallet connecting is disabled we return only embedded wallets
1033
1071
  if (!this.walletManager?.connector)
1034
1072
  return embedded;
1035
- const providers = await this.getWalletProviders();
1073
+ const providers = walletProviders ?? (await this.getWalletProviders());
1036
1074
  const groupedProviders = new Map();
1037
1075
  for (const provider of providers) {
1038
- const walletId = provider.info?.name?.toLowerCase().replace(/\s+/g, "-") || "unknown";
1076
+ const walletId = provider.info?.name?.toLowerCase().replace(/\s+/g, "-") ||
1077
+ "unknown";
1039
1078
  const group = groupedProviders.get(walletId) || [];
1040
1079
  group.push(provider);
1041
1080
  groupedProviders.set(walletId, group);
@@ -1061,12 +1100,10 @@ class TurnkeyClient {
1061
1100
  return wallet;
1062
1101
  }))).filter((wallet) => wallet.accounts.length > 0);
1063
1102
  return [...embedded, ...connected];
1064
- }
1065
- catch (error) {
1066
- if (error instanceof TurnkeyError)
1067
- throw error;
1068
- throw new TurnkeyError("Failed to fetch wallets", TurnkeyErrorCodes.FETCH_WALLETS_ERROR, error);
1069
- }
1103
+ }, {
1104
+ errorMessage: "Failed to fetch wallets",
1105
+ errorCode: TurnkeyErrorCodes.FETCH_WALLETS_ERROR,
1106
+ });
1070
1107
  };
1071
1108
  /**
1072
1109
  * Fetches all accounts for a specific wallet, including both embedded and connected wallet accounts.
@@ -1090,58 +1127,90 @@ class TurnkeyClient {
1090
1127
  if (!session) {
1091
1128
  throw new TurnkeyError("No active session found. Please log in first.", TurnkeyErrorCodes.NO_SESSION_FOUND);
1092
1129
  }
1093
- // this is an embedded wallet so we fetch accounts from Turnkey
1094
- if (wallet.source === WalletSource.Embedded) {
1095
- const embedded = [];
1096
- const res = await this.httpClient.getWalletAccounts({
1097
- walletId: wallet.walletId,
1098
- organizationId: session.organizationId,
1099
- paginationOptions: paginationOptions || { limit: "100" },
1100
- }, stampWith);
1101
- if (!res || !res.accounts) {
1102
- throw new TurnkeyError("No wallet accounts found in the response", TurnkeyErrorCodes.BAD_RESPONSE);
1103
- }
1104
- for (const account of res.accounts) {
1105
- embedded.push({
1106
- ...account,
1107
- source: WalletSource.Embedded,
1108
- });
1109
- }
1110
- return embedded;
1111
- }
1112
- // this is an external wallet so we fetch accounts from the connected wallet provider
1113
- // if wallet connecting is disabled we return only embedded wallets
1114
- // we should never reach this point if wallet connecting is disabled
1115
- if (!this.walletManager?.connector)
1116
- return [];
1117
- const connected = [];
1118
- const providers = walletProviders ?? (await this.getWalletProviders());
1119
- const matching = providers.filter((p) => p.info?.name?.toLowerCase().replace(/\s+/g, "-") === wallet.walletId &&
1120
- p.connectedAddresses.length > 0);
1121
- for (const provider of matching) {
1122
- const timestamp = toExternalTimestamp();
1123
- for (const address of provider.connectedAddresses) {
1124
- const account = {
1125
- walletAccountId: `${wallet.walletId}-${provider.interfaceType}-${address}`,
1126
- organizationId: session.organizationId,
1130
+ return withTurnkeyErrorHandling(async () => {
1131
+ // this is an embedded wallet so we fetch accounts from Turnkey
1132
+ if (wallet.source === WalletSource.Embedded) {
1133
+ const embedded = [];
1134
+ const res = await this.httpClient.getWalletAccounts({
1127
1135
  walletId: wallet.walletId,
1128
- curve: isEthereumWallet(provider) ? Curve.SECP256K1 : Curve.ED25519,
1129
- pathFormat: "PATH_FORMAT_BIP32",
1130
- path: WalletSource.Connected,
1131
- source: WalletSource.Connected,
1132
- addressFormat: isEthereumWallet(provider)
1133
- ? "ADDRESS_FORMAT_ETHEREUM"
1134
- : "ADDRESS_FORMAT_SOLANA",
1135
- address,
1136
- createdAt: timestamp,
1137
- updatedAt: timestamp,
1138
- ...getWalletAccountMethods(this.walletManager.connector.sign.bind(this.walletManager.connector), provider),
1139
- ...(isSolanaWallet(provider) && { publicKey: address }),
1140
- };
1141
- connected.push(account);
1136
+ organizationId: session.organizationId,
1137
+ paginationOptions: paginationOptions || { limit: "100" },
1138
+ }, stampWith);
1139
+ if (!res || !res.accounts) {
1140
+ throw new TurnkeyError("No wallet accounts found in the response", TurnkeyErrorCodes.BAD_RESPONSE);
1141
+ }
1142
+ for (const account of res.accounts) {
1143
+ embedded.push({
1144
+ ...account,
1145
+ source: WalletSource.Embedded,
1146
+ });
1147
+ }
1148
+ return embedded;
1142
1149
  }
1143
- }
1144
- return connected;
1150
+ // this is an external wallet so we fetch accounts from the connected wallet provider
1151
+ // if wallet connecting is disabled we return only embedded wallets
1152
+ // we should never reach this point if wallet connecting is disabled
1153
+ if (!this.walletManager?.connector)
1154
+ return [];
1155
+ const connected = [];
1156
+ const providers = walletProviders ?? (await this.getWalletProviders());
1157
+ const matching = providers.filter((p) => p.info?.name?.toLowerCase().replace(/\s+/g, "-") ===
1158
+ wallet.walletId && p.connectedAddresses.length > 0);
1159
+ const sign = this.walletManager.connector.sign.bind(this.walletManager.connector);
1160
+ for (const provider of matching) {
1161
+ const timestamp = toExternalTimestamp();
1162
+ for (const address of provider.connectedAddresses) {
1163
+ if (isEthereumProvider(provider)) {
1164
+ const evmAccount = {
1165
+ walletAccountId: `${wallet.walletId}-${provider.interfaceType}-${address}`,
1166
+ organizationId: session.organizationId,
1167
+ walletId: wallet.walletId,
1168
+ pathFormat: "PATH_FORMAT_BIP32",
1169
+ path: WalletSource.Connected,
1170
+ source: WalletSource.Connected,
1171
+ address,
1172
+ createdAt: timestamp,
1173
+ updatedAt: timestamp,
1174
+ // ethereum specific
1175
+ curve: Curve.SECP256K1,
1176
+ addressFormat: "ADDRESS_FORMAT_ETHEREUM",
1177
+ chainInfo: provider.chainInfo,
1178
+ signMessage: (msg) => sign(msg, provider, SignIntent.SignMessage),
1179
+ signAndSendTransaction: (tx) => sign(tx, provider, SignIntent.SignAndSendTransaction),
1180
+ };
1181
+ connected.push(evmAccount);
1182
+ continue;
1183
+ }
1184
+ if (isSolanaProvider(provider)) {
1185
+ const solAccount = {
1186
+ walletAccountId: `${wallet.walletId}-${provider.interfaceType}-${address}`,
1187
+ organizationId: session.organizationId,
1188
+ walletId: wallet.walletId,
1189
+ pathFormat: "PATH_FORMAT_BIP32",
1190
+ path: WalletSource.Connected,
1191
+ source: WalletSource.Connected,
1192
+ address,
1193
+ createdAt: timestamp,
1194
+ updatedAt: timestamp,
1195
+ // solana specific
1196
+ publicKey: address,
1197
+ curve: Curve.ED25519,
1198
+ addressFormat: "ADDRESS_FORMAT_SOLANA",
1199
+ chainInfo: provider.chainInfo,
1200
+ signMessage: (msg) => sign(msg, provider, SignIntent.SignMessage),
1201
+ signTransaction: (tx) => sign(tx, provider, SignIntent.SignTransaction),
1202
+ };
1203
+ connected.push(solAccount);
1204
+ continue;
1205
+ }
1206
+ throw new Error(`Unsupported wallet chain: ${provider.chainInfo}. Supported chains are Ethereum and Solana.`);
1207
+ }
1208
+ }
1209
+ return connected;
1210
+ }, {
1211
+ errorMessage: "Failed to fetch wallet accounts",
1212
+ errorCode: TurnkeyErrorCodes.FETCH_WALLET_ACCOUNTS_ERROR,
1213
+ });
1145
1214
  };
1146
1215
  /**
1147
1216
  * Signs a message using the specified wallet account.
@@ -1175,7 +1244,7 @@ class TurnkeyClient {
1175
1244
  const { message, walletAccount, stampWith, addEthereumPrefix } = params;
1176
1245
  const hashFunction = params.hashFunction || getHashFunction(walletAccount.addressFormat);
1177
1246
  const payloadEncoding = params.encoding || getEncodingType(walletAccount.addressFormat);
1178
- try {
1247
+ return withTurnkeyErrorHandling(async () => {
1179
1248
  const isEthereum = walletAccount.addressFormat === "ADDRESS_FORMAT_ETHEREUM";
1180
1249
  if (walletAccount.source === WalletSource.Connected) {
1181
1250
  // this is a connected wallet
@@ -1207,12 +1276,10 @@ class TurnkeyClient {
1207
1276
  }
1208
1277
  return response.activity.result
1209
1278
  .signRawPayloadResult;
1210
- }
1211
- catch (error) {
1212
- if (error instanceof TurnkeyError)
1213
- throw error;
1214
- throw new TurnkeyError(`Failed to sign message - ${error?.message ? error.message : "Unknown error"}`, TurnkeyErrorCodes.SIGN_MESSAGE_ERROR);
1215
- }
1279
+ }, {
1280
+ errorMessage: "Failed to sign message",
1281
+ errorCode: TurnkeyErrorCodes.SIGN_MESSAGE_ERROR,
1282
+ });
1216
1283
  };
1217
1284
  /**
1218
1285
  * Signs a transaction using the specified wallet account.
@@ -1232,17 +1299,18 @@ class TurnkeyClient {
1232
1299
  */
1233
1300
  this.signTransaction = async (params) => {
1234
1301
  const { walletAccount, unsignedTransaction, transactionType, stampWith } = params;
1235
- try {
1302
+ return withTurnkeyErrorHandling(async () => {
1236
1303
  if (walletAccount.source === WalletSource.Connected) {
1237
- // this is a connected wallet account
1238
- if (!walletAccount.signTransaction) {
1239
- const isEthereum = walletAccount.addressFormat === "ADDRESS_FORMAT_ETHEREUM";
1240
- const reason = isEthereum
1241
- ? "Ethereum connected wallets do not support raw transaction signing due to EIP-1193 limitations."
1242
- : "This connected wallet does not support raw transaction signing.";
1243
- throw new TurnkeyError(`Failed to sign transaction: ${reason} ${isEthereum ? "Use signAndSendTransaction instead." : ""}`, TurnkeyErrorCodes.SIGN_TRANSACTION_ERROR);
1304
+ switch (walletAccount.chainInfo.namespace) {
1305
+ case Chain.Ethereum:
1306
+ throw new TurnkeyError("Ethereum connected wallets do not support raw transaction signing. Use signAndSendTransaction instead.", TurnkeyErrorCodes.INVALID_REQUEST);
1307
+ case Chain.Solana:
1308
+ // not sure why typescript isn't inferring the type here
1309
+ // if namespace is Chain.Solana, then it must be a ConnectedSolanaWalletAccount
1310
+ return walletAccount.signTransaction(unsignedTransaction);
1311
+ default:
1312
+ throw new TurnkeyError("Unsupported connected wallet type.", TurnkeyErrorCodes.INVALID_REQUEST);
1244
1313
  }
1245
- return await walletAccount?.signTransaction(unsignedTransaction);
1246
1314
  }
1247
1315
  // this is an embedded wallet account
1248
1316
  const signTransaction = await this.httpClient.signTransaction({
@@ -1251,12 +1319,10 @@ class TurnkeyClient {
1251
1319
  type: transactionType,
1252
1320
  }, stampWith);
1253
1321
  return signTransaction.signedTransaction;
1254
- }
1255
- catch (error) {
1256
- if (error instanceof TurnkeyError)
1257
- throw error;
1258
- throw new TurnkeyError(`Failed to sign transaction`, TurnkeyErrorCodes.SIGN_TRANSACTION_ERROR, error);
1259
- }
1322
+ }, {
1323
+ errorMessage: "Failed to sign transaction",
1324
+ errorCode: TurnkeyErrorCodes.SIGN_TRANSACTION_ERROR,
1325
+ });
1260
1326
  };
1261
1327
  /**
1262
1328
  * Signs and broadcasts a transaction using the specified wallet account.
@@ -1280,22 +1346,20 @@ class TurnkeyClient {
1280
1346
  */
1281
1347
  this.signAndSendTransaction = async (params) => {
1282
1348
  const { walletAccount, unsignedTransaction, transactionType, rpcUrl, stampWith, } = params;
1283
- try {
1349
+ return withTurnkeyErrorHandling(async () => {
1284
1350
  if (walletAccount.source === WalletSource.Connected) {
1285
1351
  // this is a connected wallet account
1286
- switch (transactionType) {
1287
- case "TRANSACTION_TYPE_ETHEREUM":
1288
- if (!walletAccount.signAndSendTransaction) {
1289
- throw new TurnkeyError("This connected wallet does not support signAndSendTransaction.", TurnkeyErrorCodes.SIGN_AND_SEND_TRANSACTION_ERROR);
1290
- }
1352
+ switch (walletAccount.chainInfo.namespace) {
1353
+ case Chain.Ethereum:
1354
+ // not sure why typescript isn't inferring the type here
1355
+ // if namespace is Chain.Ethereum, then it must be a ConnectedEthereumWalletAccount
1291
1356
  return await walletAccount.signAndSendTransaction(unsignedTransaction);
1292
- case "TRANSACTION_TYPE_SOLANA":
1357
+ case Chain.Solana:
1293
1358
  if (!rpcUrl) {
1294
1359
  throw new TurnkeyError("Missing rpcUrl: connected Solana wallets require an RPC URL to broadcast transactions.", TurnkeyErrorCodes.SIGN_AND_SEND_TRANSACTION_ERROR);
1295
1360
  }
1296
- if (!walletAccount.signTransaction) {
1297
- throw new TurnkeyError("This connected wallet does not support signAndSendTransaction.", TurnkeyErrorCodes.SIGN_AND_SEND_TRANSACTION_ERROR);
1298
- }
1361
+ // not sure why typescript isn't inferring the type here
1362
+ // if namespace is Chain.Solana, then it must be a ConnectedSolanaWalletAccount
1299
1363
  const signature = await walletAccount.signTransaction(unsignedTransaction);
1300
1364
  return await broadcastTransaction({
1301
1365
  signedTransaction: signature,
@@ -1324,12 +1388,10 @@ class TurnkeyClient {
1324
1388
  transactionType,
1325
1389
  });
1326
1390
  return txHash;
1327
- }
1328
- catch (error) {
1329
- if (error instanceof TurnkeyError)
1330
- throw error;
1331
- throw new TurnkeyError(`Failed to sign and send transaction`, TurnkeyErrorCodes.SIGN_AND_SEND_TRANSACTION_ERROR, error);
1332
- }
1391
+ }, {
1392
+ errorMessage: "Failed to sign and send transaction",
1393
+ errorCode: TurnkeyErrorCodes.SIGN_AND_SEND_TRANSACTION_ERROR,
1394
+ });
1333
1395
  };
1334
1396
  /**
1335
1397
  * Fetches the user details for the current session or a specified user.
@@ -1357,18 +1419,16 @@ class TurnkeyClient {
1357
1419
  throw new TurnkeyError("User ID must be provided to fetch user", TurnkeyErrorCodes.INVALID_REQUEST);
1358
1420
  }
1359
1421
  const organizationId = params?.organizationId || session.organizationId;
1360
- try {
1422
+ return withTurnkeyErrorHandling(async () => {
1361
1423
  const userResponse = await this.httpClient.getUser({ organizationId, userId }, stampWith);
1362
1424
  if (!userResponse || !userResponse.user) {
1363
1425
  throw new TurnkeyError("No user found in the response", TurnkeyErrorCodes.BAD_RESPONSE);
1364
1426
  }
1365
1427
  return userResponse.user;
1366
- }
1367
- catch (error) {
1368
- if (error instanceof TurnkeyError)
1369
- throw error;
1370
- throw new TurnkeyError(`Failed to fetch user`, TurnkeyErrorCodes.FETCH_USER_ERROR, error);
1371
- }
1428
+ }, {
1429
+ errorMessage: "Failed to fetch user",
1430
+ errorCode: TurnkeyErrorCodes.FETCH_USER_ERROR,
1431
+ });
1372
1432
  };
1373
1433
  /**
1374
1434
  * Updates the user's email address.
@@ -1393,7 +1453,7 @@ class TurnkeyClient {
1393
1453
  throw new TurnkeyError("No active session found. Please log in first.", TurnkeyErrorCodes.NO_SESSION_FOUND);
1394
1454
  }
1395
1455
  const userId = params?.userId || session.userId;
1396
- try {
1456
+ return withTurnkeyErrorHandling(async () => {
1397
1457
  const existingUser = await this.httpClient.proxyGetAccount({
1398
1458
  filterType: FilterType.Email,
1399
1459
  filterValue: email,
@@ -1410,12 +1470,10 @@ class TurnkeyClient {
1410
1470
  throw new TurnkeyError("No user ID found in the update user email response", TurnkeyErrorCodes.BAD_RESPONSE);
1411
1471
  }
1412
1472
  return res.userId;
1413
- }
1414
- catch (error) {
1415
- if (error instanceof TurnkeyError)
1416
- throw error;
1417
- throw new TurnkeyError(`Failed to update user email`, TurnkeyErrorCodes.UPDATE_USER_EMAIL_ERROR, error);
1418
- }
1473
+ }, {
1474
+ errorMessage: "Failed to update user email",
1475
+ errorCode: TurnkeyErrorCodes.UPDATE_USER_EMAIL_ERROR,
1476
+ });
1419
1477
  };
1420
1478
  /**
1421
1479
  * Removes the user's email address.
@@ -1436,15 +1494,20 @@ class TurnkeyClient {
1436
1494
  if (!session) {
1437
1495
  throw new TurnkeyError("No active session found. Please log in first.", TurnkeyErrorCodes.NO_SESSION_FOUND);
1438
1496
  }
1439
- const userId = params?.userId || session.userId;
1440
- const res = await this.httpClient.updateUserEmail({
1441
- userId: userId,
1442
- userEmail: "",
1443
- }, stampWith);
1444
- if (!res || !res.userId) {
1445
- throw new TurnkeyError("No user ID found in the remove user email response", TurnkeyErrorCodes.BAD_RESPONSE);
1446
- }
1447
- return res.userId;
1497
+ return withTurnkeyErrorHandling(async () => {
1498
+ const userId = params?.userId || session.userId;
1499
+ const res = await this.httpClient.updateUserEmail({
1500
+ userId: userId,
1501
+ userEmail: "",
1502
+ }, stampWith);
1503
+ if (!res || !res.userId) {
1504
+ throw new TurnkeyError("No user ID found in the remove user email response", TurnkeyErrorCodes.BAD_RESPONSE);
1505
+ }
1506
+ return res.userId;
1507
+ }, {
1508
+ errorMessage: "Failed to remove user email",
1509
+ errorCode: TurnkeyErrorCodes.UPDATE_USER_EMAIL_ERROR,
1510
+ });
1448
1511
  };
1449
1512
  /**
1450
1513
  * Updates the user's phone number.
@@ -1469,7 +1532,7 @@ class TurnkeyClient {
1469
1532
  throw new TurnkeyError("No active session found. Please log in first.", TurnkeyErrorCodes.NO_SESSION_FOUND);
1470
1533
  }
1471
1534
  const userId = params?.userId || session.userId;
1472
- try {
1535
+ return withTurnkeyErrorHandling(async () => {
1473
1536
  const res = await this.httpClient.updateUserPhoneNumber({
1474
1537
  userId,
1475
1538
  userPhoneNumber: phoneNumber,
@@ -1479,12 +1542,10 @@ class TurnkeyClient {
1479
1542
  throw new TurnkeyError("Failed to update user phone number", TurnkeyErrorCodes.UPDATE_USER_PHONE_NUMBER_ERROR);
1480
1543
  }
1481
1544
  return res.userId;
1482
- }
1483
- catch (error) {
1484
- if (error instanceof TurnkeyError)
1485
- throw error;
1486
- throw new TurnkeyError(`Failed to update user phone number`, TurnkeyErrorCodes.UPDATE_USER_PHONE_NUMBER_ERROR, error);
1487
- }
1545
+ }, {
1546
+ errorMessage: "Failed to update user phone number",
1547
+ errorCode: TurnkeyErrorCodes.UPDATE_USER_PHONE_NUMBER_ERROR,
1548
+ });
1488
1549
  };
1489
1550
  /**
1490
1551
  * Removes the user's phone number.
@@ -1506,14 +1567,19 @@ class TurnkeyClient {
1506
1567
  throw new TurnkeyError("No active session found. Please log in first.", TurnkeyErrorCodes.NO_SESSION_FOUND);
1507
1568
  }
1508
1569
  const userId = params?.userId || session.userId;
1509
- const res = await this.httpClient.updateUserPhoneNumber({
1510
- userId,
1511
- userPhoneNumber: "",
1512
- }, stampWith);
1513
- if (!res || !res.userId) {
1514
- throw new TurnkeyError("Failed to remove user phone number", TurnkeyErrorCodes.UPDATE_USER_PHONE_NUMBER_ERROR);
1515
- }
1516
- return res.userId;
1570
+ return withTurnkeyErrorHandling(async () => {
1571
+ const res = await this.httpClient.updateUserPhoneNumber({
1572
+ userId,
1573
+ userPhoneNumber: "",
1574
+ }, stampWith);
1575
+ if (!res || !res.userId) {
1576
+ throw new TurnkeyError("Failed to remove user phone number", TurnkeyErrorCodes.UPDATE_USER_PHONE_NUMBER_ERROR);
1577
+ }
1578
+ return res.userId;
1579
+ }, {
1580
+ errorMessage: "Failed to remove user phone number",
1581
+ errorCode: TurnkeyErrorCodes.UPDATE_USER_PHONE_NUMBER_ERROR,
1582
+ });
1517
1583
  };
1518
1584
  /**
1519
1585
  * Updates the user's name.
@@ -1537,7 +1603,7 @@ class TurnkeyClient {
1537
1603
  throw new TurnkeyError("No active session found. Please log in first.", TurnkeyErrorCodes.NO_SESSION_FOUND);
1538
1604
  }
1539
1605
  const userId = params?.userId || session.userId;
1540
- try {
1606
+ return withTurnkeyErrorHandling(async () => {
1541
1607
  const res = await this.httpClient.updateUserName({
1542
1608
  userId,
1543
1609
  userName,
@@ -1546,12 +1612,10 @@ class TurnkeyClient {
1546
1612
  throw new TurnkeyError("No user ID found in the update user name response", TurnkeyErrorCodes.BAD_RESPONSE);
1547
1613
  }
1548
1614
  return res.userId;
1549
- }
1550
- catch (error) {
1551
- if (error instanceof TurnkeyError)
1552
- throw error;
1553
- throw new TurnkeyError(`Failed to update user name`, TurnkeyErrorCodes.UPDATE_USER_NAME_ERROR, error);
1554
- }
1615
+ }, {
1616
+ errorMessage: "Failed to update user name",
1617
+ errorCode: TurnkeyErrorCodes.UPDATE_USER_NAME_ERROR,
1618
+ });
1555
1619
  };
1556
1620
  /**
1557
1621
  * Adds an OAuth provider to the user.
@@ -1576,7 +1640,7 @@ class TurnkeyClient {
1576
1640
  if (!session) {
1577
1641
  throw new TurnkeyError("No active session found. Please log in first.", TurnkeyErrorCodes.NO_SESSION_FOUND);
1578
1642
  }
1579
- try {
1643
+ return withTurnkeyErrorHandling(async () => {
1580
1644
  const accountRes = await this.httpClient.proxyGetAccount({
1581
1645
  filterType: "OIDC_TOKEN",
1582
1646
  filterValue: oidcToken,
@@ -1620,12 +1684,10 @@ class TurnkeyClient {
1620
1684
  throw new TurnkeyError("Failed to create OAuth provider", TurnkeyErrorCodes.ADD_OAUTH_PROVIDER_ERROR);
1621
1685
  }
1622
1686
  return createProviderRes?.providerIds || [];
1623
- }
1624
- catch (error) {
1625
- if (error instanceof TurnkeyError)
1626
- throw error;
1627
- throw new TurnkeyError(`Failed to fetch account for OAuth provider`, TurnkeyErrorCodes.ACCOUNT_FETCH_ERROR, error);
1628
- }
1687
+ }, {
1688
+ errorMessage: "Failed to add OAuth provider",
1689
+ errorCode: TurnkeyErrorCodes.ADD_OAUTH_PROVIDER_ERROR,
1690
+ });
1629
1691
  };
1630
1692
  /**
1631
1693
  * Removes a list of OAuth providers from the user.
@@ -1649,14 +1711,19 @@ class TurnkeyClient {
1649
1711
  throw new TurnkeyError("No active session found. Please log in first.", TurnkeyErrorCodes.NO_SESSION_FOUND);
1650
1712
  }
1651
1713
  const userId = params?.userId || session.userId;
1652
- const res = await this.httpClient.deleteOauthProviders({
1653
- userId,
1654
- providerIds,
1655
- }, stampWith);
1656
- if (!res) {
1657
- throw new TurnkeyError("Failed to remove OAuth provider", TurnkeyErrorCodes.REMOVE_OAUTH_PROVIDER_ERROR);
1658
- }
1659
- return res.providerIds;
1714
+ return withTurnkeyErrorHandling(async () => {
1715
+ const res = await this.httpClient.deleteOauthProviders({
1716
+ userId,
1717
+ providerIds,
1718
+ }, stampWith);
1719
+ if (!res) {
1720
+ throw new TurnkeyError("Failed to remove OAuth provider", TurnkeyErrorCodes.REMOVE_OAUTH_PROVIDER_ERROR);
1721
+ }
1722
+ return res.providerIds;
1723
+ }, {
1724
+ errorMessage: "Failed to remove OAuth provider",
1725
+ errorCode: TurnkeyErrorCodes.REMOVE_OAUTH_PROVIDER_ERROR,
1726
+ });
1660
1727
  };
1661
1728
  /**
1662
1729
  * Adds a new passkey authenticator for the user.
@@ -1678,7 +1745,7 @@ class TurnkeyClient {
1678
1745
  const { stampWith } = params || {};
1679
1746
  const name = params?.name || `Turnkey Passkey-${Date.now()}`;
1680
1747
  const displayName = params?.displayName || name;
1681
- try {
1748
+ return withTurnkeyErrorHandling(async () => {
1682
1749
  const session = await this.storageManager.getActiveSession();
1683
1750
  if (!session) {
1684
1751
  throw new TurnkeyError("No active session found. Please log in first.", TurnkeyErrorCodes.NO_SESSION_FOUND);
@@ -1703,12 +1770,10 @@ class TurnkeyClient {
1703
1770
  ],
1704
1771
  }, stampWith);
1705
1772
  return res?.authenticatorIds || [];
1706
- }
1707
- catch (error) {
1708
- if (error instanceof TurnkeyError)
1709
- throw error;
1710
- throw new TurnkeyError(`Failed to add passkey`, TurnkeyErrorCodes.ADD_PASSKEY_ERROR, error);
1711
- }
1773
+ }, {
1774
+ errorMessage: "Failed to add passkey",
1775
+ errorCode: TurnkeyErrorCodes.ADD_PASSKEY_ERROR,
1776
+ });
1712
1777
  };
1713
1778
  /**
1714
1779
  * Removes passkeys (authenticator) from the user.
@@ -1732,14 +1797,19 @@ class TurnkeyClient {
1732
1797
  throw new TurnkeyError("No active session found. Please log in first.", TurnkeyErrorCodes.NO_SESSION_FOUND);
1733
1798
  }
1734
1799
  const userId = params?.userId || session.userId;
1735
- const res = await this.httpClient.deleteAuthenticators({
1736
- userId,
1737
- authenticatorIds,
1738
- }, stampWith);
1739
- if (!res) {
1740
- throw new TurnkeyError("Failed to remove passkey", TurnkeyErrorCodes.REMOVE_PASSKEY_ERROR);
1741
- }
1742
- return res.authenticatorIds;
1800
+ return withTurnkeyErrorHandling(async () => {
1801
+ const res = await this.httpClient.deleteAuthenticators({
1802
+ userId,
1803
+ authenticatorIds,
1804
+ }, stampWith);
1805
+ if (!res) {
1806
+ throw new TurnkeyError("No response found in the remove passkey response", TurnkeyErrorCodes.REMOVE_PASSKEY_ERROR);
1807
+ }
1808
+ return res.authenticatorIds;
1809
+ }, {
1810
+ errorMessage: "Failed to remove passkey",
1811
+ errorCode: TurnkeyErrorCodes.REMOVE_PASSKEY_ERROR,
1812
+ });
1743
1813
  };
1744
1814
  /**
1745
1815
  * Creates a new wallet for sub-organization.
@@ -1778,7 +1848,7 @@ class TurnkeyClient {
1778
1848
  ...DEFAULT_SOLANA_ACCOUNTS,
1779
1849
  ];
1780
1850
  }
1781
- try {
1851
+ return withTurnkeyErrorHandling(async () => {
1782
1852
  const res = await this.httpClient.createWallet({
1783
1853
  organizationId: organizationId || session.organizationId,
1784
1854
  walletName,
@@ -1789,12 +1859,10 @@ class TurnkeyClient {
1789
1859
  throw new TurnkeyError("No wallet found in the create wallet response", TurnkeyErrorCodes.BAD_RESPONSE);
1790
1860
  }
1791
1861
  return res.walletId;
1792
- }
1793
- catch (error) {
1794
- if (error instanceof TurnkeyError)
1795
- throw error;
1796
- throw new TurnkeyError(`Failed to create wallet`, TurnkeyErrorCodes.CREATE_WALLET_ERROR, error);
1797
- }
1862
+ }, {
1863
+ errorMessage: "Failed to create wallet",
1864
+ errorCode: TurnkeyErrorCodes.CREATE_WALLET_ERROR,
1865
+ });
1798
1866
  };
1799
1867
  /**
1800
1868
  * Creates new accounts in the specified wallet.
@@ -1819,7 +1887,7 @@ class TurnkeyClient {
1819
1887
  if (!session) {
1820
1888
  throw new TurnkeyError("No active session found. Please log in first.", TurnkeyErrorCodes.NO_SESSION_FOUND);
1821
1889
  }
1822
- try {
1890
+ return withTurnkeyErrorHandling(async () => {
1823
1891
  let walletAccounts = [];
1824
1892
  if (accounts && !isWalletAccountArray(accounts)) {
1825
1893
  // Query existing wallet accounts to avoid duplicates
@@ -1845,12 +1913,10 @@ class TurnkeyClient {
1845
1913
  throw new TurnkeyError("No account found in the create wallet account response", TurnkeyErrorCodes.BAD_RESPONSE);
1846
1914
  }
1847
1915
  return res.addresses;
1848
- }
1849
- catch (error) {
1850
- if (error instanceof TurnkeyError)
1851
- throw error;
1852
- throw new TurnkeyError(`Failed to create wallet account`, TurnkeyErrorCodes.CREATE_WALLET_ACCOUNT_ERROR, error);
1853
- }
1916
+ }, {
1917
+ errorMessage: "Failed to create wallet account",
1918
+ errorCode: TurnkeyErrorCodes.CREATE_WALLET_ACCOUNT_ERROR,
1919
+ });
1854
1920
  };
1855
1921
  /**
1856
1922
  * Exports a wallet as an encrypted bundle.
@@ -1875,7 +1941,7 @@ class TurnkeyClient {
1875
1941
  if (!session) {
1876
1942
  throw new TurnkeyError("No active session found. Please log in first.", TurnkeyErrorCodes.NO_SESSION_FOUND);
1877
1943
  }
1878
- try {
1944
+ return withTurnkeyErrorHandling(async () => {
1879
1945
  const res = await this.httpClient.exportWallet({
1880
1946
  walletId,
1881
1947
  targetPublicKey,
@@ -1885,12 +1951,85 @@ class TurnkeyClient {
1885
1951
  throw new TurnkeyError("No export bundle found in the response", TurnkeyErrorCodes.BAD_RESPONSE);
1886
1952
  }
1887
1953
  return res.exportBundle;
1954
+ }, {
1955
+ errorMessage: "Failed to export wallet",
1956
+ errorCode: TurnkeyErrorCodes.EXPORT_WALLET_ERROR,
1957
+ });
1958
+ };
1959
+ /**
1960
+ * Exports a private key as an encrypted bundle.
1961
+ *
1962
+ * - This function exports the specified private key as an encrypted bundle, suitable for backup or transfer.
1963
+ * - The exported bundle contains the private key's key material, encrypted to the provided target public key.
1964
+ * - If a targetPublicKey is provided, the bundle will be encrypted to that public key; otherwise, an error will be thrown.
1965
+ * - If an organizationId is provided, the private key will be exported under that sub-organization; otherwise, the current session's organizationId is used.
1966
+ * - Optionally allows stamping the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
1967
+ *
1968
+ * @param params.privateKeyId - ID of the private key to export.
1969
+ * @param params.targetPublicKey - public key to encrypt the bundle to (required).
1970
+ * @param params.organizationId - organization ID to export the private key under a specific sub
1971
+ * @param params.stampWith - parameter to stamp the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
1972
+ * @returns A promise that resolves to an `ExportBundle` object containing the encrypted private key and metadata.
1973
+ * @throws {TurnkeyError} If there is no active session, if the targetPublicKey is missing, or if there is an error exporting the private key.
1974
+ */
1975
+ this.exportPrivateKey = async (params) => {
1976
+ const { privateKeyId, targetPublicKey, stampWith, organizationId } = params;
1977
+ const session = await this.storageManager.getActiveSession();
1978
+ if (!session) {
1979
+ throw new TurnkeyError("No active session found. Please log in first.", TurnkeyErrorCodes.NO_SESSION_FOUND);
1888
1980
  }
1889
- catch (error) {
1890
- if (error instanceof TurnkeyError)
1891
- throw error;
1892
- throw new TurnkeyError(`Failed to export wallet`, TurnkeyErrorCodes.EXPORT_WALLET_ERROR, error);
1981
+ return withTurnkeyErrorHandling(async () => {
1982
+ const res = await this.httpClient.exportPrivateKey({
1983
+ privateKeyId,
1984
+ targetPublicKey,
1985
+ organizationId: organizationId || session.organizationId,
1986
+ }, stampWith);
1987
+ if (!res.exportBundle) {
1988
+ throw new TurnkeyError("No export bundle found in the response", TurnkeyErrorCodes.BAD_RESPONSE);
1989
+ }
1990
+ return res.exportBundle;
1991
+ }, {
1992
+ errorMessage: "Failed to export private key",
1993
+ errorCode: TurnkeyErrorCodes.EXPORT_PRIVATE_KEY_ERROR,
1994
+ });
1995
+ };
1996
+ /**
1997
+ * Exports a wallet account as an encrypted bundle.
1998
+ *
1999
+ * - This function exports the specified wallet account as an encrypted bundle, suitable for backup or transfer.
2000
+ * - The exported bundle contains the wallet account's key material, encrypted to the provided target public key.
2001
+ * - If a targetPublicKey is provided, the bundle will be encrypted to that public key; otherwise, an error will be thrown.
2002
+ * - If an organizationId is provided, the wallet account will be exported under that sub-organization; otherwise, the current session's organizationId is used.
2003
+ * - Optionally allows stamping the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
2004
+ *
2005
+ * @param params.address - address of the wallet account to export.
2006
+ * @param params.targetPublicKey - public key to encrypt the bundle to.
2007
+ * @param params.organizationId - organization ID to export the wallet account under a specific sub-organization.
2008
+ * @param params.stampWith - parameter to stamp the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
2009
+ * @returns A promise that resolves to an `ExportBundle` object containing the encrypted wallet account and metadata.
2010
+ * @throws {TurnkeyError} If there is no active session, if the targetPublicKey is missing, or if there is an error exporting the wallet account.
2011
+ *
2012
+ */
2013
+ this.exportWalletAccount = async (params) => {
2014
+ const { address, targetPublicKey, stampWith, organizationId } = params;
2015
+ const session = await this.storageManager.getActiveSession();
2016
+ if (!session) {
2017
+ throw new TurnkeyError("No active session found. Please log in first.", TurnkeyErrorCodes.NO_SESSION_FOUND);
1893
2018
  }
2019
+ return withTurnkeyErrorHandling(async () => {
2020
+ const res = await this.httpClient.exportWalletAccount({
2021
+ address,
2022
+ targetPublicKey,
2023
+ organizationId: organizationId || session.organizationId,
2024
+ }, stampWith);
2025
+ if (!res.exportBundle) {
2026
+ throw new TurnkeyError("No export bundle found in the response", TurnkeyErrorCodes.BAD_RESPONSE);
2027
+ }
2028
+ return res.exportBundle;
2029
+ }, {
2030
+ errorMessage: "Failed to export wallet account",
2031
+ errorCode: TurnkeyErrorCodes.EXPORT_WALLET_ACCOUNT_ERROR,
2032
+ });
1894
2033
  };
1895
2034
  /**
1896
2035
  * Imports a wallet from an encrypted bundle.
@@ -1898,7 +2037,7 @@ class TurnkeyClient {
1898
2037
  * - This function imports a wallet using the provided encrypted bundle and creates accounts based on the provided parameters.
1899
2038
  * - If a userId is provided, the wallet will be imported for that specific user; otherwise, it uses the current session's userId.
1900
2039
  * - If an accounts array is provided, those accounts will be created in the imported wallet; otherwise, default Ethereum and Solana accounts will be created.
1901
- * - The encrypted bunlde MUST be encrypted to
2040
+ * - The encrypted bundle MUST be encrypted to
1902
2041
  * - Automatically ensures an active session exists before making the request.
1903
2042
  * - Optionally allows stamping the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
1904
2043
  *
@@ -1916,7 +2055,7 @@ class TurnkeyClient {
1916
2055
  if (!session) {
1917
2056
  throw new TurnkeyError("No active session found. Please log in first.", TurnkeyErrorCodes.NO_SESSION_FOUND);
1918
2057
  }
1919
- try {
2058
+ return withTurnkeyErrorHandling(async () => {
1920
2059
  const res = await this.httpClient.importWallet({
1921
2060
  organizationId: session.organizationId,
1922
2061
  userId: userId || session.userId,
@@ -1931,12 +2070,66 @@ class TurnkeyClient {
1931
2070
  throw new TurnkeyError("No wallet ID found in the import response", TurnkeyErrorCodes.BAD_RESPONSE);
1932
2071
  }
1933
2072
  return res.walletId;
2073
+ }, {
2074
+ errorMessage: "Failed to import wallet",
2075
+ errorCode: TurnkeyErrorCodes.IMPORT_WALLET_ERROR,
2076
+ customMessageByMessages: {
2077
+ "invalid mnemonic": {
2078
+ message: "Invalid mnemonic input",
2079
+ code: TurnkeyErrorCodes.BAD_REQUEST,
2080
+ },
2081
+ },
2082
+ });
2083
+ };
2084
+ /**
2085
+ * Imports a private key from an encrypted bundle.
2086
+ *
2087
+ * - This function imports a private key using the provided encrypted bundle.
2088
+ * - If a userId is provided, the private key will be imported for that specific user; otherwise, it uses the current session's userId.
2089
+ * - Requires address formats to
2090
+ * - Automatically infers the cryptographic curve used to generate the private key based on the address format (can be optionally overriden if needed).
2091
+ * - The encrypted bundle MUST be encrypted to ensure security.
2092
+ * - Automatically ensures an active session exists before making the request.
2093
+ * - Optionally allows stamping the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
2094
+ *
2095
+ * @param params.encryptedBundle - encrypted bundle containing the private key key material and metadata.
2096
+ * @param params.privateKeyName - name of the private key to create upon import.
2097
+ * @param params.curve - the cryptographic curve used to generate a given private key
2098
+ * @param params.addressFormat - address format of the private key to import.
2099
+ * @param params.userId - user ID to import the wallet for a specific user (defaults to the current session's userId).
2100
+ * @param params.stampWith - parameter to stamp the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
2101
+ * @returns A promise that resolves to the ID of the imported wallet.
2102
+ * @throws {TurnkeyError} If there is no active session, if the encrypted bundle is invalid, or if there is an error importing the wallet.
2103
+ */
2104
+ this.importPrivateKey = async (params) => {
2105
+ const { encryptedBundle, privateKeyName, addressFormats, curve, userId, stampWith, } = params;
2106
+ const session = await this.storageManager.getActiveSession();
2107
+ if (!session) {
2108
+ throw new TurnkeyError("No active session found. Please log in first.", TurnkeyErrorCodes.NO_SESSION_FOUND);
1934
2109
  }
1935
- catch (error) {
1936
- if (error instanceof TurnkeyError)
1937
- throw error;
1938
- throw new TurnkeyError(`Failed to import wallet`, TurnkeyErrorCodes.IMPORT_WALLET_ERROR, error);
1939
- }
2110
+ return withTurnkeyErrorHandling(async () => {
2111
+ const res = await this.httpClient.importPrivateKey({
2112
+ organizationId: session.organizationId,
2113
+ userId: userId || session.userId,
2114
+ encryptedBundle,
2115
+ privateKeyName,
2116
+ curve,
2117
+ addressFormats,
2118
+ }, stampWith);
2119
+ if (!res || !res.privateKeyId) {
2120
+ throw new TurnkeyError("No wallet ID found in the import response", TurnkeyErrorCodes.BAD_RESPONSE);
2121
+ }
2122
+ return res.privateKeyId;
2123
+ }, {
2124
+ errorMessage: "Failed to import wallet",
2125
+ errorCode: TurnkeyErrorCodes.IMPORT_WALLET_ERROR,
2126
+ customMessageByMessages: {
2127
+ "invalid mnemonic": {
2128
+ message: "Invalid mnemonic input",
2129
+ code: TurnkeyErrorCodes.BAD_REQUEST,
2130
+ },
2131
+ },
2132
+ });
1940
2133
  };
1941
2134
  /**
1942
2135
  * Deletes the current sub-organization (sub-org) for the active session.
@@ -1958,14 +2151,12 @@ class TurnkeyClient {
1958
2151
  if (!session) {
1959
2152
  throw new TurnkeyError("No active session found. Please log in first.", TurnkeyErrorCodes.NO_SESSION_FOUND);
1960
2153
  }
1961
- try {
2154
+ return withTurnkeyErrorHandling(async () => {
1962
2155
  return await this.httpClient.deleteSubOrganization({ deleteWithoutExport }, stampWith);
1963
- }
1964
- catch (error) {
1965
- if (error instanceof TurnkeyError)
1966
- throw error;
1967
- throw new TurnkeyError(`Failed to delete sub-organization`, TurnkeyErrorCodes.DELETE_SUB_ORGANIZATION_ERROR, error);
1968
- }
2156
+ }, {
2157
+ errorMessage: "Failed to delete sub-organization",
2158
+ errorCode: TurnkeyErrorCodes.DELETE_SUB_ORGANIZATION_ERROR,
2159
+ });
1969
2160
  };
1970
2161
  /**
1971
2162
  * Stores a session token and updates the session associated with the specified session key, or by default the active session.
@@ -1985,21 +2176,14 @@ class TurnkeyClient {
1985
2176
  const { sessionToken, sessionKey = SessionKey.DefaultSessionkey } = params;
1986
2177
  if (!sessionToken)
1987
2178
  return;
1988
- try {
1989
- const sessionToReplace = await this.storageManager.getSession(sessionKey);
2179
+ withTurnkeyErrorHandling(async () => {
1990
2180
  await this.storageManager.storeSession(sessionToken, sessionKey);
1991
- if (sessionToReplace) {
1992
- await this.apiKeyStamper?.deleteKeyPair(sessionToReplace.publicKey);
1993
- }
1994
- }
1995
- catch (error) {
1996
- if (error instanceof TurnkeyError)
1997
- throw error;
1998
- throw new TurnkeyError(`Failed to store session`, TurnkeyErrorCodes.STORE_SESSION_ERROR, error);
1999
- }
2000
- finally {
2001
- await this.clearUnusedKeyPairs();
2002
- }
2181
+ }, {
2182
+ errorMessage: "Failed to store session",
2183
+ errorCode: TurnkeyErrorCodes.STORE_SESSION_ERROR,
2184
+ }, {
2185
+ finallyFn: async () => await this.clearUnusedKeyPairs(),
2186
+ });
2003
2187
  };
2004
2188
  /**
2005
2189
  * Clears the session associated with the specified session key, or the active session by default.
@@ -2015,7 +2199,7 @@ class TurnkeyClient {
2015
2199
  */
2016
2200
  this.clearSession = async (params) => {
2017
2201
  const { sessionKey = SessionKey.DefaultSessionkey } = params || {};
2018
- try {
2202
+ withTurnkeyErrorHandling(async () => {
2019
2203
  const session = await this.storageManager.getSession(sessionKey);
2020
2204
  if (session) {
2021
2205
  await this.apiKeyStamper?.deleteKeyPair(session.publicKey);
@@ -2024,12 +2208,10 @@ class TurnkeyClient {
2024
2208
  else {
2025
2209
  throw new TurnkeyError(`No session found with key: ${sessionKey}`, TurnkeyErrorCodes.NOT_FOUND);
2026
2210
  }
2027
- }
2028
- catch (error) {
2029
- if (error instanceof TurnkeyError)
2030
- throw error;
2031
- throw new TurnkeyError(`Failed to delete session`, TurnkeyErrorCodes.CLEAR_SESSION_ERROR, error);
2032
- }
2211
+ }, {
2212
+ errorMessage: "Failed to delete session",
2213
+ errorCode: TurnkeyErrorCodes.CLEAR_SESSION_ERROR,
2214
+ });
2033
2215
  };
2034
2216
  /**
2035
2217
  * Clears all sessions and resets the active session state.
@@ -2043,7 +2225,7 @@ class TurnkeyClient {
2043
2225
  * @throws {TurnkeyError} If no sessions exist or if there is an error clearing all sessions.
2044
2226
  */
2045
2227
  this.clearAllSessions = async () => {
2046
- try {
2228
+ withTurnkeyErrorHandling(async () => {
2047
2229
  const sessionKeys = await this.storageManager.listSessionKeys();
2048
2230
  if (sessionKeys.length === 0) {
2049
2231
  throw new TurnkeyError("No sessions found to clear.", TurnkeyErrorCodes.NO_SESSION_FOUND);
@@ -2051,12 +2233,10 @@ class TurnkeyClient {
2051
2233
  for (const sessionKey of sessionKeys) {
2052
2234
  this.clearSession({ sessionKey });
2053
2235
  }
2054
- }
2055
- catch (error) {
2056
- if (error instanceof TurnkeyError)
2057
- throw error;
2058
- throw new TurnkeyError(`Failed to clear all sessions`, TurnkeyErrorCodes.CLEAR_ALL_SESSIONS_ERROR, error);
2059
- }
2236
+ }, {
2237
+ errorMessage: "Failed to clear all sessions",
2238
+ errorCode: TurnkeyErrorCodes.CLEAR_ALL_SESSIONS_ERROR,
2239
+ });
2060
2240
  };
2061
2241
  /**
2062
2242
  * Refreshes the session associated with the specified session key, or the active session by default.
@@ -2091,7 +2271,7 @@ class TurnkeyClient {
2091
2271
  throw new TurnkeyError("HTTP client is not initialized. Please initialize the client before refreshing the session.", TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
2092
2272
  }
2093
2273
  let keyPair;
2094
- try {
2274
+ return withTurnkeyErrorHandling(async () => {
2095
2275
  keyPair = publicKey ?? (await this.apiKeyStamper?.createKeyPair());
2096
2276
  if (!keyPair) {
2097
2277
  throw new TurnkeyError("Failed to create new key pair.", TurnkeyErrorCodes.INTERNAL_ERROR);
@@ -2109,12 +2289,10 @@ class TurnkeyClient {
2109
2289
  ...(sessionKey && { sessionKey }),
2110
2290
  });
2111
2291
  return res;
2112
- }
2113
- catch (error) {
2114
- if (error instanceof TurnkeyError)
2115
- throw error;
2116
- throw new TurnkeyError(`Failed to refresh session`, TurnkeyErrorCodes.REFRESH_SESSION_ERROR, error);
2117
- }
2292
+ }, {
2293
+ errorMessage: "Failed to refresh session",
2294
+ errorCode: TurnkeyErrorCodes.REFRESH_SESSION_ERROR,
2295
+ });
2118
2296
  };
2119
2297
  /**
2120
2298
  * Retrieves the session associated with the specified session key, or the active session by default.
@@ -2128,15 +2306,13 @@ class TurnkeyClient {
2128
2306
  * @throws {TurnkeyError} If there is an error retrieving the session from storage.
2129
2307
  */
2130
2308
  this.getSession = async (params) => {
2131
- try {
2309
+ return withTurnkeyErrorHandling(async () => {
2132
2310
  const { sessionKey = await this.storageManager.getActiveSessionKey() } = params || {};
2133
2311
  return this.storageManager.getSession(sessionKey);
2134
- }
2135
- catch (error) {
2136
- if (error instanceof TurnkeyError)
2137
- throw error;
2138
- throw new TurnkeyError(`Failed to get session with key`, TurnkeyErrorCodes.GET_SESSION_ERROR, error);
2139
- }
2312
+ }, {
2313
+ errorMessage: "Failed to get session with key " + params?.sessionKey,
2314
+ errorCode: TurnkeyErrorCodes.GET_SESSION_ERROR,
2315
+ });
2140
2316
  };
2141
2317
  /**
2142
2318
  * Retrieves all sessions stored in persistent storage.
@@ -2150,7 +2326,7 @@ class TurnkeyClient {
2150
2326
  * @throws {TurnkeyError} If there is an error retrieving sessions from storage.
2151
2327
  */
2152
2328
  this.getAllSessions = async () => {
2153
- try {
2329
+ return withTurnkeyErrorHandling(async () => {
2154
2330
  const sessionKeys = await this.storageManager.listSessionKeys();
2155
2331
  if (!sessionKeys || sessionKeys.length === 0) {
2156
2332
  return undefined;
@@ -2162,13 +2338,11 @@ class TurnkeyClient {
2162
2338
  sessions[sessionKey] = session;
2163
2339
  }
2164
2340
  }
2165
- return sessions;
2166
- }
2167
- catch (error) {
2168
- if (error instanceof TurnkeyError)
2169
- throw error;
2170
- throw new TurnkeyError(`Failed to get all sessions`, TurnkeyErrorCodes.GET_ALL_SESSIONS_ERROR, error);
2171
- }
2341
+ return sessions || undefined;
2342
+ }, {
2343
+ errorMessage: "Failed to get all sessions",
2344
+ errorCode: TurnkeyErrorCodes.GET_ALL_SESSIONS_ERROR,
2345
+ });
2172
2346
  };
2173
2347
  /**
2174
2348
  * Sets the active session to the specified session key.
@@ -2184,14 +2358,12 @@ class TurnkeyClient {
2184
2358
  */
2185
2359
  this.setActiveSession = async (params) => {
2186
2360
  const { sessionKey } = params;
2187
- try {
2361
+ return withTurnkeyErrorHandling(async () => {
2188
2362
  await this.storageManager.setActiveSessionKey(sessionKey);
2189
- }
2190
- catch (error) {
2191
- if (error instanceof TurnkeyError)
2192
- throw error;
2193
- throw new TurnkeyError(`Failed to set active session`, TurnkeyErrorCodes.SET_ACTIVE_SESSION_ERROR, error);
2194
- }
2363
+ }, {
2364
+ errorMessage: "Failed to set active session",
2365
+ errorCode: TurnkeyErrorCodes.SET_ACTIVE_SESSION_ERROR,
2366
+ });
2195
2367
  };
2196
2368
  /**
2197
2369
  * Retrieves the active session key currently set in persistent storage.
@@ -2205,14 +2377,12 @@ class TurnkeyClient {
2205
2377
  * @throws {TurnkeyError} If there is an error retrieving the active session key from storage.
2206
2378
  */
2207
2379
  this.getActiveSessionKey = async () => {
2208
- try {
2380
+ return withTurnkeyErrorHandling(async () => {
2209
2381
  return await this.storageManager.getActiveSessionKey();
2210
- }
2211
- catch (error) {
2212
- if (error instanceof TurnkeyError)
2213
- throw error;
2214
- throw new TurnkeyError(`Failed to get active session key`, TurnkeyErrorCodes.GET_ACTIVE_SESSION_KEY_ERROR, error);
2215
- }
2382
+ }, {
2383
+ errorMessage: "Failed to get active session key",
2384
+ errorCode: TurnkeyErrorCodes.GET_ACTIVE_SESSION_KEY_ERROR,
2385
+ });
2216
2386
  };
2217
2387
  /**
2218
2388
  * Clears any unused API key pairs from persistent storage.
@@ -2226,7 +2396,7 @@ class TurnkeyClient {
2226
2396
  * @throws {TurnkeyError} If there is an error listing, checking, or deleting unused key pairs.
2227
2397
  */
2228
2398
  this.clearUnusedKeyPairs = async () => {
2229
- try {
2399
+ withTurnkeyErrorHandling(async () => {
2230
2400
  const publicKeys = await this.apiKeyStamper?.listKeyPairs();
2231
2401
  if (!publicKeys || publicKeys.length === 0) {
2232
2402
  return;
@@ -2249,12 +2419,10 @@ class TurnkeyClient {
2249
2419
  }
2250
2420
  }
2251
2421
  }
2252
- }
2253
- catch (error) {
2254
- if (error instanceof TurnkeyError)
2255
- throw error;
2256
- throw new TurnkeyError(`Failed to clear unused key pairs`, TurnkeyErrorCodes.CLEAR_UNUSED_KEY_PAIRS_ERROR, error);
2257
- }
2422
+ }, {
2423
+ errorMessage: "Failed to clear unused key pairs",
2424
+ errorCode: TurnkeyErrorCodes.CLEAR_UNUSED_KEY_PAIRS_ERROR,
2425
+ });
2258
2426
  };
2259
2427
  /**
2260
2428
  * Creates a new API key pair and returns the public key.
@@ -2271,23 +2439,21 @@ class TurnkeyClient {
2271
2439
  * @throws {TurnkeyError} If the API key stamper is not initialized or if there is an error during key pair creation or storage.
2272
2440
  */
2273
2441
  this.createApiKeyPair = async (params) => {
2274
- if (!this.apiKeyStamper) {
2275
- throw new TurnkeyError("API Key Stamper is not initialized.", TurnkeyErrorCodes.INTERNAL_ERROR);
2276
- }
2277
- const externalKeyPair = params?.externalKeyPair;
2278
- const storeOverride = params?.storeOverride ?? false;
2279
- try {
2442
+ return withTurnkeyErrorHandling(async () => {
2443
+ const externalKeyPair = params?.externalKeyPair;
2444
+ const storeOverride = params?.storeOverride ?? false;
2445
+ if (!this.apiKeyStamper) {
2446
+ throw new TurnkeyError("API Key Stamper is not initialized.", TurnkeyErrorCodes.INTERNAL_ERROR);
2447
+ }
2280
2448
  const publicKey = await this.apiKeyStamper.createKeyPair(externalKeyPair ? externalKeyPair : undefined);
2281
2449
  if (storeOverride && publicKey) {
2282
2450
  await this.apiKeyStamper.setPublicKeyOverride(publicKey);
2283
2451
  }
2284
2452
  return publicKey;
2285
- }
2286
- catch (error) {
2287
- if (error instanceof TurnkeyError)
2288
- throw error;
2289
- throw new TurnkeyError(`Failed to create API key pair`, TurnkeyErrorCodes.CREATE_API_KEY_PAIR_ERROR, error);
2290
- }
2453
+ }, {
2454
+ errorMessage: "Failed to create API key pair",
2455
+ errorCode: TurnkeyErrorCodes.CREATE_API_KEY_PAIR_ERROR,
2456
+ });
2291
2457
  };
2292
2458
  /**
2293
2459
  * Fetches the WalletKit proxy authentication configuration from the auth proxy.
@@ -2301,18 +2467,16 @@ class TurnkeyClient {
2301
2467
  * @throws {TurnkeyError} If there is an error retrieving the proxy authentication configuration from the auth proxy.
2302
2468
  */
2303
2469
  this.getProxyAuthConfig = async () => {
2304
- try {
2470
+ return withTurnkeyErrorHandling(async () => {
2305
2471
  const res = await this.httpClient.proxyGetWalletKitConfig({});
2306
2472
  if (!res) {
2307
2473
  throw new TurnkeyError(`Failed to fetch auth proxy config`, TurnkeyErrorCodes.GET_PROXY_AUTH_CONFIG_ERROR);
2308
2474
  }
2309
2475
  return res;
2310
- }
2311
- catch (error) {
2312
- if (error instanceof TurnkeyError)
2313
- throw error;
2314
- throw new TurnkeyError(`Failed to get auth proxy config`, TurnkeyErrorCodes.GET_PROXY_AUTH_CONFIG_ERROR, error);
2315
- }
2476
+ }, {
2477
+ errorMessage: "Failed to get auth proxy config",
2478
+ errorCode: TurnkeyErrorCodes.GET_PROXY_AUTH_CONFIG_ERROR,
2479
+ });
2316
2480
  };
2317
2481
  this.config = config;
2318
2482
  // Just store any explicitly provided stampers