@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.
@@ -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.toString(),
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
- return this.signTypedData(args.params[0]);
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
- return await account.signTypedData(parsedData);
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"), {
@@ -1,5 +1,5 @@
1
1
  import { HttpRestClient } from "@injectivelabs/utils";
2
- import { BaseConcreteStrategy, ConcreteEvmWalletStrategyArgs, ConcreteWalletStrategy, Eip1193Provider, SendTransactionOptions, StdSignDoc, TurnkeyMetadata, TurnkeyProvider, WalletDeviceType, WalletMetadata, WalletStrategyEvmOptions } from "@injectivelabs/wallet-base";
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: TurnkeyProvider): Promise<string>;
92
- confirmOAuth(provider: TurnkeyProvider, oidcToken: string): Promise<string>;
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
  }
@@ -1,5 +1,5 @@
1
1
  import { HttpRestClient } from "@injectivelabs/utils";
2
- import { BaseConcreteStrategy, ConcreteEvmWalletStrategyArgs, ConcreteWalletStrategy, Eip1193Provider, SendTransactionOptions, StdSignDoc, TurnkeyMetadata, TurnkeyProvider, WalletDeviceType, WalletMetadata, WalletStrategyEvmOptions } from "@injectivelabs/wallet-base";
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: TurnkeyProvider): Promise<string>;
92
- confirmOAuth(provider: TurnkeyProvider, oidcToken: string): Promise<string>;
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.toString(),
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
- return this.signTypedData(args.params[0]);
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
- return await account.signTypedData(parsedData);
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.15",
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.2.3",
46
- "@turnkey/viem": "0.9.10",
45
+ "@turnkey/sdk-browser": "5.16.1",
46
+ "@turnkey/viem": "0.13.1",
47
47
  "viem": "^2.41.2",
48
- "@injectivelabs/exceptions": "1.19.15",
49
- "@injectivelabs/utils": "1.19.15",
50
- "@injectivelabs/ts-types": "1.19.15",
51
- "@injectivelabs/wallet-base": "1.19.15",
52
- "@injectivelabs/sdk-ts": "1.19.15"
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"