@injectivelabs/wallet-turnkey 1.19.15 → 1.19.16
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.
- package/dist/cjs/index.cjs +141 -7
- package/dist/cjs/index.d.cts +27 -4
- package/dist/esm/index.d.ts +27 -4
- package/dist/esm/index.js +142 -8
- package/package.json +8 -8
package/dist/cjs/index.cjs
CHANGED
|
@@ -44,6 +44,29 @@ var TurnkeyOtpWallet = class {
|
|
|
44
44
|
});
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
|
+
static async initSmsOTP(args) {
|
|
48
|
+
const { client, indexedDbClient, expirationSeconds } = args;
|
|
49
|
+
try {
|
|
50
|
+
await indexedDbClient.resetKeyPair();
|
|
51
|
+
const publicKey = await indexedDbClient.getPublicKey();
|
|
52
|
+
if (!publicKey) throw new __injectivelabs_exceptions.WalletException(/* @__PURE__ */ new Error("Public key not found"));
|
|
53
|
+
const response = await client.post(args.otpInitPath || TURNKEY_OTP_INIT_PATH, {
|
|
54
|
+
phone: args.phone,
|
|
55
|
+
isUsingIndexedDB: true,
|
|
56
|
+
suborgId: args.subOrgId,
|
|
57
|
+
targetPublicKey: publicKey,
|
|
58
|
+
invalidateExistingSessions: args.invalidateExistingSessions,
|
|
59
|
+
expirationSeconds: expirationSeconds || DEFAULT_TURNKEY_REFRESH_SECONDS
|
|
60
|
+
});
|
|
61
|
+
return response === null || response === void 0 ? void 0 : response.data;
|
|
62
|
+
} catch (e) {
|
|
63
|
+
throw new __injectivelabs_exceptions.WalletException(new Error(e.message), {
|
|
64
|
+
code: __injectivelabs_exceptions.UnspecifiedErrorCode,
|
|
65
|
+
type: __injectivelabs_exceptions.ErrorType.WalletError,
|
|
66
|
+
contextModule: "turnkey-init-sms-otp"
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
47
70
|
static async confirmEmailOTP(args) {
|
|
48
71
|
const { client, expirationSeconds, targetPublicKey } = args;
|
|
49
72
|
try {
|
|
@@ -114,6 +137,35 @@ var TurnkeyOauthWallet = class {
|
|
|
114
137
|
|
|
115
138
|
//#endregion
|
|
116
139
|
//#region src/utils.ts
|
|
140
|
+
function generateBase64Url(byteLength) {
|
|
141
|
+
const bytes = new Uint8Array(byteLength);
|
|
142
|
+
crypto.getRandomValues(bytes);
|
|
143
|
+
return btoa(String.fromCharCode(...bytes)).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
144
|
+
}
|
|
145
|
+
function sha256ToBase64Url(input) {
|
|
146
|
+
const hash = (0, __injectivelabs_sdk_ts_utils.sha256)(new TextEncoder().encode(input));
|
|
147
|
+
return btoa(String.fromCharCode(...hash)).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
148
|
+
}
|
|
149
|
+
function generateTwitterPkce() {
|
|
150
|
+
const state = generateBase64Url(32);
|
|
151
|
+
const codeVerifier = generateBase64Url(32);
|
|
152
|
+
return {
|
|
153
|
+
state,
|
|
154
|
+
codeVerifier,
|
|
155
|
+
codeChallenge: sha256ToBase64Url(codeVerifier)
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
function generateTwitterUrl({ state, clientId, redirectUri, codeChallenge }) {
|
|
159
|
+
const url = new URL("https://twitter.com/i/oauth2/authorize");
|
|
160
|
+
url.searchParams.set("state", state);
|
|
161
|
+
url.searchParams.set("client_id", clientId);
|
|
162
|
+
url.searchParams.set("response_type", "code");
|
|
163
|
+
url.searchParams.set("redirect_uri", redirectUri);
|
|
164
|
+
url.searchParams.set("code_challenge", codeChallenge);
|
|
165
|
+
url.searchParams.set("code_challenge_method", "S256");
|
|
166
|
+
url.searchParams.set("scope", "tweet.read users.read users.email offline.access");
|
|
167
|
+
return url.toString();
|
|
168
|
+
}
|
|
117
169
|
function generateGoogleUrl({ nonce, clientId, redirectUri, scope = "openid profile email", prompt = "consent" }) {
|
|
118
170
|
if (!clientId) throw new Error("Google client ID not found");
|
|
119
171
|
return `https://accounts.google.com/o/oauth2/v2/auth?prompt=${prompt}&client_id=${clientId}&redirect_uri=${redirectUri}&response_type=id_token&scope=${scope}&nonce=${nonce}`;
|
|
@@ -173,9 +225,9 @@ var TurnkeyWallet = class {
|
|
|
173
225
|
constructor(metadata) {
|
|
174
226
|
_defineProperty(this, "otpId", void 0);
|
|
175
227
|
_defineProperty(this, "turnkey", void 0);
|
|
176
|
-
_defineProperty(this, "userOrganizationId", void 0);
|
|
177
228
|
_defineProperty(this, "client", void 0);
|
|
178
229
|
_defineProperty(this, "metadata", void 0);
|
|
230
|
+
_defineProperty(this, "userOrganizationId", void 0);
|
|
179
231
|
_defineProperty(this, "indexedDbClient", void 0);
|
|
180
232
|
_defineProperty(this, "accountMap", {});
|
|
181
233
|
this.metadata = metadata;
|
|
@@ -268,9 +320,9 @@ var TurnkeyWallet = class {
|
|
|
268
320
|
async initOTP(email) {
|
|
269
321
|
const indexedDbClient = await this.getIndexedDbClient();
|
|
270
322
|
const result = await TurnkeyOtpWallet.initEmailOTP({
|
|
271
|
-
client: this.client,
|
|
272
|
-
indexedDbClient,
|
|
273
323
|
email,
|
|
324
|
+
indexedDbClient,
|
|
325
|
+
client: this.client,
|
|
274
326
|
otpInitPath: this.metadata.otpInitPath || TURNKEY_OTP_INIT_PATH
|
|
275
327
|
});
|
|
276
328
|
if (!result || !result.otpId) throw new __injectivelabs_exceptions.WalletException(/* @__PURE__ */ new Error("Failed to initialize OTP"));
|
|
@@ -278,6 +330,19 @@ var TurnkeyWallet = class {
|
|
|
278
330
|
if (result === null || result === void 0 ? void 0 : result.otpId) this.otpId = result.otpId;
|
|
279
331
|
return result;
|
|
280
332
|
}
|
|
333
|
+
async initSms(phone) {
|
|
334
|
+
const indexedDbClient = await this.getIndexedDbClient();
|
|
335
|
+
const result = await TurnkeyOtpWallet.initSmsOTP({
|
|
336
|
+
phone,
|
|
337
|
+
indexedDbClient,
|
|
338
|
+
client: this.client,
|
|
339
|
+
otpInitPath: this.metadata.otpInitPath || TURNKEY_OTP_INIT_PATH
|
|
340
|
+
});
|
|
341
|
+
if (!result || !result.otpId) throw new __injectivelabs_exceptions.WalletException(/* @__PURE__ */ new Error("Failed to initialize SMS OTP"));
|
|
342
|
+
if (result === null || result === void 0 ? void 0 : result.organizationId) this.userOrganizationId = result.organizationId;
|
|
343
|
+
if (result === null || result === void 0 ? void 0 : result.otpId) this.otpId = result.otpId;
|
|
344
|
+
return result;
|
|
345
|
+
}
|
|
281
346
|
async confirmOTP(otpCode) {
|
|
282
347
|
const indexedDbClient = await this.getIndexedDbClient();
|
|
283
348
|
const targetPublicKey = await indexedDbClient.getPublicKey();
|
|
@@ -286,10 +351,10 @@ var TurnkeyWallet = class {
|
|
|
286
351
|
if (!this.userOrganizationId) throw new __injectivelabs_exceptions.WalletException(/* @__PURE__ */ new Error("Organization ID is required"));
|
|
287
352
|
const result = await TurnkeyOtpWallet.confirmEmailOTP({
|
|
288
353
|
otpCode,
|
|
354
|
+
targetPublicKey,
|
|
289
355
|
client: this.client,
|
|
290
356
|
emailOTPId: this.otpId,
|
|
291
357
|
organizationId: this.userOrganizationId,
|
|
292
|
-
targetPublicKey,
|
|
293
358
|
otpVerifyPath: this.metadata.otpVerifyPath || TURNKEY_OTP_VERIFY_PATH
|
|
294
359
|
});
|
|
295
360
|
if (!result || !result.session) throw new __injectivelabs_exceptions.WalletException(/* @__PURE__ */ new Error("Failed to confirm OTP"));
|
|
@@ -309,6 +374,30 @@ var TurnkeyWallet = class {
|
|
|
309
374
|
redirectUri: this.metadata.googleRedirectUri
|
|
310
375
|
});
|
|
311
376
|
}
|
|
377
|
+
async initOAuth2(provider) {
|
|
378
|
+
if (provider === __injectivelabs_wallet_base.TurnkeyProvider.Twitter) {
|
|
379
|
+
if (!this.metadata.twitterClientId || !this.metadata.twitterRedirectUri) throw new __injectivelabs_exceptions.WalletException(/* @__PURE__ */ new Error("twitterClientId and twitterRedirectUri are required"));
|
|
380
|
+
const indexedDbClient = await this.getIndexedDbClient();
|
|
381
|
+
await indexedDbClient.resetKeyPair();
|
|
382
|
+
const targetPublicKey = await indexedDbClient.getPublicKey();
|
|
383
|
+
if (!targetPublicKey) throw new __injectivelabs_exceptions.WalletException(/* @__PURE__ */ new Error("Target public key is missing. Please ensure your wallet is properly initialized."));
|
|
384
|
+
const { state, codeVerifier, codeChallenge } = generateTwitterPkce();
|
|
385
|
+
return {
|
|
386
|
+
pkce: {
|
|
387
|
+
state,
|
|
388
|
+
codeVerifier,
|
|
389
|
+
targetPublicKey
|
|
390
|
+
},
|
|
391
|
+
url: generateTwitterUrl({
|
|
392
|
+
state,
|
|
393
|
+
codeChallenge,
|
|
394
|
+
clientId: this.metadata.twitterClientId,
|
|
395
|
+
redirectUri: this.metadata.twitterRedirectUri
|
|
396
|
+
})
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
throw new __injectivelabs_exceptions.WalletException(/* @__PURE__ */ new Error(`${provider} is not supported for OAuth2`));
|
|
400
|
+
}
|
|
312
401
|
async confirmOAuth(provider, oidcToken) {
|
|
313
402
|
if (provider === __injectivelabs_wallet_base.TurnkeyProvider.Apple) throw new __injectivelabs_exceptions.WalletException(/* @__PURE__ */ new Error("Apple sign in option is currently not supported"));
|
|
314
403
|
const indexedDbClient = await this.getIndexedDbClient();
|
|
@@ -316,7 +405,7 @@ var TurnkeyWallet = class {
|
|
|
316
405
|
oidcToken,
|
|
317
406
|
indexedDbClient,
|
|
318
407
|
client: this.client,
|
|
319
|
-
providerName: provider
|
|
408
|
+
providerName: provider,
|
|
320
409
|
oauthLoginPath: this.metadata.oauthLoginPath || TURNKEY_OAUTH_PATH
|
|
321
410
|
});
|
|
322
411
|
if (!oauthResult || !oauthResult.credentialBundle) throw new __injectivelabs_exceptions.WalletException(/* @__PURE__ */ new Error("Unexpected OAuth result"));
|
|
@@ -324,6 +413,25 @@ var TurnkeyWallet = class {
|
|
|
324
413
|
this.userOrganizationId = oauthResult.organizationId;
|
|
325
414
|
return oauthResult.credentialBundle;
|
|
326
415
|
}
|
|
416
|
+
async confirmOAuth2({ authCode, codeVerifier, providerName, targetPublicKey }) {
|
|
417
|
+
var _response$data, _response$data2;
|
|
418
|
+
const indexedDbClient = await this.getIndexedDbClient();
|
|
419
|
+
const path = this.metadata.oauth2ExchangePath || "turnkey/oauth2";
|
|
420
|
+
const response = await this.client.post(path, {
|
|
421
|
+
authCode,
|
|
422
|
+
codeVerifier,
|
|
423
|
+
targetPublicKey,
|
|
424
|
+
providerName
|
|
425
|
+
});
|
|
426
|
+
if (!(response === null || response === void 0 || (_response$data = response.data) === null || _response$data === void 0 ? void 0 : _response$data.credentialBundle) || !(response === null || response === void 0 || (_response$data2 = response.data) === null || _response$data2 === void 0 ? void 0 : _response$data2.organizationId)) throw new __injectivelabs_exceptions.WalletException(/* @__PURE__ */ new Error(`${providerName} OAuth2 exchange failed`));
|
|
427
|
+
const { credentialBundle, organizationId, email } = response.data;
|
|
428
|
+
await indexedDbClient.loginWithSession(credentialBundle);
|
|
429
|
+
this.userOrganizationId = organizationId;
|
|
430
|
+
return {
|
|
431
|
+
session: credentialBundle,
|
|
432
|
+
email
|
|
433
|
+
};
|
|
434
|
+
}
|
|
327
435
|
async refreshSession() {
|
|
328
436
|
var _session$session;
|
|
329
437
|
const session = await this.getSession();
|
|
@@ -368,8 +476,10 @@ const parseChainId = (chainId) => {
|
|
|
368
476
|
return parseInt(chainId, 10);
|
|
369
477
|
};
|
|
370
478
|
const getEip1193ProviderForTurnkey = async (account, chainId, params = {}) => {
|
|
479
|
+
var _account$sign;
|
|
371
480
|
return new CustomEip1193Provider({
|
|
372
481
|
chainId: parseChainId(chainId),
|
|
482
|
+
sign: (_account$sign = account.sign) === null || _account$sign === void 0 ? void 0 : _account$sign.bind(account),
|
|
373
483
|
signTypedData: account.signTypedData.bind(account),
|
|
374
484
|
signMessage: account.signMessage.bind(account),
|
|
375
485
|
signTransaction: account.signTransaction.bind(account),
|
|
@@ -383,6 +493,7 @@ var CustomEip1193Provider = class {
|
|
|
383
493
|
constructor(args) {
|
|
384
494
|
var _args$chainId;
|
|
385
495
|
_defineProperty(this, "chainId", void 0);
|
|
496
|
+
_defineProperty(this, "sign", void 0);
|
|
386
497
|
_defineProperty(this, "signTypedData", void 0);
|
|
387
498
|
_defineProperty(this, "signMessage", void 0);
|
|
388
499
|
_defineProperty(this, "signTransaction", void 0);
|
|
@@ -391,6 +502,7 @@ var CustomEip1193Provider = class {
|
|
|
391
502
|
_defineProperty(this, "account", void 0);
|
|
392
503
|
_defineProperty(this, "address", void 0);
|
|
393
504
|
this.chainId = (_args$chainId = args.chainId) !== null && _args$chainId !== void 0 ? _args$chainId : 1;
|
|
505
|
+
this.sign = args.sign;
|
|
394
506
|
this.signTypedData = args.signTypedData;
|
|
395
507
|
this.signMessage = args.signMessage;
|
|
396
508
|
this.account = args.account;
|
|
@@ -426,7 +538,20 @@ var CustomEip1193Provider = class {
|
|
|
426
538
|
if (args.method === "eth_requestAccounts") return this.requestAccounts();
|
|
427
539
|
if (args.method === "eth_signTypedData") {
|
|
428
540
|
if (!args.params) throw new Error("params is required");
|
|
429
|
-
|
|
541
|
+
const typedData = args.params[0];
|
|
542
|
+
if (this.sign) {
|
|
543
|
+
const typedDataHash = (0, viem.hashTypedData)({
|
|
544
|
+
domain: {
|
|
545
|
+
...typedData.domain,
|
|
546
|
+
chainId: typedData.domain.chainId != null ? parseChainId(typedData.domain.chainId) : void 0
|
|
547
|
+
},
|
|
548
|
+
types: typedData.types,
|
|
549
|
+
primaryType: typedData.primaryType,
|
|
550
|
+
message: typedData.message
|
|
551
|
+
});
|
|
552
|
+
return this.sign({ hash: typedDataHash });
|
|
553
|
+
}
|
|
554
|
+
return this.signTypedData(typedData);
|
|
430
555
|
}
|
|
431
556
|
if (args.method === "eth_signMessage") {
|
|
432
557
|
if (!args.params) throw new Error("params is required");
|
|
@@ -630,7 +755,16 @@ var TurnkeyWalletStrategy = class extends __injectivelabs_wallet_base.BaseConcre
|
|
|
630
755
|
});
|
|
631
756
|
}
|
|
632
757
|
if (((_parsedData$domain = parsedData.domain) === null || _parsedData$domain === void 0 ? void 0 : _parsedData$domain.chainId) && typeof parsedData.domain.chainId === "string") parsedData.domain.chainId = Number(parsedData.domain.chainId);
|
|
633
|
-
|
|
758
|
+
if (account.sign) {
|
|
759
|
+
const typedDataHash = (0, viem.hashTypedData)({
|
|
760
|
+
types: parsedData.types,
|
|
761
|
+
domain: parsedData.domain,
|
|
762
|
+
message: parsedData.message,
|
|
763
|
+
primaryType: parsedData.primaryType
|
|
764
|
+
});
|
|
765
|
+
return account.sign({ hash: typedDataHash });
|
|
766
|
+
}
|
|
767
|
+
return account.signTypedData(parsedData);
|
|
634
768
|
}
|
|
635
769
|
async signCosmosTransaction(_transaction) {
|
|
636
770
|
throw new __injectivelabs_exceptions.WalletException(/* @__PURE__ */ new Error("This wallet does not support signing Cosmos transactions"), {
|
package/dist/cjs/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { HttpRestClient } from "@injectivelabs/utils";
|
|
2
|
-
import { BaseConcreteStrategy, ConcreteEvmWalletStrategyArgs, ConcreteWalletStrategy, Eip1193Provider, SendTransactionOptions, StdSignDoc, TurnkeyMetadata,
|
|
2
|
+
import { BaseConcreteStrategy, ConcreteEvmWalletStrategyArgs, ConcreteWalletStrategy, Eip1193Provider, SendTransactionOptions, StdSignDoc, TurnkeyMetadata, TurnkeyOAuthProvider, WalletDeviceType, WalletMetadata, WalletStrategyEvmOptions } from "@injectivelabs/wallet-base";
|
|
3
3
|
import { AccountAddress, EvmChainId } from "@injectivelabs/ts-types";
|
|
4
4
|
import * as _turnkey_sdk_browser0 from "@turnkey/sdk-browser";
|
|
5
5
|
import { Turnkey, TurnkeyIndexedDbClient } from "@turnkey/sdk-browser";
|
|
@@ -67,9 +67,9 @@ type TurnkeyConfirmEmailOTPResponse = {
|
|
|
67
67
|
declare class TurnkeyWallet {
|
|
68
68
|
private otpId?;
|
|
69
69
|
protected turnkey?: Turnkey;
|
|
70
|
-
userOrganizationId?: string;
|
|
71
70
|
protected client: HttpRestClient;
|
|
72
71
|
private metadata;
|
|
72
|
+
userOrganizationId?: string;
|
|
73
73
|
protected indexedDbClient?: TurnkeyIndexedDbClient;
|
|
74
74
|
private accountMap;
|
|
75
75
|
setMetadata(metadata: Partial<TurnkeyMetadata>): void;
|
|
@@ -87,9 +87,32 @@ declare class TurnkeyWallet {
|
|
|
87
87
|
getAccounts(): Promise<string[]>;
|
|
88
88
|
getOrCreateAndGetAccount(address: string): Promise<ReturnType<typeof createAccount>>;
|
|
89
89
|
initOTP(email: string): Promise<TurnkeyOTPCredentialsResponse>;
|
|
90
|
+
initSms(phone: string): Promise<TurnkeyOTPCredentialsResponse>;
|
|
90
91
|
confirmOTP(otpCode: string): Promise<TurnkeyConfirmEmailOTPResponse>;
|
|
91
|
-
initOAuth(provider:
|
|
92
|
-
|
|
92
|
+
initOAuth(provider: TurnkeyOAuthProvider): Promise<string>;
|
|
93
|
+
initOAuth2(provider: TurnkeyOAuthProvider): Promise<{
|
|
94
|
+
pkce: {
|
|
95
|
+
state: string;
|
|
96
|
+
codeVerifier: string;
|
|
97
|
+
targetPublicKey: string;
|
|
98
|
+
};
|
|
99
|
+
url: string;
|
|
100
|
+
}>;
|
|
101
|
+
confirmOAuth(provider: TurnkeyOAuthProvider, oidcToken: string): Promise<string>;
|
|
102
|
+
confirmOAuth2({
|
|
103
|
+
authCode,
|
|
104
|
+
codeVerifier,
|
|
105
|
+
providerName,
|
|
106
|
+
targetPublicKey
|
|
107
|
+
}: {
|
|
108
|
+
authCode: string;
|
|
109
|
+
codeVerifier: string;
|
|
110
|
+
targetPublicKey: string;
|
|
111
|
+
providerName: TurnkeyOAuthProvider;
|
|
112
|
+
}): Promise<{
|
|
113
|
+
session: string;
|
|
114
|
+
email: string | undefined;
|
|
115
|
+
}>;
|
|
93
116
|
refreshSession(): Promise<string>;
|
|
94
117
|
private initClient;
|
|
95
118
|
}
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { HttpRestClient } from "@injectivelabs/utils";
|
|
2
|
-
import { BaseConcreteStrategy, ConcreteEvmWalletStrategyArgs, ConcreteWalletStrategy, Eip1193Provider, SendTransactionOptions, StdSignDoc, TurnkeyMetadata,
|
|
2
|
+
import { BaseConcreteStrategy, ConcreteEvmWalletStrategyArgs, ConcreteWalletStrategy, Eip1193Provider, SendTransactionOptions, StdSignDoc, TurnkeyMetadata, TurnkeyOAuthProvider, WalletDeviceType, WalletMetadata, WalletStrategyEvmOptions } from "@injectivelabs/wallet-base";
|
|
3
3
|
import { createAccount } from "@turnkey/viem";
|
|
4
4
|
import * as _turnkey_sdk_browser0 from "@turnkey/sdk-browser";
|
|
5
5
|
import { Turnkey, TurnkeyIndexedDbClient } from "@turnkey/sdk-browser";
|
|
@@ -67,9 +67,9 @@ type TurnkeyConfirmEmailOTPResponse = {
|
|
|
67
67
|
declare class TurnkeyWallet {
|
|
68
68
|
private otpId?;
|
|
69
69
|
protected turnkey?: Turnkey;
|
|
70
|
-
userOrganizationId?: string;
|
|
71
70
|
protected client: HttpRestClient;
|
|
72
71
|
private metadata;
|
|
72
|
+
userOrganizationId?: string;
|
|
73
73
|
protected indexedDbClient?: TurnkeyIndexedDbClient;
|
|
74
74
|
private accountMap;
|
|
75
75
|
setMetadata(metadata: Partial<TurnkeyMetadata>): void;
|
|
@@ -87,9 +87,32 @@ declare class TurnkeyWallet {
|
|
|
87
87
|
getAccounts(): Promise<string[]>;
|
|
88
88
|
getOrCreateAndGetAccount(address: string): Promise<ReturnType<typeof createAccount>>;
|
|
89
89
|
initOTP(email: string): Promise<TurnkeyOTPCredentialsResponse>;
|
|
90
|
+
initSms(phone: string): Promise<TurnkeyOTPCredentialsResponse>;
|
|
90
91
|
confirmOTP(otpCode: string): Promise<TurnkeyConfirmEmailOTPResponse>;
|
|
91
|
-
initOAuth(provider:
|
|
92
|
-
|
|
92
|
+
initOAuth(provider: TurnkeyOAuthProvider): Promise<string>;
|
|
93
|
+
initOAuth2(provider: TurnkeyOAuthProvider): Promise<{
|
|
94
|
+
pkce: {
|
|
95
|
+
state: string;
|
|
96
|
+
codeVerifier: string;
|
|
97
|
+
targetPublicKey: string;
|
|
98
|
+
};
|
|
99
|
+
url: string;
|
|
100
|
+
}>;
|
|
101
|
+
confirmOAuth(provider: TurnkeyOAuthProvider, oidcToken: string): Promise<string>;
|
|
102
|
+
confirmOAuth2({
|
|
103
|
+
authCode,
|
|
104
|
+
codeVerifier,
|
|
105
|
+
providerName,
|
|
106
|
+
targetPublicKey
|
|
107
|
+
}: {
|
|
108
|
+
authCode: string;
|
|
109
|
+
codeVerifier: string;
|
|
110
|
+
targetPublicKey: string;
|
|
111
|
+
providerName: TurnkeyOAuthProvider;
|
|
112
|
+
}): Promise<{
|
|
113
|
+
session: string;
|
|
114
|
+
email: string | undefined;
|
|
115
|
+
}>;
|
|
93
116
|
refreshSession(): Promise<string>;
|
|
94
117
|
private initClient;
|
|
95
118
|
}
|
package/dist/esm/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getAddress } from "viem";
|
|
1
|
+
import { getAddress, hashTypedData } from "viem";
|
|
2
2
|
import { HttpRestClient } from "@injectivelabs/utils";
|
|
3
3
|
import { TxGrpcApi } from "@injectivelabs/sdk-ts/core/tx";
|
|
4
4
|
import { getEthereumAddress, getInjectiveAddress, sha256 } from "@injectivelabs/sdk-ts/utils";
|
|
@@ -44,6 +44,29 @@ var TurnkeyOtpWallet = class {
|
|
|
44
44
|
});
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
|
+
static async initSmsOTP(args) {
|
|
48
|
+
const { client, indexedDbClient, expirationSeconds } = args;
|
|
49
|
+
try {
|
|
50
|
+
await indexedDbClient.resetKeyPair();
|
|
51
|
+
const publicKey = await indexedDbClient.getPublicKey();
|
|
52
|
+
if (!publicKey) throw new WalletException(/* @__PURE__ */ new Error("Public key not found"));
|
|
53
|
+
const response = await client.post(args.otpInitPath || TURNKEY_OTP_INIT_PATH, {
|
|
54
|
+
phone: args.phone,
|
|
55
|
+
isUsingIndexedDB: true,
|
|
56
|
+
suborgId: args.subOrgId,
|
|
57
|
+
targetPublicKey: publicKey,
|
|
58
|
+
invalidateExistingSessions: args.invalidateExistingSessions,
|
|
59
|
+
expirationSeconds: expirationSeconds || DEFAULT_TURNKEY_REFRESH_SECONDS
|
|
60
|
+
});
|
|
61
|
+
return response === null || response === void 0 ? void 0 : response.data;
|
|
62
|
+
} catch (e) {
|
|
63
|
+
throw new WalletException(new Error(e.message), {
|
|
64
|
+
code: UnspecifiedErrorCode,
|
|
65
|
+
type: ErrorType.WalletError,
|
|
66
|
+
contextModule: "turnkey-init-sms-otp"
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
47
70
|
static async confirmEmailOTP(args) {
|
|
48
71
|
const { client, expirationSeconds, targetPublicKey } = args;
|
|
49
72
|
try {
|
|
@@ -114,6 +137,35 @@ var TurnkeyOauthWallet = class {
|
|
|
114
137
|
|
|
115
138
|
//#endregion
|
|
116
139
|
//#region src/utils.ts
|
|
140
|
+
function generateBase64Url(byteLength) {
|
|
141
|
+
const bytes = new Uint8Array(byteLength);
|
|
142
|
+
crypto.getRandomValues(bytes);
|
|
143
|
+
return btoa(String.fromCharCode(...bytes)).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
144
|
+
}
|
|
145
|
+
function sha256ToBase64Url(input) {
|
|
146
|
+
const hash = sha256(new TextEncoder().encode(input));
|
|
147
|
+
return btoa(String.fromCharCode(...hash)).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
148
|
+
}
|
|
149
|
+
function generateTwitterPkce() {
|
|
150
|
+
const state = generateBase64Url(32);
|
|
151
|
+
const codeVerifier = generateBase64Url(32);
|
|
152
|
+
return {
|
|
153
|
+
state,
|
|
154
|
+
codeVerifier,
|
|
155
|
+
codeChallenge: sha256ToBase64Url(codeVerifier)
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
function generateTwitterUrl({ state, clientId, redirectUri, codeChallenge }) {
|
|
159
|
+
const url = new URL("https://twitter.com/i/oauth2/authorize");
|
|
160
|
+
url.searchParams.set("state", state);
|
|
161
|
+
url.searchParams.set("client_id", clientId);
|
|
162
|
+
url.searchParams.set("response_type", "code");
|
|
163
|
+
url.searchParams.set("redirect_uri", redirectUri);
|
|
164
|
+
url.searchParams.set("code_challenge", codeChallenge);
|
|
165
|
+
url.searchParams.set("code_challenge_method", "S256");
|
|
166
|
+
url.searchParams.set("scope", "tweet.read users.read users.email offline.access");
|
|
167
|
+
return url.toString();
|
|
168
|
+
}
|
|
117
169
|
function generateGoogleUrl({ nonce, clientId, redirectUri, scope = "openid profile email", prompt = "consent" }) {
|
|
118
170
|
if (!clientId) throw new Error("Google client ID not found");
|
|
119
171
|
return `https://accounts.google.com/o/oauth2/v2/auth?prompt=${prompt}&client_id=${clientId}&redirect_uri=${redirectUri}&response_type=id_token&scope=${scope}&nonce=${nonce}`;
|
|
@@ -173,9 +225,9 @@ var TurnkeyWallet = class {
|
|
|
173
225
|
constructor(metadata) {
|
|
174
226
|
_defineProperty(this, "otpId", void 0);
|
|
175
227
|
_defineProperty(this, "turnkey", void 0);
|
|
176
|
-
_defineProperty(this, "userOrganizationId", void 0);
|
|
177
228
|
_defineProperty(this, "client", void 0);
|
|
178
229
|
_defineProperty(this, "metadata", void 0);
|
|
230
|
+
_defineProperty(this, "userOrganizationId", void 0);
|
|
179
231
|
_defineProperty(this, "indexedDbClient", void 0);
|
|
180
232
|
_defineProperty(this, "accountMap", {});
|
|
181
233
|
this.metadata = metadata;
|
|
@@ -268,9 +320,9 @@ var TurnkeyWallet = class {
|
|
|
268
320
|
async initOTP(email) {
|
|
269
321
|
const indexedDbClient = await this.getIndexedDbClient();
|
|
270
322
|
const result = await TurnkeyOtpWallet.initEmailOTP({
|
|
271
|
-
client: this.client,
|
|
272
|
-
indexedDbClient,
|
|
273
323
|
email,
|
|
324
|
+
indexedDbClient,
|
|
325
|
+
client: this.client,
|
|
274
326
|
otpInitPath: this.metadata.otpInitPath || TURNKEY_OTP_INIT_PATH
|
|
275
327
|
});
|
|
276
328
|
if (!result || !result.otpId) throw new WalletException(/* @__PURE__ */ new Error("Failed to initialize OTP"));
|
|
@@ -278,6 +330,19 @@ var TurnkeyWallet = class {
|
|
|
278
330
|
if (result === null || result === void 0 ? void 0 : result.otpId) this.otpId = result.otpId;
|
|
279
331
|
return result;
|
|
280
332
|
}
|
|
333
|
+
async initSms(phone) {
|
|
334
|
+
const indexedDbClient = await this.getIndexedDbClient();
|
|
335
|
+
const result = await TurnkeyOtpWallet.initSmsOTP({
|
|
336
|
+
phone,
|
|
337
|
+
indexedDbClient,
|
|
338
|
+
client: this.client,
|
|
339
|
+
otpInitPath: this.metadata.otpInitPath || TURNKEY_OTP_INIT_PATH
|
|
340
|
+
});
|
|
341
|
+
if (!result || !result.otpId) throw new WalletException(/* @__PURE__ */ new Error("Failed to initialize SMS OTP"));
|
|
342
|
+
if (result === null || result === void 0 ? void 0 : result.organizationId) this.userOrganizationId = result.organizationId;
|
|
343
|
+
if (result === null || result === void 0 ? void 0 : result.otpId) this.otpId = result.otpId;
|
|
344
|
+
return result;
|
|
345
|
+
}
|
|
281
346
|
async confirmOTP(otpCode) {
|
|
282
347
|
const indexedDbClient = await this.getIndexedDbClient();
|
|
283
348
|
const targetPublicKey = await indexedDbClient.getPublicKey();
|
|
@@ -286,10 +351,10 @@ var TurnkeyWallet = class {
|
|
|
286
351
|
if (!this.userOrganizationId) throw new WalletException(/* @__PURE__ */ new Error("Organization ID is required"));
|
|
287
352
|
const result = await TurnkeyOtpWallet.confirmEmailOTP({
|
|
288
353
|
otpCode,
|
|
354
|
+
targetPublicKey,
|
|
289
355
|
client: this.client,
|
|
290
356
|
emailOTPId: this.otpId,
|
|
291
357
|
organizationId: this.userOrganizationId,
|
|
292
|
-
targetPublicKey,
|
|
293
358
|
otpVerifyPath: this.metadata.otpVerifyPath || TURNKEY_OTP_VERIFY_PATH
|
|
294
359
|
});
|
|
295
360
|
if (!result || !result.session) throw new WalletException(/* @__PURE__ */ new Error("Failed to confirm OTP"));
|
|
@@ -309,6 +374,30 @@ var TurnkeyWallet = class {
|
|
|
309
374
|
redirectUri: this.metadata.googleRedirectUri
|
|
310
375
|
});
|
|
311
376
|
}
|
|
377
|
+
async initOAuth2(provider) {
|
|
378
|
+
if (provider === TurnkeyProvider.Twitter) {
|
|
379
|
+
if (!this.metadata.twitterClientId || !this.metadata.twitterRedirectUri) throw new WalletException(/* @__PURE__ */ new Error("twitterClientId and twitterRedirectUri are required"));
|
|
380
|
+
const indexedDbClient = await this.getIndexedDbClient();
|
|
381
|
+
await indexedDbClient.resetKeyPair();
|
|
382
|
+
const targetPublicKey = await indexedDbClient.getPublicKey();
|
|
383
|
+
if (!targetPublicKey) throw new WalletException(/* @__PURE__ */ new Error("Target public key is missing. Please ensure your wallet is properly initialized."));
|
|
384
|
+
const { state, codeVerifier, codeChallenge } = generateTwitterPkce();
|
|
385
|
+
return {
|
|
386
|
+
pkce: {
|
|
387
|
+
state,
|
|
388
|
+
codeVerifier,
|
|
389
|
+
targetPublicKey
|
|
390
|
+
},
|
|
391
|
+
url: generateTwitterUrl({
|
|
392
|
+
state,
|
|
393
|
+
codeChallenge,
|
|
394
|
+
clientId: this.metadata.twitterClientId,
|
|
395
|
+
redirectUri: this.metadata.twitterRedirectUri
|
|
396
|
+
})
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
throw new WalletException(/* @__PURE__ */ new Error(`${provider} is not supported for OAuth2`));
|
|
400
|
+
}
|
|
312
401
|
async confirmOAuth(provider, oidcToken) {
|
|
313
402
|
if (provider === TurnkeyProvider.Apple) throw new WalletException(/* @__PURE__ */ new Error("Apple sign in option is currently not supported"));
|
|
314
403
|
const indexedDbClient = await this.getIndexedDbClient();
|
|
@@ -316,7 +405,7 @@ var TurnkeyWallet = class {
|
|
|
316
405
|
oidcToken,
|
|
317
406
|
indexedDbClient,
|
|
318
407
|
client: this.client,
|
|
319
|
-
providerName: provider
|
|
408
|
+
providerName: provider,
|
|
320
409
|
oauthLoginPath: this.metadata.oauthLoginPath || TURNKEY_OAUTH_PATH
|
|
321
410
|
});
|
|
322
411
|
if (!oauthResult || !oauthResult.credentialBundle) throw new WalletException(/* @__PURE__ */ new Error("Unexpected OAuth result"));
|
|
@@ -324,6 +413,25 @@ var TurnkeyWallet = class {
|
|
|
324
413
|
this.userOrganizationId = oauthResult.organizationId;
|
|
325
414
|
return oauthResult.credentialBundle;
|
|
326
415
|
}
|
|
416
|
+
async confirmOAuth2({ authCode, codeVerifier, providerName, targetPublicKey }) {
|
|
417
|
+
var _response$data, _response$data2;
|
|
418
|
+
const indexedDbClient = await this.getIndexedDbClient();
|
|
419
|
+
const path = this.metadata.oauth2ExchangePath || "turnkey/oauth2";
|
|
420
|
+
const response = await this.client.post(path, {
|
|
421
|
+
authCode,
|
|
422
|
+
codeVerifier,
|
|
423
|
+
targetPublicKey,
|
|
424
|
+
providerName
|
|
425
|
+
});
|
|
426
|
+
if (!(response === null || response === void 0 || (_response$data = response.data) === null || _response$data === void 0 ? void 0 : _response$data.credentialBundle) || !(response === null || response === void 0 || (_response$data2 = response.data) === null || _response$data2 === void 0 ? void 0 : _response$data2.organizationId)) throw new WalletException(/* @__PURE__ */ new Error(`${providerName} OAuth2 exchange failed`));
|
|
427
|
+
const { credentialBundle, organizationId, email } = response.data;
|
|
428
|
+
await indexedDbClient.loginWithSession(credentialBundle);
|
|
429
|
+
this.userOrganizationId = organizationId;
|
|
430
|
+
return {
|
|
431
|
+
session: credentialBundle,
|
|
432
|
+
email
|
|
433
|
+
};
|
|
434
|
+
}
|
|
327
435
|
async refreshSession() {
|
|
328
436
|
var _session$session;
|
|
329
437
|
const session = await this.getSession();
|
|
@@ -368,8 +476,10 @@ const parseChainId = (chainId) => {
|
|
|
368
476
|
return parseInt(chainId, 10);
|
|
369
477
|
};
|
|
370
478
|
const getEip1193ProviderForTurnkey = async (account, chainId, params = {}) => {
|
|
479
|
+
var _account$sign;
|
|
371
480
|
return new CustomEip1193Provider({
|
|
372
481
|
chainId: parseChainId(chainId),
|
|
482
|
+
sign: (_account$sign = account.sign) === null || _account$sign === void 0 ? void 0 : _account$sign.bind(account),
|
|
373
483
|
signTypedData: account.signTypedData.bind(account),
|
|
374
484
|
signMessage: account.signMessage.bind(account),
|
|
375
485
|
signTransaction: account.signTransaction.bind(account),
|
|
@@ -383,6 +493,7 @@ var CustomEip1193Provider = class {
|
|
|
383
493
|
constructor(args) {
|
|
384
494
|
var _args$chainId;
|
|
385
495
|
_defineProperty(this, "chainId", void 0);
|
|
496
|
+
_defineProperty(this, "sign", void 0);
|
|
386
497
|
_defineProperty(this, "signTypedData", void 0);
|
|
387
498
|
_defineProperty(this, "signMessage", void 0);
|
|
388
499
|
_defineProperty(this, "signTransaction", void 0);
|
|
@@ -391,6 +502,7 @@ var CustomEip1193Provider = class {
|
|
|
391
502
|
_defineProperty(this, "account", void 0);
|
|
392
503
|
_defineProperty(this, "address", void 0);
|
|
393
504
|
this.chainId = (_args$chainId = args.chainId) !== null && _args$chainId !== void 0 ? _args$chainId : 1;
|
|
505
|
+
this.sign = args.sign;
|
|
394
506
|
this.signTypedData = args.signTypedData;
|
|
395
507
|
this.signMessage = args.signMessage;
|
|
396
508
|
this.account = args.account;
|
|
@@ -426,7 +538,20 @@ var CustomEip1193Provider = class {
|
|
|
426
538
|
if (args.method === "eth_requestAccounts") return this.requestAccounts();
|
|
427
539
|
if (args.method === "eth_signTypedData") {
|
|
428
540
|
if (!args.params) throw new Error("params is required");
|
|
429
|
-
|
|
541
|
+
const typedData = args.params[0];
|
|
542
|
+
if (this.sign) {
|
|
543
|
+
const typedDataHash = hashTypedData({
|
|
544
|
+
domain: {
|
|
545
|
+
...typedData.domain,
|
|
546
|
+
chainId: typedData.domain.chainId != null ? parseChainId(typedData.domain.chainId) : void 0
|
|
547
|
+
},
|
|
548
|
+
types: typedData.types,
|
|
549
|
+
primaryType: typedData.primaryType,
|
|
550
|
+
message: typedData.message
|
|
551
|
+
});
|
|
552
|
+
return this.sign({ hash: typedDataHash });
|
|
553
|
+
}
|
|
554
|
+
return this.signTypedData(typedData);
|
|
430
555
|
}
|
|
431
556
|
if (args.method === "eth_signMessage") {
|
|
432
557
|
if (!args.params) throw new Error("params is required");
|
|
@@ -630,7 +755,16 @@ var TurnkeyWalletStrategy = class extends BaseConcreteStrategy {
|
|
|
630
755
|
});
|
|
631
756
|
}
|
|
632
757
|
if (((_parsedData$domain = parsedData.domain) === null || _parsedData$domain === void 0 ? void 0 : _parsedData$domain.chainId) && typeof parsedData.domain.chainId === "string") parsedData.domain.chainId = Number(parsedData.domain.chainId);
|
|
633
|
-
|
|
758
|
+
if (account.sign) {
|
|
759
|
+
const typedDataHash = hashTypedData({
|
|
760
|
+
types: parsedData.types,
|
|
761
|
+
domain: parsedData.domain,
|
|
762
|
+
message: parsedData.message,
|
|
763
|
+
primaryType: parsedData.primaryType
|
|
764
|
+
});
|
|
765
|
+
return account.sign({ hash: typedDataHash });
|
|
766
|
+
}
|
|
767
|
+
return account.signTypedData(parsedData);
|
|
634
768
|
}
|
|
635
769
|
async signCosmosTransaction(_transaction) {
|
|
636
770
|
throw new WalletException(/* @__PURE__ */ new Error("This wallet does not support signing Cosmos transactions"), {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@injectivelabs/wallet-turnkey",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.16",
|
|
4
4
|
"description": "Turnkey wallet strategy for use with @injectivelabs/wallet-core.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": {
|
|
@@ -42,14 +42,14 @@
|
|
|
42
42
|
"dist"
|
|
43
43
|
],
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@turnkey/sdk-browser": "5.
|
|
46
|
-
"@turnkey/viem": "0.
|
|
45
|
+
"@turnkey/sdk-browser": "5.16.1",
|
|
46
|
+
"@turnkey/viem": "0.13.1",
|
|
47
47
|
"viem": "^2.41.2",
|
|
48
|
-
"@injectivelabs/exceptions": "1.19.
|
|
49
|
-
"@injectivelabs/
|
|
50
|
-
"@injectivelabs/
|
|
51
|
-
"@injectivelabs/
|
|
52
|
-
"@injectivelabs/
|
|
48
|
+
"@injectivelabs/exceptions": "1.19.16",
|
|
49
|
+
"@injectivelabs/sdk-ts": "1.19.16",
|
|
50
|
+
"@injectivelabs/wallet-base": "1.19.16",
|
|
51
|
+
"@injectivelabs/utils": "1.19.16",
|
|
52
|
+
"@injectivelabs/ts-types": "1.19.16"
|
|
53
53
|
},
|
|
54
54
|
"publishConfig": {
|
|
55
55
|
"access": "public"
|