@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,255 @@
1
+ import { createAccount } from '@turnkey/viem';
2
+ import { HttpRestClient } from '@injectivelabs/utils';
3
+ import { getInjectiveAddress } from '@injectivelabs/sdk-ts';
4
+ import { Turnkey, SessionType } from '@turnkey/sdk-browser';
5
+ import { WalletAction, TurnkeyProvider } from '@injectivelabs/wallet-base';
6
+ import { ErrorType, WalletException, GeneralException, UnspecifiedErrorCode, TurnkeyWalletSessionException, } from '@injectivelabs/exceptions';
7
+ import { TurnkeyOtpWallet } from './otp.js';
8
+ import { TurnkeyErrorCodes } from '../types.js';
9
+ import { TurnkeyOauthWallet } from './oauth.js';
10
+ import { generateGoogleUrl } from '../../utils.js';
11
+ import { TURNKEY_OAUTH_PATH, TURNKEY_OTP_INIT_PATH, TURNKEY_OTP_VERIFY_PATH, } from '../consts.js';
12
+ export class TurnkeyWallet {
13
+ otpId;
14
+ turnkey;
15
+ userOrganizationId;
16
+ client;
17
+ metadata;
18
+ indexedDbClient;
19
+ accountMap = {};
20
+ setMetadata(metadata) {
21
+ this.metadata = { ...this.metadata, ...metadata };
22
+ }
23
+ constructor(metadata) {
24
+ this.metadata = metadata;
25
+ this.client = new HttpRestClient(metadata.apiServerEndpoint);
26
+ }
27
+ static async getTurnkeyInstance(metadata) {
28
+ const { turnkey, indexedDbClient } = await createTurnkeyClient(metadata);
29
+ return {
30
+ turnkey,
31
+ indexedDbClient,
32
+ };
33
+ }
34
+ async getTurnkey() {
35
+ if (!this.indexedDbClient) {
36
+ await this.initClient();
37
+ }
38
+ if (!this.turnkey) {
39
+ this.turnkey = new Turnkey(this.metadata);
40
+ }
41
+ return this.turnkey;
42
+ }
43
+ async getIndexedDbClient() {
44
+ if (!this.indexedDbClient) {
45
+ await this.initClient();
46
+ }
47
+ if (!this.indexedDbClient) {
48
+ throw new WalletException(new Error('Indexed DB client not initialized'));
49
+ }
50
+ return this.indexedDbClient;
51
+ }
52
+ async getSession(existingCredentialBundle) {
53
+ try {
54
+ const { metadata } = this;
55
+ const indexedDbClient = await this.getIndexedDbClient();
56
+ const turnkey = await this.getTurnkey();
57
+ const session = await turnkey.getSession();
58
+ const organizationId = session?.organizationId || metadata.defaultOrganizationId;
59
+ const credentialBundle = existingCredentialBundle || session?.token;
60
+ if (!credentialBundle) {
61
+ return {
62
+ session: undefined,
63
+ organizationId,
64
+ };
65
+ }
66
+ const user = await indexedDbClient.getWhoami();
67
+ const actualOrganizationId = user?.organizationId || session?.organizationId || organizationId;
68
+ if (!user) {
69
+ return {
70
+ session: undefined,
71
+ organizationId: actualOrganizationId,
72
+ };
73
+ }
74
+ this.userOrganizationId = actualOrganizationId;
75
+ return {
76
+ session,
77
+ organizationId: actualOrganizationId,
78
+ };
79
+ }
80
+ catch {
81
+ throw new TurnkeyWalletSessionException(new Error('Session expired. Please login again.'));
82
+ }
83
+ }
84
+ async getAccounts() {
85
+ const indexedDbClient = await this.getIndexedDbClient();
86
+ if (!this.userOrganizationId) {
87
+ return [];
88
+ }
89
+ try {
90
+ const response = await indexedDbClient.getWallets({
91
+ organizationId: this.userOrganizationId,
92
+ });
93
+ const accounts = await Promise.allSettled(response.wallets.map((wallet) => indexedDbClient.getWalletAccounts({
94
+ walletId: wallet.walletId,
95
+ organizationId: this.userOrganizationId,
96
+ })));
97
+ const filteredAccounts = accounts
98
+ .filter((account) => account.status === 'fulfilled')
99
+ .flatMap((result) => result.value?.accounts)
100
+ .filter((wa) => !!wa &&
101
+ wa.addressFormat === 'ADDRESS_FORMAT_ETHEREUM' &&
102
+ !!wa.address);
103
+ return filteredAccounts.map((account) => getInjectiveAddress(account.address));
104
+ }
105
+ catch (e) {
106
+ if (e.code === TurnkeyErrorCodes.UserLoggedOut) {
107
+ throw new WalletException(new Error('User is not logged in'), {
108
+ code: UnspecifiedErrorCode,
109
+ type: ErrorType.WalletError,
110
+ contextModule: WalletAction.GetAccounts,
111
+ contextCode: TurnkeyErrorCodes.UserLoggedOut,
112
+ });
113
+ }
114
+ throw new WalletException(new Error(e.message), {
115
+ code: UnspecifiedErrorCode,
116
+ type: ErrorType.WalletError,
117
+ contextModule: 'turnkey-wallet-get-accounts',
118
+ });
119
+ }
120
+ }
121
+ async getOrCreateAndGetAccount(address) {
122
+ const { accountMap } = this;
123
+ const indexedDbClient = await this.getIndexedDbClient();
124
+ const organizationId = this.userOrganizationId;
125
+ if (accountMap[address] || accountMap[address.toLowerCase()]) {
126
+ return accountMap[address] || accountMap[address.toLowerCase()];
127
+ }
128
+ if (!organizationId) {
129
+ throw new WalletException(new Error('Organization ID is required'));
130
+ }
131
+ indexedDbClient.config.organizationId = organizationId;
132
+ if (!address) {
133
+ throw new WalletException(new Error('Account address not found'));
134
+ }
135
+ const turnkeyAccount = await createAccount({
136
+ organizationId,
137
+ signWith: address,
138
+ client: indexedDbClient,
139
+ });
140
+ this.accountMap[address] = turnkeyAccount;
141
+ return turnkeyAccount;
142
+ }
143
+ async initOTP(email) {
144
+ const indexedDbClient = await this.getIndexedDbClient();
145
+ const result = await TurnkeyOtpWallet.initEmailOTP({
146
+ client: this.client,
147
+ indexedDbClient,
148
+ email,
149
+ otpInitPath: this.metadata.otpInitPath || TURNKEY_OTP_INIT_PATH,
150
+ });
151
+ if (!result || !result.otpId) {
152
+ throw new WalletException(new Error('Failed to initialize OTP'));
153
+ }
154
+ if (result?.organizationId) {
155
+ this.userOrganizationId = result.organizationId;
156
+ }
157
+ if (result?.otpId) {
158
+ this.otpId = result.otpId;
159
+ }
160
+ return result;
161
+ }
162
+ async confirmOTP(otpCode) {
163
+ const indexedDbClient = await this.getIndexedDbClient();
164
+ const targetPublicKey = await indexedDbClient.getPublicKey();
165
+ if (!this.otpId) {
166
+ throw new WalletException(new Error('OTP ID is required'));
167
+ }
168
+ if (!targetPublicKey) {
169
+ throw new WalletException(new Error('Target public key not found'));
170
+ }
171
+ if (!this.userOrganizationId) {
172
+ throw new WalletException(new Error('Organization ID is required'));
173
+ }
174
+ const result = await TurnkeyOtpWallet.confirmEmailOTP({
175
+ otpCode,
176
+ client: this.client,
177
+ emailOTPId: this.otpId,
178
+ organizationId: this.userOrganizationId,
179
+ targetPublicKey,
180
+ otpVerifyPath: this.metadata.otpVerifyPath || TURNKEY_OTP_VERIFY_PATH,
181
+ });
182
+ if (!result || !result.session) {
183
+ throw new WalletException(new Error('Failed to confirm OTP'));
184
+ }
185
+ await indexedDbClient.loginWithSession(result.session);
186
+ this.userOrganizationId = result.organizationId;
187
+ return result;
188
+ }
189
+ async initOAuth(provider) {
190
+ if (provider === TurnkeyProvider.Apple) {
191
+ throw new WalletException(new Error('Apple sign in option is currently not supported'));
192
+ }
193
+ const indexedDbClient = await this.getIndexedDbClient();
194
+ const nonce = await TurnkeyOauthWallet.generateOAuthNonce(indexedDbClient);
195
+ if (!this.metadata?.googleClientId || !this.metadata?.googleRedirectUri) {
196
+ throw new WalletException(new Error('googleClientId and googleRedirectUri are required'));
197
+ }
198
+ return generateGoogleUrl({
199
+ nonce,
200
+ clientId: this.metadata.googleClientId,
201
+ redirectUri: this.metadata.googleRedirectUri,
202
+ });
203
+ }
204
+ async confirmOAuth(provider, oidcToken) {
205
+ if (provider === TurnkeyProvider.Apple) {
206
+ throw new WalletException(new Error('Apple sign in option is currently not supported'));
207
+ }
208
+ const indexedDbClient = await this.getIndexedDbClient();
209
+ const oauthResult = await TurnkeyOauthWallet.oauthLogin({
210
+ oidcToken,
211
+ indexedDbClient,
212
+ client: this.client,
213
+ providerName: provider.toString(),
214
+ oauthLoginPath: this.metadata.oauthLoginPath || TURNKEY_OAUTH_PATH,
215
+ });
216
+ if (!oauthResult || !oauthResult.credentialBundle) {
217
+ throw new WalletException(new Error('Unexpected OAuth result'));
218
+ }
219
+ await indexedDbClient.loginWithSession(oauthResult.credentialBundle);
220
+ this.userOrganizationId = oauthResult.organizationId;
221
+ return oauthResult.credentialBundle;
222
+ }
223
+ async refreshSession() {
224
+ const session = await this.getSession();
225
+ const indexedDbClient = await this.getIndexedDbClient();
226
+ if (session.session?.token) {
227
+ await indexedDbClient.refreshSession({
228
+ sessionType: SessionType.READ_WRITE,
229
+ expirationSeconds: this.metadata.expirationSeconds,
230
+ });
231
+ this.userOrganizationId = session.organizationId;
232
+ return session.session.token;
233
+ }
234
+ throw new TurnkeyWalletSessionException(new Error('Session expired. Please login again.'));
235
+ }
236
+ async initClient() {
237
+ const { metadata } = this;
238
+ const { turnkey, indexedDbClient } = await createTurnkeyClient(metadata);
239
+ this.turnkey = turnkey;
240
+ this.indexedDbClient = indexedDbClient;
241
+ return { turnkey, indexedDbClient };
242
+ }
243
+ }
244
+ async function createTurnkeyClient(metadata) {
245
+ const turnkey = new Turnkey(metadata);
246
+ const indexedDbClient = await turnkey.indexedDbClient();
247
+ await indexedDbClient.init();
248
+ if (!turnkey) {
249
+ throw new GeneralException(new Error('Turnkey is not initialized'));
250
+ }
251
+ return {
252
+ turnkey,
253
+ indexedDbClient,
254
+ };
255
+ }
@@ -0,0 +1,28 @@
1
+ export declare const TurnkeyErrorCodes: {
2
+ readonly UserLoggedOut: 7;
3
+ };
4
+ export type TurnkeyErrorCodes = (typeof TurnkeyErrorCodes)[keyof typeof TurnkeyErrorCodes];
5
+ export type TurnkeyOAuthArgs = {
6
+ provider: 'google';
7
+ oidcToken: string;
8
+ oauthLoginEndpoint: string;
9
+ };
10
+ export type TurnkeyEmailArgs = {
11
+ provider: 'email';
12
+ email: string;
13
+ initEmailOTPEndpoint: string;
14
+ };
15
+ export type TurnkeyEnableArgs = TurnkeyOAuthArgs | TurnkeyEmailArgs;
16
+ export type TurnkeyOTPCredentialsResponse = {
17
+ otpId: string;
18
+ organizationId: string;
19
+ };
20
+ export type TurnkeyConfirmEmailOTPResponse = {
21
+ session: string;
22
+ organizationId: string;
23
+ };
24
+ export type TurnkeyOauthLoginResponse = {
25
+ organizationId: string;
26
+ credentialBundle: string;
27
+ message: string;
28
+ };
@@ -0,0 +1,3 @@
1
+ export const TurnkeyErrorCodes = {
2
+ UserLoggedOut: 7,
3
+ };
@@ -0,0 +1,7 @@
1
+ export declare function generateGoogleUrl({ nonce, clientId, redirectUri, scope, prompt, }: {
2
+ nonce: string;
3
+ clientId: string;
4
+ redirectUri: string;
5
+ scope?: string;
6
+ prompt?: string;
7
+ }): string;
@@ -0,0 +1,7 @@
1
+ export function generateGoogleUrl({ nonce, clientId, redirectUri, scope = 'openid profile email', prompt = 'consent', }) {
2
+ if (!clientId) {
3
+ throw new Error('Google client ID not found');
4
+ }
5
+ const responseType = 'id_token';
6
+ return `https://accounts.google.com/o/oauth2/v2/auth?prompt=${prompt}&client_id=${clientId}&redirect_uri=${redirectUri}&response_type=${responseType}&scope=${scope}&nonce=${nonce}`;
7
+ }
package/package.json CHANGED
@@ -1,71 +1,81 @@
1
1
  {
2
2
  "name": "@injectivelabs/wallet-turnkey",
3
- "version": "1.16.38-alpha.7",
4
3
  "description": "Turnkey wallet strategy for use with @injectivelabs/wallet-core.",
5
- "license": "Apache-2.0",
4
+ "version": "1.16.38",
5
+ "sideEffects": false,
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "type": "module",
6
10
  "author": {
7
11
  "name": "InjectiveLabs",
8
12
  "email": "admin@injectivelabs.org"
9
13
  },
10
- "type": "module",
11
- "sideEffects": false,
14
+ "license": "Apache-2.0",
15
+ "types": "dist/cjs/index.d.ts",
16
+ "main": "dist/cjs/index.js",
17
+ "module": "dist/esm/index.js",
18
+ "files": [
19
+ "dist"
20
+ ],
21
+ "_moduleAliases": {
22
+ "~wallet-turnkey": "dist"
23
+ },
12
24
  "exports": {
13
25
  ".": {
14
26
  "react-native": {
15
27
  "import": "./dist/esm/index.js",
16
- "require": "./dist/cjs/index.cjs",
17
- "types": "./dist/cjs/index.d.cts",
18
- "default": "./dist/cjs/index.cjs"
28
+ "require": "./dist/cjs/index.js",
29
+ "types": "./dist/cjs/index.d.ts",
30
+ "default": "./dist/cjs/index.js"
19
31
  },
20
32
  "require": {
21
- "types": "./dist/cjs/index.d.cts",
22
- "default": "./dist/cjs/index.cjs"
33
+ "types": "./dist/cjs/index.d.ts",
34
+ "default": "./dist/cjs/index.js"
23
35
  },
24
36
  "import": {
25
37
  "types": "./dist/esm/index.d.ts",
26
38
  "default": "./dist/esm/index.js"
27
39
  },
28
40
  "default": {
29
- "types": "./dist/cjs/index.d.cts",
30
- "default": "./dist/cjs/index.cjs"
41
+ "types": "./dist/cjs/index.d.ts",
42
+ "default": "./dist/cjs/index.js"
31
43
  }
32
44
  }
33
45
  },
34
- "main": "dist/cjs/index.cjs",
35
- "module": "dist/esm/index.js",
36
- "types": "dist/cjs/index.d.cts",
37
- "files": [
38
- "dist"
39
- ],
40
- "dependencies": {
41
- "@turnkey/sdk-browser": "^5.13.4",
42
- "@turnkey/viem": "^0.14.16",
43
- "viem": "^2.41.2",
44
- "@injectivelabs/exceptions": "1.16.38-alpha.4",
45
- "@injectivelabs/sdk-ts": "1.16.38-alpha.7",
46
- "@injectivelabs/ts-types": "1.16.38-alpha.3",
47
- "@injectivelabs/utils": "1.16.38-alpha.5",
48
- "@injectivelabs/wallet-base": "1.16.38-alpha.7"
49
- },
50
- "publishConfig": {
51
- "access": "public"
52
- },
53
- "_moduleAliases": {
54
- "~wallet-turnkey": "dist"
55
- },
56
46
  "scripts": {
57
- "build": "pnpm type-check && tsdown",
58
- "build:fast": "tsdown",
59
- "build:watch": "tsdown --watch",
60
- "clean": "shx rm -rf dist coverage *.log junit.xml && shx mkdir -p dist",
61
- "type-check": "tsc --noEmit",
62
- "test": "vitest",
63
- "test:watch": "vitest --watch",
64
- "test:ci": "vitest run --coverage --reporter=verbose",
65
- "coverage": "vitest run --coverage",
47
+ "build": "pnpm build:esm && pnpm build:cjs && pnpm build:post",
48
+ "build:cjs": "tsc --build --force tsconfig.build.json",
49
+ "build:esm": "tsc --build --force tsconfig.build.esm.json",
50
+ "build:watch": "tsc --build -w tsconfig.build.json && tsc -w --build tsconfig.build.esm.json && pnpm build:post",
51
+ "build:post": "shx cp ../../../etc/stub/package.json.stub dist/cjs/package.json && shx cp ../../../etc/stub/package.esm.json.stub dist/esm/package.json",
52
+ "clean": "tsc --build tsconfig.build.json --clean && tsc --build tsconfig.build.esm.json --clean && shx rm -rf coverage *.log junit.xml dist && jest --clearCache && shx mkdir -p dist",
53
+ "test": "jest",
54
+ "test:watch": "jest --watch",
55
+ "test:ci": "jest --coverage --ci --reporters='jest-junit'",
56
+ "coverage": "jest --coverage",
66
57
  "coverage:show": "live-server coverage",
67
58
  "dev": "ts-node -r tsconfig-paths/register src/index.ts",
68
- "start": "node dist/index.js",
69
- "lint": "eslint . --ext .ts,.js"
70
- }
71
- }
59
+ "start": "node dist/index.js"
60
+ },
61
+ "dependencies": {
62
+ "@injectivelabs/exceptions": "1.16.38",
63
+ "@injectivelabs/sdk-ts": "1.16.38",
64
+ "@injectivelabs/ts-types": "1.16.38",
65
+ "@injectivelabs/utils": "1.16.38",
66
+ "@injectivelabs/wallet-base": "1.16.38",
67
+ "@turnkey/sdk-browser": "5.2.3",
68
+ "@turnkey/viem": "^0.9.10",
69
+ "viem": "^2.40.3"
70
+ },
71
+ "devDependencies": {
72
+ "jest": "^29.0.0",
73
+ "live-server": "^1.2.1",
74
+ "shx": "^0.3.4",
75
+ "ts-jest": "^29.0.0",
76
+ "ts-node": "^10.9.1",
77
+ "tsconfig-paths": "^4.2.0",
78
+ "typescript": "^5.0.0"
79
+ },
80
+ "gitHead": "c67633f9ba4c5efb2c969c3df815d54995459966"
81
+ }