@injectivelabs/wallet-turnkey 1.16.38-alpha.7 → 1.16.38

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 (41) hide show
  1. package/dist/cjs/index.d.ts +3 -0
  2. package/dist/cjs/index.js +21 -0
  3. package/dist/cjs/package.json +2 -2
  4. package/dist/cjs/strategy/Eip1193Provider.d.ts +3 -0
  5. package/dist/cjs/strategy/Eip1193Provider.js +131 -0
  6. package/dist/cjs/strategy/consts.d.ts +13 -0
  7. package/dist/cjs/strategy/consts.js +16 -0
  8. package/dist/cjs/strategy/strategy.d.ts +48 -0
  9. package/dist/cjs/strategy/strategy.js +275 -0
  10. package/dist/cjs/strategy/turnkey/oauth.d.ts +16 -0
  11. package/dist/cjs/strategy/turnkey/oauth.js +53 -0
  12. package/dist/cjs/strategy/turnkey/otp.d.ts +23 -0
  13. package/dist/cjs/strategy/turnkey/otp.js +65 -0
  14. package/dist/cjs/strategy/turnkey/turnkey.d.ts +35 -0
  15. package/dist/cjs/strategy/turnkey/turnkey.js +259 -0
  16. package/dist/cjs/strategy/types.d.ts +28 -0
  17. package/dist/cjs/strategy/types.js +6 -0
  18. package/dist/cjs/utils.d.ts +7 -0
  19. package/dist/cjs/utils.js +10 -0
  20. package/dist/esm/index.d.ts +3 -97
  21. package/dist/esm/index.js +3 -688
  22. package/dist/esm/package.json +2 -2
  23. package/dist/esm/strategy/Eip1193Provider.d.ts +3 -0
  24. package/dist/esm/strategy/Eip1193Provider.js +127 -0
  25. package/dist/esm/strategy/consts.d.ts +13 -0
  26. package/dist/esm/strategy/consts.js +13 -0
  27. package/dist/esm/strategy/strategy.d.ts +48 -0
  28. package/dist/esm/strategy/strategy.js +271 -0
  29. package/dist/esm/strategy/turnkey/oauth.d.ts +16 -0
  30. package/dist/esm/strategy/turnkey/oauth.js +49 -0
  31. package/dist/esm/strategy/turnkey/otp.d.ts +23 -0
  32. package/dist/esm/strategy/turnkey/otp.js +61 -0
  33. package/dist/esm/strategy/turnkey/turnkey.d.ts +35 -0
  34. package/dist/esm/strategy/turnkey/turnkey.js +255 -0
  35. package/dist/esm/strategy/types.d.ts +28 -0
  36. package/dist/esm/strategy/types.js +3 -0
  37. package/dist/esm/utils.d.ts +7 -0
  38. package/dist/esm/utils.js +7 -0
  39. package/package.json +56 -46
  40. package/dist/cjs/index.cjs +0 -689
  41. package/dist/cjs/index.d.cts +0 -97
@@ -0,0 +1,3 @@
1
+ import type { LocalAccount } from 'viem';
2
+ import type { Eip1193Provider } from '@injectivelabs/wallet-base';
3
+ export declare const getEip1193ProviderForTurnkey: (account: LocalAccount, chainId: string) => Promise<Eip1193Provider>;
@@ -0,0 +1,127 @@
1
+ import { getEvmChainConfig, getViemPublicClient, getViemWalletClient, } from '@injectivelabs/wallet-base';
2
+ export const getEip1193ProviderForTurnkey = async (account, chainId) => {
3
+ const provider = new CustomEip1193Provider({
4
+ chainId: parseInt(chainId, 16),
5
+ signTypedData: account.signTypedData.bind(account),
6
+ signMessage: account.signMessage.bind(account),
7
+ signTransaction: account.signTransaction.bind(account),
8
+ account,
9
+ address: account.address,
10
+ });
11
+ return provider;
12
+ };
13
+ class CustomEip1193Provider {
14
+ chainId;
15
+ signTypedData;
16
+ signMessage;
17
+ signTransaction;
18
+ account;
19
+ address;
20
+ constructor(args) {
21
+ this.chainId = args.chainId ?? 1;
22
+ this.signTypedData = args.signTypedData;
23
+ this.signMessage = args.signMessage;
24
+ this.account = args.account;
25
+ this.address = args.address;
26
+ this.signTransaction = args.signTransaction;
27
+ }
28
+ async requestAccounts() {
29
+ return [this.address];
30
+ }
31
+ getClient() {
32
+ return getViemWalletClient({
33
+ chainId: this.chainId,
34
+ account: this.account,
35
+ });
36
+ }
37
+ getChain() {
38
+ return getEvmChainConfig(this.chainId);
39
+ }
40
+ on(_event, _listener) {
41
+ throw new Error('Not implemented');
42
+ }
43
+ removeListener(..._args) {
44
+ throw new Error('Not implemented!');
45
+ }
46
+ async request(args) {
47
+ if (args.method === 'eth_requestAccounts') {
48
+ return this.requestAccounts();
49
+ }
50
+ if (args.method === 'eth_signTypedData') {
51
+ if (!args.params) {
52
+ throw new Error('params is required');
53
+ }
54
+ return this.signTypedData(args.params[0]);
55
+ }
56
+ if (args.method === 'eth_signMessage') {
57
+ if (!args.params) {
58
+ throw new Error('params is required');
59
+ }
60
+ return this.signMessage(args.params[0]);
61
+ }
62
+ if (args.method === 'eth_chainId') {
63
+ return this.chainId;
64
+ }
65
+ if (args.method === 'wallet_switchEthereumChain') {
66
+ if (!args.params) {
67
+ throw new Error('params is required');
68
+ }
69
+ const chainId = String(args.params[0].chainId).replace('0x', '');
70
+ this.chainId = parseInt(chainId, 16);
71
+ return true;
72
+ }
73
+ if (args.method === 'eth_sendTransaction') {
74
+ if (!args.params) {
75
+ throw new Error('params is required');
76
+ }
77
+ const accountClient = getViemWalletClient({
78
+ chainId: this.chainId,
79
+ account: this.account,
80
+ });
81
+ const client = this.getClient();
82
+ const parseHexValue = (value) => {
83
+ if (typeof value === 'string') {
84
+ const hexValue = value.startsWith('0x') ? value : `0x${value}`;
85
+ return BigInt(hexValue);
86
+ }
87
+ return BigInt(value);
88
+ };
89
+ const txData = args.params[0];
90
+ const processedTransaction = { ...txData };
91
+ const hexFields = [
92
+ 'value',
93
+ 'gas',
94
+ 'gasLimit',
95
+ 'gasPrice',
96
+ 'maxFeePerGas',
97
+ 'maxPriorityFeePerGas',
98
+ ];
99
+ for (const field of hexFields) {
100
+ if (processedTransaction[field] !== undefined) {
101
+ processedTransaction[field] = parseHexValue(processedTransaction[field]);
102
+ }
103
+ }
104
+ const preparedTransaction = await accountClient.prepareTransactionRequest(processedTransaction);
105
+ const signedTransaction = await this.signTransaction(preparedTransaction);
106
+ const tx = await client.sendRawTransaction({
107
+ serializedTransaction: signedTransaction,
108
+ });
109
+ return tx;
110
+ }
111
+ if (args.method === 'eth_getTransactionCount') {
112
+ if (!args.params) {
113
+ throw new Error('params is required');
114
+ }
115
+ const client = getViemPublicClient(this.chainId);
116
+ const count = await client.getTransactionCount({
117
+ address: this.address,
118
+ blockTag: 'pending',
119
+ });
120
+ return `0x${count.toString(16)}`;
121
+ }
122
+ return this.getClient().request({
123
+ method: args.method,
124
+ params: args.params,
125
+ });
126
+ }
127
+ }
@@ -0,0 +1,13 @@
1
+ export declare const TURNKEY_OAUTH_PATH = "turnkey/oauth";
2
+ export declare const TURNKEY_OTP_PATH = "turnkey/otp";
3
+ export declare const TURNKEY_OTP_INIT_PATH = "turnkey/otp/init";
4
+ export declare const TURNKEY_OTP_VERIFY_PATH = "turnkey/otp/verify";
5
+ export declare const DEFAULT_TURNKEY_REFRESH_SECONDS = "86400";
6
+ export declare const DEFAULT_EVM_CHAIN_CONFIG: {
7
+ name: string;
8
+ nativeCurrency: {
9
+ name: string;
10
+ symbol: string;
11
+ decimals: number;
12
+ };
13
+ };
@@ -0,0 +1,13 @@
1
+ export const TURNKEY_OAUTH_PATH = 'turnkey/oauth';
2
+ export const TURNKEY_OTP_PATH = 'turnkey/otp';
3
+ export const TURNKEY_OTP_INIT_PATH = `${TURNKEY_OTP_PATH}/init`;
4
+ export const TURNKEY_OTP_VERIFY_PATH = `${TURNKEY_OTP_PATH}/verify`;
5
+ export const DEFAULT_TURNKEY_REFRESH_SECONDS = '86400';
6
+ export const DEFAULT_EVM_CHAIN_CONFIG = {
7
+ name: 'Injective',
8
+ nativeCurrency: {
9
+ name: 'Injective',
10
+ symbol: 'INJ',
11
+ decimals: 18,
12
+ },
13
+ };
@@ -0,0 +1,48 @@
1
+ import { HttpRestClient } from '@injectivelabs/utils';
2
+ import { WalletDeviceType, type WalletMetadata, BaseConcreteStrategy } from '@injectivelabs/wallet-base';
3
+ import { TurnkeyWallet } from './turnkey/turnkey.js';
4
+ import type { EvmChainId } from '@injectivelabs/ts-types';
5
+ import type { AccountAddress } from '@injectivelabs/ts-types';
6
+ import type { TurnkeyIndexedDbClient } from '@turnkey/sdk-browser';
7
+ import type { TxRaw, AminoSignResponse, DirectSignResponse } from '@injectivelabs/sdk-ts';
8
+ import type { StdSignDoc, Eip1193Provider, ConcreteWalletStrategy, SendTransactionOptions, WalletStrategyEvmOptions, ConcreteEvmWalletStrategyArgs } from '@injectivelabs/wallet-base';
9
+ export declare class TurnkeyWalletStrategy extends BaseConcreteStrategy implements ConcreteWalletStrategy {
10
+ turnkeyWallet?: TurnkeyWallet;
11
+ evmOptions: WalletStrategyEvmOptions;
12
+ client: HttpRestClient;
13
+ constructor(args: ConcreteEvmWalletStrategyArgs & {
14
+ apiServerEndpoint?: string;
15
+ });
16
+ getWalletDeviceType(): Promise<WalletDeviceType>;
17
+ setMetadata(metadata?: {
18
+ turnkey?: Partial<WalletMetadata['turnkey']>;
19
+ }): void;
20
+ enable(): Promise<boolean>;
21
+ disconnect(): Promise<void>;
22
+ getAddresses(): Promise<string[]>;
23
+ getSessionOrConfirm(_address?: string): Promise<string>;
24
+ getWalletClient<TurnkeyWallet>(): Promise<TurnkeyWallet>;
25
+ sendEvmTransaction(transaction: unknown, args: {
26
+ address: AccountAddress;
27
+ evmChainId: EvmChainId;
28
+ }): Promise<string>;
29
+ sendTransaction(transaction: TxRaw, options: SendTransactionOptions): Promise<any>;
30
+ signEip712TypedData(eip712json: string, address: AccountAddress): Promise<string>;
31
+ signCosmosTransaction(_transaction: {
32
+ txRaw: TxRaw;
33
+ accountNumber: number;
34
+ chainId: string;
35
+ address: string;
36
+ }): Promise<DirectSignResponse>;
37
+ signAminoCosmosTransaction(_transaction: {
38
+ address: string;
39
+ signDoc: StdSignDoc;
40
+ }): Promise<AminoSignResponse>;
41
+ signArbitrary(_signer: AccountAddress, _data: string | Uint8Array): Promise<string>;
42
+ getEthereumChainId(): Promise<string>;
43
+ getEvmTransactionReceipt(txHash: string, evmChainId?: EvmChainId): Promise<Record<string, any>>;
44
+ getPubKey(): Promise<string>;
45
+ getIndexedDbClient(): Promise<TurnkeyIndexedDbClient>;
46
+ private getTurnkeyWallet;
47
+ getEip1193Provider(): Promise<Eip1193Provider>;
48
+ }
@@ -0,0 +1,271 @@
1
+ import { getAddress } from 'viem';
2
+ import { TxGrpcApi } from '@injectivelabs/sdk-ts';
3
+ import { getEthereumAddress } from '@injectivelabs/sdk-ts';
4
+ import { sleep, HttpRestClient } from '@injectivelabs/utils';
5
+ import { ErrorType, WalletException, UnspecifiedErrorCode, TransactionException, CosmosWalletException, } from '@injectivelabs/exceptions';
6
+ import { WalletAction, WalletDeviceType, getViemWalletClient, getViemPublicClient, BaseConcreteStrategy, } from '@injectivelabs/wallet-base';
7
+ import { TurnkeyErrorCodes } from './types.js';
8
+ import { TurnkeyWallet } from './turnkey/turnkey.js';
9
+ import { getEip1193ProviderForTurnkey } from './Eip1193Provider.js';
10
+ export class TurnkeyWalletStrategy extends BaseConcreteStrategy {
11
+ turnkeyWallet;
12
+ evmOptions;
13
+ client;
14
+ constructor(args) {
15
+ super(args);
16
+ const endpoint = args.apiServerEndpoint || this.metadata?.turnkey?.apiServerEndpoint;
17
+ if (!endpoint) {
18
+ throw new WalletException(new Error('apiServerEndpoint is required'));
19
+ }
20
+ this.client = new HttpRestClient(endpoint);
21
+ this.evmOptions = args.evmOptions;
22
+ }
23
+ async getWalletDeviceType() {
24
+ return Promise.resolve(WalletDeviceType.Browser);
25
+ }
26
+ setMetadata(metadata) {
27
+ if (metadata?.turnkey) {
28
+ this.metadata = {
29
+ ...this.metadata,
30
+ turnkey: {
31
+ ...this.metadata?.turnkey,
32
+ ...metadata.turnkey,
33
+ },
34
+ };
35
+ this.turnkeyWallet?.setMetadata(this.metadata?.turnkey);
36
+ }
37
+ }
38
+ async enable() {
39
+ const turnkeyWallet = await this.getTurnkeyWallet();
40
+ try {
41
+ const session = await turnkeyWallet.getSession();
42
+ if (session.session) {
43
+ // User is already logged in, we don't need to do anything in the next steps
44
+ if (this.metadata?.turnkey) {
45
+ this.metadata.turnkey.session = session.session;
46
+ }
47
+ return true;
48
+ }
49
+ return !!(await turnkeyWallet.getIndexedDbClient());
50
+ }
51
+ catch {
52
+ return false;
53
+ }
54
+ }
55
+ async disconnect() {
56
+ const turnkeyWallet = await this.getTurnkeyWallet();
57
+ const turnkey = await turnkeyWallet.getTurnkey();
58
+ const indexedDbClient = await turnkeyWallet.getIndexedDbClient();
59
+ const isUserLoggedIn = await turnkey.getSession();
60
+ if (!isUserLoggedIn) {
61
+ return;
62
+ }
63
+ await Promise.allSettled([turnkey.logout(), indexedDbClient.clear()]);
64
+ }
65
+ async getAddresses() {
66
+ const turnkeyWallet = await this.getTurnkeyWallet();
67
+ try {
68
+ return await turnkeyWallet.getAccounts();
69
+ }
70
+ catch (e) {
71
+ if (e.contextCode === TurnkeyErrorCodes.UserLoggedOut) {
72
+ await this.disconnect();
73
+ throw e;
74
+ }
75
+ throw new WalletException(new Error(e.message), {
76
+ code: UnspecifiedErrorCode,
77
+ type: ErrorType.WalletError,
78
+ contextModule: WalletAction.GetAccounts,
79
+ });
80
+ }
81
+ }
82
+ async getSessionOrConfirm(_address) {
83
+ const turnkeyWallet = await this.getTurnkeyWallet();
84
+ return await turnkeyWallet.refreshSession();
85
+ }
86
+ async getWalletClient() {
87
+ return (await this.getTurnkeyWallet());
88
+ }
89
+ async sendEvmTransaction(transaction, args) {
90
+ try {
91
+ const options = this.evmOptions;
92
+ const turnkeyWallet = await this.getTurnkeyWallet();
93
+ const chainId = args.evmChainId || options.evmChainId;
94
+ const url = options.rpcUrl || options.rpcUrls?.[args.evmChainId];
95
+ if (!url) {
96
+ throw new WalletException(new Error('Please pass rpcUrl within the evmOptions'), {
97
+ code: UnspecifiedErrorCode,
98
+ context: WalletAction.SendEvmTransaction,
99
+ });
100
+ }
101
+ const account = await turnkeyWallet.getOrCreateAndGetAccount(getAddress(args.address));
102
+ const accountClient = getViemWalletClient({
103
+ chainId,
104
+ account: account,
105
+ rpcUrl: url,
106
+ });
107
+ const parseHexValue = (value) => {
108
+ if (typeof value === 'string') {
109
+ const hexValue = value.startsWith('0x') ? value : `0x${value}`;
110
+ return BigInt(hexValue);
111
+ }
112
+ return BigInt(value);
113
+ };
114
+ const txData = transaction;
115
+ const processedTransaction = { ...txData };
116
+ const hexFields = [
117
+ 'value',
118
+ 'gas',
119
+ 'gasLimit',
120
+ 'gasPrice',
121
+ 'maxFeePerGas',
122
+ 'maxPriorityFeePerGas',
123
+ ];
124
+ for (const field of hexFields) {
125
+ if (processedTransaction[field] !== undefined) {
126
+ processedTransaction[field] = parseHexValue(processedTransaction[field]);
127
+ }
128
+ }
129
+ const preparedTransaction = await accountClient.prepareTransactionRequest(processedTransaction);
130
+ delete preparedTransaction.account;
131
+ const signedTransaction = await accountClient.signTransaction(preparedTransaction);
132
+ const tx = await accountClient.sendRawTransaction({
133
+ serializedTransaction: signedTransaction,
134
+ });
135
+ return tx;
136
+ }
137
+ catch (e) {
138
+ throw new WalletException(e, {
139
+ code: UnspecifiedErrorCode,
140
+ context: WalletAction.SendEvmTransaction,
141
+ });
142
+ }
143
+ }
144
+ async sendTransaction(transaction, options) {
145
+ const { endpoints, txTimeout } = options;
146
+ if (!endpoints) {
147
+ throw new WalletException(new Error('You have to pass endpoints.grpc within the options for using Turnkey wallet'));
148
+ }
149
+ const txApi = new TxGrpcApi(endpoints.grpc);
150
+ const response = await txApi.broadcast(transaction, { txTimeout });
151
+ if (response.code !== 0) {
152
+ throw new TransactionException(new Error(response.rawLog), {
153
+ code: UnspecifiedErrorCode,
154
+ contextCode: response.code,
155
+ contextModule: response.codespace,
156
+ });
157
+ }
158
+ return response;
159
+ }
160
+ async signEip712TypedData(eip712json, address) {
161
+ const turnkeyWallet = await this.getTurnkeyWallet();
162
+ //? Turnkey expects the case sensitive address and the current impl of getChecksumAddress from sdk-ts doesn't play nice with browser envs
163
+ const checksumAddress = getAddress(address);
164
+ const account = await turnkeyWallet.getOrCreateAndGetAccount(checksumAddress);
165
+ if (!account) {
166
+ throw new WalletException(new Error('Turnkey account not found'));
167
+ }
168
+ let parsedData;
169
+ try {
170
+ parsedData = JSON.parse(eip712json);
171
+ }
172
+ catch {
173
+ throw new WalletException(new Error('Failed to parse EIP-712 data: Invalid JSON format'), {
174
+ code: UnspecifiedErrorCode,
175
+ type: ErrorType.WalletError,
176
+ contextModule: WalletAction.SignTransaction,
177
+ });
178
+ }
179
+ const signature = await account.signTypedData(parsedData);
180
+ return signature;
181
+ }
182
+ async signCosmosTransaction(_transaction) {
183
+ throw new WalletException(new Error('This wallet does not support signing Cosmos transactions'), {
184
+ code: UnspecifiedErrorCode,
185
+ type: ErrorType.WalletError,
186
+ contextModule: WalletAction.SignTransaction,
187
+ });
188
+ }
189
+ async signAminoCosmosTransaction(_transaction) {
190
+ throw new WalletException(new Error('This wallet does not support signAminoCosmosTransaction'), {
191
+ code: UnspecifiedErrorCode,
192
+ type: ErrorType.WalletError,
193
+ contextModule: WalletAction.SignTransaction,
194
+ });
195
+ }
196
+ async signArbitrary(_signer, _data) {
197
+ throw new WalletException(new Error('This wallet does not support signArbitrary'), {
198
+ code: UnspecifiedErrorCode,
199
+ type: ErrorType.WalletError,
200
+ contextModule: WalletAction.SignTransaction,
201
+ });
202
+ }
203
+ async getEthereumChainId() {
204
+ throw new CosmosWalletException(new Error('getEthereumChainId is not supported on Turnkey wallet'), {
205
+ code: UnspecifiedErrorCode,
206
+ context: WalletAction.GetChainId,
207
+ });
208
+ }
209
+ async getEvmTransactionReceipt(txHash, evmChainId) {
210
+ const options = this.evmOptions;
211
+ const maxAttempts = 10;
212
+ const interval = 3000;
213
+ const chainId = evmChainId || options.evmChainId;
214
+ const url = options.rpcUrl || options.rpcUrls?.[chainId];
215
+ if (!url) {
216
+ throw new WalletException(new Error('Please pass rpcUrl within the evmOptions'), {
217
+ code: UnspecifiedErrorCode,
218
+ context: WalletAction.GetEvmTransactionReceipt,
219
+ });
220
+ }
221
+ const publicClient = getViemPublicClient(chainId, url);
222
+ let attempts = 0;
223
+ while (attempts < maxAttempts) {
224
+ attempts++;
225
+ await sleep(interval);
226
+ try {
227
+ const receipt = await publicClient.getTransactionReceipt({
228
+ hash: txHash,
229
+ });
230
+ if (receipt) {
231
+ return receipt;
232
+ }
233
+ }
234
+ catch { }
235
+ }
236
+ throw new Error(`Failed to retrieve transaction receipt for txHash: ${txHash}`);
237
+ }
238
+ async getPubKey() {
239
+ throw new WalletException(new Error('You can only fetch PubKey from Cosmos native wallets'));
240
+ }
241
+ async getIndexedDbClient() {
242
+ const turnkeyWallet = await this.getTurnkeyWallet();
243
+ const indexedDbClient = await turnkeyWallet.getIndexedDbClient();
244
+ return indexedDbClient;
245
+ }
246
+ async getTurnkeyWallet() {
247
+ const { metadata } = this;
248
+ if (!this.turnkeyWallet) {
249
+ if (!metadata?.turnkey) {
250
+ throw new WalletException(new Error('Turnkey metadata is required'));
251
+ }
252
+ if (!metadata.turnkey.apiBaseUrl) {
253
+ throw new WalletException(new Error('Turnkey apiBaseUrl is required'));
254
+ }
255
+ if (!metadata.turnkey.apiServerEndpoint) {
256
+ throw new WalletException(new Error('Turnkey apiServerEndpoint is required'));
257
+ }
258
+ this.turnkeyWallet = new TurnkeyWallet(metadata.turnkey);
259
+ }
260
+ return this.turnkeyWallet;
261
+ }
262
+ async getEip1193Provider() {
263
+ const turnkeyWallet = await this.getTurnkeyWallet();
264
+ const addresses = await turnkeyWallet.getAccounts();
265
+ //? Turnkey expects the case sensitive address and the current impl of getChecksumAddress from sdk-ts doesn't play nice with browser envs
266
+ const checksumAddress = getAddress(getEthereumAddress(addresses[0]));
267
+ const account = await turnkeyWallet.getOrCreateAndGetAccount(checksumAddress);
268
+ const eip1193Provider = await getEip1193ProviderForTurnkey(account, String(this.evmOptions.evmChainId));
269
+ return eip1193Provider;
270
+ }
271
+ }
@@ -0,0 +1,16 @@
1
+ import type { HttpRestClient } from '@injectivelabs/utils';
2
+ import type { TurnkeyIndexedDbClient } from '@turnkey/sdk-browser';
3
+ export declare class TurnkeyOauthWallet {
4
+ static generateOAuthNonce(indexedDbClient: TurnkeyIndexedDbClient): Promise<string>;
5
+ static oauthLogin(args: {
6
+ oidcToken: string;
7
+ client: HttpRestClient;
8
+ oauthLoginPath?: string;
9
+ providerName: 'google' | 'apple';
10
+ indexedDbClient: TurnkeyIndexedDbClient;
11
+ expirationSeconds?: number;
12
+ }): Promise<{
13
+ organizationId: string;
14
+ credentialBundle: string;
15
+ } | undefined>;
16
+ }
@@ -0,0 +1,49 @@
1
+ import { sha256 } from '@injectivelabs/sdk-ts';
2
+ import { ErrorType, WalletException, UnspecifiedErrorCode, } from '@injectivelabs/exceptions';
3
+ import { TURNKEY_OAUTH_PATH, DEFAULT_TURNKEY_REFRESH_SECONDS, } from '../consts.js';
4
+ export class TurnkeyOauthWallet {
5
+ static async generateOAuthNonce(indexedDbClient) {
6
+ try {
7
+ await indexedDbClient.resetKeyPair();
8
+ const targetPublicKey = await indexedDbClient.getPublicKey();
9
+ if (!targetPublicKey) {
10
+ throw new WalletException(new Error('Target public key not found'));
11
+ }
12
+ return Array.from(sha256(new TextEncoder().encode(targetPublicKey)))
13
+ .map((b) => b.toString(16).padStart(2, '0'))
14
+ .join('');
15
+ }
16
+ catch (e) {
17
+ throw new WalletException(new Error(e.message), {
18
+ code: UnspecifiedErrorCode,
19
+ type: ErrorType.WalletError,
20
+ contextModule: 'turnkey-generate-oauth-nonce',
21
+ });
22
+ }
23
+ }
24
+ static async oauthLogin(args) {
25
+ const { client, indexedDbClient, expirationSeconds } = args;
26
+ const path = args.oauthLoginPath || TURNKEY_OAUTH_PATH;
27
+ try {
28
+ const targetPublicKey = await indexedDbClient.getPublicKey();
29
+ if (!targetPublicKey) {
30
+ throw new WalletException(new Error('Target public key not found'));
31
+ }
32
+ // client.$post is undefined, resorting to this for now
33
+ const response = await client.post(path, {
34
+ targetPublicKey,
35
+ oidcToken: args.oidcToken,
36
+ providerName: args.providerName,
37
+ expirationSeconds: (expirationSeconds || DEFAULT_TURNKEY_REFRESH_SECONDS)?.toString(),
38
+ });
39
+ return response.data;
40
+ }
41
+ catch (e) {
42
+ throw new WalletException(new Error(e.message), {
43
+ code: UnspecifiedErrorCode,
44
+ type: ErrorType.WalletError,
45
+ contextModule: 'turnkey-oauth-login',
46
+ });
47
+ }
48
+ }
49
+ }
@@ -0,0 +1,23 @@
1
+ import { type TurnkeyConfirmEmailOTPResponse, type TurnkeyOTPCredentialsResponse } from './../types.js';
2
+ import type { HttpRestClient } from '@injectivelabs/utils';
3
+ import type { TurnkeyIndexedDbClient } from '@turnkey/sdk-browser';
4
+ export declare class TurnkeyOtpWallet {
5
+ static initEmailOTP(args: {
6
+ email: string;
7
+ subOrgId?: string;
8
+ otpInitPath?: string;
9
+ client: HttpRestClient;
10
+ indexedDbClient: TurnkeyIndexedDbClient;
11
+ invalidateExistingSessions?: boolean;
12
+ expirationSeconds?: number;
13
+ }): Promise<TurnkeyOTPCredentialsResponse | undefined>;
14
+ static confirmEmailOTP(args: {
15
+ otpCode: string;
16
+ emailOTPId: string;
17
+ client: HttpRestClient;
18
+ targetPublicKey: string;
19
+ organizationId: string;
20
+ otpVerifyPath?: string;
21
+ expirationSeconds?: number;
22
+ }): Promise<TurnkeyConfirmEmailOTPResponse | undefined>;
23
+ }
@@ -0,0 +1,61 @@
1
+ import { ErrorType, WalletException, UnspecifiedErrorCode, } from '@injectivelabs/exceptions';
2
+ import { DEFAULT_TURNKEY_REFRESH_SECONDS, TURNKEY_OTP_INIT_PATH, TURNKEY_OTP_VERIFY_PATH, } from '../consts.js';
3
+ export class TurnkeyOtpWallet {
4
+ static async initEmailOTP(args) {
5
+ const { client, indexedDbClient, expirationSeconds } = args;
6
+ try {
7
+ await indexedDbClient.resetKeyPair();
8
+ let publicKey = await indexedDbClient.getPublicKey();
9
+ if (!publicKey) {
10
+ throw new WalletException(new Error('Public key not found'));
11
+ }
12
+ // client.$post is undefined, resorting to this for now
13
+ const response = await client.post(args.otpInitPath || TURNKEY_OTP_INIT_PATH, {
14
+ targetPublicKey: publicKey,
15
+ email: args.email,
16
+ suborgId: args.subOrgId,
17
+ invalidateExistingSessions: args.invalidateExistingSessions,
18
+ isUsingIndexedDB: true,
19
+ expirationSeconds: expirationSeconds || DEFAULT_TURNKEY_REFRESH_SECONDS,
20
+ });
21
+ return response?.data;
22
+ }
23
+ catch (e) {
24
+ throw new WalletException(new Error(e.message), {
25
+ code: UnspecifiedErrorCode,
26
+ type: ErrorType.WalletError,
27
+ contextModule: 'turnkey-init-email-otp',
28
+ });
29
+ }
30
+ }
31
+ static async confirmEmailOTP(args) {
32
+ const { client, expirationSeconds, targetPublicKey } = args;
33
+ try {
34
+ const organizationId = args.organizationId;
35
+ const emailOTPId = args.emailOTPId;
36
+ const otpVerifyPath = args.otpVerifyPath || TURNKEY_OTP_VERIFY_PATH;
37
+ if (!emailOTPId) {
38
+ throw new WalletException(new Error('Email OTP ID is required'));
39
+ }
40
+ if (!organizationId) {
41
+ throw new WalletException(new Error('Organization ID is required'));
42
+ }
43
+ const response = await client.post(otpVerifyPath, {
44
+ isUsingIndexedDB: true,
45
+ targetPublicKey,
46
+ otpId: emailOTPId,
47
+ otpCode: args.otpCode,
48
+ suborgID: organizationId,
49
+ expirationSeconds: (expirationSeconds || DEFAULT_TURNKEY_REFRESH_SECONDS)?.toString(),
50
+ });
51
+ return response?.data;
52
+ }
53
+ catch (e) {
54
+ throw new WalletException(new Error(e.message), {
55
+ code: UnspecifiedErrorCode,
56
+ type: ErrorType.WalletError,
57
+ contextModule: 'turnkey-confirm-email-otp',
58
+ });
59
+ }
60
+ }
61
+ }
@@ -0,0 +1,35 @@
1
+ import { createAccount } from '@turnkey/viem';
2
+ import { HttpRestClient } from '@injectivelabs/utils';
3
+ import { Turnkey } from '@turnkey/sdk-browser';
4
+ import { TurnkeyProvider } from '@injectivelabs/wallet-base';
5
+ import type { TurnkeyMetadata } from '@injectivelabs/wallet-base';
6
+ import type { TurnkeyIndexedDbClient } from '@turnkey/sdk-browser';
7
+ export declare class TurnkeyWallet {
8
+ private otpId?;
9
+ protected turnkey?: Turnkey;
10
+ userOrganizationId?: string;
11
+ protected client: HttpRestClient;
12
+ private metadata;
13
+ protected indexedDbClient?: TurnkeyIndexedDbClient;
14
+ private accountMap;
15
+ setMetadata(metadata: Partial<TurnkeyMetadata>): void;
16
+ constructor(metadata: TurnkeyMetadata);
17
+ static getTurnkeyInstance(metadata: TurnkeyMetadata): Promise<{
18
+ turnkey: Turnkey;
19
+ indexedDbClient: TurnkeyIndexedDbClient;
20
+ }>;
21
+ getTurnkey(): Promise<Turnkey>;
22
+ getIndexedDbClient(): Promise<TurnkeyIndexedDbClient>;
23
+ getSession(existingCredentialBundle?: string): Promise<{
24
+ session: import("@turnkey/sdk-browser").Session | undefined;
25
+ organizationId: string;
26
+ }>;
27
+ getAccounts(): Promise<string[]>;
28
+ getOrCreateAndGetAccount(address: string): Promise<ReturnType<typeof createAccount>>;
29
+ initOTP(email: string): Promise<import("../types.js").TurnkeyOTPCredentialsResponse>;
30
+ confirmOTP(otpCode: string): Promise<import("../types.js").TurnkeyConfirmEmailOTPResponse>;
31
+ initOAuth(provider: TurnkeyProvider): Promise<string>;
32
+ confirmOAuth(provider: TurnkeyProvider, oidcToken: string): Promise<string>;
33
+ refreshSession(): Promise<string>;
34
+ private initClient;
35
+ }