@turnkey/core 1.0.0-beta.6 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. package/README.MD +3 -1
  2. package/dist/__clients__/core.d.ts +196 -324
  3. package/dist/__clients__/core.d.ts.map +1 -1
  4. package/dist/__clients__/core.js +571 -271
  5. package/dist/__clients__/core.js.map +1 -1
  6. package/dist/__clients__/core.mjs +522 -222
  7. package/dist/__clients__/core.mjs.map +1 -1
  8. package/dist/__generated__/sdk-client-base.d.ts +8 -2
  9. package/dist/__generated__/sdk-client-base.d.ts.map +1 -1
  10. package/dist/__generated__/sdk-client-base.js +95 -6
  11. package/dist/__generated__/sdk-client-base.js.map +1 -1
  12. package/dist/__generated__/sdk-client-base.mjs +90 -1
  13. package/dist/__generated__/sdk-client-base.mjs.map +1 -1
  14. package/dist/__generated__/version.d.ts +1 -1
  15. package/dist/__generated__/version.d.ts.map +1 -1
  16. package/dist/__generated__/version.js +1 -1
  17. package/dist/__generated__/version.mjs +1 -1
  18. package/dist/__inputs__/public_api.types.d.ts +163 -26
  19. package/dist/__inputs__/public_api.types.d.ts.map +1 -1
  20. package/dist/__polyfills__/window.js.map +1 -1
  21. package/dist/__polyfills__/window.mjs.map +1 -1
  22. package/dist/__stampers__/api/base.d.ts +1 -1
  23. package/dist/__stampers__/api/base.d.ts.map +1 -1
  24. package/dist/__stampers__/api/base.js.map +1 -1
  25. package/dist/__stampers__/api/base.mjs.map +1 -1
  26. package/dist/__stampers__/api/mobile/stamper.d.ts +1 -1
  27. package/dist/__stampers__/api/mobile/stamper.d.ts.map +1 -1
  28. package/dist/__stampers__/api/mobile/stamper.js.map +1 -1
  29. package/dist/__stampers__/api/mobile/stamper.mjs.map +1 -1
  30. package/dist/__stampers__/api/web/stamper.d.ts +1 -1
  31. package/dist/__stampers__/api/web/stamper.d.ts.map +1 -1
  32. package/dist/__stampers__/api/web/stamper.js.map +1 -1
  33. package/dist/__stampers__/api/web/stamper.mjs.map +1 -1
  34. package/dist/__stampers__/passkey/base.d.ts +1 -1
  35. package/dist/__stampers__/passkey/base.d.ts.map +1 -1
  36. package/dist/__stampers__/passkey/base.js.map +1 -1
  37. package/dist/__stampers__/passkey/base.mjs.map +1 -1
  38. package/dist/__storage__/base.d.ts +1 -1
  39. package/dist/__storage__/base.d.ts.map +1 -1
  40. package/dist/__storage__/base.js.map +1 -1
  41. package/dist/__storage__/base.mjs.map +1 -1
  42. package/dist/__storage__/mobile/storage.d.ts +1 -1
  43. package/dist/__storage__/mobile/storage.d.ts.map +1 -1
  44. package/dist/__storage__/mobile/storage.js +4 -3
  45. package/dist/__storage__/mobile/storage.js.map +1 -1
  46. package/dist/__storage__/mobile/storage.mjs +2 -1
  47. package/dist/__storage__/mobile/storage.mjs.map +1 -1
  48. package/dist/__storage__/web/storage.d.ts +1 -1
  49. package/dist/__storage__/web/storage.d.ts.map +1 -1
  50. package/dist/__storage__/web/storage.js +4 -3
  51. package/dist/__storage__/web/storage.js.map +1 -1
  52. package/dist/__storage__/web/storage.mjs +2 -1
  53. package/dist/__storage__/web/storage.mjs.map +1 -1
  54. package/dist/__typedoc-entry__/index.d.ts +3 -0
  55. package/dist/__typedoc-entry__/index.d.ts.map +1 -0
  56. package/dist/__types__/auth.d.ts +150 -0
  57. package/dist/__types__/auth.d.ts.map +1 -0
  58. package/dist/__types__/auth.js +43 -0
  59. package/dist/__types__/auth.js.map +1 -0
  60. package/dist/__types__/auth.mjs +40 -0
  61. package/dist/__types__/auth.mjs.map +1 -0
  62. package/dist/__types__/config.d.ts +140 -0
  63. package/dist/__types__/config.d.ts.map +1 -0
  64. package/dist/__types__/error.d.ts +13 -0
  65. package/dist/__types__/error.d.ts.map +1 -0
  66. package/dist/__types__/error.js +18 -0
  67. package/dist/__types__/error.js.map +1 -0
  68. package/dist/__types__/error.mjs +16 -0
  69. package/dist/__types__/error.mjs.map +1 -0
  70. package/dist/__types__/export.d.ts +10 -0
  71. package/dist/__types__/export.d.ts.map +1 -0
  72. package/dist/__types__/external-wallets.d.ts +202 -0
  73. package/dist/__types__/external-wallets.d.ts.map +1 -0
  74. package/dist/__types__/external-wallets.js +35 -0
  75. package/dist/__types__/external-wallets.js.map +1 -0
  76. package/dist/__types__/external-wallets.mjs +35 -0
  77. package/dist/__types__/external-wallets.mjs.map +1 -0
  78. package/dist/__types__/index.d.ts +7 -0
  79. package/dist/__types__/index.d.ts.map +1 -0
  80. package/dist/__types__/method-types.d.ts +314 -0
  81. package/dist/__types__/method-types.d.ts.map +1 -0
  82. package/dist/__wallet__/base.d.ts +1 -1
  83. package/dist/__wallet__/base.d.ts.map +1 -1
  84. package/dist/__wallet__/base.js +6 -6
  85. package/dist/__wallet__/base.js.map +1 -1
  86. package/dist/__wallet__/base.mjs +2 -2
  87. package/dist/__wallet__/base.mjs.map +1 -1
  88. package/dist/__wallet__/connector.d.ts +3 -3
  89. package/dist/__wallet__/connector.d.ts.map +1 -1
  90. package/dist/__wallet__/connector.js +5 -4
  91. package/dist/__wallet__/connector.js.map +1 -1
  92. package/dist/__wallet__/connector.mjs +4 -3
  93. package/dist/__wallet__/connector.mjs.map +1 -1
  94. package/dist/__wallet__/mobile/manager.d.ts +1 -1
  95. package/dist/__wallet__/mobile/manager.d.ts.map +1 -1
  96. package/dist/__wallet__/mobile/manager.js +5 -4
  97. package/dist/__wallet__/mobile/manager.js.map +1 -1
  98. package/dist/__wallet__/mobile/manager.mjs +2 -1
  99. package/dist/__wallet__/mobile/manager.mjs.map +1 -1
  100. package/dist/__wallet__/stamper.d.ts +1 -1
  101. package/dist/__wallet__/stamper.d.ts.map +1 -1
  102. package/dist/__wallet__/stamper.js +9 -8
  103. package/dist/__wallet__/stamper.js.map +1 -1
  104. package/dist/__wallet__/stamper.mjs +2 -1
  105. package/dist/__wallet__/stamper.mjs.map +1 -1
  106. package/dist/__wallet__/wallet-connect/base.d.ts +4 -2
  107. package/dist/__wallet__/wallet-connect/base.d.ts.map +1 -1
  108. package/dist/__wallet__/wallet-connect/base.js +74 -32
  109. package/dist/__wallet__/wallet-connect/base.js.map +1 -1
  110. package/dist/__wallet__/wallet-connect/base.mjs +55 -13
  111. package/dist/__wallet__/wallet-connect/base.mjs.map +1 -1
  112. package/dist/__wallet__/wallet-connect/client.d.ts +30 -9
  113. package/dist/__wallet__/wallet-connect/client.d.ts.map +1 -1
  114. package/dist/__wallet__/wallet-connect/client.js +73 -11
  115. package/dist/__wallet__/wallet-connect/client.js.map +1 -1
  116. package/dist/__wallet__/wallet-connect/client.mjs +73 -11
  117. package/dist/__wallet__/wallet-connect/client.mjs.map +1 -1
  118. package/dist/__wallet__/web/manager.d.ts +1 -1
  119. package/dist/__wallet__/web/manager.d.ts.map +1 -1
  120. package/dist/__wallet__/web/manager.js +11 -10
  121. package/dist/__wallet__/web/manager.js.map +1 -1
  122. package/dist/__wallet__/web/manager.mjs +2 -1
  123. package/dist/__wallet__/web/manager.mjs.map +1 -1
  124. package/dist/__wallet__/web/native/ethereum.d.ts +3 -3
  125. package/dist/__wallet__/web/native/ethereum.d.ts.map +1 -1
  126. package/dist/__wallet__/web/native/ethereum.js +11 -10
  127. package/dist/__wallet__/web/native/ethereum.js.map +1 -1
  128. package/dist/__wallet__/web/native/ethereum.mjs +4 -3
  129. package/dist/__wallet__/web/native/ethereum.mjs.map +1 -1
  130. package/dist/__wallet__/web/native/solana.d.ts +3 -3
  131. package/dist/__wallet__/web/native/solana.d.ts.map +1 -1
  132. package/dist/__wallet__/web/native/solana.js +13 -13
  133. package/dist/__wallet__/web/native/solana.js.map +1 -1
  134. package/dist/__wallet__/web/native/solana.mjs +8 -8
  135. package/dist/__wallet__/web/native/solana.mjs.map +1 -1
  136. package/dist/index.d.ts +2 -1
  137. package/dist/index.d.ts.map +1 -1
  138. package/dist/index.js +29 -21
  139. package/dist/index.js.map +1 -1
  140. package/dist/index.mjs +4 -2
  141. package/dist/index.mjs.map +1 -1
  142. package/dist/turnkey-helpers.js.map +1 -1
  143. package/dist/turnkey-helpers.mjs.map +1 -1
  144. package/dist/utils.d.ts +11 -23
  145. package/dist/utils.d.ts.map +1 -1
  146. package/dist/utils.js +120 -45
  147. package/dist/utils.js.map +1 -1
  148. package/dist/utils.mjs +102 -30
  149. package/dist/utils.mjs.map +1 -1
  150. package/package.json +8 -9
  151. package/dist/__types__/base.d.ts +0 -527
  152. package/dist/__types__/base.d.ts.map +0 -1
  153. package/dist/__types__/base.js +0 -89
  154. package/dist/__types__/base.js.map +0 -1
  155. package/dist/__types__/base.mjs +0 -85
  156. package/dist/__types__/base.mjs.map +0 -1
@@ -2,14 +2,15 @@
2
2
 
3
3
  var sdkClientBase = require('../__generated__/sdk-client-base.js');
4
4
  var sdkTypes = require('@turnkey/sdk-types');
5
- var base = require('../__types__/base.js');
5
+ var auth = require('../__types__/auth.js');
6
+ var externalWallets = require('../__types__/external-wallets.js');
6
7
  var utils = require('../utils.js');
7
- var base$1 = require('../__storage__/base.js');
8
- var base$2 = require('../__stampers__/api/base.js');
9
- var base$3 = require('../__stampers__/passkey/base.js');
8
+ var base = require('../__storage__/base.js');
9
+ var base$1 = require('../__stampers__/api/base.js');
10
+ var base$2 = require('../__stampers__/passkey/base.js');
10
11
  var turnkeyHelpers = require('../turnkey-helpers.js');
11
12
  var jwtDecode = require('jwt-decode');
12
- var base$4 = require('../__wallet__/base.js');
13
+ var base$3 = require('../__wallet__/base.js');
13
14
  var ethers = require('ethers');
14
15
 
15
16
  class TurnkeyClient {
@@ -24,29 +25,30 @@ class TurnkeyClient {
24
25
  * - The resulting attestation and challenge can be used to register the passkey with Turnkey.
25
26
  *
26
27
  * @param params.name - display name for the passkey (defaults to a generated name based on the current timestamp).
27
- * @param params.stampWith - parameter to stamp the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
28
28
  * @param params.challenge - challenge string to use for passkey registration. If not provided, a new challenge will be generated.
29
- * @returns A promise that resolves to an object containing:
30
- * - attestation: attestation object returned from the passkey creation process.
31
- * - encodedChallenge: encoded challenge string used for passkey registration.
29
+ * @returns A promise that resolves to {@link CreatePasskeyResult}
32
30
  * @throws {TurnkeyError} If there is an error during passkey creation, or if the platform is unsupported.
33
31
  */
34
32
  this.createPasskey = async (params) => {
33
+ const { name: nameFromParams, challenge } = params || {};
35
34
  return utils.withTurnkeyErrorHandling(async () => {
36
- const name = utils.isValidPasskeyName(params?.name || `passkey-${Date.now()}`);
35
+ if (!this.passkeyStamper) {
36
+ throw new sdkTypes.TurnkeyError("Passkey stamper is not initialized", sdkTypes.TurnkeyErrorCodes.INTERNAL_ERROR);
37
+ }
38
+ const name = utils.isValidPasskeyName(nameFromParams || `passkey-${Date.now()}`);
37
39
  let passkey;
38
40
  if (utils.isWeb()) {
39
- const res = await this.passkeyStamper?.createWebPasskey({
41
+ const res = await this.passkeyStamper.createWebPasskey({
40
42
  publicKey: {
41
43
  user: {
42
44
  name,
43
45
  displayName: name,
44
46
  },
45
- ...(params?.challenge && { challenge: params.challenge }),
47
+ ...(challenge && { challenge }),
46
48
  },
47
49
  });
48
50
  if (!res) {
49
- throw new sdkTypes.TurnkeyError("Failed to create React Native passkey", sdkTypes.TurnkeyErrorCodes.INTERNAL_ERROR);
51
+ throw new sdkTypes.TurnkeyError("Failed to create Web passkey", sdkTypes.TurnkeyErrorCodes.INTERNAL_ERROR);
50
52
  }
51
53
  passkey = {
52
54
  encodedChallenge: res?.encodedChallenge,
@@ -54,7 +56,7 @@ class TurnkeyClient {
54
56
  };
55
57
  }
56
58
  else if (utils.isReactNative()) {
57
- const res = await this.passkeyStamper?.createReactNativePasskey({
59
+ const res = await this.passkeyStamper.createReactNativePasskey({
58
60
  name,
59
61
  displayName: name,
60
62
  });
@@ -73,7 +75,7 @@ class TurnkeyClient {
73
75
  }, {
74
76
  errorMessage: "Failed to create passkey",
75
77
  errorCode: sdkTypes.TurnkeyErrorCodes.CREATE_PASSKEY_ERROR,
76
- customMessageByMessages: {
78
+ customErrorsByMessages: {
77
79
  "timed out or was not allowed": {
78
80
  message: "Passkey creation was cancelled by the user.",
79
81
  code: sdkTypes.TurnkeyErrorCodes.SELECT_PASSKEY_CANCELLED,
@@ -127,6 +129,7 @@ class TurnkeyClient {
127
129
  * @param params.publicKey - public key to use for authentication. If not provided, a new key pair will be generated.
128
130
  * @param params.sessionKey - session key to use for session creation (defaults to the default session key).
129
131
  * @param params.expirationSeconds - session expiration time in seconds (defaults to the configured default).
132
+ * @param params.organizationId - organization ID to target (defaults to the session's organization ID or the parent organization ID).
130
133
  * @returns A promise that resolves to a {@link PasskeyAuthResult}, which includes:
131
134
  * - `sessionToken`: the signed JWT session token.
132
135
  * - `credentialId`: an empty string.
@@ -137,16 +140,16 @@ class TurnkeyClient {
137
140
  return await utils.withTurnkeyErrorHandling(async () => {
138
141
  generatedPublicKey =
139
142
  params?.publicKey || (await this.apiKeyStamper?.createKeyPair());
140
- const sessionKey = params?.sessionKey || base.SessionKey.DefaultSessionkey;
141
- const expirationSeconds = params?.expirationSeconds || base.DEFAULT_SESSION_EXPIRATION_IN_SECONDS;
143
+ const sessionKey = params?.sessionKey || auth.SessionKey.DefaultSessionkey;
144
+ const expirationSeconds = params?.expirationSeconds || auth.DEFAULT_SESSION_EXPIRATION_IN_SECONDS;
142
145
  if (!generatedPublicKey) {
143
146
  throw new sdkTypes.TurnkeyError("A publickey could not be found or generated.", sdkTypes.TurnkeyErrorCodes.INTERNAL_ERROR);
144
147
  }
145
148
  const sessionResponse = await this.httpClient.stampLogin({
146
149
  publicKey: generatedPublicKey,
147
- organizationId: this.config.organizationId,
150
+ organizationId: params?.organizationId ?? this.config.organizationId,
148
151
  expirationSeconds,
149
- }, base.StamperType.Passkey);
152
+ }, auth.StamperType.Passkey);
150
153
  await this.storeSession({
151
154
  sessionToken: sessionResponse.session,
152
155
  sessionKey,
@@ -162,7 +165,7 @@ class TurnkeyClient {
162
165
  }, {
163
166
  errorMessage: "Unable to log in with the provided passkey",
164
167
  errorCode: sdkTypes.TurnkeyErrorCodes.PASSKEY_LOGIN_AUTH_ERROR,
165
- customMessageByMessages: {
168
+ customErrorsByMessages: {
166
169
  "timed out or was not allowed": {
167
170
  message: "Passkey login was cancelled by the user.",
168
171
  code: sdkTypes.TurnkeyErrorCodes.SELECT_PASSKEY_CANCELLED,
@@ -195,13 +198,14 @@ class TurnkeyClient {
195
198
  * @param params.sessionKey - session key to use for storing the session (defaults to the default session key).
196
199
  * @param params.expirationSeconds - session expiration time in seconds (defaults to the configured default).
197
200
  * @param params.challenge - challenge string to use for passkey registration. If not provided, a new challenge will be generated.
201
+ * @param params.organizationId - organization ID to target (defaults to the session's organization ID or the parent organization ID).
198
202
  * @returns A promise that resolves to a {@link PasskeyAuthResult}, which includes:
199
203
  * - `sessionToken`: the signed JWT session token.
200
204
  * - `credentialId`: the credential ID associated with the passkey created.
201
205
  * @throws {TurnkeyError} If there is an error during passkey creation, sub-organization creation, or session storage.
202
206
  */
203
207
  this.signUpWithPasskey = async (params) => {
204
- const { createSubOrgParams, passkeyDisplayName, sessionKey = base.SessionKey.DefaultSessionkey, expirationSeconds = base.DEFAULT_SESSION_EXPIRATION_IN_SECONDS, } = params || {};
208
+ const { createSubOrgParams, passkeyDisplayName, sessionKey = auth.SessionKey.DefaultSessionkey, expirationSeconds = auth.DEFAULT_SESSION_EXPIRATION_IN_SECONDS, organizationId, } = params || {};
205
209
  let generatedPublicKey = undefined;
206
210
  return utils.withTurnkeyErrorHandling(async () => {
207
211
  generatedPublicKey = await this.apiKeyStamper?.createKeyPair();
@@ -244,7 +248,7 @@ class TurnkeyClient {
244
248
  this.apiKeyStamper?.setTemporaryPublicKey(generatedPublicKey);
245
249
  const sessionResponse = await this.httpClient.stampLogin({
246
250
  publicKey: newGeneratedKeyPair,
247
- organizationId: this.config.organizationId,
251
+ organizationId: organizationId ?? this.config.organizationId,
248
252
  expirationSeconds,
249
253
  });
250
254
  await this.apiKeyStamper?.deleteKeyPair(generatedPublicKey);
@@ -284,7 +288,7 @@ class TurnkeyClient {
284
288
  * @returns A promise that resolves to an array of wallet providers.
285
289
  * @throws {TurnkeyError} If the wallet manager is uninitialized or provider retrieval fails.
286
290
  */
287
- this.getWalletProviders = async (chain) => {
291
+ this.fetchWalletProviders = async (chain) => {
288
292
  return utils.withTurnkeyErrorHandling(async () => {
289
293
  if (!this.walletManager) {
290
294
  throw new sdkTypes.TurnkeyError("Wallet manager is not initialized", sdkTypes.TurnkeyErrorCodes.WALLET_MANAGER_COMPONENT_NOT_INITIALIZED);
@@ -301,7 +305,7 @@ class TurnkeyClient {
301
305
  * - Requires the wallet manager and its connector to be initialized.
302
306
  *
303
307
  * @param walletProvider - wallet provider to connect.
304
- * @returns A promise that resolves once the wallet account is connected.
308
+ * @returns A promise that resolves with the connected wallet's address.
305
309
  * @throws {TurnkeyError} If the wallet manager is uninitialized or the connection fails.
306
310
  */
307
311
  this.connectWalletAccount = async (walletProvider) => {
@@ -309,7 +313,7 @@ class TurnkeyClient {
309
313
  if (!this.walletManager?.connector) {
310
314
  throw new sdkTypes.TurnkeyError("Wallet connector is not initialized", sdkTypes.TurnkeyErrorCodes.WALLET_MANAGER_COMPONENT_NOT_INITIALIZED);
311
315
  }
312
- await this.walletManager.connector.connectWalletAccount(walletProvider);
316
+ return await this.walletManager.connector.connectWalletAccount(walletProvider);
313
317
  }, {
314
318
  errorMessage: "Unable to connect wallet account",
315
319
  errorCode: sdkTypes.TurnkeyErrorCodes.CONNECT_WALLET_ACCOUNT_ERROR,
@@ -346,7 +350,7 @@ class TurnkeyClient {
346
350
  *
347
351
  * @param params.walletAccount - The wallet account whose provider should be switched.
348
352
  * @param params.chainOrId - The target chain, specified as a chain ID string or a SwitchableChain object.
349
- * @param params.walletProviders - Optional list of wallet providers to search; falls back to `getWalletProviders()` if omitted.
353
+ * @param params.walletProviders - Optional list of wallet providers to search; falls back to `fetchWalletProviders()` if omitted.
350
354
  * @returns A promise that resolves once the chain switch is complete.
351
355
  *
352
356
  * @throws {TurnkeyError} If the wallet manager is uninitialized, the provider is not connected, or the switch fails.
@@ -357,10 +361,10 @@ class TurnkeyClient {
357
361
  if (!this.walletManager?.connector) {
358
362
  throw new sdkTypes.TurnkeyError("Wallet connector is not initialized", sdkTypes.TurnkeyErrorCodes.WALLET_MANAGER_COMPONENT_NOT_INITIALIZED);
359
363
  }
360
- if (walletAccount.source === base.WalletSource.Embedded) {
364
+ if (walletAccount.source === externalWallets.WalletSource.Embedded) {
361
365
  throw new sdkTypes.TurnkeyError("You can only switch chains for connected wallet accounts", sdkTypes.TurnkeyErrorCodes.NOT_FOUND);
362
366
  }
363
- const providers = walletProviders ?? (await this.getWalletProviders());
367
+ const providers = walletProviders ?? (await this.fetchWalletProviders());
364
368
  const walletProvider = utils.findWalletProviderFromAddress(walletAccount.address, providers);
365
369
  if (!walletProvider) {
366
370
  throw new sdkTypes.TurnkeyError("Wallet provider not found", sdkTypes.TurnkeyErrorCodes.SWITCH_WALLET_CHAIN_ERROR);
@@ -388,6 +392,7 @@ class TurnkeyClient {
388
392
  * @param params.publicKey - optional public key to associate with the session (generated if not provided).
389
393
  * @param params.sessionKey - optional key to store the session under (defaults to the default session key).
390
394
  * @param params.expirationSeconds - optional session expiration time in seconds (defaults to the configured default).
395
+ * @param params.organizationId - organization ID to target (defaults to the session's organization ID or the parent organization ID).
391
396
  * @returns A promise that resolves to a {@link WalletAuthResult}, which includes:
392
397
  * - `sessionToken`: the signed JWT session token.
393
398
  * - `address`: the authenticated wallet address.
@@ -399,18 +404,18 @@ class TurnkeyClient {
399
404
  if (!this.walletManager?.stamper) {
400
405
  throw new sdkTypes.TurnkeyError("Wallet stamper is not initialized", sdkTypes.TurnkeyErrorCodes.WALLET_MANAGER_COMPONENT_NOT_INITIALIZED);
401
406
  }
402
- const sessionKey = params.sessionKey || base.SessionKey.DefaultSessionkey;
407
+ const sessionKey = params.sessionKey || auth.SessionKey.DefaultSessionkey;
403
408
  const walletProvider = params.walletProvider;
404
- const expirationSeconds = params?.expirationSeconds || base.DEFAULT_SESSION_EXPIRATION_IN_SECONDS;
409
+ const expirationSeconds = params?.expirationSeconds || auth.DEFAULT_SESSION_EXPIRATION_IN_SECONDS;
405
410
  if (!publicKey) {
406
411
  throw new sdkTypes.TurnkeyError("A publickey could not be found or generated.", sdkTypes.TurnkeyErrorCodes.INTERNAL_ERROR);
407
412
  }
408
413
  this.walletManager.stamper.setProvider(walletProvider.interfaceType, walletProvider);
409
414
  const sessionResponse = await this.httpClient.stampLogin({
410
415
  publicKey,
411
- organizationId: this.config.organizationId,
416
+ organizationId: params?.organizationId ?? this.config.organizationId,
412
417
  expirationSeconds,
413
- }, base.StamperType.Wallet);
418
+ }, auth.StamperType.Wallet);
414
419
  await this.storeSession({
415
420
  sessionToken: sessionResponse.session,
416
421
  sessionKey,
@@ -452,13 +457,14 @@ class TurnkeyClient {
452
457
  * @param params.createSubOrgParams - parameters for creating a sub-organization (e.g., authenticators, user metadata).
453
458
  * @param params.sessionKey - session key to use for storing the session (defaults to the default session key).
454
459
  * @param params.expirationSeconds - session expiration time in seconds (defaults to the configured default).
460
+ * @param params.organizationId - organization ID to target (defaults to the session's organization ID or the parent organization ID).
455
461
  * @returns A promise that resolves to a {@link WalletAuthResult}, which includes:
456
462
  * - `sessionToken`: the signed JWT session token.
457
463
  * - `address`: the authenticated wallet address.
458
464
  * @throws {TurnkeyError} If there is an error during wallet authentication, sub-organization creation, session storage, or cleanup.
459
465
  */
460
466
  this.signUpWithWallet = async (params) => {
461
- const { walletProvider, createSubOrgParams, sessionKey = base.SessionKey.DefaultSessionkey, expirationSeconds = base.DEFAULT_SESSION_EXPIRATION_IN_SECONDS, } = params;
467
+ const { walletProvider, createSubOrgParams, sessionKey = auth.SessionKey.DefaultSessionkey, expirationSeconds = auth.DEFAULT_SESSION_EXPIRATION_IN_SECONDS, } = params;
462
468
  let generatedPublicKey = undefined;
463
469
  return utils.withTurnkeyErrorHandling(async () => {
464
470
  if (!this.walletManager?.stamper) {
@@ -543,6 +549,7 @@ class TurnkeyClient {
543
549
  * @param params.createSubOrgParams - optional parameters for creating a sub-organization (e.g., authenticators, user metadata).
544
550
  * @param params.sessionKey - session key to use for storing the session (defaults to the default session key).
545
551
  * @param params.expirationSeconds - session expiration time in seconds (defaults to the configured default).
552
+ * @param params.organizationId - organization ID to target (defaults to the session's organization ID or the parent organization ID).
546
553
  * @returns A promise that resolves to an object containing:
547
554
  * - `sessionToken`: the signed JWT session token.
548
555
  * - `address`: the authenticated wallet address.
@@ -551,9 +558,9 @@ class TurnkeyClient {
551
558
  */
552
559
  this.loginOrSignupWithWallet = async (params) => {
553
560
  const createSubOrgParams = params.createSubOrgParams;
554
- const sessionKey = params.sessionKey || base.SessionKey.DefaultSessionkey;
561
+ const sessionKey = params.sessionKey || auth.SessionKey.DefaultSessionkey;
555
562
  const walletProvider = params.walletProvider;
556
- const expirationSeconds = params.expirationSeconds || base.DEFAULT_SESSION_EXPIRATION_IN_SECONDS;
563
+ const expirationSeconds = params.expirationSeconds || auth.DEFAULT_SESSION_EXPIRATION_IN_SECONDS;
557
564
  let generatedPublicKey = undefined;
558
565
  return utils.withTurnkeyErrorHandling(async () => {
559
566
  if (!this.walletManager?.stamper) {
@@ -569,11 +576,15 @@ class TurnkeyClient {
569
576
  publicKey: generatedPublicKey,
570
577
  organizationId: this.config.organizationId,
571
578
  expirationSeconds,
572
- }, base.StamperType.Wallet);
579
+ }, auth.StamperType.Wallet);
573
580
  }, {
574
581
  errorMessage: "Failed to create stamped request for wallet login",
575
582
  errorCode: sdkTypes.TurnkeyErrorCodes.WALLET_LOGIN_OR_SIGNUP_ERROR,
576
- customMessageByMessages: {
583
+ customErrorsByMessages: {
584
+ "WalletConnect: The connection request has expired. Please scan the QR code again.": {
585
+ message: "Your WalletConnect session expired. Please scan the QR code again.",
586
+ code: sdkTypes.TurnkeyErrorCodes.WALLET_CONNECT_EXPIRED,
587
+ },
577
588
  "Failed to sign the message": {
578
589
  message: "Wallet auth was cancelled by the user.",
579
590
  code: sdkTypes.TurnkeyErrorCodes.CONNECT_WALLET_CANCELLED,
@@ -585,13 +596,13 @@ class TurnkeyClient {
585
596
  }
586
597
  let publicKey;
587
598
  switch (walletProvider.chainInfo.namespace) {
588
- case base.Chain.Ethereum: {
599
+ case externalWallets.Chain.Ethereum: {
589
600
  // for Ethereum, there is no way to get the public key from the wallet address
590
601
  // so we derive it from the signed request
591
602
  publicKey = utils.getPublicKeyFromStampHeader(signedRequest.stamp.stampHeaderValue);
592
603
  break;
593
604
  }
594
- case base.Chain.Solana: {
605
+ case externalWallets.Chain.Solana: {
595
606
  // for Solana, we can get the public key from the wallet address
596
607
  // since the wallet address is the public key
597
608
  // this doesn't require any action from the user as long as the wallet is connected
@@ -605,7 +616,7 @@ class TurnkeyClient {
605
616
  // here we check if the subOrg exists and create one
606
617
  // then we send off the stamped request to Turnkey
607
618
  const accountRes = await this.httpClient.proxyGetAccount({
608
- filterType: base.FilterType.PublicKey,
619
+ filterType: auth.FilterType.PublicKey,
609
620
  filterValue: publicKey,
610
621
  });
611
622
  if (!accountRes) {
@@ -684,6 +695,7 @@ class TurnkeyClient {
684
695
  *
685
696
  * @param params.otpType - type of OTP to initialize (OtpType.Email or OtpType.Sms).
686
697
  * @param params.contact - contact information for the user (e.g., email address or phone number).
698
+ * @param params.organizationId - optional organization ID to target (defaults to the session's organization ID or the parent organization ID).
687
699
  * @returns A promise that resolves to the OTP ID required for verification.
688
700
  * @throws {TurnkeyError} If there is an error during the OTP initialization process or if the maximum number of OTPs has been reached.
689
701
  */
@@ -697,7 +709,7 @@ class TurnkeyClient {
697
709
  }, {
698
710
  errorMessage: "Failed to initialize OTP",
699
711
  errorCode: sdkTypes.TurnkeyErrorCodes.INIT_OTP_ERROR,
700
- customMessageByMessages: {
712
+ customErrorsByMessages: {
701
713
  "Max number of OTPs have been initiated": {
702
714
  message: "Maximum number of OTPs has been reached for this contact.",
703
715
  code: sdkTypes.TurnkeyErrorCodes.MAX_OTP_INITIATED_ERROR,
@@ -733,7 +745,7 @@ class TurnkeyClient {
733
745
  throw new sdkTypes.TurnkeyError(`OTP verification failed`, sdkTypes.TurnkeyErrorCodes.INTERNAL_ERROR);
734
746
  }
735
747
  const accountRes = await this.httpClient.proxyGetAccount({
736
- filterType: base.OtpTypeToFilterTypeMap[otpType],
748
+ filterType: auth.OtpTypeToFilterTypeMap[otpType],
737
749
  filterValue: contact,
738
750
  });
739
751
  if (!accountRes) {
@@ -747,7 +759,7 @@ class TurnkeyClient {
747
759
  }, {
748
760
  errorMessage: "Failed to verify OTP",
749
761
  errorCode: sdkTypes.TurnkeyErrorCodes.VERIFY_OTP_ERROR,
750
- customMessageByMessages: {
762
+ customErrorsByMessages: {
751
763
  "Invalid OTP code": {
752
764
  message: "The provided OTP code is invalid.",
753
765
  code: sdkTypes.TurnkeyErrorCodes.INVALID_OTP_CODE,
@@ -773,7 +785,7 @@ class TurnkeyClient {
773
785
  * @throws {TurnkeyError} If there is an error during the OTP login process or if key pair cleanup fails.
774
786
  */
775
787
  this.loginWithOtp = async (params) => {
776
- const { verificationToken, invalidateExisting = false, publicKey = await this.apiKeyStamper?.createKeyPair(), sessionKey = base.SessionKey.DefaultSessionkey, } = params;
788
+ const { verificationToken, invalidateExisting = false, publicKey = await this.apiKeyStamper?.createKeyPair(), sessionKey = auth.SessionKey.DefaultSessionkey, } = params;
777
789
  return utils.withTurnkeyErrorHandling(async () => {
778
790
  const res = await this.httpClient.proxyOtpLogin({
779
791
  verificationToken,
@@ -834,7 +846,7 @@ class TurnkeyClient {
834
846
  const signUpBody = utils.buildSignUpBody({
835
847
  createSubOrgParams: {
836
848
  ...createSubOrgParams,
837
- ...(otpType === base.OtpType.Email
849
+ ...(otpType === auth.OtpType.Email
838
850
  ? { userEmail: contact }
839
851
  : { userPhoneNumber: contact }),
840
852
  verificationToken,
@@ -946,7 +958,7 @@ class TurnkeyClient {
946
958
  * @throws {TurnkeyError} If there is an error during the OAuth completion process, such as account lookup, sign-up, or login.
947
959
  */
948
960
  this.completeOauth = async (params) => {
949
- const { oidcToken, publicKey, createSubOrgParams, providerName = "OpenID Connect Provider" + Date.now(), sessionKey = base.SessionKey.DefaultSessionkey, invalidateExisting = false, } = params;
961
+ const { oidcToken, publicKey, createSubOrgParams, providerName = "OpenID Connect Provider" + " " + Date.now(), sessionKey = auth.SessionKey.DefaultSessionkey, invalidateExisting = false, } = params;
950
962
  return utils.withTurnkeyErrorHandling(async () => {
951
963
  const accountRes = await this.httpClient.proxyGetAccount({
952
964
  filterType: "OIDC_TOKEN",
@@ -1005,7 +1017,7 @@ class TurnkeyClient {
1005
1017
  * @throws {TurnkeyError} If there is an error during the OAuth login process or if key pair cleanup fails.
1006
1018
  */
1007
1019
  this.loginWithOauth = async (params) => {
1008
- const { oidcToken, invalidateExisting = false, publicKey, sessionKey = base.SessionKey.DefaultSessionkey, } = params;
1020
+ const { oidcToken, invalidateExisting = false, publicKey, sessionKey = auth.SessionKey.DefaultSessionkey, } = params;
1009
1021
  return utils.withTurnkeyErrorHandling(async () => {
1010
1022
  if (!publicKey) {
1011
1023
  throw new sdkTypes.TurnkeyError("Public key must be provided to log in with OAuth. Please create a key pair first.", sdkTypes.TurnkeyErrorCodes.MISSING_PARAMS);
@@ -1029,7 +1041,7 @@ class TurnkeyClient {
1029
1041
  }, {
1030
1042
  errorMessage: "Failed to complete OAuth login",
1031
1043
  errorCode: sdkTypes.TurnkeyErrorCodes.OAUTH_LOGIN_ERROR,
1032
- customMessageByMessages: {
1044
+ customErrorsByMessages: {
1033
1045
  "OAUTH disallowed": {
1034
1046
  message: "OAuth is disabled on the dashboard for this organization.",
1035
1047
  code: sdkTypes.TurnkeyErrorCodes.AUTH_METHOD_NOT_ENABLED,
@@ -1102,39 +1114,64 @@ class TurnkeyClient {
1102
1114
  * - Returns both embedded and connected wallets in a single array, each with their respective accounts populated.
1103
1115
  * - Optionally allows stamping the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
1104
1116
  *
1105
- * @param params.stampWith - parameter to stamp the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
1106
1117
  * @param params.walletProviders - array of wallet providers to use for fetching wallets.
1118
+ * @param params.organizationId - organization ID to target (defaults to the session's organization ID).
1119
+ * @param params.userId - user ID to target (defaults to the session's user ID).
1120
+ * @param params.connectedOnly - if true, fetches only connected wallets; if false or undefined, fetches both embedded and connected wallets.
1121
+ * @param params.stampWith - parameter to stamp the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
1107
1122
  * @returns A promise that resolves to an array of `Wallet` objects.
1108
1123
  * @throws {TurnkeyError} If no active session is found or if there is an error fetching wallets.
1109
1124
  */
1110
1125
  this.fetchWallets = async (params) => {
1111
- const { stampWith, walletProviders } = params || {};
1126
+ const { walletProviders, organizationId: organizationIdFromParams, userId: userIdFromParams, connectedOnly, stampWith, } = params || {};
1112
1127
  const session = await this.storageManager.getActiveSession();
1113
- if (!session) {
1114
- throw new sdkTypes.TurnkeyError("No active session found. Please log in first.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
1128
+ if (!session && !connectedOnly) {
1129
+ throw new sdkTypes.TurnkeyError("No active session found. Fetching embedded wallets requires a valid session. If you only need connected wallets, set the 'connectedOnly' parameter to true.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
1130
+ }
1131
+ // if `connectedOnly` is true, we need to make sure the walletManager is initialized
1132
+ // or else we can't fetch connected wallets, and we throw an error
1133
+ if (connectedOnly && !this.walletManager?.connector) {
1134
+ throw new sdkTypes.TurnkeyError("Wallet connector is not initialized", sdkTypes.TurnkeyErrorCodes.WALLET_MANAGER_COMPONENT_NOT_INITIALIZED);
1115
1135
  }
1116
1136
  return utils.withTurnkeyErrorHandling(async () => {
1117
- const res = await this.httpClient.getWallets({ organizationId: session.organizationId }, stampWith);
1118
- if (!res || !res.wallets) {
1119
- throw new sdkTypes.TurnkeyError("No wallets found in the response", sdkTypes.TurnkeyErrorCodes.BAD_RESPONSE);
1120
- }
1121
- const embedded = await Promise.all(res.wallets.map(async (wallet) => {
1122
- const embeddedWallet = {
1123
- ...wallet,
1124
- source: base.WalletSource.Embedded,
1125
- accounts: [],
1126
- };
1127
- const accounts = await this.fetchWalletAccounts({
1128
- wallet: embeddedWallet,
1129
- ...(stampWith !== undefined && { stampWith }),
1130
- });
1131
- embeddedWallet.accounts = accounts;
1132
- return embeddedWallet;
1133
- }));
1137
+ let embedded = [];
1138
+ // if connectedOnly is true, we skip fetching embedded wallets
1139
+ if (!connectedOnly) {
1140
+ const organizationId = organizationIdFromParams || session?.organizationId;
1141
+ if (!organizationId) {
1142
+ throw new sdkTypes.TurnkeyError("No organization ID provided and no active session found. Please log in first or pass in an organization ID.", sdkTypes.TurnkeyErrorCodes.INVALID_REQUEST);
1143
+ }
1144
+ const userId = userIdFromParams || session?.userId;
1145
+ if (!userId) {
1146
+ throw new sdkTypes.TurnkeyError("No user ID provided and no active session found. Please log in first or pass in a user ID.", sdkTypes.TurnkeyErrorCodes.INVALID_REQUEST);
1147
+ }
1148
+ const res = await this.httpClient.getWalletAccounts({
1149
+ organizationId,
1150
+ includeWalletDetails: true,
1151
+ }, stampWith);
1152
+ const walletsRes = await this.httpClient.getWallets({
1153
+ organizationId,
1154
+ }, stampWith);
1155
+ if (!res || !res.accounts) {
1156
+ throw new sdkTypes.TurnkeyError("No wallet accounts found in the response", sdkTypes.TurnkeyErrorCodes.BAD_RESPONSE);
1157
+ }
1158
+ // create a map of walletId to EmbeddedWallet for easy lookup
1159
+ const walletMap = new Map(walletsRes.wallets.map((wallet) => [
1160
+ wallet.walletId,
1161
+ {
1162
+ ...wallet,
1163
+ source: externalWallets.WalletSource.Embedded,
1164
+ accounts: [],
1165
+ },
1166
+ ]));
1167
+ // map the accounts to their respective wallets
1168
+ embedded = utils.mapAccountsToWallet(res.accounts, walletMap);
1169
+ }
1134
1170
  // if wallet connecting is disabled we return only embedded wallets
1171
+ // this will never be hit if `connectedOnly` is true because of the check above
1135
1172
  if (!this.walletManager?.connector)
1136
1173
  return embedded;
1137
- const providers = walletProviders ?? (await this.getWalletProviders());
1174
+ const providers = walletProviders ?? (await this.fetchWalletProviders());
1138
1175
  const groupedProviders = new Map();
1139
1176
  for (const provider of providers) {
1140
1177
  // connected wallets don't all have some uuid we can use for the walletId
@@ -1145,10 +1182,14 @@ class TurnkeyClient {
1145
1182
  group.push(provider);
1146
1183
  groupedProviders.set(walletId, group);
1147
1184
  }
1148
- const connected = (await Promise.all(Array.from(groupedProviders.entries()).map(async ([walletId, grouped]) => {
1185
+ // has to be done in a for of loop so we can await each fetchWalletAccounts call individually
1186
+ // otherwise await Promise.all would cause them all to fire at once breaking passkey only set ups
1187
+ // (multiple wallet fetches at once causing "OperationError: A request is already pending.")
1188
+ let connected = [];
1189
+ for (const [walletId, grouped] of groupedProviders.entries()) {
1149
1190
  const timestamp = utils.toExternalTimestamp();
1150
1191
  const wallet = {
1151
- source: base.WalletSource.Connected,
1192
+ source: externalWallets.WalletSource.Connected,
1152
1193
  walletId,
1153
1194
  walletName: grouped[0]?.info?.name ?? "Unknown",
1154
1195
  createdAt: timestamp,
@@ -1161,10 +1202,16 @@ class TurnkeyClient {
1161
1202
  wallet,
1162
1203
  walletProviders: grouped,
1163
1204
  ...(stampWith !== undefined && { stampWith }),
1205
+ ...(organizationIdFromParams !== undefined && {
1206
+ organizationId: organizationIdFromParams,
1207
+ }),
1208
+ ...(userIdFromParams !== undefined && { userId: userIdFromParams }),
1164
1209
  });
1165
1210
  wallet.accounts = accounts;
1166
- return wallet;
1167
- }))).filter((wallet) => wallet.accounts.length > 0);
1211
+ if (wallet.accounts.length > 0) {
1212
+ connected.push(wallet);
1213
+ }
1214
+ }
1168
1215
  return [...embedded, ...connected];
1169
1216
  }, {
1170
1217
  errorMessage: "Failed to fetch wallets",
@@ -1184,22 +1231,30 @@ class TurnkeyClient {
1184
1231
  * @param params.walletProviders - list of wallet providers to filter by (used for connected wallets).
1185
1232
  * @param params.paginationOptions - pagination options for embedded wallets.
1186
1233
  * @param params.stampWith - parameter to stamp the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
1234
+ * @param params.organizationId - organization ID to target (defaults to the session's organization ID).
1235
+ * @param params.userId - user ID to target (defaults to the session's user ID).
1236
+ *
1187
1237
  * @returns A promise that resolves to an array of `v1WalletAccount` objects.
1188
1238
  * @throws {TurnkeyError} If no active session is found or if there is an error fetching wallet accounts.
1189
1239
  */
1190
1240
  this.fetchWalletAccounts = async (params) => {
1191
1241
  const { wallet, stampWith, walletProviders, paginationOptions } = params;
1192
1242
  const session = await this.storageManager.getActiveSession();
1193
- if (!session) {
1194
- throw new sdkTypes.TurnkeyError("No active session found. Please log in first.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
1195
- }
1243
+ const organizationId = params?.organizationId || session?.organizationId;
1244
+ const userId = params?.userId || session?.userId;
1196
1245
  return utils.withTurnkeyErrorHandling(async () => {
1197
1246
  // this is an embedded wallet so we fetch accounts from Turnkey
1198
- if (wallet.source === base.WalletSource.Embedded) {
1247
+ if (wallet.source === externalWallets.WalletSource.Embedded) {
1199
1248
  const embedded = [];
1249
+ if (!organizationId) {
1250
+ throw new sdkTypes.TurnkeyError("No organization ID provided and no active session found. Please log in first or pass in an organization ID.", sdkTypes.TurnkeyErrorCodes.INVALID_REQUEST);
1251
+ }
1252
+ if (!userId) {
1253
+ throw new sdkTypes.TurnkeyError("No user ID provided and no active session found. Please log in first or pass in a user ID.", sdkTypes.TurnkeyErrorCodes.INVALID_REQUEST);
1254
+ }
1200
1255
  const res = await this.httpClient.getWalletAccounts({
1201
1256
  walletId: wallet.walletId,
1202
- organizationId: session.organizationId,
1257
+ organizationId,
1203
1258
  paginationOptions: paginationOptions || { limit: "100" },
1204
1259
  }, stampWith);
1205
1260
  if (!res || !res.accounts) {
@@ -1208,7 +1263,7 @@ class TurnkeyClient {
1208
1263
  for (const account of res.accounts) {
1209
1264
  embedded.push({
1210
1265
  ...account,
1211
- source: base.WalletSource.Embedded,
1266
+ source: externalWallets.WalletSource.Embedded,
1212
1267
  });
1213
1268
  }
1214
1269
  return embedded;
@@ -1219,7 +1274,7 @@ class TurnkeyClient {
1219
1274
  if (!this.walletManager?.connector)
1220
1275
  return [];
1221
1276
  const connected = [];
1222
- const providers = walletProviders ?? (await this.getWalletProviders());
1277
+ const providers = walletProviders ?? (await this.fetchWalletProviders());
1223
1278
  // Context: connected wallets don't all have some uuid we can use for the walletId so what
1224
1279
  // we do is we use a normalized version of the name for the wallet, like "metamask"
1225
1280
  // or "phantom-wallet"
@@ -1230,31 +1285,40 @@ class TurnkeyClient {
1230
1285
  const matching = providers.filter((p) => p.info?.name?.toLowerCase().replace(/\s+/g, "-") ===
1231
1286
  wallet.walletId && p.connectedAddresses.length > 0);
1232
1287
  const sign = this.walletManager.connector.sign.bind(this.walletManager.connector);
1233
- const user = await this.fetchUser({
1234
- stampWith,
1235
- });
1236
- const { ethereum: ethereumAddresses, solana: solanaAddresses } = utils.getAuthenticatorAddresses(user);
1288
+ let ethereumAddresses = [];
1289
+ let solanaAddresses = [];
1290
+ // we only fetch the user if we have to the organizationId and userId
1291
+ // if not that means `isAuthenticator` will always be false
1292
+ if (organizationId && userId) {
1293
+ const user = await this.fetchUser({
1294
+ userId,
1295
+ organizationId,
1296
+ stampWith,
1297
+ });
1298
+ ({ ethereum: ethereumAddresses, solana: solanaAddresses } =
1299
+ utils.getAuthenticatorAddresses(user));
1300
+ }
1237
1301
  for (const provider of matching) {
1238
1302
  const timestamp = utils.toExternalTimestamp();
1239
1303
  for (const address of provider.connectedAddresses) {
1240
1304
  if (utils.isEthereumProvider(provider)) {
1241
1305
  const evmAccount = {
1242
1306
  walletAccountId: `${wallet.walletId}-${provider.interfaceType}-${address}`,
1243
- organizationId: session.organizationId,
1307
+ organizationId: organizationId ?? "",
1244
1308
  walletId: wallet.walletId,
1245
1309
  pathFormat: "PATH_FORMAT_BIP32",
1246
- path: base.WalletSource.Connected,
1247
- source: base.WalletSource.Connected,
1310
+ path: externalWallets.WalletSource.Connected,
1311
+ source: externalWallets.WalletSource.Connected,
1248
1312
  address,
1249
1313
  createdAt: timestamp,
1250
1314
  updatedAt: timestamp,
1251
1315
  // ethereum specific
1252
- curve: base.Curve.SECP256K1,
1316
+ curve: externalWallets.Curve.SECP256K1,
1253
1317
  addressFormat: "ADDRESS_FORMAT_ETHEREUM",
1254
1318
  chainInfo: provider.chainInfo,
1255
1319
  isAuthenticator: ethereumAddresses.includes(address.toLowerCase()),
1256
- signMessage: (msg) => sign(msg, provider, base.SignIntent.SignMessage),
1257
- signAndSendTransaction: (tx) => sign(tx, provider, base.SignIntent.SignAndSendTransaction),
1320
+ signMessage: (msg) => sign(msg, provider, externalWallets.SignIntent.SignMessage),
1321
+ signAndSendTransaction: (tx) => sign(tx, provider, externalWallets.SignIntent.SignAndSendTransaction),
1258
1322
  };
1259
1323
  connected.push(evmAccount);
1260
1324
  continue;
@@ -1262,22 +1326,22 @@ class TurnkeyClient {
1262
1326
  if (utils.isSolanaProvider(provider)) {
1263
1327
  const solAccount = {
1264
1328
  walletAccountId: `${wallet.walletId}-${provider.interfaceType}-${address}`,
1265
- organizationId: session.organizationId,
1329
+ organizationId: organizationId ?? "",
1266
1330
  walletId: wallet.walletId,
1267
1331
  pathFormat: "PATH_FORMAT_BIP32",
1268
- path: base.WalletSource.Connected,
1269
- source: base.WalletSource.Connected,
1332
+ path: externalWallets.WalletSource.Connected,
1333
+ source: externalWallets.WalletSource.Connected,
1270
1334
  address,
1271
1335
  createdAt: timestamp,
1272
1336
  updatedAt: timestamp,
1273
1337
  // solana specific
1274
1338
  publicKey: address,
1275
- curve: base.Curve.ED25519,
1339
+ curve: externalWallets.Curve.ED25519,
1276
1340
  addressFormat: "ADDRESS_FORMAT_SOLANA",
1277
1341
  chainInfo: provider.chainInfo,
1278
1342
  isAuthenticator: solanaAddresses.includes(address),
1279
- signMessage: (msg) => sign(msg, provider, base.SignIntent.SignMessage),
1280
- signTransaction: (tx) => sign(tx, provider, base.SignIntent.SignTransaction),
1343
+ signMessage: (msg) => sign(msg, provider, externalWallets.SignIntent.SignMessage),
1344
+ signTransaction: (tx) => sign(tx, provider, externalWallets.SignIntent.SignTransaction),
1281
1345
  };
1282
1346
  connected.push(solAccount);
1283
1347
  continue;
@@ -1298,17 +1362,19 @@ class TurnkeyClient {
1298
1362
  * - Supports stamping the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
1299
1363
  *
1300
1364
  * @param params.stampWith - parameter to stamp the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
1365
+ * @param params.organizationId - organization ID to target (defaults to the session's organization ID).
1301
1366
  * @returns A promise that resolves to an array of `v1PrivateKey` objects.
1302
1367
  * @throws {TurnkeyError} If no active session is found or if there is an error fetching private keys.
1303
1368
  */
1304
1369
  this.fetchPrivateKeys = async (params) => {
1305
1370
  const { stampWith } = params || {};
1306
- const session = await this.storageManager.getActiveSession();
1307
- if (!session) {
1308
- throw new sdkTypes.TurnkeyError("No active session found. Please log in first.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
1371
+ const session = await utils.getActiveSessionOrThrowIfRequired(stampWith, this.storageManager.getActiveSession);
1372
+ const organizationId = params?.organizationId || session?.organizationId;
1373
+ if (!organizationId) {
1374
+ throw new sdkTypes.TurnkeyError("No organization ID provided and no active session found. Please log in first or pass in an organization ID.", sdkTypes.TurnkeyErrorCodes.INVALID_REQUEST);
1309
1375
  }
1310
1376
  return utils.withTurnkeyErrorHandling(async () => {
1311
- const res = await this.httpClient.getPrivateKeys({ organizationId: session.organizationId }, stampWith);
1377
+ const res = await this.httpClient.getPrivateKeys({ organizationId }, stampWith);
1312
1378
  if (!res) {
1313
1379
  throw new sdkTypes.TurnkeyError("Failed to fetch private keys", sdkTypes.TurnkeyErrorCodes.BAD_RESPONSE);
1314
1380
  }
@@ -1321,61 +1387,77 @@ class TurnkeyClient {
1321
1387
  /**
1322
1388
  * Signs a message using the specified wallet account.
1323
1389
  *
1324
- * - Supports both embedded and connected wallets.
1325
- * - For **connected wallets**:
1390
+ * Behavior differs depending on the wallet type:
1391
+ *
1392
+ * - **Connected wallets**
1326
1393
  * - Delegates signing to the wallet provider’s native signing method.
1327
- * - **Important:** For Ethereum wallets (e.g., MetaMask), signatures follow [EIP-191](https://eips.ethereum.org/EIPS/eip-191).
1328
- * The message is automatically prefixed with `"\x19Ethereum Signed Message:\n" + message length`
1329
- * before signing. As a result, this signature **cannot be used as a raw transaction signature**
1330
- * or broadcast on-chain.
1331
- * - For **embedded wallets**, uses the Turnkey API to sign the message directly.
1332
- * - Automatically handles message encoding and hashing based on the wallet account’s address format,
1394
+ * - *Ethereum*: signatures always follow [EIP-191](https://eips.ethereum.org/EIPS/eip-191).
1395
+ * - The wallet automatically prefixes messages with
1396
+ * `"\x19Ethereum Signed Message:\n" + message length` before signing.
1397
+ * - As a result, these signatures cannot be used as raw transaction signatures or broadcast on-chain.
1398
+ * - If `addEthereumPrefix` is set to `false`, an error is thrown because connected Ethereum wallets always prefix.
1399
+ * - *Other chains*: follows the native connected wallet behavior.
1400
+ *
1401
+ * - **Embedded wallets**
1402
+ * - Uses the Turnkey API to sign the message directly.
1403
+ * - Supports optional `addEthereumPrefix`:
1404
+ * - If `true` (default for Ethereum), the message is prefixed before signing.
1405
+ * - If `false`, the raw message is signed without any prefix.
1406
+ *
1407
+ * Additional details:
1408
+ * - Automatically handles encoding and hashing based on the wallet account’s address format,
1333
1409
  * unless explicitly overridden.
1410
+ * - Optionally allows stamping with a specific stamper
1411
+ * (`StamperType.Passkey`, `StamperType.ApiKey`, or `StamperType.Wallet`).
1334
1412
  *
1335
- * @param params.message - message to sign.
1413
+ * @param params.message - plaintext (UTF-8) message to sign.
1336
1414
  * @param params.walletAccount - wallet account to use for signing.
1337
- * @param params.encoding - override for the payload encoding (defaults to the encoding appropriate for the address type).
1338
- * @param params.hashFunction - override for the hash function (defaults to the hash function appropriate for the address type).
1339
- * @param params.stampWith - stamper to tag the signing request (e.g., Passkey, ApiKey, or Wallet).
1340
- * @param params.addEthereumPrefix - whether to prefix the message with Ethereum's `"\x19Ethereum Signed Message:\n"` string.
1341
- * - If `true` (default for Ethereum), the message is prefixed before signing.
1342
- * - If `false`:
1343
- * - Connected wallets will throw an error because they always prefix automatically.
1344
- * - Embedded wallets will sign the raw message without any prefix.
1345
- *
1346
- * @returns A promise resolving to a `v1SignRawPayloadResult` containing the signature and metadata.
1347
- * @throws {TurnkeyError} If signing fails, if the wallet account does not support signing, or if the response is invalid.
1415
+ * @param params.encoding - override for payload encoding (defaults to the encoding appropriate for the address format).
1416
+ * @param params.hashFunction - override for hash function (defaults to the function appropriate for the address format).
1417
+ * @param params.stampWith - optional stamper for the signing request.
1418
+ * @param params.addEthereumPrefix - whether to prefix the message with Ethereums
1419
+ * `"\x19Ethereum Signed Message:\n"` string (default: `true` for Ethereum).
1420
+ * @param params.organizationId - organization ID to target (defaults to the session's organization ID).
1421
+ *
1422
+ * @returns A promise that resolves to a `v1SignRawPayloadResult` containing the signature and metadata.
1423
+ * @throws {TurnkeyError} If signing fails, the wallet type does not support message signing, or the response is invalid.
1348
1424
  */
1349
1425
  this.signMessage = async (params) => {
1350
- const { message, walletAccount, stampWith, addEthereumPrefix } = params;
1426
+ const { message, walletAccount, stampWith, addEthereumPrefix, organizationId, } = params;
1351
1427
  const hashFunction = params.hashFunction || utils.getHashFunction(walletAccount.addressFormat);
1352
1428
  const payloadEncoding = params.encoding || utils.getEncodingType(walletAccount.addressFormat);
1353
1429
  return utils.withTurnkeyErrorHandling(async () => {
1354
1430
  const isEthereum = walletAccount.addressFormat === "ADDRESS_FORMAT_ETHEREUM";
1355
- if (walletAccount.source === base.WalletSource.Connected) {
1431
+ if (walletAccount.source === externalWallets.WalletSource.Connected) {
1356
1432
  // this is a connected wallet
1357
1433
  if (!addEthereumPrefix && isEthereum) {
1358
1434
  throw new sdkTypes.TurnkeyError("Connected Ethereum wallets automatically prefix messages. Use `addEthereumPrefix: true`.", sdkTypes.TurnkeyErrorCodes.SIGN_MESSAGE_ERROR);
1359
1435
  }
1360
1436
  let encodedMessage = message;
1361
1437
  if (isEthereum) {
1362
- encodedMessage = utils.getEncodedMessage(walletAccount.addressFormat, message);
1438
+ const msgBytes = ethers.toUtf8Bytes(message);
1439
+ encodedMessage = utils.getEncodedMessage(payloadEncoding, msgBytes);
1363
1440
  }
1364
1441
  const sigHex = await walletAccount.signMessage(encodedMessage);
1365
1442
  return utils.splitSignature(sigHex, walletAccount.addressFormat);
1366
1443
  }
1367
1444
  // this is an embedded wallet
1368
- let messageToEncode = message;
1445
+ let msgBytes = ethers.toUtf8Bytes(message);
1369
1446
  if (addEthereumPrefix && isEthereum) {
1370
- const prefix = `\x19Ethereum Signed Message:\n${ethers.toUtf8Bytes(message).length}`;
1371
- messageToEncode = prefix + message;
1372
- }
1373
- const encodedMessage = utils.getEncodedMessage(walletAccount.addressFormat, messageToEncode);
1447
+ const prefix = `\x19Ethereum Signed Message:\n${msgBytes.length}`;
1448
+ const prefixBytes = ethers.toUtf8Bytes(prefix);
1449
+ const combined = new Uint8Array(prefixBytes.length + msgBytes.length);
1450
+ combined.set(prefixBytes, 0);
1451
+ combined.set(msgBytes, prefixBytes.length);
1452
+ msgBytes = combined;
1453
+ }
1454
+ const encodedMessage = utils.getEncodedMessage(payloadEncoding, msgBytes);
1374
1455
  const response = await this.httpClient.signRawPayload({
1375
1456
  signWith: walletAccount.address,
1376
1457
  payload: encodedMessage,
1377
1458
  encoding: payloadEncoding,
1378
1459
  hashFunction,
1460
+ ...(organizationId && { organizationId }),
1379
1461
  }, stampWith);
1380
1462
  if (response.activity.failure) {
1381
1463
  throw new sdkTypes.TurnkeyError("Failed to sign message, no signed payload returned", sdkTypes.TurnkeyErrorCodes.SIGN_MESSAGE_ERROR);
@@ -1390,27 +1472,35 @@ class TurnkeyClient {
1390
1472
  /**
1391
1473
  * Signs a transaction using the specified wallet account.
1392
1474
  *
1393
- * - This function signs a blockchain transaction using the provided wallet address and transaction data.
1394
- * - Supports all Turnkey-supported blockchain networks (e.g., Ethereum, Solana, Tron).
1395
- * - Automatically determines the appropriate signing method based on the transaction type.
1396
- * - Delegates signing to the Turnkey API, which returns the signed transaction and related metadata.
1397
- * - Optionally allows stamping the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
1475
+ * Behavior differs depending on the type of wallet:
1476
+ *
1477
+ * - **Connected wallets**
1478
+ * - Ethereum: does not support raw transaction signing. Calling this function will throw an error instructing you to use `signAndSendTransaction` instead.
1479
+ * - Solana: supports raw transaction signing via the connected wallet provider.
1480
+ * - Other chains: not supported; will throw an error.
1481
+ *
1482
+ * - **Embedded wallets**
1483
+ * - Delegates signing to the Turnkey API, which returns the signed transaction.
1484
+ * - Supports all Turnkey-supported transaction types (e.g., Ethereum, Solana, Tron).
1485
+ * - Optionally allows stamping with a specific stamper (`StamperType.Passkey`, `StamperType.ApiKey`, or `StamperType.Wallet`).
1398
1486
  *
1399
- * @param params.walletAccount - wallet account to use for signing the transaction.
1400
- * @param params.unsignedTransaction - unsigned transaction data (serialized as a string) to be signed.
1487
+ * @param params.walletAccount - wallet account to use for signing.
1488
+ * @param params.unsignedTransaction - unsigned transaction data as a serialized
1489
+ * string in the canonical encoding for the given `transactionType`.
1401
1490
  * @param params.transactionType - type of transaction (e.g., "TRANSACTION_TYPE_ETHEREUM", "TRANSACTION_TYPE_SOLANA", "TRANSACTION_TYPE_TRON").
1402
- * @param params.stampWith - parameter to stamp the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
1403
- * @returns A promise that resolves to a `TSignTransactionResponse` object containing the signed transaction and any additional signing metadata.
1404
- * @throws {TurnkeyError} If there is an error signing the transaction or if the response is invalid.
1491
+ * @param params.stampWith - stamper to use for signing (`StamperType.Passkey`, `StamperType.ApiKey`, or `StamperType.Wallet`).
1492
+ * @param params.organizationId - organization ID to target (defaults to the session's organization ID).
1493
+ * @returns A promise that resolves to the signed transaction string.
1494
+ * @throws {TurnkeyError} If the wallet type is unsupported, signing fails, or the response is invalid.
1405
1495
  */
1406
1496
  this.signTransaction = async (params) => {
1407
- const { walletAccount, unsignedTransaction, transactionType, stampWith } = params;
1497
+ const { walletAccount, unsignedTransaction, transactionType, stampWith, organizationId, } = params;
1408
1498
  return utils.withTurnkeyErrorHandling(async () => {
1409
- if (walletAccount.source === base.WalletSource.Connected) {
1499
+ if (walletAccount.source === externalWallets.WalletSource.Connected) {
1410
1500
  switch (walletAccount.chainInfo.namespace) {
1411
- case base.Chain.Ethereum:
1501
+ case externalWallets.Chain.Ethereum:
1412
1502
  throw new sdkTypes.TurnkeyError("Ethereum connected wallets do not support raw transaction signing. Use signAndSendTransaction instead.", sdkTypes.TurnkeyErrorCodes.INVALID_REQUEST);
1413
- case base.Chain.Solana:
1503
+ case externalWallets.Chain.Solana:
1414
1504
  // not sure why typescript isn't inferring the type here
1415
1505
  // if namespace is Chain.Solana, then it must be a ConnectedSolanaWalletAccount
1416
1506
  return walletAccount.signTransaction(unsignedTransaction);
@@ -1423,6 +1513,7 @@ class TurnkeyClient {
1423
1513
  signWith: walletAccount.address,
1424
1514
  unsignedTransaction,
1425
1515
  type: transactionType,
1516
+ ...(organizationId && { organizationId }),
1426
1517
  }, stampWith);
1427
1518
  return signTransaction.signedTransaction;
1428
1519
  }, {
@@ -1433,34 +1524,41 @@ class TurnkeyClient {
1433
1524
  /**
1434
1525
  * Signs and broadcasts a transaction using the specified wallet account.
1435
1526
  *
1436
- * - For **connected wallets**:
1437
- * - Calls the wallet’s native `signAndSendTransaction` method.
1438
- * - Does **not** require an `rpcUrl`.
1527
+ * Behavior differs depending on the type of wallet:
1439
1528
  *
1440
- * - For **embedded wallets**:
1529
+ * - **Connected wallets**
1530
+ * - *Ethereum*: delegates to the wallet’s native `signAndSendTransaction` method.
1531
+ * - Does **not** require an `rpcUrl` (the wallet handles broadcasting).
1532
+ * - *Solana*: signs the transaction locally with the connected wallet, but requires an `rpcUrl` to broadcast it.
1533
+ * - Other chains: not supported; will throw an error.
1534
+ *
1535
+ * - **Embedded wallets**
1441
1536
  * - Signs the transaction using the Turnkey API.
1442
- * - Requires an `rpcUrl` to broadcast the transaction.
1443
- * - Broadcasts the transaction using a JSON-RPC client.
1444
- *
1445
- * @param params.walletAccount - wallet account to use for signing and sending.
1446
- * @param params.unsignedTransaction - unsigned transaction (serialized string).
1447
- * @param params.transactionType - transaction type (e.g., "TRANSACTION_TYPE_SOLANA").
1448
- * @param params.rpcUrl - required for embedded wallets to broadcast the signed transaction.
1449
- * @param params.stampWith - optional stamper to tag the signing request.
1537
+ * - Requires an `rpcUrl` to broadcast the signed transaction, since Turnkey does not broadcast directly.
1538
+ * - Broadcasts the transaction using a JSON-RPC client and returns the resulting transaction hash/signature.
1539
+ * - Optionally allows stamping with a specific stamper (`StamperType.Passkey`, `StamperType.ApiKey`, or `StamperType.Wallet`).
1540
+ *
1541
+ * @param params.walletAccount - wallet account to use for signing and broadcasting.
1542
+ * @param params.unsignedTransaction - unsigned transaction data as a serialized
1543
+ * string in the canonical encoding for the given `transactionType`.
1544
+ * @param params.transactionType - type of transaction (e.g., `"TRANSACTION_TYPE_SOLANA"`, `"TRANSACTION_TYPE_ETHEREUM"`).
1545
+ * @param params.rpcUrl - JSON-RPC endpoint used for broadcasting (required for Solana connected wallets and all embedded wallets).
1546
+ * @param params.stampWith - optional stamper to use when signing (`StamperType.Passkey`, `StamperType.ApiKey`, or `StamperType.Wallet`).
1547
+ * @param params.organizationId - **Only for Turnkey embedded wallets**: organization ID to target (defaults to the session's organization ID).
1450
1548
  * @returns A promise that resolves to a transaction signature or hash.
1451
- * @throws {TurnkeyError} If signing or broadcasting fails.
1549
+ * @throws {TurnkeyError} If the wallet type is unsupported, or if signing/broadcasting fails.
1452
1550
  */
1453
1551
  this.signAndSendTransaction = async (params) => {
1454
- const { walletAccount, unsignedTransaction, transactionType, rpcUrl, stampWith, } = params;
1552
+ const { walletAccount, unsignedTransaction, transactionType, rpcUrl, stampWith, organizationId, } = params;
1455
1553
  return utils.withTurnkeyErrorHandling(async () => {
1456
- if (walletAccount.source === base.WalletSource.Connected) {
1554
+ if (walletAccount.source === externalWallets.WalletSource.Connected) {
1457
1555
  // this is a connected wallet account
1458
1556
  switch (walletAccount.chainInfo.namespace) {
1459
- case base.Chain.Ethereum:
1557
+ case externalWallets.Chain.Ethereum:
1460
1558
  // not sure why typescript isn't inferring the type here
1461
1559
  // if namespace is Chain.Ethereum, then it must be a ConnectedEthereumWalletAccount
1462
1560
  return await walletAccount.signAndSendTransaction(unsignedTransaction);
1463
- case base.Chain.Solana:
1561
+ case externalWallets.Chain.Solana:
1464
1562
  if (!rpcUrl) {
1465
1563
  throw new sdkTypes.TurnkeyError("Missing rpcUrl: connected Solana wallets require an RPC URL to broadcast transactions.", sdkTypes.TurnkeyErrorCodes.SIGN_AND_SEND_TRANSACTION_ERROR);
1466
1564
  }
@@ -1486,6 +1584,7 @@ class TurnkeyClient {
1486
1584
  signWith: walletAccount.address,
1487
1585
  unsignedTransaction,
1488
1586
  type: transactionType,
1587
+ ...(organizationId && { organizationId }),
1489
1588
  }, stampWith);
1490
1589
  const signedTx = signTransactionResponse.signedTransaction;
1491
1590
  const txHash = await utils.broadcastTransaction({
@@ -1515,16 +1614,16 @@ class TurnkeyClient {
1515
1614
  * @throws {TurnkeyError} If there is no active session, if there is no userId, or if there is an error fetching user details.
1516
1615
  */
1517
1616
  this.fetchUser = async (params) => {
1518
- const { stampWith } = params || {};
1519
- const session = await this.storageManager.getActiveSession();
1520
- if (!session) {
1521
- throw new sdkTypes.TurnkeyError("No active session found. Please log in first.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
1522
- }
1523
- const userId = params?.userId || session.userId;
1617
+ const { organizationId: organizationIdFromParams, userId: userIdFromParams, stampWith, } = params || {};
1618
+ const session = await utils.getActiveSessionOrThrowIfRequired(stampWith, this.storageManager.getActiveSession);
1619
+ const userId = userIdFromParams || session?.userId;
1524
1620
  if (!userId) {
1525
1621
  throw new sdkTypes.TurnkeyError("User ID must be provided to fetch user", sdkTypes.TurnkeyErrorCodes.INVALID_REQUEST);
1526
1622
  }
1527
- const organizationId = params?.organizationId || session.organizationId;
1623
+ const organizationId = organizationIdFromParams || session?.organizationId;
1624
+ if (!organizationId) {
1625
+ throw new sdkTypes.TurnkeyError("Organization ID must be provided to fetch user", sdkTypes.TurnkeyErrorCodes.INVALID_REQUEST);
1626
+ }
1528
1627
  return utils.withTurnkeyErrorHandling(async () => {
1529
1628
  const userResponse = await this.httpClient.getUser({ organizationId, userId }, stampWith);
1530
1629
  if (!userResponse || !userResponse.user) {
@@ -1536,6 +1635,170 @@ class TurnkeyClient {
1536
1635
  errorCode: sdkTypes.TurnkeyErrorCodes.FETCH_USER_ERROR,
1537
1636
  });
1538
1637
  };
1638
+ /**
1639
+ * Fetches an existing user by P-256 API key public key, or creates a new one if none exists.
1640
+ *
1641
+ * - This function is idempotent: multiple calls with the same `publicKey` will always return the same user.
1642
+ * - Attempts to find a user whose API keys include the given P-256 public key.
1643
+ * - If a matching user is found, it is returned as-is.
1644
+ * - If no matching user is found, a new user is created with the given public key as a P-256 API key.
1645
+ *
1646
+ * @param params.publicKey - the P-256 public key to use for lookup and creation.
1647
+ * @param params.createParams.userName - optional username to assign if creating a new user (defaults to `"Public Key User"`).
1648
+ * @param params.createParams.apiKeyName - optional API key name to assign if creating a new API key (defaults to `public-key-user-${publicKey}`).
1649
+ * @param params.organizationId - organization ID to specify the sub-organization (defaults to the current session's organizationId).
1650
+ * @param params.stampWith - parameter to stamp the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
1651
+ * @returns A promise that resolves to the existing or newly created {@link v1User}.
1652
+ * @throws {TurnkeyError} If there is no active session, if the input is invalid, if user retrieval fails, or if user creation fails.
1653
+ */
1654
+ this.fetchOrCreateP256ApiKeyUser = async (params) => {
1655
+ const { publicKey, createParams, stampWith, organizationId: organizationIdFromParams, } = params;
1656
+ return utils.withTurnkeyErrorHandling(async () => {
1657
+ const session = await utils.getActiveSessionOrThrowIfRequired(stampWith, this.storageManager.getActiveSession);
1658
+ const organizationId = organizationIdFromParams || session?.organizationId;
1659
+ if (!organizationId) {
1660
+ throw new sdkTypes.TurnkeyError("Organization ID is required to fetch or create P-256 API key user.", sdkTypes.TurnkeyErrorCodes.INVALID_REQUEST);
1661
+ }
1662
+ // we validate their input
1663
+ if (!publicKey?.trim()) {
1664
+ throw new sdkTypes.TurnkeyError("'publicKey' is required and cannot be empty.", sdkTypes.TurnkeyErrorCodes.INVALID_REQUEST);
1665
+ }
1666
+ const usersResponse = await this.httpClient.getUsers({
1667
+ organizationId,
1668
+ }, stampWith);
1669
+ if (!usersResponse || !usersResponse.users) {
1670
+ throw new sdkTypes.TurnkeyError("No users found in the response", sdkTypes.TurnkeyErrorCodes.BAD_RESPONSE);
1671
+ }
1672
+ const userWithPublicKey = usersResponse.users.find((user) => user.apiKeys.some((apiKey) => apiKey.credential.publicKey === publicKey &&
1673
+ apiKey.credential.type === "CREDENTIAL_TYPE_API_KEY_P256"));
1674
+ // the user already exists, so we return it
1675
+ if (userWithPublicKey) {
1676
+ return userWithPublicKey;
1677
+ }
1678
+ // at this point we know the user doesn't exist, so we create it
1679
+ const userName = createParams?.userName?.trim() || "Public Key User";
1680
+ const apiKeyName = createParams?.apiKeyName?.trim() || `public-key-user-${publicKey}`;
1681
+ const createUserResp = await this.httpClient.createUsers({
1682
+ organizationId,
1683
+ users: [
1684
+ {
1685
+ userName: userName,
1686
+ userTags: [],
1687
+ apiKeys: [
1688
+ {
1689
+ apiKeyName: apiKeyName,
1690
+ curveType: "API_KEY_CURVE_P256",
1691
+ publicKey,
1692
+ },
1693
+ ],
1694
+ authenticators: [],
1695
+ oauthProviders: [],
1696
+ },
1697
+ ],
1698
+ }, stampWith);
1699
+ if (!createUserResp?.userIds ||
1700
+ createUserResp.userIds.length === 0 ||
1701
+ !createUserResp.userIds[0]) {
1702
+ throw new sdkTypes.TurnkeyError("Failed to create P-256 API key user", sdkTypes.TurnkeyErrorCodes.CREATE_USERS_ERROR);
1703
+ }
1704
+ const newUserId = createUserResp.userIds[0];
1705
+ return await this.fetchUser({
1706
+ organizationId,
1707
+ userId: newUserId,
1708
+ stampWith,
1709
+ });
1710
+ }, {
1711
+ errorMessage: "Failed to get or create P-256 API key user",
1712
+ errorCode: sdkTypes.TurnkeyErrorCodes.CREATE_USERS_ERROR,
1713
+ });
1714
+ };
1715
+ /**
1716
+ * Fetches each requested policy if it exists, or creates it if it does not.
1717
+ *
1718
+ * - This function is idempotent: multiple calls with the same policies will not create duplicates.
1719
+ * - For every policy in the request:
1720
+ * - If it already exists, it is returned with its `policyId`.
1721
+ * - If it does not exist, it is created and returned with its new `policyId`.
1722
+ *
1723
+ * @param params.policies - the list of policies to fetch or create.
1724
+ * @param params.stampWith - parameter to stamp the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
1725
+ * @param params.organizationId - organization ID to specify the sub-organization (defaults to the current session's organizationId).
1726
+ * @returns A promise that resolves to an array of objects, each containing:
1727
+ * - `policyId`: the unique identifier of the policy.
1728
+ * - `policyName`: human-readable name of the policy.
1729
+ * - `effect`: the instruction to DENY or ALLOW an activity.
1730
+ * - `condition`: (optional) the condition expression that triggers the effect.
1731
+ * - `consensus`: (optional) the consensus expression that triggers the effect.
1732
+ * - `notes`: (optional) developer notes or description for the policy.
1733
+ * @throws {TurnkeyError} If there is no active session, if the input is invalid,
1734
+ * if fetching policies fails, or if creating policies fails.
1735
+ */
1736
+ this.fetchOrCreatePolicies = async (params) => {
1737
+ const { policies, stampWith } = params;
1738
+ return await utils.withTurnkeyErrorHandling(async () => {
1739
+ const session = await utils.getActiveSessionOrThrowIfRequired(stampWith, this.storageManager.getActiveSession);
1740
+ if (!Array.isArray(policies) || policies.length === 0) {
1741
+ throw new sdkTypes.TurnkeyError("'policies' must be a non-empty array of policy definitions.", sdkTypes.TurnkeyErrorCodes.INVALID_REQUEST);
1742
+ }
1743
+ const organizationId = params?.organizationId ?? session?.organizationId;
1744
+ if (!organizationId) {
1745
+ throw new sdkTypes.TurnkeyError("Organization ID is required to fetch or create policies.", sdkTypes.TurnkeyErrorCodes.INVALID_REQUEST);
1746
+ }
1747
+ // we first fetch existing policies
1748
+ const existingPoliciesResponse = await this.httpClient.getPolicies({
1749
+ organizationId,
1750
+ }, stampWith);
1751
+ const existingPolicies = existingPoliciesResponse.policies || [];
1752
+ // we create a map of existing policies by their signature
1753
+ // where the policySignature maps to its policyId
1754
+ const existingPoliciesSignatureMap = {};
1755
+ for (const existingPolicy of existingPolicies) {
1756
+ const signature = utils.getPolicySignature(existingPolicy);
1757
+ existingPoliciesSignatureMap[signature] = existingPolicy.policyId;
1758
+ }
1759
+ // we go through each requested policy and check if it already exists
1760
+ // if it exists, we add it to the alreadyExistingPolicies list
1761
+ // if it doesn't exist, we add it to the missingPolicies list
1762
+ const alreadyExistingPolicies = [];
1763
+ const missingPolicies = [];
1764
+ for (const policy of policies) {
1765
+ const existingId = existingPoliciesSignatureMap[utils.getPolicySignature(policy)];
1766
+ if (existingId) {
1767
+ alreadyExistingPolicies.push({ ...policy, policyId: existingId });
1768
+ }
1769
+ else {
1770
+ missingPolicies.push(policy);
1771
+ }
1772
+ }
1773
+ // if there are no missing policies, that means we're done
1774
+ // so we return them with their respective IDs
1775
+ if (missingPolicies.length === 0) {
1776
+ return alreadyExistingPolicies;
1777
+ }
1778
+ // at this point we know there is at least one missing policy.
1779
+ // so we create the missing policies and then return the full list
1780
+ const createPoliciesResponse = await this.httpClient.createPolicies({
1781
+ organizationId,
1782
+ policies: missingPolicies,
1783
+ }, stampWith);
1784
+ // assign returned IDs back to the missing ones in order
1785
+ if (!createPoliciesResponse || !createPoliciesResponse.policyIds) {
1786
+ throw new sdkTypes.TurnkeyError("Failed to create missing policies", sdkTypes.TurnkeyErrorCodes.CREATE_POLICY_ERROR);
1787
+ }
1788
+ const newlyCreatedPolicies = missingPolicies.map((p, idx) => ({
1789
+ ...p,
1790
+ // we can safely assert the ID exists because we know Turnkey's api
1791
+ // will return one ID for each created policy or throw an error
1792
+ policyId: createPoliciesResponse.policyIds[idx],
1793
+ }));
1794
+ // we return the full list of policies, both existing and the newly created
1795
+ // which includes each of their respective IDs
1796
+ return [...alreadyExistingPolicies, ...newlyCreatedPolicies];
1797
+ }, {
1798
+ errorMessage: "Failed to get or create policies",
1799
+ errorCode: sdkTypes.TurnkeyErrorCodes.CREATE_USERS_ERROR,
1800
+ });
1801
+ };
1539
1802
  /**
1540
1803
  * Updates the user's email address.
1541
1804
  *
@@ -1549,19 +1812,20 @@ class TurnkeyClient {
1549
1812
  * @param params.verificationToken - verification token from OTP email verification (required if verifying the email).
1550
1813
  * @param params.userId - user ID to update a specific user's email (defaults to the current session's userId).
1551
1814
  * @param params.stampWith - parameter to stamp the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
1815
+ * @param params.organizationId - organization ID to specify the sub-organization (defaults to the current session's organizationId).
1552
1816
  * @returns A promise that resolves to the userId of the updated user.
1553
1817
  * @throws {TurnkeyError} If there is no active session, if the userId is missing, or if there is an error updating or verifying the user email.
1554
1818
  */
1555
1819
  this.updateUserEmail = async (params) => {
1556
- const { verificationToken, email, stampWith } = params;
1557
- const session = await this.storageManager.getActiveSession();
1558
- if (!session) {
1559
- throw new sdkTypes.TurnkeyError("No active session found. Please log in first.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
1820
+ const { verificationToken, email, stampWith, organizationId } = params;
1821
+ const session = await utils.getActiveSessionOrThrowIfRequired(stampWith, this.storageManager.getActiveSession);
1822
+ const userId = params?.userId || session?.userId;
1823
+ if (!userId) {
1824
+ throw new sdkTypes.TurnkeyError("User ID must be provided to update user email", sdkTypes.TurnkeyErrorCodes.INVALID_REQUEST);
1560
1825
  }
1561
- const userId = params?.userId || session.userId;
1562
1826
  return utils.withTurnkeyErrorHandling(async () => {
1563
1827
  const existingUser = await this.httpClient.proxyGetAccount({
1564
- filterType: base.FilterType.Email,
1828
+ filterType: auth.FilterType.Email,
1565
1829
  filterValue: email,
1566
1830
  });
1567
1831
  if (existingUser.organizationId) {
@@ -1571,6 +1835,7 @@ class TurnkeyClient {
1571
1835
  userId: userId,
1572
1836
  userEmail: email,
1573
1837
  ...(verificationToken && { verificationToken }),
1838
+ ...(organizationId && { organizationId }),
1574
1839
  }, stampWith);
1575
1840
  if (!res || !res.userId) {
1576
1841
  throw new sdkTypes.TurnkeyError("No user ID found in the update user email response", sdkTypes.TurnkeyErrorCodes.BAD_RESPONSE);
@@ -1591,20 +1856,22 @@ class TurnkeyClient {
1591
1856
  *
1592
1857
  * @param params.userId - user ID to remove a specific user's email address (defaults to the current session's userId).
1593
1858
  * @param params.stampWith - parameter to stamp the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
1859
+ * @param params.organizationId - organization ID to specify the sub-organization (defaults to the current session's organizationId).
1594
1860
  * @returns A promise that resolves to the userId of the user whose email was removed.
1595
1861
  * @throws {TurnkeyError} If there is no active session, if the userId is missing, or if there is an error removing the user email.
1596
1862
  */
1597
1863
  this.removeUserEmail = async (params) => {
1598
- const { stampWith } = params || {};
1599
- const session = await this.storageManager.getActiveSession();
1600
- if (!session) {
1601
- throw new sdkTypes.TurnkeyError("No active session found. Please log in first.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
1602
- }
1864
+ const { stampWith, organizationId } = params || {};
1865
+ const session = await utils.getActiveSessionOrThrowIfRequired(stampWith, this.storageManager.getActiveSession);
1603
1866
  return utils.withTurnkeyErrorHandling(async () => {
1604
- const userId = params?.userId || session.userId;
1867
+ const userId = params?.userId || session?.userId;
1868
+ if (!userId) {
1869
+ throw new sdkTypes.TurnkeyError("User ID must be provided to remove user email", sdkTypes.TurnkeyErrorCodes.INVALID_REQUEST);
1870
+ }
1605
1871
  const res = await this.httpClient.updateUserEmail({
1606
1872
  userId: userId,
1607
1873
  userEmail: "",
1874
+ ...(organizationId && { organizationId }),
1608
1875
  }, stampWith);
1609
1876
  if (!res || !res.userId) {
1610
1877
  throw new sdkTypes.TurnkeyError("No user ID found in the remove user email response", sdkTypes.TurnkeyErrorCodes.BAD_RESPONSE);
@@ -1628,21 +1895,23 @@ class TurnkeyClient {
1628
1895
  * @param params.verificationToken - verification token from OTP phone verification (required if verifying the phone number).
1629
1896
  * @param params.userId - user ID to update a specific user's phone number (defaults to the current session's userId).
1630
1897
  * @param params.stampWith - parameter to stamp the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
1898
+ * @param params.organizationId - organization ID to specify the sub-organization (defaults to the current session's organizationId).
1631
1899
  * @returns A promise that resolves to the userId of the updated user.
1632
1900
  * @throws {TurnkeyError} If there is no active session, if the userId is missing, or if there is an error updating or verifying the user phone number.
1633
1901
  */
1634
1902
  this.updateUserPhoneNumber = async (params) => {
1635
- const { verificationToken, phoneNumber, stampWith } = params;
1636
- const session = await this.storageManager.getActiveSession();
1637
- if (!session) {
1638
- throw new sdkTypes.TurnkeyError("No active session found. Please log in first.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
1903
+ const { verificationToken, phoneNumber, stampWith, organizationId } = params;
1904
+ const session = await utils.getActiveSessionOrThrowIfRequired(stampWith, this.storageManager.getActiveSession);
1905
+ const userId = params?.userId || session?.userId;
1906
+ if (!userId) {
1907
+ throw new sdkTypes.TurnkeyError("User ID must be provided to update user phone number", sdkTypes.TurnkeyErrorCodes.INVALID_REQUEST);
1639
1908
  }
1640
- const userId = params?.userId || session.userId;
1641
1909
  return utils.withTurnkeyErrorHandling(async () => {
1642
1910
  const res = await this.httpClient.updateUserPhoneNumber({
1643
1911
  userId,
1644
1912
  userPhoneNumber: phoneNumber,
1645
1913
  ...(verificationToken && { verificationToken }),
1914
+ ...(organizationId && { organizationId }),
1646
1915
  }, stampWith);
1647
1916
  if (!res || !res.userId) {
1648
1917
  throw new sdkTypes.TurnkeyError("Failed to update user phone number", sdkTypes.TurnkeyErrorCodes.UPDATE_USER_PHONE_NUMBER_ERROR);
@@ -1663,20 +1932,22 @@ class TurnkeyClient {
1663
1932
  *
1664
1933
  * @param params.userId - user ID to remove a specific user's phone number (defaults to the current session's userId).
1665
1934
  * @param params.stampWith - parameter to stamp the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
1935
+ * @param params.organizationId - organization ID to specify the sub-organization (defaults to the current session's organizationId).
1666
1936
  * @returns A promise that resolves to the userId of the user whose phone number was removed.
1667
1937
  * @throws {TurnkeyError} If there is no active session, if the userId is missing, or if there is an error removing the user phone number.
1668
1938
  */
1669
1939
  this.removeUserPhoneNumber = async (params) => {
1670
- const { stampWith } = params || {};
1671
- const session = await this.storageManager.getActiveSession();
1672
- if (!session) {
1673
- throw new sdkTypes.TurnkeyError("No active session found. Please log in first.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
1940
+ const { stampWith, organizationId } = params || {};
1941
+ const session = await utils.getActiveSessionOrThrowIfRequired(stampWith, this.storageManager.getActiveSession);
1942
+ const userId = params?.userId || session?.userId;
1943
+ if (!userId) {
1944
+ throw new sdkTypes.TurnkeyError("User ID must be provided to remove user phone number", sdkTypes.TurnkeyErrorCodes.INVALID_REQUEST);
1674
1945
  }
1675
- const userId = params?.userId || session.userId;
1676
1946
  return utils.withTurnkeyErrorHandling(async () => {
1677
1947
  const res = await this.httpClient.updateUserPhoneNumber({
1678
1948
  userId,
1679
1949
  userPhoneNumber: "",
1950
+ ...(organizationId && { organizationId }),
1680
1951
  }, stampWith);
1681
1952
  if (!res || !res.userId) {
1682
1953
  throw new sdkTypes.TurnkeyError("Failed to remove user phone number", sdkTypes.TurnkeyErrorCodes.UPDATE_USER_PHONE_NUMBER_ERROR);
@@ -1699,20 +1970,22 @@ class TurnkeyClient {
1699
1970
  * @param params.userName - new name to set for the user.
1700
1971
  * @param params.userId - user ID to update a specific user's name (defaults to the current session's userId).
1701
1972
  * @param params.stampWith - parameter to stamp the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
1973
+ * @param params.organizationId - organization ID to specify the sub-organization (defaults to the current session's organizationId).
1702
1974
  * @returns A promise that resolves to the userId of the updated user.
1703
1975
  * @throws {TurnkeyError} If there is no active session, if the userId is missing, or if there is an error updating the user name.
1704
1976
  */
1705
1977
  this.updateUserName = async (params) => {
1706
- const { userName, stampWith } = params;
1707
- const session = await this.storageManager.getActiveSession();
1708
- if (!session) {
1709
- throw new sdkTypes.TurnkeyError("No active session found. Please log in first.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
1978
+ const { userName, stampWith, organizationId } = params;
1979
+ const session = await utils.getActiveSessionOrThrowIfRequired(stampWith, this.storageManager.getActiveSession);
1980
+ const userId = params?.userId || session?.userId;
1981
+ if (!userId) {
1982
+ throw new sdkTypes.TurnkeyError("User ID must be provided to update user name", sdkTypes.TurnkeyErrorCodes.INVALID_REQUEST);
1710
1983
  }
1711
- const userId = params?.userId || session.userId;
1712
1984
  return utils.withTurnkeyErrorHandling(async () => {
1713
1985
  const res = await this.httpClient.updateUserName({
1714
1986
  userId,
1715
1987
  userName,
1988
+ ...(organizationId && { organizationId }),
1716
1989
  }, stampWith);
1717
1990
  if (!res || !res.userId) {
1718
1991
  throw new sdkTypes.TurnkeyError("No user ID found in the update user name response", sdkTypes.TurnkeyErrorCodes.BAD_RESPONSE);
@@ -1735,6 +2008,7 @@ class TurnkeyClient {
1735
2008
  *
1736
2009
  * @param params.providerName - name of the OAuth provider to add (e.g., "Google", "Apple").
1737
2010
  * @param params.oidcToken - OIDC token for the OAuth provider.
2011
+ * @param params.organizationId - organization ID to specify the sub-organization (defaults to the current session's organizationId).
1738
2012
  * @param params.userId - user ID to add the provider for a specific user (defaults to current session's userId).
1739
2013
  * @param params.stampWith - parameter to stamp the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
1740
2014
  * @returns A promise that resolves to an array of provider IDs associated with the user.
@@ -1742,29 +2016,34 @@ class TurnkeyClient {
1742
2016
  */
1743
2017
  this.addOauthProvider = async (params) => {
1744
2018
  const { providerName, oidcToken, stampWith } = params;
1745
- const session = await this.storageManager.getActiveSession();
1746
- if (!session) {
1747
- throw new sdkTypes.TurnkeyError("No active session found. Please log in first.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
1748
- }
2019
+ const session = await utils.getActiveSessionOrThrowIfRequired(stampWith, this.storageManager.getActiveSession);
1749
2020
  return utils.withTurnkeyErrorHandling(async () => {
1750
2021
  const accountRes = await this.httpClient.proxyGetAccount({
1751
2022
  filterType: "OIDC_TOKEN",
1752
2023
  filterValue: oidcToken,
1753
2024
  });
1754
2025
  if (!accountRes) {
1755
- throw new sdkTypes.TurnkeyError(`Account fetch failed}`, sdkTypes.TurnkeyErrorCodes.ACCOUNT_FETCH_ERROR);
2026
+ throw new sdkTypes.TurnkeyError(`Account fetch failed`, sdkTypes.TurnkeyErrorCodes.ACCOUNT_FETCH_ERROR);
1756
2027
  }
1757
2028
  if (accountRes.organizationId) {
1758
2029
  throw new sdkTypes.TurnkeyError("Account already exists with this OIDC token", sdkTypes.TurnkeyErrorCodes.ACCOUNT_ALREADY_EXISTS);
1759
2030
  }
1760
- const userId = params?.userId || session.userId;
1761
- const { email: oidcEmail, iss } = jwtDecode.jwtDecode(oidcToken) || {}; // Parse the oidc token so we can get the email. Pass it in to updateUser then call createOauthProviders. This will be verified by Turnkey.
2031
+ const userId = params?.userId || session?.userId;
2032
+ if (!userId) {
2033
+ throw new sdkTypes.TurnkeyError("User ID must be provided to add OAuth provider", sdkTypes.TurnkeyErrorCodes.INVALID_REQUEST);
2034
+ }
2035
+ const organizationId = params?.organizationId ?? session?.organizationId;
2036
+ if (!organizationId) {
2037
+ throw new sdkTypes.TurnkeyError("Organization ID is required to add OAuth provider", sdkTypes.TurnkeyErrorCodes.INVALID_REQUEST);
2038
+ }
2039
+ // parse the oidc token so we can get the email. Pass it in to updateUser then call createOauthProviders. This will be verified by Turnkey.
2040
+ const { email: oidcEmail, iss } = jwtDecode.jwtDecode(oidcToken) || {};
1762
2041
  if (iss === utils.googleISS) {
1763
2042
  const verifiedSuborg = await this.httpClient.proxyGetAccount({
1764
2043
  filterType: "EMAIL",
1765
2044
  filterValue: oidcEmail,
1766
2045
  });
1767
- const isVerified = verifiedSuborg.organizationId === session.organizationId;
2046
+ const isVerified = verifiedSuborg.organizationId === organizationId;
1768
2047
  const user = await this.fetchUser({
1769
2048
  userId,
1770
2049
  stampWith,
@@ -1807,20 +2086,22 @@ class TurnkeyClient {
1807
2086
  * @param params.providerIds - IDs of the OAuth providers to remove.
1808
2087
  * @param params.userId - user ID to remove the provider for a specific user (defaults to the current session's userId).
1809
2088
  * @param params.stampWith - parameter to stamp the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
2089
+ * @param params.organizationId - organization ID to specify the sub-organization (defaults to the current session's organizationId).
1810
2090
  * @returns A promise that resolves to an array of provider IDs that were removed.
1811
2091
  * @throws {TurnkeyError} If there is no active session, if the userId is missing, or if there is an error removing the OAuth provider.
1812
2092
  */
1813
2093
  this.removeOauthProviders = async (params) => {
1814
- const { providerIds, stampWith } = params;
1815
- const session = await this.storageManager.getActiveSession();
1816
- if (!session) {
1817
- throw new sdkTypes.TurnkeyError("No active session found. Please log in first.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
2094
+ const { providerIds, stampWith, organizationId } = params;
2095
+ const session = await utils.getActiveSessionOrThrowIfRequired(stampWith, this.storageManager.getActiveSession);
2096
+ const userId = params?.userId || session?.userId;
2097
+ if (!userId) {
2098
+ throw new sdkTypes.TurnkeyError("User ID must be provided to remove OAuth provider", sdkTypes.TurnkeyErrorCodes.INVALID_REQUEST);
1818
2099
  }
1819
- const userId = params?.userId || session.userId;
1820
2100
  return utils.withTurnkeyErrorHandling(async () => {
1821
2101
  const res = await this.httpClient.deleteOauthProviders({
1822
2102
  userId,
1823
2103
  providerIds,
2104
+ ...(organizationId && { organizationId }),
1824
2105
  }, stampWith);
1825
2106
  if (!res) {
1826
2107
  throw new sdkTypes.TurnkeyError("Failed to remove OAuth provider", sdkTypes.TurnkeyErrorCodes.REMOVE_OAUTH_PROVIDER_ERROR);
@@ -1844,21 +2125,21 @@ class TurnkeyClient {
1844
2125
  * @param params.displayName - display name of the passkey (defaults to the value of `name`).
1845
2126
  * @param params.userId - user ID to add the passkey for a specific user (defaults to the current session's userId).
1846
2127
  * @param params.stampWith - parameter to stamp the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
2128
+ * @param params.organizationId - organization ID to specify the sub-organization (defaults to the current session's organizationId).
1847
2129
  * @returns A promise that resolves to an array of authenticator IDs for the newly added passkey(s).
1848
2130
  * @throws {TurnkeyError} If there is no active session, if passkey creation fails, or if there is an error adding the passkey.
1849
2131
  */
1850
2132
  this.addPasskey = async (params) => {
1851
- const { stampWith } = params || {};
2133
+ const { stampWith, organizationId } = params || {};
1852
2134
  const name = params?.name || `Turnkey Passkey-${Date.now()}`;
1853
2135
  return utils.withTurnkeyErrorHandling(async () => {
1854
- const session = await this.storageManager.getActiveSession();
1855
- if (!session) {
1856
- throw new sdkTypes.TurnkeyError("No active session found. Please log in first.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
2136
+ const session = await utils.getActiveSessionOrThrowIfRequired(stampWith, this.storageManager.getActiveSession);
2137
+ const userId = params?.userId || session?.userId;
2138
+ if (!userId) {
2139
+ throw new sdkTypes.TurnkeyError("User ID must be provided to add passkey", sdkTypes.TurnkeyErrorCodes.INVALID_REQUEST);
1857
2140
  }
1858
- const userId = params?.userId || session.userId;
1859
2141
  const { encodedChallenge, attestation } = await this.createPasskey({
1860
2142
  name,
1861
- ...(stampWith && { stampWith }),
1862
2143
  });
1863
2144
  if (!attestation || !encodedChallenge) {
1864
2145
  throw new sdkTypes.TurnkeyError("Failed to create passkey challenge and attestation", sdkTypes.TurnkeyErrorCodes.CREATE_PASSKEY_ERROR);
@@ -1872,6 +2153,7 @@ class TurnkeyClient {
1872
2153
  attestation,
1873
2154
  },
1874
2155
  ],
2156
+ ...(organizationId && { organizationId }),
1875
2157
  }, stampWith);
1876
2158
  return res?.authenticatorIds || [];
1877
2159
  }, {
@@ -1891,20 +2173,22 @@ class TurnkeyClient {
1891
2173
  * @param params.authenticatorIds - IDs of the authenticators (passkeys) to remove.
1892
2174
  * @param params.userId - user ID to remove the passkeys for a specific user (defaults to the current session's userId).
1893
2175
  * @param params.stampWith - parameter to stamp the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
2176
+ * @param params.organizationId - organization ID to specify the sub-organization (defaults to the current session's organizationId).
1894
2177
  * @returns A promise that resolves to an array of authenticator IDs that were removed.
1895
2178
  * @throws {TurnkeyError} If there is no active session, if the userId is missing, or if there is an error removing the passkeys.
1896
2179
  */
1897
2180
  this.removePasskeys = async (params) => {
1898
- const { authenticatorIds, stampWith } = params;
1899
- const session = await this.storageManager.getActiveSession();
1900
- if (!session) {
1901
- throw new sdkTypes.TurnkeyError("No active session found. Please log in first.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
2181
+ const { authenticatorIds, stampWith, organizationId } = params;
2182
+ const session = await utils.getActiveSessionOrThrowIfRequired(stampWith, this.storageManager.getActiveSession);
2183
+ const userId = params?.userId || session?.userId;
2184
+ if (!userId) {
2185
+ throw new sdkTypes.TurnkeyError("User ID must be provided to remove passkey", sdkTypes.TurnkeyErrorCodes.INVALID_REQUEST);
1902
2186
  }
1903
- const userId = params?.userId || session.userId;
1904
2187
  return utils.withTurnkeyErrorHandling(async () => {
1905
2188
  const res = await this.httpClient.deleteAuthenticators({
1906
2189
  userId,
1907
2190
  authenticatorIds,
2191
+ ...(organizationId && { organizationId }),
1908
2192
  }, stampWith);
1909
2193
  if (!res) {
1910
2194
  throw new sdkTypes.TurnkeyError("No response found in the remove passkey response", sdkTypes.TurnkeyErrorCodes.REMOVE_PASSKEY_ERROR);
@@ -1935,10 +2219,11 @@ class TurnkeyClient {
1935
2219
  * @throws {TurnkeyError} If there is no active session or if there is an error creating the wallet.
1936
2220
  */
1937
2221
  this.createWallet = async (params) => {
1938
- const { walletName, accounts, organizationId, mnemonicLength, stampWith } = params;
1939
- const session = await this.storageManager.getActiveSession();
1940
- if (!session) {
1941
- throw new sdkTypes.TurnkeyError("No active session found. Please log in first.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
2222
+ const { walletName, accounts, organizationId: organizationIdFromParams, mnemonicLength, stampWith, } = params;
2223
+ const session = await utils.getActiveSessionOrThrowIfRequired(stampWith, this.storageManager.getActiveSession);
2224
+ const organizationId = organizationIdFromParams || session?.organizationId;
2225
+ if (!organizationId) {
2226
+ throw new sdkTypes.TurnkeyError("Organization ID must be provided to create wallet", sdkTypes.TurnkeyErrorCodes.INVALID_REQUEST);
1942
2227
  }
1943
2228
  let walletAccounts = [];
1944
2229
  if (accounts && !utils.isWalletAccountArray(accounts)) {
@@ -1954,7 +2239,7 @@ class TurnkeyClient {
1954
2239
  }
1955
2240
  return utils.withTurnkeyErrorHandling(async () => {
1956
2241
  const res = await this.httpClient.createWallet({
1957
- organizationId: organizationId || session.organizationId,
2242
+ organizationId: organizationId,
1958
2243
  walletName,
1959
2244
  accounts: walletAccounts,
1960
2245
  mnemonicLength: mnemonicLength || 12,
@@ -1986,10 +2271,11 @@ class TurnkeyClient {
1986
2271
  * @throws {TurnkeyError} If there is no active session, if the wallet does not exist, or if there is an error creating the wallet accounts.
1987
2272
  */
1988
2273
  this.createWalletAccounts = async (params) => {
1989
- const { accounts, walletId, organizationId, stampWith } = params;
1990
- const session = await this.storageManager.getActiveSession();
1991
- if (!session) {
1992
- throw new sdkTypes.TurnkeyError("No active session found. Please log in first.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
2274
+ const { accounts, walletId, organizationId: organizationIdFromParams, stampWith, } = params;
2275
+ const session = await utils.getActiveSessionOrThrowIfRequired(stampWith, this.storageManager.getActiveSession);
2276
+ const organizationId = organizationIdFromParams || session?.organizationId;
2277
+ if (!organizationId) {
2278
+ throw new sdkTypes.TurnkeyError("Organization ID must be provided to create wallet accounts", sdkTypes.TurnkeyErrorCodes.INVALID_REQUEST);
1993
2279
  }
1994
2280
  return utils.withTurnkeyErrorHandling(async () => {
1995
2281
  let walletAccounts = [];
@@ -1997,7 +2283,7 @@ class TurnkeyClient {
1997
2283
  // Query existing wallet accounts to avoid duplicates
1998
2284
  const existingWalletAccounts = await this.httpClient.getWalletAccounts({
1999
2285
  walletId,
2000
- organizationId: organizationId || session.organizationId,
2286
+ organizationId: organizationId,
2001
2287
  paginationOptions: { limit: "100" },
2002
2288
  }, stampWith);
2003
2289
  walletAccounts = utils.generateWalletAccountsFromAddressFormat({
@@ -2009,7 +2295,7 @@ class TurnkeyClient {
2009
2295
  walletAccounts = accounts;
2010
2296
  }
2011
2297
  const res = await this.httpClient.createWalletAccounts({
2012
- organizationId: organizationId || session.organizationId,
2298
+ organizationId: organizationId,
2013
2299
  walletId,
2014
2300
  accounts: walletAccounts,
2015
2301
  }, stampWith);
@@ -2040,16 +2326,17 @@ class TurnkeyClient {
2040
2326
  * @throws {TurnkeyError} If there is no active session, if the targetPublicKey is missing, or if there is an error exporting the wallet.
2041
2327
  */
2042
2328
  this.exportWallet = async (params) => {
2043
- const { walletId, targetPublicKey, stampWith, organizationId } = params;
2044
- const session = await this.storageManager.getActiveSession();
2045
- if (!session) {
2046
- throw new sdkTypes.TurnkeyError("No active session found. Please log in first.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
2329
+ const { walletId, targetPublicKey, stampWith, organizationId: organizationIdFromParams, } = params;
2330
+ const session = await utils.getActiveSessionOrThrowIfRequired(stampWith, this.storageManager.getActiveSession);
2331
+ const organizationId = organizationIdFromParams || session?.organizationId;
2332
+ if (!organizationId) {
2333
+ throw new sdkTypes.TurnkeyError("Organization ID must be provided to export wallet", sdkTypes.TurnkeyErrorCodes.INVALID_REQUEST);
2047
2334
  }
2048
2335
  return utils.withTurnkeyErrorHandling(async () => {
2049
2336
  const res = await this.httpClient.exportWallet({
2050
2337
  walletId,
2051
2338
  targetPublicKey,
2052
- organizationId: organizationId || session.organizationId,
2339
+ organizationId: organizationId,
2053
2340
  }, stampWith);
2054
2341
  if (!res.exportBundle) {
2055
2342
  throw new sdkTypes.TurnkeyError("No export bundle found in the response", sdkTypes.TurnkeyErrorCodes.BAD_RESPONSE);
@@ -2077,16 +2364,17 @@ class TurnkeyClient {
2077
2364
  * @throws {TurnkeyError} If there is no active session, if the targetPublicKey is missing, or if there is an error exporting the private key.
2078
2365
  */
2079
2366
  this.exportPrivateKey = async (params) => {
2080
- const { privateKeyId, targetPublicKey, stampWith, organizationId } = params;
2081
- const session = await this.storageManager.getActiveSession();
2082
- if (!session) {
2083
- throw new sdkTypes.TurnkeyError("No active session found. Please log in first.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
2367
+ const { privateKeyId, targetPublicKey, stampWith, organizationId: organizationIdFromParams, } = params;
2368
+ const session = await utils.getActiveSessionOrThrowIfRequired(stampWith, this.storageManager.getActiveSession);
2369
+ const organizationId = organizationIdFromParams || session?.organizationId;
2370
+ if (!organizationId) {
2371
+ throw new sdkTypes.TurnkeyError("Organization ID must be provided to export private key", sdkTypes.TurnkeyErrorCodes.INVALID_REQUEST);
2084
2372
  }
2085
2373
  return utils.withTurnkeyErrorHandling(async () => {
2086
2374
  const res = await this.httpClient.exportPrivateKey({
2087
2375
  privateKeyId,
2088
2376
  targetPublicKey,
2089
- organizationId: organizationId || session.organizationId,
2377
+ organizationId: organizationId,
2090
2378
  }, stampWith);
2091
2379
  if (!res.exportBundle) {
2092
2380
  throw new sdkTypes.TurnkeyError("No export bundle found in the response", sdkTypes.TurnkeyErrorCodes.BAD_RESPONSE);
@@ -2115,16 +2403,17 @@ class TurnkeyClient {
2115
2403
  *
2116
2404
  */
2117
2405
  this.exportWalletAccount = async (params) => {
2118
- const { address, targetPublicKey, stampWith, organizationId } = params;
2119
- const session = await this.storageManager.getActiveSession();
2120
- if (!session) {
2121
- throw new sdkTypes.TurnkeyError("No active session found. Please log in first.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
2406
+ const { address, targetPublicKey, stampWith, organizationId: organizationIdFromParams, } = params;
2407
+ const session = await utils.getActiveSessionOrThrowIfRequired(stampWith, this.storageManager.getActiveSession);
2408
+ const organizationId = organizationIdFromParams || session?.organizationId;
2409
+ if (!organizationId) {
2410
+ throw new sdkTypes.TurnkeyError("Organization ID must be provided to export wallet account", sdkTypes.TurnkeyErrorCodes.INVALID_REQUEST);
2122
2411
  }
2123
2412
  return utils.withTurnkeyErrorHandling(async () => {
2124
2413
  const res = await this.httpClient.exportWalletAccount({
2125
2414
  address,
2126
2415
  targetPublicKey,
2127
- organizationId: organizationId || session.organizationId,
2416
+ organizationId: organizationId,
2128
2417
  }, stampWith);
2129
2418
  if (!res.exportBundle) {
2130
2419
  throw new sdkTypes.TurnkeyError("No export bundle found in the response", sdkTypes.TurnkeyErrorCodes.BAD_RESPONSE);
@@ -2148,21 +2437,27 @@ class TurnkeyClient {
2148
2437
  * @param params.encryptedBundle - encrypted bundle containing the wallet seed phrase and metadata.
2149
2438
  * @param params.walletName - name of the wallet to create upon import.
2150
2439
  * @param params.accounts - array of account parameters to create in the imported wallet (defaults to standard Ethereum and Solana accounts).
2440
+ * @param params.organizationId - organization ID to import the wallet under a specific sub-organization (wallet will be associated with the sub-organization).
2151
2441
  * @param params.userId - user ID to import the wallet for a specific user (defaults to the current session's userId).
2152
2442
  * @param params.stampWith - parameter to stamp the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
2153
2443
  * @returns A promise that resolves to the ID of the imported wallet.
2154
2444
  * @throws {TurnkeyError} If there is no active session, if the encrypted bundle is invalid, or if there is an error importing the wallet.
2155
2445
  */
2156
2446
  this.importWallet = async (params) => {
2157
- const { encryptedBundle, accounts, walletName, userId, stampWith } = params;
2158
- const session = await this.storageManager.getActiveSession();
2159
- if (!session) {
2160
- throw new sdkTypes.TurnkeyError("No active session found. Please log in first.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
2447
+ const { encryptedBundle, accounts, walletName, organizationId: organizationIdFromParams, userId: userIdFromParams, stampWith, } = params;
2448
+ const session = await utils.getActiveSessionOrThrowIfRequired(stampWith, this.storageManager.getActiveSession);
2449
+ const organizationId = organizationIdFromParams || session?.organizationId;
2450
+ if (!organizationId) {
2451
+ throw new sdkTypes.TurnkeyError("Organization ID must be provided to import wallet", sdkTypes.TurnkeyErrorCodes.INVALID_REQUEST);
2452
+ }
2453
+ const userId = userIdFromParams || session?.userId;
2454
+ if (!userId) {
2455
+ throw new sdkTypes.TurnkeyError("User ID must be provided to import wallet", sdkTypes.TurnkeyErrorCodes.INVALID_REQUEST);
2161
2456
  }
2162
2457
  return utils.withTurnkeyErrorHandling(async () => {
2163
2458
  const res = await this.httpClient.importWallet({
2164
- organizationId: session.organizationId,
2165
- userId: userId || session.userId,
2459
+ organizationId: organizationId,
2460
+ userId: userId,
2166
2461
  encryptedBundle,
2167
2462
  walletName,
2168
2463
  accounts: accounts || [
@@ -2177,7 +2472,7 @@ class TurnkeyClient {
2177
2472
  }, {
2178
2473
  errorMessage: "Failed to import wallet",
2179
2474
  errorCode: sdkTypes.TurnkeyErrorCodes.IMPORT_WALLET_ERROR,
2180
- customMessageByMessages: {
2475
+ customErrorsByMessages: {
2181
2476
  "invalid mnemonic": {
2182
2477
  message: "Invalid mnemonic input",
2183
2478
  code: sdkTypes.TurnkeyErrorCodes.BAD_REQUEST,
@@ -2200,21 +2495,27 @@ class TurnkeyClient {
2200
2495
  * @param params.privateKeyName - name of the private key to create upon import.
2201
2496
  * @param params.curve - the cryptographic curve used to generate a given private key
2202
2497
  * @param params.addressFormat - address format of the private key to import.
2498
+ * @param params.organizationId - organization ID to import the private key under a specific sub-organization (private key will be associated with the sub-organization).
2203
2499
  * @param params.userId - user ID to import the wallet for a specific user (defaults to the current session's userId).
2204
2500
  * @param params.stampWith - parameter to stamp the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
2205
2501
  * @returns A promise that resolves to the ID of the imported wallet.
2206
2502
  * @throws {TurnkeyError} If there is no active session, if the encrypted bundle is invalid, or if there is an error importing the wallet.
2207
2503
  */
2208
2504
  this.importPrivateKey = async (params) => {
2209
- const { encryptedBundle, privateKeyName, addressFormats, curve, userId, stampWith, } = params;
2210
- const session = await this.storageManager.getActiveSession();
2211
- if (!session) {
2212
- throw new sdkTypes.TurnkeyError("No active session found. Please log in first.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
2505
+ const { encryptedBundle, privateKeyName, addressFormats, curve, organizationId: organizationIdFromParams, userId: userIdFromParams, stampWith, } = params;
2506
+ const session = await utils.getActiveSessionOrThrowIfRequired(stampWith, this.storageManager.getActiveSession);
2507
+ const organizationId = organizationIdFromParams || session?.organizationId;
2508
+ if (!organizationId) {
2509
+ throw new sdkTypes.TurnkeyError("Organization ID must be provided to import private key", sdkTypes.TurnkeyErrorCodes.INVALID_REQUEST);
2510
+ }
2511
+ const userId = userIdFromParams || session?.userId;
2512
+ if (!userId) {
2513
+ throw new sdkTypes.TurnkeyError("User ID must be provided to import private key", sdkTypes.TurnkeyErrorCodes.INVALID_REQUEST);
2213
2514
  }
2214
2515
  return utils.withTurnkeyErrorHandling(async () => {
2215
2516
  const res = await this.httpClient.importPrivateKey({
2216
- organizationId: session.organizationId,
2217
- userId: userId || session.userId,
2517
+ organizationId,
2518
+ userId,
2218
2519
  encryptedBundle,
2219
2520
  privateKeyName,
2220
2521
  curve,
@@ -2227,7 +2528,7 @@ class TurnkeyClient {
2227
2528
  }, {
2228
2529
  errorMessage: "Failed to import wallet",
2229
2530
  errorCode: sdkTypes.TurnkeyErrorCodes.IMPORT_WALLET_ERROR,
2230
- customMessageByMessages: {
2531
+ customErrorsByMessages: {
2231
2532
  "invalid mnemonic": {
2232
2533
  message: "Invalid mnemonic input",
2233
2534
  code: sdkTypes.TurnkeyErrorCodes.BAD_REQUEST,
@@ -2245,18 +2546,17 @@ class TurnkeyClient {
2245
2546
  * - Optionally allows stamping the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
2246
2547
  *
2247
2548
  * @param params.deleteWithoutExport - flag to delete the sub-organization without requiring all wallets to be exported first (defaults to false).
2549
+ * @param params.organizationId - organization ID to delete a specific sub-organization (defaults to the current session's organizationId).
2248
2550
  * @param params.stampWith - parameter to stamp the request with a specific stamper.
2249
2551
  * @returns A promise that resolves to a `TDeleteSubOrganizationResponse` object containing the result of the deletion.
2250
2552
  * @throws {TurnkeyError} If there is no active session or if there is an error deleting the sub-organization.
2251
2553
  */
2252
2554
  this.deleteSubOrganization = async (params) => {
2253
- const { deleteWithoutExport = false, stampWith } = params || {};
2254
- const session = await this.storageManager.getActiveSession();
2255
- if (!session) {
2256
- throw new sdkTypes.TurnkeyError("No active session found. Please log in first.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
2257
- }
2555
+ const { deleteWithoutExport = false, organizationId: organizationIdFromParams, stampWith, } = params || {};
2556
+ const session = await utils.getActiveSessionOrThrowIfRequired(stampWith, this.storageManager.getActiveSession);
2557
+ const organizationId = organizationIdFromParams || session?.organizationId;
2258
2558
  return utils.withTurnkeyErrorHandling(async () => {
2259
- return await this.httpClient.deleteSubOrganization({ deleteWithoutExport }, stampWith);
2559
+ return await this.httpClient.deleteSubOrganization({ deleteWithoutExport, ...(organizationId && { organizationId }) }, stampWith);
2260
2560
  }, {
2261
2561
  errorMessage: "Failed to delete sub-organization",
2262
2562
  errorCode: sdkTypes.TurnkeyErrorCodes.DELETE_SUB_ORGANIZATION_ERROR,
@@ -2277,7 +2577,7 @@ class TurnkeyClient {
2277
2577
  * @throws {TurnkeyError} If there is an error storing the session or cleaning up key pairs.
2278
2578
  */
2279
2579
  this.storeSession = async (params) => {
2280
- const { sessionToken, sessionKey = base.SessionKey.DefaultSessionkey } = params;
2580
+ const { sessionToken, sessionKey = auth.SessionKey.DefaultSessionkey } = params;
2281
2581
  if (!sessionToken)
2282
2582
  return;
2283
2583
  utils.withTurnkeyErrorHandling(async () => {
@@ -2302,7 +2602,7 @@ class TurnkeyClient {
2302
2602
  * @throws {TurnkeyError} If the session does not exist or if there is an error clearing the session.
2303
2603
  */
2304
2604
  this.clearSession = async (params) => {
2305
- const { sessionKey = base.SessionKey.DefaultSessionkey } = params || {};
2605
+ const { sessionKey = auth.SessionKey.DefaultSessionkey } = params || {};
2306
2606
  utils.withTurnkeyErrorHandling(async () => {
2307
2607
  const session = await this.storageManager.getSession(sessionKey);
2308
2608
  if (session) {
@@ -2360,7 +2660,7 @@ class TurnkeyClient {
2360
2660
  * @throws {TurnkeyError} If the session key does not exist, if there is no active session, or if there is an error refreshing the session.
2361
2661
  */
2362
2662
  this.refreshSession = async (params) => {
2363
- const { sessionKey = await this.storageManager.getActiveSessionKey(), expirationSeconds = base.DEFAULT_SESSION_EXPIRATION_IN_SECONDS, publicKey, invalidateExisitng = false, } = params || {};
2663
+ const { sessionKey = await this.storageManager.getActiveSessionKey(), expirationSeconds = auth.DEFAULT_SESSION_EXPIRATION_IN_SECONDS, publicKey, invalidateExisitng = false, } = params || {};
2364
2664
  if (!sessionKey) {
2365
2665
  throw new sdkTypes.TurnkeyError("No session key provided or active session to refresh session", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
2366
2666
  }
@@ -2591,17 +2891,17 @@ class TurnkeyClient {
2591
2891
  async init() {
2592
2892
  // Initialize storage manager
2593
2893
  // TODO (Amir): StorageManager should be a class that extends StorageBase and has an init method
2594
- this.storageManager = await base$1.createStorageManager();
2894
+ this.storageManager = await base.createStorageManager();
2595
2895
  // Initialize the API key stamper
2596
- this.apiKeyStamper = new base$2.CrossPlatformApiKeyStamper(this.storageManager);
2896
+ this.apiKeyStamper = new base$1.CrossPlatformApiKeyStamper(this.storageManager);
2597
2897
  await this.apiKeyStamper.init();
2598
2898
  if (this.config.passkeyConfig) {
2599
- this.passkeyStamper = new base$3.CrossPlatformPasskeyStamper(this.config.passkeyConfig);
2899
+ this.passkeyStamper = new base$2.CrossPlatformPasskeyStamper(this.config.passkeyConfig);
2600
2900
  await this.passkeyStamper.init();
2601
2901
  }
2602
2902
  if (this.config.walletConfig?.features?.auth ||
2603
2903
  this.config.walletConfig?.features?.connecting) {
2604
- this.walletManager = await base$4.createWalletManager(this.config.walletConfig);
2904
+ this.walletManager = await base$3.createWalletManager(this.config.walletConfig);
2605
2905
  }
2606
2906
  // We can comfortably default to the prod urls here
2607
2907
  const apiBaseUrl = this.config.apiBaseUrl || "https://api.turnkey.com";