@injectivelabs/wallet-turnkey 1.16.5 → 1.16.6-alpha.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.
@@ -15,76 +15,66 @@ const utils_js_1 = require("../../utils.js");
15
15
  class TurnkeyWallet {
16
16
  otpId;
17
17
  turnkey;
18
- organizationId;
18
+ userOrganizationId;
19
19
  client;
20
20
  metadata;
21
- iframeClient;
21
+ indexedDbClient;
22
22
  accountMap = {};
23
23
  setMetadata(metadata) {
24
24
  this.metadata = { ...this.metadata, ...metadata };
25
25
  }
26
26
  constructor(metadata) {
27
27
  this.metadata = metadata;
28
- this.organizationId = metadata.organizationId;
29
28
  this.client = new utils_1.HttpRestClient(metadata.apiServerEndpoint);
30
29
  }
31
30
  static async getTurnkeyInstance(metadata) {
32
- const { turnkey, iframeClient } = await createTurnkeyIFrame(metadata);
31
+ const { turnkey, indexedDbClient } = await createTurnkeyClient(metadata);
33
32
  return {
34
33
  turnkey,
35
- iframeClient,
34
+ indexedDbClient,
36
35
  };
37
36
  }
38
37
  async getTurnkey() {
39
- if (!this.iframeClient) {
40
- await this.initFrame();
38
+ if (!this.indexedDbClient) {
39
+ await this.initClient();
41
40
  }
42
41
  if (!this.turnkey) {
43
42
  this.turnkey = new sdk_browser_1.Turnkey(this.metadata);
44
43
  }
45
44
  return this.turnkey;
46
45
  }
47
- async getIframeClient() {
48
- if (!this.iframeClient) {
49
- await this.initFrame();
46
+ async getIndexedDbClient() {
47
+ if (!this.indexedDbClient) {
48
+ await this.initClient();
50
49
  }
51
- if (!this.iframeClient) {
52
- throw new exceptions_1.WalletException(new Error('Iframe client not initialized'));
50
+ if (!this.indexedDbClient) {
51
+ throw new exceptions_1.WalletException(new Error('Indexed DB client not initialized'));
53
52
  }
54
- return this.iframeClient;
53
+ return this.indexedDbClient;
55
54
  }
56
55
  async getSession(existingCredentialBundle) {
57
- const { metadata } = this;
58
- const iframeClient = await this.getIframeClient();
59
- const turnkey = await this.getTurnkey();
60
- const currentSession = await turnkey.getSession();
61
- const organizationId = currentSession?.organizationId || metadata.defaultOrganizationId;
62
- const credentialBundle = existingCredentialBundle || currentSession?.token;
63
- if (!credentialBundle) {
64
- return {
65
- session: undefined,
66
- organizationId,
67
- };
68
- }
69
56
  try {
70
- const loginResult = await iframeClient.injectCredentialBundle(credentialBundle);
71
- // If there is no session, we want to force a refresh to enable to browser SDK to handle key storage and proper session management.
72
- await iframeClient.refreshSession({
73
- sessionType: sdk_browser_1.SessionType.READ_WRITE,
74
- targetPublicKey: iframeClient.iframePublicKey,
75
- expirationSeconds: this.metadata.expirationSeconds,
76
- });
77
- const [session, user] = await Promise.all([
78
- turnkey.getSession(),
79
- iframeClient.getWhoami(),
80
- ]);
57
+ const { metadata } = this;
58
+ const indexedDbClient = await this.getIndexedDbClient();
59
+ const turnkey = await this.getTurnkey();
60
+ const session = await turnkey.getSession();
61
+ const organizationId = session?.organizationId || metadata.defaultOrganizationId;
62
+ const credentialBundle = existingCredentialBundle || session?.token;
63
+ if (!credentialBundle) {
64
+ return {
65
+ session: undefined,
66
+ organizationId,
67
+ };
68
+ }
69
+ const user = await indexedDbClient.getWhoami();
81
70
  const actualOrganizationId = user?.organizationId || session?.organizationId || organizationId;
82
- if (!loginResult) {
71
+ if (!user) {
83
72
  return {
84
73
  session: undefined,
85
74
  organizationId: actualOrganizationId,
86
75
  };
87
76
  }
77
+ this.userOrganizationId = actualOrganizationId;
88
78
  return {
89
79
  session,
90
80
  organizationId: actualOrganizationId,
@@ -95,17 +85,17 @@ class TurnkeyWallet {
95
85
  }
96
86
  }
97
87
  async getAccounts() {
98
- const iframeClient = await this.getIframeClient();
99
- if (!this.organizationId) {
88
+ const indexedDbClient = await this.getIndexedDbClient();
89
+ if (!this.userOrganizationId) {
100
90
  return [];
101
91
  }
102
92
  try {
103
- const response = await iframeClient.getWallets({
104
- organizationId: this.organizationId,
93
+ const response = await indexedDbClient.getWallets({
94
+ organizationId: this.userOrganizationId,
105
95
  });
106
- const accounts = await Promise.allSettled(response.wallets.map((wallet) => iframeClient.getWalletAccounts({
96
+ const accounts = await Promise.allSettled(response.wallets.map((wallet) => indexedDbClient.getWalletAccounts({
107
97
  walletId: wallet.walletId,
108
- organizationId: this.organizationId,
98
+ organizationId: this.userOrganizationId,
109
99
  })));
110
100
  const filteredAccounts = accounts
111
101
  .filter((account) => account.status === 'fulfilled')
@@ -131,61 +121,33 @@ class TurnkeyWallet {
131
121
  });
132
122
  }
133
123
  }
134
- async getOrCreateAndGetAccount(address, organizationId) {
124
+ async getOrCreateAndGetAccount(address) {
135
125
  const { accountMap } = this;
136
- const iframeClient = await this.getIframeClient();
126
+ const indexedDbClient = await this.getIndexedDbClient();
127
+ const organizationId = this.userOrganizationId;
137
128
  if (accountMap[address] || accountMap[address.toLowerCase()]) {
138
129
  return accountMap[address] || accountMap[address.toLowerCase()];
139
130
  }
140
131
  if (!organizationId) {
141
132
  throw new exceptions_1.WalletException(new Error('Organization ID is required'));
142
133
  }
143
- iframeClient.config.organizationId = organizationId;
134
+ indexedDbClient.config.organizationId = organizationId;
144
135
  if (!address) {
145
136
  throw new exceptions_1.WalletException(new Error('Account address not found'));
146
137
  }
147
138
  const turnkeyAccount = await (0, viem_1.createAccount)({
148
139
  organizationId,
149
140
  signWith: address,
150
- client: iframeClient,
141
+ client: indexedDbClient,
151
142
  });
152
143
  this.accountMap[address] = turnkeyAccount;
153
144
  return turnkeyAccount;
154
145
  }
155
- async injectAndRefresh(credentialBundle, options) {
156
- const expirationSeconds = options.expirationSeconds || consts_js_1.DEFAULT_TURNKEY_REFRESH_SECONDS;
157
- const iframeClient = await this.getIframeClient();
158
- await iframeClient.injectCredentialBundle(credentialBundle);
159
- await iframeClient.loginWithBundle({
160
- bundle: credentialBundle,
161
- expirationSeconds,
162
- });
163
- await iframeClient.refreshSession({
164
- sessionType: sdk_browser_1.SessionType.READ_WRITE,
165
- targetPublicKey: iframeClient.iframePublicKey,
166
- expirationSeconds,
167
- });
168
- const session = await this.turnkey?.getSession();
169
- if (!session) {
170
- throw new exceptions_1.TurnkeyWalletSessionException(new Error('Session expired. Please login again.'));
171
- }
172
- this.organizationId = session.organizationId;
173
- this.metadata.organizationId = session.organizationId;
174
- // Refresh the session 2 minutes before it expires
175
- setTimeout(() => {
176
- iframeClient.refreshSession({
177
- expirationSeconds: session?.expiry,
178
- sessionType: sdk_browser_1.SessionType.READ_WRITE,
179
- targetPublicKey: iframeClient.iframePublicKey,
180
- });
181
- }, (parseInt(expirationSeconds) - 120) * 1000);
182
- return;
183
- }
184
146
  async initOTP(email) {
185
- const iframeClient = await this.getIframeClient();
147
+ const indexedDbClient = await this.getIndexedDbClient();
186
148
  const result = await otp_js_1.TurnkeyOtpWallet.initEmailOTP({
187
149
  client: this.client,
188
- iframeClient,
150
+ indexedDbClient,
189
151
  email,
190
152
  otpInitPath: this.metadata.otpInitPath || consts_js_1.TURNKEY_OTP_INIT_PATH,
191
153
  });
@@ -193,7 +155,7 @@ class TurnkeyWallet {
193
155
  throw new exceptions_1.WalletException(new Error('Failed to initialize OTP'));
194
156
  }
195
157
  if (result?.organizationId) {
196
- this.organizationId = result.organizationId;
158
+ this.userOrganizationId = result.organizationId;
197
159
  }
198
160
  if (result?.otpId) {
199
161
  this.otpId = result.otpId;
@@ -201,30 +163,35 @@ class TurnkeyWallet {
201
163
  return result;
202
164
  }
203
165
  async confirmOTP(otpCode) {
204
- const iframeClient = await this.getIframeClient();
166
+ const indexedDbClient = await this.getIndexedDbClient();
167
+ const targetPublicKey = await indexedDbClient.getPublicKey();
205
168
  if (!this.otpId) {
206
169
  throw new exceptions_1.WalletException(new Error('OTP ID is required'));
207
170
  }
171
+ if (!targetPublicKey) {
172
+ throw new exceptions_1.WalletException(new Error('Target public key not found'));
173
+ }
174
+ if (!this.userOrganizationId) {
175
+ throw new exceptions_1.WalletException(new Error('Organization ID is required'));
176
+ }
208
177
  const result = await otp_js_1.TurnkeyOtpWallet.confirmEmailOTP({
209
178
  otpCode,
210
- iframeClient,
211
179
  client: this.client,
212
180
  emailOTPId: this.otpId,
213
- organizationId: this.organizationId,
181
+ organizationId: this.userOrganizationId,
182
+ targetPublicKey,
214
183
  otpVerifyPath: this.metadata.otpVerifyPath || consts_js_1.TURNKEY_OTP_VERIFY_PATH,
215
184
  });
216
- if (!result || !result.credentialBundle) {
185
+ if (!result || !result.session) {
217
186
  throw new exceptions_1.WalletException(new Error('Failed to confirm OTP'));
218
187
  }
219
- await this.injectAndRefresh(result.credentialBundle, {
220
- organizationId: result.organizationId,
221
- expirationSeconds: this.metadata.expirationSeconds,
222
- });
188
+ await indexedDbClient.loginWithSession(result.session);
189
+ this.userOrganizationId = result.organizationId;
223
190
  return result;
224
191
  }
225
192
  async initOAuth(provider) {
226
- const iframeClient = await this.getIframeClient();
227
- const nonce = await oauth_js_1.TurnkeyOauthWallet.generateOAuthNonce(iframeClient);
193
+ const indexedDbClient = await this.getIndexedDbClient();
194
+ const nonce = await oauth_js_1.TurnkeyOauthWallet.generateOAuthNonce(indexedDbClient);
228
195
  if (provider === wallet_base_1.TurnkeyProvider.Apple) {
229
196
  // TODO: implement the ability to generate Apple OAuth URL
230
197
  return nonce;
@@ -239,10 +206,10 @@ class TurnkeyWallet {
239
206
  });
240
207
  }
241
208
  async confirmOAuth(provider, oidcToken) {
242
- const iframeClient = await this.getIframeClient();
209
+ const indexedDbClient = await this.getIndexedDbClient();
243
210
  const oauthResult = await oauth_js_1.TurnkeyOauthWallet.oauthLogin({
244
211
  oidcToken,
245
- iframeClient,
212
+ indexedDbClient,
246
213
  client: this.client,
247
214
  providerName: provider.toString(),
248
215
  oauthLoginPath: this.metadata.oauthLoginPath || consts_js_1.TURNKEY_OAUTH_PATH,
@@ -250,54 +217,41 @@ class TurnkeyWallet {
250
217
  if (!oauthResult || !oauthResult.credentialBundle) {
251
218
  throw new exceptions_1.WalletException(new Error('Unexpected OAuth result'));
252
219
  }
253
- await this.injectAndRefresh(oauthResult.credentialBundle, {
254
- organizationId: oauthResult.organizationId,
255
- expirationSeconds: this.metadata.expirationSeconds,
256
- });
220
+ await indexedDbClient.loginWithSession(oauthResult.credentialBundle);
221
+ this.userOrganizationId = oauthResult.organizationId;
257
222
  return oauthResult.credentialBundle;
258
223
  }
259
224
  async refreshSession() {
260
225
  const session = await this.getSession();
226
+ const indexedDbClient = await this.getIndexedDbClient();
261
227
  if (session.session?.token) {
262
- await this.injectAndRefresh(session.session.token, {
263
- expirationSeconds: this.metadata.expirationSeconds || consts_js_1.DEFAULT_TURNKEY_REFRESH_SECONDS,
228
+ await indexedDbClient.refreshSession({
229
+ sessionType: sdk_browser_1.SessionType.READ_WRITE,
230
+ expirationSeconds: this.metadata.expirationSeconds,
264
231
  });
232
+ this.userOrganizationId = session.organizationId;
265
233
  return session.session.token;
266
234
  }
267
235
  throw new exceptions_1.TurnkeyWalletSessionException(new Error('Session expired. Please login again.'));
268
236
  }
269
- async initFrame() {
237
+ async initClient() {
270
238
  const { metadata } = this;
271
- const { turnkey, iframeClient } = await createTurnkeyIFrame(metadata);
239
+ const { turnkey, indexedDbClient } = await createTurnkeyClient(metadata);
272
240
  this.turnkey = turnkey;
273
- this.iframeClient = iframeClient;
241
+ this.indexedDbClient = indexedDbClient;
242
+ return { turnkey, indexedDbClient };
274
243
  }
275
244
  }
276
245
  exports.TurnkeyWallet = TurnkeyWallet;
277
- async function createTurnkeyIFrame(metadata) {
246
+ async function createTurnkeyClient(metadata) {
278
247
  const turnkey = new sdk_browser_1.Turnkey(metadata);
279
- const turnkeyAuthIframeElementId = metadata.iframeElementId || 'turnkey-auth-iframe-element-id';
280
- if (!metadata.iframeContainerId) {
281
- throw new exceptions_1.GeneralException(new Error('iframeContainerId is required'));
282
- }
248
+ const indexedDbClient = await turnkey.indexedDbClient();
249
+ await indexedDbClient.init();
283
250
  if (!turnkey) {
284
251
  throw new exceptions_1.GeneralException(new Error('Turnkey is not initialized'));
285
252
  }
286
- const iframe = document.getElementById(metadata.iframeContainerId);
287
- if (!iframe) {
288
- throw new exceptions_1.GeneralException(new Error('iframe is null'));
289
- }
290
- const existingIframeClient = document.getElementById(turnkeyAuthIframeElementId);
291
- if (existingIframeClient) {
292
- existingIframeClient.remove();
293
- }
294
- const iframeClient = await turnkey.iframeClient({
295
- iframeContainer: iframe,
296
- iframeElementId: turnkeyAuthIframeElementId,
297
- iframeUrl: metadata?.iframeUrl || 'https://auth.turnkey.com',
298
- });
299
253
  return {
300
254
  turnkey,
301
- iframeClient,
255
+ indexedDbClient,
302
256
  };
303
257
  }
@@ -17,7 +17,7 @@ export type TurnkeyOTPCredentialsResponse = {
17
17
  organizationId: string;
18
18
  };
19
19
  export type TurnkeyConfirmEmailOTPResponse = {
20
- credentialBundle: string;
20
+ session: string;
21
21
  organizationId: string;
22
22
  };
23
23
  export type TurnkeyOauthLoginResponse = {
@@ -1,14 +1,14 @@
1
1
  import { TxRaw, AminoSignResponse, DirectSignResponse } from '@injectivelabs/sdk-ts';
2
+ import { StdSignDoc, WalletDeviceType, type WalletMetadata, BaseConcreteStrategy, ConcreteWalletStrategy, SendTransactionOptions, WalletStrategyEvmOptions, ConcreteEvmWalletStrategyArgs } from '@injectivelabs/wallet-base';
2
3
  import { HttpRestClient } from '@injectivelabs/utils';
3
- import { AccountAddress, EthereumChainId } from '@injectivelabs/ts-types';
4
- import { TurnkeyIframeClient } from '@turnkey/sdk-browser';
5
- import { StdSignDoc, WalletDeviceType, type WalletMetadata, BaseConcreteStrategy, ConcreteWalletStrategy, SendTransactionOptions, WalletStrategyEthereumOptions, ConcreteEthereumWalletStrategyArgs } from '@injectivelabs/wallet-base';
4
+ import { TurnkeyIndexedDbClient } from '@turnkey/sdk-browser';
5
+ import { AccountAddress, EvmChainId } from '@injectivelabs/ts-types';
6
6
  import { TurnkeyWallet } from './turnkey/turnkey.js';
7
7
  export declare class TurnkeyWalletStrategy extends BaseConcreteStrategy implements ConcreteWalletStrategy {
8
8
  turnkeyWallet?: TurnkeyWallet;
9
- ethereumOptions: WalletStrategyEthereumOptions;
9
+ evmOptions: WalletStrategyEvmOptions;
10
10
  client: HttpRestClient;
11
- constructor(args: ConcreteEthereumWalletStrategyArgs & {
11
+ constructor(args: ConcreteEvmWalletStrategyArgs & {
12
12
  apiServerEndpoint?: string;
13
13
  });
14
14
  getWalletDeviceType(): Promise<WalletDeviceType>;
@@ -22,7 +22,7 @@ export declare class TurnkeyWalletStrategy extends BaseConcreteStrategy implemen
22
22
  getWalletClient<TurnkeyWallet>(): Promise<TurnkeyWallet>;
23
23
  sendEvmTransaction(transaction: unknown, args: {
24
24
  address: AccountAddress;
25
- ethereumChainId: EthereumChainId;
25
+ evmChainId: EvmChainId;
26
26
  }): Promise<string>;
27
27
  sendTransaction(transaction: TxRaw, options: SendTransactionOptions): Promise<any>;
28
28
  signEip712TypedData(eip712json: string, address: AccountAddress): Promise<string>;
@@ -38,9 +38,8 @@ export declare class TurnkeyWalletStrategy extends BaseConcreteStrategy implemen
38
38
  }): Promise<AminoSignResponse>;
39
39
  signArbitrary(_signer: AccountAddress, _data: string | Uint8Array): Promise<string>;
40
40
  getEthereumChainId(): Promise<string>;
41
- getEvmTransactionReceipt(txHash: string, ethereumChainId?: EthereumChainId): Promise<Record<string, any>>;
41
+ getEvmTransactionReceipt(txHash: string, evmChainId?: EvmChainId): Promise<Record<string, any>>;
42
42
  getPubKey(): Promise<string>;
43
- getIframeClient(): Promise<TurnkeyIframeClient>;
43
+ getIndexedDbClient(): Promise<TurnkeyIndexedDbClient>;
44
44
  private getTurnkeyWallet;
45
- private getOrganizationId;
46
45
  }
@@ -1,16 +1,15 @@
1
1
  /* eslint-disable class-methods-use-this */
2
2
  import { TxGrpcApi, } from '@injectivelabs/sdk-ts';
3
3
  import { ErrorType, WalletException, UnspecifiedErrorCode, TransactionException, CosmosWalletException, } from '@injectivelabs/exceptions';
4
- import { getAddress } from 'viem';
5
- import { sleep, HttpRestClient } from '@injectivelabs/utils';
6
- import { http, createPublicClient, createWalletClient, } from 'viem';
4
+ import { http, getAddress, createPublicClient, createWalletClient, } from 'viem';
7
5
  import { WalletAction, WalletDeviceType, BaseConcreteStrategy, } from '@injectivelabs/wallet-base';
6
+ import { sleep, HttpRestClient } from '@injectivelabs/utils';
8
7
  import { TurnkeyErrorCodes } from './types.js';
9
8
  import { TurnkeyWallet } from './turnkey/turnkey.js';
10
9
  import { DEFAULT_EVM_CHAIN_CONFIG } from './consts.js';
11
10
  export class TurnkeyWalletStrategy extends BaseConcreteStrategy {
12
11
  turnkeyWallet;
13
- ethereumOptions;
12
+ evmOptions;
14
13
  client;
15
14
  constructor(args) {
16
15
  super(args);
@@ -19,7 +18,7 @@ export class TurnkeyWalletStrategy extends BaseConcreteStrategy {
19
18
  throw new WalletException(new Error('apiServerEndpoint is required'));
20
19
  }
21
20
  this.client = new HttpRestClient(endpoint);
22
- this.ethereumOptions = args.ethereumOptions;
21
+ this.evmOptions = args.evmOptions;
23
22
  }
24
23
  async getWalletDeviceType() {
25
24
  return Promise.resolve(WalletDeviceType.Browser);
@@ -47,7 +46,7 @@ export class TurnkeyWalletStrategy extends BaseConcreteStrategy {
47
46
  }
48
47
  return true;
49
48
  }
50
- return !!(await turnkeyWallet.getIframeClient());
49
+ return !!(await turnkeyWallet.getIndexedDbClient());
51
50
  }
52
51
  catch (e) {
53
52
  return false;
@@ -56,15 +55,15 @@ export class TurnkeyWalletStrategy extends BaseConcreteStrategy {
56
55
  async disconnect() {
57
56
  const turnkeyWallet = await this.getTurnkeyWallet();
58
57
  const turnkey = await turnkeyWallet.getTurnkey();
58
+ const indexedDbClient = await turnkeyWallet.getIndexedDbClient();
59
59
  const isUserLoggedIn = await turnkey.getSession();
60
60
  if (!isUserLoggedIn) {
61
61
  return;
62
62
  }
63
- await turnkey.logout();
63
+ await Promise.allSettled([turnkey.logout(), indexedDbClient.clear()]);
64
64
  }
65
65
  async getAddresses() {
66
66
  const turnkeyWallet = await this.getTurnkeyWallet();
67
- await turnkeyWallet.getSession();
68
67
  try {
69
68
  return await turnkeyWallet.getAccounts();
70
69
  }
@@ -89,18 +88,17 @@ export class TurnkeyWalletStrategy extends BaseConcreteStrategy {
89
88
  }
90
89
  async sendEvmTransaction(transaction, args) {
91
90
  try {
92
- const options = this.ethereumOptions;
91
+ const options = this.evmOptions;
93
92
  const turnkeyWallet = await this.getTurnkeyWallet();
94
- const organizationId = await this.getOrganizationId();
95
- const chainId = args.ethereumChainId || options.ethereumChainId;
96
- const url = options.rpcUrl || options.rpcUrls?.[args.ethereumChainId];
93
+ const chainId = args.evmChainId || options.evmChainId;
94
+ const url = options.rpcUrl || options.rpcUrls?.[args.evmChainId];
97
95
  if (!url) {
98
- throw new WalletException(new Error('Please pass rpcUrl within the ethereumOptions'), {
96
+ throw new WalletException(new Error('Please pass rpcUrl within the evmOptions'), {
99
97
  code: UnspecifiedErrorCode,
100
98
  context: WalletAction.SendEvmTransaction,
101
99
  });
102
100
  }
103
- const account = await turnkeyWallet.getOrCreateAndGetAccount(getAddress(args.address), organizationId);
101
+ const account = await turnkeyWallet.getOrCreateAndGetAccount(getAddress(args.address));
104
102
  const accountClient = createWalletClient({
105
103
  account: account,
106
104
  chain: {
@@ -147,10 +145,9 @@ export class TurnkeyWalletStrategy extends BaseConcreteStrategy {
147
145
  }
148
146
  async signEip712TypedData(eip712json, address) {
149
147
  const turnkeyWallet = await this.getTurnkeyWallet();
150
- const organizationId = await this.getOrganizationId();
151
148
  //? Turnkey expects the case sensitive address and the current impl of getChecksumAddress from sdk-ts doesn't play nice with browser envs
152
149
  const checksumAddress = getAddress(address);
153
- const account = await turnkeyWallet.getOrCreateAndGetAccount(checksumAddress, organizationId);
150
+ const account = await turnkeyWallet.getOrCreateAndGetAccount(checksumAddress);
154
151
  if (!account) {
155
152
  throw new WalletException(new Error('Turnkey account not found'));
156
153
  }
@@ -196,14 +193,14 @@ export class TurnkeyWalletStrategy extends BaseConcreteStrategy {
196
193
  context: WalletAction.GetChainId,
197
194
  });
198
195
  }
199
- async getEvmTransactionReceipt(txHash, ethereumChainId) {
200
- const options = this.ethereumOptions;
196
+ async getEvmTransactionReceipt(txHash, evmChainId) {
197
+ const options = this.evmOptions;
201
198
  const maxAttempts = 10;
202
199
  const interval = 3000;
203
- const chainId = ethereumChainId || options.ethereumChainId;
200
+ const chainId = evmChainId || options.evmChainId;
204
201
  const url = options.rpcUrl || options.rpcUrls?.[chainId];
205
202
  if (!url) {
206
- throw new WalletException(new Error('Please pass rpcUrl within the ethereumOptions'), {
203
+ throw new WalletException(new Error('Please pass rpcUrl within the evmOptions'), {
207
204
  code: UnspecifiedErrorCode,
208
205
  context: WalletAction.GetEvmTransactionReceipt,
209
206
  });
@@ -240,9 +237,10 @@ export class TurnkeyWalletStrategy extends BaseConcreteStrategy {
240
237
  async getPubKey() {
241
238
  throw new WalletException(new Error('You can only fetch PubKey from Cosmos native wallets'));
242
239
  }
243
- async getIframeClient() {
240
+ async getIndexedDbClient() {
244
241
  const turnkeyWallet = await this.getTurnkeyWallet();
245
- return turnkeyWallet.getIframeClient();
242
+ const indexedDbClient = await turnkeyWallet.getIndexedDbClient();
243
+ return indexedDbClient;
246
244
  }
247
245
  async getTurnkeyWallet() {
248
246
  const { metadata } = this;
@@ -256,20 +254,8 @@ export class TurnkeyWalletStrategy extends BaseConcreteStrategy {
256
254
  if (!metadata.turnkey.apiServerEndpoint) {
257
255
  throw new WalletException(new Error('Turnkey apiServerEndpoint is required'));
258
256
  }
259
- if (!metadata.turnkey.defaultOrganizationId) {
260
- throw new WalletException(new Error('Turnkey defaultOrganizationId is required'));
261
- }
262
257
  this.turnkeyWallet = new TurnkeyWallet(metadata.turnkey);
263
258
  }
264
259
  return this.turnkeyWallet;
265
260
  }
266
- async getOrganizationId() {
267
- const { metadata } = this;
268
- const organizationId = metadata?.turnkey?.organizationId ||
269
- metadata?.turnkey?.defaultOrganizationId;
270
- if (!organizationId) {
271
- throw new WalletException(new Error('Organization ID is required'));
272
- }
273
- return organizationId;
274
- }
275
261
  }
@@ -1,13 +1,13 @@
1
- import type { TurnkeyIframeClient } from '@turnkey/sdk-browser';
1
+ import type { TurnkeyIndexedDbClient } from '@turnkey/sdk-browser';
2
2
  import { type HttpRestClient } from '@injectivelabs/utils';
3
3
  export declare class TurnkeyOauthWallet {
4
- static generateOAuthNonce(iframeClient: TurnkeyIframeClient): Promise<string>;
4
+ static generateOAuthNonce(indexedDbClient: TurnkeyIndexedDbClient): Promise<string>;
5
5
  static oauthLogin(args: {
6
6
  oidcToken: string;
7
7
  client: HttpRestClient;
8
8
  oauthLoginPath?: string;
9
9
  providerName: 'google' | 'apple';
10
- iframeClient: TurnkeyIframeClient;
10
+ indexedDbClient: TurnkeyIndexedDbClient;
11
11
  expirationSeconds?: number;
12
12
  }): Promise<{
13
13
  organizationId: string;
@@ -2,9 +2,10 @@ import { ErrorType, WalletException, UnspecifiedErrorCode, } from '@injectivelab
2
2
  import { sha256 } from '@injectivelabs/sdk-ts';
3
3
  import { DEFAULT_TURNKEY_REFRESH_SECONDS, TURNKEY_OAUTH_PATH, } from '../consts.js';
4
4
  export class TurnkeyOauthWallet {
5
- static async generateOAuthNonce(iframeClient) {
5
+ static async generateOAuthNonce(indexedDbClient) {
6
6
  try {
7
- const targetPublicKey = iframeClient.iframePublicKey;
7
+ await indexedDbClient.resetKeyPair();
8
+ const targetPublicKey = await indexedDbClient.getPublicKey();
8
9
  if (!targetPublicKey) {
9
10
  throw new WalletException(new Error('Target public key not found'));
10
11
  }
@@ -21,10 +22,10 @@ export class TurnkeyOauthWallet {
21
22
  }
22
23
  }
23
24
  static async oauthLogin(args) {
24
- const { client, iframeClient, expirationSeconds } = args;
25
+ const { client, indexedDbClient, expirationSeconds } = args;
25
26
  const path = args.oauthLoginPath || TURNKEY_OAUTH_PATH;
26
27
  try {
27
- const targetPublicKey = iframeClient.iframePublicKey;
28
+ const targetPublicKey = await indexedDbClient.getPublicKey();
28
29
  if (!targetPublicKey) {
29
30
  throw new WalletException(new Error('Target public key not found'));
30
31
  }
@@ -1,4 +1,4 @@
1
- import { type TurnkeyIframeClient } from '@turnkey/sdk-browser';
1
+ import { TurnkeyIndexedDbClient } from '@turnkey/sdk-browser';
2
2
  import { type TurnkeyConfirmEmailOTPResponse, type TurnkeyOTPCredentialsResponse } from './../types.js';
3
3
  import { type HttpRestClient } from '@injectivelabs/utils';
4
4
  export declare class TurnkeyOtpWallet {
@@ -7,15 +7,16 @@ export declare class TurnkeyOtpWallet {
7
7
  subOrgId?: string;
8
8
  otpInitPath?: string;
9
9
  client: HttpRestClient;
10
- iframeClient: TurnkeyIframeClient;
10
+ indexedDbClient: TurnkeyIndexedDbClient;
11
11
  invalidateExistingSessions?: boolean;
12
+ expirationSeconds?: number;
12
13
  }): Promise<TurnkeyOTPCredentialsResponse | undefined>;
13
14
  static confirmEmailOTP(args: {
14
15
  otpCode: string;
15
16
  emailOTPId: string;
16
17
  client: HttpRestClient;
18
+ targetPublicKey: string;
17
19
  organizationId: string;
18
- iframeClient: TurnkeyIframeClient;
19
20
  otpVerifyPath?: string;
20
21
  expirationSeconds?: number;
21
22
  }): Promise<TurnkeyConfirmEmailOTPResponse | undefined>;
@@ -2,18 +2,21 @@ import { ErrorType, WalletException, UnspecifiedErrorCode, } from '@injectivelab
2
2
  import { DEFAULT_TURNKEY_REFRESH_SECONDS, TURNKEY_OTP_INIT_PATH, TURNKEY_OTP_VERIFY_PATH, } from '../consts.js';
3
3
  export class TurnkeyOtpWallet {
4
4
  static async initEmailOTP(args) {
5
- const { client, iframeClient } = args;
5
+ const { client, indexedDbClient, expirationSeconds } = args;
6
6
  try {
7
- const targetPublicKey = iframeClient.iframePublicKey;
8
- if (!targetPublicKey) {
9
- throw new WalletException(new Error('Target public key not found'));
7
+ await indexedDbClient.resetKeyPair();
8
+ let publicKey = await indexedDbClient.getPublicKey();
9
+ if (!publicKey) {
10
+ throw new WalletException(new Error('Public key not found'));
10
11
  }
11
12
  // client.$post is undefined, resorting to this for now
12
13
  const response = await client.post(args.otpInitPath || TURNKEY_OTP_INIT_PATH, {
13
- targetPublicKey,
14
+ targetPublicKey: publicKey,
14
15
  email: args.email,
15
16
  suborgId: args.subOrgId,
16
17
  invalidateExistingSessions: args.invalidateExistingSessions,
18
+ isUsingIndexedDB: true,
19
+ expirationSeconds: expirationSeconds || DEFAULT_TURNKEY_REFRESH_SECONDS,
17
20
  });
18
21
  return response?.data;
19
22
  }
@@ -26,15 +29,11 @@ export class TurnkeyOtpWallet {
26
29
  }
27
30
  }
28
31
  static async confirmEmailOTP(args) {
29
- const { client, iframeClient, expirationSeconds } = args;
32
+ const { client, expirationSeconds, targetPublicKey } = args;
30
33
  try {
31
34
  const organizationId = args.organizationId;
32
35
  const emailOTPId = args.emailOTPId;
33
- const targetPublicKey = iframeClient.iframePublicKey;
34
36
  const otpVerifyPath = args.otpVerifyPath || TURNKEY_OTP_VERIFY_PATH;
35
- if (!targetPublicKey) {
36
- throw new WalletException(new Error('Target public key not found'));
37
- }
38
37
  if (!emailOTPId) {
39
38
  throw new WalletException(new Error('Email OTP ID is required'));
40
39
  }
@@ -42,6 +41,7 @@ export class TurnkeyOtpWallet {
42
41
  throw new WalletException(new Error('Organization ID is required'));
43
42
  }
44
43
  const response = await client.post(otpVerifyPath, {
44
+ isUsingIndexedDB: true,
45
45
  targetPublicKey,
46
46
  otpId: emailOTPId,
47
47
  otpCode: args.otpCode,