@injectivelabs/wallet-turnkey 1.15.10
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/README.md +120 -0
- package/dist/cjs/index.d.ts +4 -0
- package/dist/cjs/index.js +23 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/strategy/consts.d.ts +4 -0
- package/dist/cjs/strategy/consts.js +7 -0
- package/dist/cjs/strategy/strategy/base.d.ts +47 -0
- package/dist/cjs/strategy/strategy/base.js +327 -0
- package/dist/cjs/strategy/strategy/oauth.d.ts +5 -0
- package/dist/cjs/strategy/strategy/oauth.js +14 -0
- package/dist/cjs/strategy/strategy/otp.d.ts +5 -0
- package/dist/cjs/strategy/strategy/otp.js +14 -0
- package/dist/cjs/strategy/turnkey/oauth.d.ts +16 -0
- package/dist/cjs/strategy/turnkey/oauth.js +51 -0
- package/dist/cjs/strategy/turnkey/otp.d.ts +21 -0
- package/dist/cjs/strategy/turnkey/otp.js +64 -0
- package/dist/cjs/strategy/turnkey/turnkey.d.ts +43 -0
- package/dist/cjs/strategy/turnkey/turnkey.js +196 -0
- package/dist/cjs/strategy/types.d.ts +26 -0
- package/dist/cjs/strategy/types.js +7 -0
- package/dist/cjs/utils.d.ts +7 -0
- package/dist/cjs/utils.js +10 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +4 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/strategy/consts.d.ts +4 -0
- package/dist/esm/strategy/consts.js +4 -0
- package/dist/esm/strategy/strategy/base.d.ts +47 -0
- package/dist/esm/strategy/strategy/base.js +323 -0
- package/dist/esm/strategy/strategy/oauth.d.ts +5 -0
- package/dist/esm/strategy/strategy/oauth.js +10 -0
- package/dist/esm/strategy/strategy/otp.d.ts +5 -0
- package/dist/esm/strategy/strategy/otp.js +10 -0
- package/dist/esm/strategy/turnkey/oauth.d.ts +16 -0
- package/dist/esm/strategy/turnkey/oauth.js +47 -0
- package/dist/esm/strategy/turnkey/otp.d.ts +21 -0
- package/dist/esm/strategy/turnkey/otp.js +60 -0
- package/dist/esm/strategy/turnkey/turnkey.d.ts +43 -0
- package/dist/esm/strategy/turnkey/turnkey.js +192 -0
- package/dist/esm/strategy/types.d.ts +26 -0
- package/dist/esm/strategy/types.js +4 -0
- package/dist/esm/utils.d.ts +7 -0
- package/dist/esm/utils.js +7 -0
- package/package.json +78 -0
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
/* eslint-disable class-methods-use-this */
|
|
2
|
+
import { ErrorType, WalletException, UnspecifiedErrorCode, TransactionException, CosmosWalletException, } from '@injectivelabs/exceptions';
|
|
3
|
+
import { TxGrpcApi, } from '@injectivelabs/sdk-ts';
|
|
4
|
+
import { HttpRestClient } from '@injectivelabs/utils';
|
|
5
|
+
import { WalletAction, TurnkeyProvider, WalletDeviceType, BaseConcreteStrategy, } from '@injectivelabs/wallet-base';
|
|
6
|
+
import { TurnkeyWallet } from '../turnkey/turnkey.js';
|
|
7
|
+
import { TurnkeyErrorCodes } from '../types.js';
|
|
8
|
+
import { TurnkeyOtpWallet } from '../turnkey/otp.js';
|
|
9
|
+
import { TurnkeyOauthWallet } from '../turnkey/oauth.js';
|
|
10
|
+
import { SessionType } from '@turnkey/sdk-browser';
|
|
11
|
+
import { getAddress } from 'viem';
|
|
12
|
+
import { generateGoogleUrl } from '../../utils.js';
|
|
13
|
+
export class BaseTurnkeyWalletStrategy extends BaseConcreteStrategy {
|
|
14
|
+
turnkeyWallet;
|
|
15
|
+
turnkeyProvider;
|
|
16
|
+
client;
|
|
17
|
+
constructor(args) {
|
|
18
|
+
super(args);
|
|
19
|
+
this.turnkeyProvider = args.provider;
|
|
20
|
+
const endpoint = args.apiServerEndpoint || this.metadata?.turnkey?.apiServerEndpoint;
|
|
21
|
+
if (!endpoint) {
|
|
22
|
+
throw new WalletException(new Error('apiServerEndpoint is required'));
|
|
23
|
+
}
|
|
24
|
+
this.client = new HttpRestClient(endpoint);
|
|
25
|
+
}
|
|
26
|
+
async getWalletDeviceType() {
|
|
27
|
+
return Promise.resolve(WalletDeviceType.Browser);
|
|
28
|
+
}
|
|
29
|
+
setMetadata(metadata) {
|
|
30
|
+
if (metadata?.turnkey) {
|
|
31
|
+
this.metadata = {
|
|
32
|
+
...this.metadata,
|
|
33
|
+
turnkey: {
|
|
34
|
+
...this.metadata?.turnkey,
|
|
35
|
+
...metadata.turnkey,
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//? This is here specifically because we have to ensure we set the organizationId on TurnkeyWallet as well
|
|
41
|
+
setOrganizationId(organizationId) {
|
|
42
|
+
this.setMetadata({ turnkey: { organizationId } });
|
|
43
|
+
this.turnkeyWallet?.setMetadata({ organizationId });
|
|
44
|
+
}
|
|
45
|
+
async enable() {
|
|
46
|
+
const turnkeyWallet = await this.getTurnkeyWallet();
|
|
47
|
+
try {
|
|
48
|
+
const session = await turnkeyWallet.getSession();
|
|
49
|
+
if (session.session) {
|
|
50
|
+
// User is already logged in, we don't need to do anything in the next steps
|
|
51
|
+
if (this.metadata?.turnkey) {
|
|
52
|
+
this.metadata.turnkey.session = session.session;
|
|
53
|
+
}
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
return !!(await turnkeyWallet.getIframeClient());
|
|
57
|
+
}
|
|
58
|
+
catch (e) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
async disconnect() {
|
|
63
|
+
const turnkeyWallet = await this.getTurnkeyWallet();
|
|
64
|
+
const turnkey = await turnkeyWallet.getTurnkey();
|
|
65
|
+
const isUserLoggedIn = await turnkey.getSession();
|
|
66
|
+
if (!isUserLoggedIn) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
await turnkey.logout();
|
|
70
|
+
}
|
|
71
|
+
async getAddresses() {
|
|
72
|
+
const turnkeyWallet = await this.getTurnkeyWallet();
|
|
73
|
+
const organizationId = await this.getOrganizationId();
|
|
74
|
+
// CHeck if the user is already connected
|
|
75
|
+
const session = await turnkeyWallet.getSession();
|
|
76
|
+
if (!session.session) {
|
|
77
|
+
const iframeClient = await turnkeyWallet.getIframeClient();
|
|
78
|
+
// Check the provider type and perform auth step accordingly
|
|
79
|
+
if (this.turnkeyProvider === TurnkeyProvider.Email) {
|
|
80
|
+
if (!this.metadata?.turnkey?.otpId) {
|
|
81
|
+
throw new WalletException(new Error('OTP ID is required'));
|
|
82
|
+
}
|
|
83
|
+
if (!this.metadata?.turnkey?.otpCode) {
|
|
84
|
+
throw new WalletException(new Error('OTP code is required'));
|
|
85
|
+
}
|
|
86
|
+
const result = await TurnkeyOtpWallet.confirmEmailOTP({
|
|
87
|
+
iframeClient,
|
|
88
|
+
organizationId,
|
|
89
|
+
client: this.client,
|
|
90
|
+
otpCode: this.metadata?.turnkey?.otpCode,
|
|
91
|
+
emailOTPId: this.metadata?.turnkey?.otpId,
|
|
92
|
+
});
|
|
93
|
+
if (result?.credentialBundle) {
|
|
94
|
+
this.metadata.turnkey.credentialBundle = result.credentialBundle;
|
|
95
|
+
await turnkeyWallet.injectAndRefresh(result.credentialBundle);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
if (!this.metadata?.turnkey?.oidcToken) {
|
|
100
|
+
throw new WalletException(new Error('Oidc token is required'));
|
|
101
|
+
}
|
|
102
|
+
const result = await TurnkeyOauthWallet.oauthLogin({
|
|
103
|
+
client: this.client,
|
|
104
|
+
iframeClient,
|
|
105
|
+
oidcToken: this.metadata?.turnkey?.oidcToken,
|
|
106
|
+
providerName: this.turnkeyProvider.toString(),
|
|
107
|
+
});
|
|
108
|
+
if (result?.credentialBundle) {
|
|
109
|
+
this.metadata.turnkey.organizationId = result.organizationId;
|
|
110
|
+
this.metadata.turnkey.credentialBundle = result.credentialBundle;
|
|
111
|
+
await turnkeyWallet.injectAndRefresh(result.credentialBundle);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
try {
|
|
116
|
+
return await turnkeyWallet.getAccounts();
|
|
117
|
+
}
|
|
118
|
+
catch (e) {
|
|
119
|
+
if (e.contextCode === TurnkeyErrorCodes.UserLoggedOut) {
|
|
120
|
+
await this.disconnect();
|
|
121
|
+
throw e;
|
|
122
|
+
}
|
|
123
|
+
throw new WalletException(new Error(e.message), {
|
|
124
|
+
code: UnspecifiedErrorCode,
|
|
125
|
+
type: ErrorType.WalletError,
|
|
126
|
+
contextModule: WalletAction.GetAccounts,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
async getSessionOrConfirm() {
|
|
131
|
+
const { turnkeyProvider, metadata, client } = this;
|
|
132
|
+
const turnkeyWallet = await this.getTurnkeyWallet();
|
|
133
|
+
const iframeClient = await turnkeyWallet.getIframeClient();
|
|
134
|
+
const session = await turnkeyWallet.getSession();
|
|
135
|
+
if (
|
|
136
|
+
// If either of these values exist on the metadata, then we want to proceed with the login flow
|
|
137
|
+
!this.metadata?.turnkey?.email &&
|
|
138
|
+
!this.metadata?.turnkey?.oidcToken &&
|
|
139
|
+
session.session?.token) {
|
|
140
|
+
await iframeClient.injectCredentialBundle(session.session?.token);
|
|
141
|
+
this.setOrganizationId(session.organizationId);
|
|
142
|
+
await iframeClient.refreshSession({
|
|
143
|
+
sessionType: SessionType.READ_WRITE,
|
|
144
|
+
targetPublicKey: iframeClient.iframePublicKey,
|
|
145
|
+
expirationSeconds: '900',
|
|
146
|
+
});
|
|
147
|
+
return session.session.token;
|
|
148
|
+
}
|
|
149
|
+
if (turnkeyProvider === TurnkeyProvider.Email) {
|
|
150
|
+
if (!metadata?.turnkey?.email) {
|
|
151
|
+
throw new WalletException(new Error('Email is required'));
|
|
152
|
+
}
|
|
153
|
+
const result = await TurnkeyOtpWallet.initEmailOTP({
|
|
154
|
+
client,
|
|
155
|
+
iframeClient,
|
|
156
|
+
email: metadata.turnkey.email,
|
|
157
|
+
otpInitPath: metadata.turnkey.otpInitPath,
|
|
158
|
+
});
|
|
159
|
+
if (result?.organizationId && this.metadata?.turnkey) {
|
|
160
|
+
this.metadata.turnkey.organizationId = result.organizationId;
|
|
161
|
+
}
|
|
162
|
+
if (result?.otpId && this.metadata?.turnkey) {
|
|
163
|
+
this.metadata.turnkey.otpId = result.otpId;
|
|
164
|
+
}
|
|
165
|
+
return result?.otpId || '';
|
|
166
|
+
}
|
|
167
|
+
if ([TurnkeyProvider.Google, TurnkeyProvider.Apple].includes(turnkeyProvider)) {
|
|
168
|
+
if (metadata?.turnkey?.oidcToken) {
|
|
169
|
+
const oauthResult = await TurnkeyOauthWallet.oauthLogin({
|
|
170
|
+
client,
|
|
171
|
+
iframeClient,
|
|
172
|
+
oidcToken: metadata.turnkey.oidcToken,
|
|
173
|
+
providerName: turnkeyProvider.toString(),
|
|
174
|
+
oauthLoginPath: metadata.turnkey.oauthLoginPath,
|
|
175
|
+
});
|
|
176
|
+
if (oauthResult?.credentialBundle) {
|
|
177
|
+
await turnkeyWallet.injectAndRefresh(oauthResult.credentialBundle);
|
|
178
|
+
}
|
|
179
|
+
if (oauthResult?.credentialBundle) {
|
|
180
|
+
const session = await turnkeyWallet.getSession();
|
|
181
|
+
if (this.metadata?.turnkey && session.organizationId) {
|
|
182
|
+
this.metadata.turnkey.organizationId = session.organizationId;
|
|
183
|
+
}
|
|
184
|
+
return oauthResult.credentialBundle;
|
|
185
|
+
}
|
|
186
|
+
throw new WalletException(new Error('Oauth result not found'));
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
const nonce = await TurnkeyOauthWallet.generateOAuthNonce(iframeClient);
|
|
190
|
+
if (!metadata?.turnkey?.googleClientId ||
|
|
191
|
+
!metadata?.turnkey?.googleRedirectUri) {
|
|
192
|
+
throw new WalletException(new Error('googleClientId and googleRedirectUri are required'));
|
|
193
|
+
}
|
|
194
|
+
if (turnkeyProvider === TurnkeyProvider.Google) {
|
|
195
|
+
return generateGoogleUrl({
|
|
196
|
+
nonce,
|
|
197
|
+
clientId: metadata.turnkey.googleClientId,
|
|
198
|
+
redirectUri: metadata.turnkey.googleRedirectUri,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
//? When we add Apple support, we might also want to return the URL as well
|
|
202
|
+
return nonce;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return '';
|
|
206
|
+
}
|
|
207
|
+
async sendEthereumTransaction(_transaction, _options) {
|
|
208
|
+
throw new WalletException(new Error('sendEthereumTransaction is not supported. Turnkey only supports sending cosmos transactions'), {
|
|
209
|
+
code: UnspecifiedErrorCode,
|
|
210
|
+
context: WalletAction.SendEthereumTransaction,
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
async sendTransaction(transaction, options) {
|
|
214
|
+
const { endpoints, txTimeout } = options;
|
|
215
|
+
if (!endpoints) {
|
|
216
|
+
throw new WalletException(new Error('You have to pass endpoints.grpc within the options for using Turnkey wallet'));
|
|
217
|
+
}
|
|
218
|
+
const txApi = new TxGrpcApi(endpoints.grpc);
|
|
219
|
+
const response = await txApi.broadcast(transaction, { txTimeout });
|
|
220
|
+
if (response.code !== 0) {
|
|
221
|
+
throw new TransactionException(new Error(response.rawLog), {
|
|
222
|
+
code: UnspecifiedErrorCode,
|
|
223
|
+
contextCode: response.code,
|
|
224
|
+
contextModule: response.codespace,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
return response;
|
|
228
|
+
}
|
|
229
|
+
async signEip712TypedData(eip712json, address) {
|
|
230
|
+
const turnkeyWallet = await this.getTurnkeyWallet();
|
|
231
|
+
const organizationId = await this.getOrganizationId();
|
|
232
|
+
//? Turnkey expects the case sensitive address and the current impl of getChecksumAddress from sdk-ts doesn't play nice with browser envs
|
|
233
|
+
const checksumAddress = getAddress(address);
|
|
234
|
+
const account = await turnkeyWallet.getOrCreateAndGetAccount(checksumAddress, organizationId);
|
|
235
|
+
if (!account) {
|
|
236
|
+
throw new WalletException(new Error('Turnkey account not found'));
|
|
237
|
+
}
|
|
238
|
+
let parsedData;
|
|
239
|
+
try {
|
|
240
|
+
parsedData = JSON.parse(eip712json);
|
|
241
|
+
}
|
|
242
|
+
catch (e) {
|
|
243
|
+
throw new WalletException(new Error('Failed to parse EIP-712 data: Invalid JSON format'), {
|
|
244
|
+
code: UnspecifiedErrorCode,
|
|
245
|
+
type: ErrorType.WalletError,
|
|
246
|
+
contextModule: WalletAction.SignTransaction,
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
const signature = await account.signTypedData(parsedData);
|
|
250
|
+
return signature;
|
|
251
|
+
}
|
|
252
|
+
// eslint-disable-next-line class-methods-use-this
|
|
253
|
+
async signCosmosTransaction(_transaction) {
|
|
254
|
+
throw new WalletException(new Error('This wallet does not support signing Cosmos transactions'), {
|
|
255
|
+
code: UnspecifiedErrorCode,
|
|
256
|
+
type: ErrorType.WalletError,
|
|
257
|
+
contextModule: WalletAction.SignTransaction,
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
async signAminoCosmosTransaction(_transaction) {
|
|
261
|
+
throw new WalletException(new Error('This wallet does not support signAminoCosmosTransaction'), {
|
|
262
|
+
code: UnspecifiedErrorCode,
|
|
263
|
+
type: ErrorType.WalletError,
|
|
264
|
+
contextModule: WalletAction.SignTransaction,
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
async signArbitrary(_signer, _data) {
|
|
268
|
+
throw new WalletException(new Error('This wallet does not support signArbitrary'), {
|
|
269
|
+
code: UnspecifiedErrorCode,
|
|
270
|
+
type: ErrorType.WalletError,
|
|
271
|
+
contextModule: WalletAction.SignTransaction,
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
async getEthereumChainId() {
|
|
275
|
+
throw new CosmosWalletException(new Error('getEthereumChainId is not supported on Turnkey wallet'), {
|
|
276
|
+
code: UnspecifiedErrorCode,
|
|
277
|
+
context: WalletAction.GetChainId,
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
async getEthereumTransactionReceipt(_txHash) {
|
|
281
|
+
throw new CosmosWalletException(new Error('getEthereumTransactionReceipt is not supported on Turnkey'), {
|
|
282
|
+
code: UnspecifiedErrorCode,
|
|
283
|
+
type: ErrorType.WalletError,
|
|
284
|
+
context: WalletAction.GetEthereumTransactionReceipt,
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
// eslint-disable-next-line class-methods-use-this
|
|
288
|
+
async getPubKey() {
|
|
289
|
+
throw new WalletException(new Error('You can only fetch PubKey from Cosmos native wallets'));
|
|
290
|
+
}
|
|
291
|
+
async getIframeClient() {
|
|
292
|
+
const turnkeyWallet = await this.getTurnkeyWallet();
|
|
293
|
+
return turnkeyWallet.getIframeClient();
|
|
294
|
+
}
|
|
295
|
+
async getTurnkeyWallet() {
|
|
296
|
+
const { metadata } = this;
|
|
297
|
+
if (!this.turnkeyWallet) {
|
|
298
|
+
if (!metadata?.turnkey) {
|
|
299
|
+
throw new WalletException(new Error('Turnkey metadata is required'));
|
|
300
|
+
}
|
|
301
|
+
if (!metadata.turnkey.apiBaseUrl) {
|
|
302
|
+
throw new WalletException(new Error('Turnkey apiBaseUrl is required'));
|
|
303
|
+
}
|
|
304
|
+
if (!metadata.turnkey.apiServerEndpoint) {
|
|
305
|
+
throw new WalletException(new Error('Turnkey apiServerEndpoint is required'));
|
|
306
|
+
}
|
|
307
|
+
if (!metadata.turnkey.defaultOrganizationId) {
|
|
308
|
+
throw new WalletException(new Error('Turnkey defaultOrganizationId is required'));
|
|
309
|
+
}
|
|
310
|
+
this.turnkeyWallet = new TurnkeyWallet(metadata.turnkey);
|
|
311
|
+
}
|
|
312
|
+
return this.turnkeyWallet;
|
|
313
|
+
}
|
|
314
|
+
async getOrganizationId() {
|
|
315
|
+
const { metadata } = this;
|
|
316
|
+
const organizationId = metadata?.turnkey?.organizationId ||
|
|
317
|
+
metadata?.turnkey?.defaultOrganizationId;
|
|
318
|
+
if (!organizationId) {
|
|
319
|
+
throw new WalletException(new Error('Organization ID is required'));
|
|
320
|
+
}
|
|
321
|
+
return organizationId;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { BaseTurnkeyWalletStrategy } from './base.js';
|
|
2
|
+
import { ConcreteEthereumWalletStrategyArgs } from '@injectivelabs/wallet-base';
|
|
3
|
+
export declare class TurnkeyOauthWalletStrategy extends BaseTurnkeyWalletStrategy {
|
|
4
|
+
constructor(args: ConcreteEthereumWalletStrategyArgs);
|
|
5
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BaseTurnkeyWalletStrategy } from './base.js';
|
|
2
|
+
import { TurnkeyProvider, } from '@injectivelabs/wallet-base';
|
|
3
|
+
export class TurnkeyOauthWalletStrategy extends BaseTurnkeyWalletStrategy {
|
|
4
|
+
constructor(args) {
|
|
5
|
+
super({
|
|
6
|
+
...args,
|
|
7
|
+
provider: TurnkeyProvider.Google,
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { BaseTurnkeyWalletStrategy } from './base.js';
|
|
2
|
+
import { ConcreteEthereumWalletStrategyArgs } from '@injectivelabs/wallet-base';
|
|
3
|
+
export declare class TurnkeyOtpWalletStrategy extends BaseTurnkeyWalletStrategy {
|
|
4
|
+
constructor(args: ConcreteEthereumWalletStrategyArgs);
|
|
5
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BaseTurnkeyWalletStrategy } from './base.js';
|
|
2
|
+
import { TurnkeyProvider } from '@injectivelabs/wallet-base';
|
|
3
|
+
export class TurnkeyOtpWalletStrategy extends BaseTurnkeyWalletStrategy {
|
|
4
|
+
constructor(args) {
|
|
5
|
+
super({
|
|
6
|
+
...args,
|
|
7
|
+
provider: TurnkeyProvider.Email,
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { TurnkeyIframeClient } from '@turnkey/sdk-browser';
|
|
2
|
+
import { type HttpRestClient } from '@injectivelabs/utils';
|
|
3
|
+
export declare class TurnkeyOauthWallet {
|
|
4
|
+
static generateOAuthNonce(iframeClient: TurnkeyIframeClient): Promise<string>;
|
|
5
|
+
static oauthLogin(args: {
|
|
6
|
+
oidcToken: string;
|
|
7
|
+
client: HttpRestClient;
|
|
8
|
+
oauthLoginPath?: string;
|
|
9
|
+
expirationSeconds?: number;
|
|
10
|
+
providerName: 'google' | 'apple';
|
|
11
|
+
iframeClient: TurnkeyIframeClient;
|
|
12
|
+
}): Promise<{
|
|
13
|
+
organizationId: string;
|
|
14
|
+
credentialBundle: string;
|
|
15
|
+
} | undefined>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { ErrorType, WalletException, UnspecifiedErrorCode, } from '@injectivelabs/exceptions';
|
|
2
|
+
import { sha256 } from '@injectivelabs/sdk-ts';
|
|
3
|
+
import { TURNKEY_OAUTH_PATH } from '../consts.js';
|
|
4
|
+
export class TurnkeyOauthWallet {
|
|
5
|
+
static async generateOAuthNonce(iframeClient) {
|
|
6
|
+
try {
|
|
7
|
+
const targetPublicKey = iframeClient.iframePublicKey;
|
|
8
|
+
if (!targetPublicKey) {
|
|
9
|
+
throw new WalletException(new Error('Target public key not found'));
|
|
10
|
+
}
|
|
11
|
+
return Array.from(sha256(new TextEncoder().encode(targetPublicKey)))
|
|
12
|
+
.map((b) => b.toString(16).padStart(2, '0'))
|
|
13
|
+
.join('');
|
|
14
|
+
}
|
|
15
|
+
catch (e) {
|
|
16
|
+
throw new WalletException(new Error(e.message), {
|
|
17
|
+
code: UnspecifiedErrorCode,
|
|
18
|
+
type: ErrorType.WalletError,
|
|
19
|
+
contextModule: 'turnkey-generate-oauth-nonce',
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
static async oauthLogin(args) {
|
|
24
|
+
const { client, iframeClient } = args;
|
|
25
|
+
const path = args.oauthLoginPath || TURNKEY_OAUTH_PATH;
|
|
26
|
+
try {
|
|
27
|
+
const targetPublicKey = iframeClient.iframePublicKey;
|
|
28
|
+
if (!targetPublicKey) {
|
|
29
|
+
throw new WalletException(new Error('Target public key not found'));
|
|
30
|
+
}
|
|
31
|
+
// client.$post is undefined, resorting to this for now
|
|
32
|
+
const response = await client.post(path, {
|
|
33
|
+
targetPublicKey,
|
|
34
|
+
oidcToken: args.oidcToken,
|
|
35
|
+
providerName: args.providerName,
|
|
36
|
+
});
|
|
37
|
+
return response.data;
|
|
38
|
+
}
|
|
39
|
+
catch (e) {
|
|
40
|
+
throw new WalletException(new Error(e.message), {
|
|
41
|
+
code: UnspecifiedErrorCode,
|
|
42
|
+
type: ErrorType.WalletError,
|
|
43
|
+
contextModule: 'turnkey-oauth-login',
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type TurnkeyIframeClient } from '@turnkey/sdk-browser';
|
|
2
|
+
import { type TurnkeyConfirmEmailOTPResponse, type TurnkeyOTPCredentialsResponse } from './../types.js';
|
|
3
|
+
import { type HttpRestClient } from '@injectivelabs/utils';
|
|
4
|
+
export declare class TurnkeyOtpWallet {
|
|
5
|
+
static initEmailOTP(args: {
|
|
6
|
+
email: string;
|
|
7
|
+
subOrgId?: string;
|
|
8
|
+
otpInitPath?: string;
|
|
9
|
+
client: HttpRestClient;
|
|
10
|
+
iframeClient: TurnkeyIframeClient;
|
|
11
|
+
invalidateExistingSessions?: boolean;
|
|
12
|
+
}): Promise<TurnkeyOTPCredentialsResponse | undefined>;
|
|
13
|
+
static confirmEmailOTP(args: {
|
|
14
|
+
otpCode: string;
|
|
15
|
+
emailOTPId?: string;
|
|
16
|
+
client: HttpRestClient;
|
|
17
|
+
organizationId?: string;
|
|
18
|
+
iframeClient: TurnkeyIframeClient;
|
|
19
|
+
otpVerifyPath?: string;
|
|
20
|
+
}): Promise<TurnkeyConfirmEmailOTPResponse | undefined>;
|
|
21
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { ErrorType, WalletException, UnspecifiedErrorCode, } from '@injectivelabs/exceptions';
|
|
2
|
+
import { TURNKEY_OTP_INIT_PATH, TURNKEY_OTP_VERIFY_PATH } from '../consts.js';
|
|
3
|
+
export class TurnkeyOtpWallet {
|
|
4
|
+
static async initEmailOTP(args) {
|
|
5
|
+
const { client, iframeClient } = args;
|
|
6
|
+
try {
|
|
7
|
+
const targetPublicKey = iframeClient.iframePublicKey;
|
|
8
|
+
if (!targetPublicKey) {
|
|
9
|
+
throw new WalletException(new Error('Target public key not found'));
|
|
10
|
+
}
|
|
11
|
+
// client.$post is undefined, resorting to this for now
|
|
12
|
+
const response = await client.post(args.otpInitPath || TURNKEY_OTP_INIT_PATH, {
|
|
13
|
+
targetPublicKey,
|
|
14
|
+
email: args.email,
|
|
15
|
+
suborgId: args.subOrgId,
|
|
16
|
+
invalidateExistingSessions: args.invalidateExistingSessions,
|
|
17
|
+
});
|
|
18
|
+
return response?.data;
|
|
19
|
+
}
|
|
20
|
+
catch (e) {
|
|
21
|
+
throw new WalletException(new Error(e.message), {
|
|
22
|
+
code: UnspecifiedErrorCode,
|
|
23
|
+
type: ErrorType.WalletError,
|
|
24
|
+
contextModule: 'turnkey-init-email-otp',
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
static async confirmEmailOTP(args) {
|
|
29
|
+
const { client, iframeClient } = args;
|
|
30
|
+
try {
|
|
31
|
+
const organizationId = args.organizationId;
|
|
32
|
+
const emailOTPId = args.emailOTPId;
|
|
33
|
+
const targetPublicKey = iframeClient.iframePublicKey;
|
|
34
|
+
const otpVerifyPath = args.otpVerifyPath || TURNKEY_OTP_VERIFY_PATH;
|
|
35
|
+
if (!targetPublicKey) {
|
|
36
|
+
throw new WalletException(new Error('Target public key not found'));
|
|
37
|
+
}
|
|
38
|
+
if (!emailOTPId) {
|
|
39
|
+
throw new WalletException(new Error('Email OTP ID is required'));
|
|
40
|
+
}
|
|
41
|
+
if (!organizationId) {
|
|
42
|
+
throw new WalletException(new Error('Organization ID is required'));
|
|
43
|
+
}
|
|
44
|
+
const response = await client.post(otpVerifyPath, {
|
|
45
|
+
targetPublicKey,
|
|
46
|
+
otpId: emailOTPId,
|
|
47
|
+
otpCode: args.otpCode,
|
|
48
|
+
suborgID: organizationId,
|
|
49
|
+
});
|
|
50
|
+
return response?.data;
|
|
51
|
+
}
|
|
52
|
+
catch (e) {
|
|
53
|
+
throw new WalletException(new Error(e.message), {
|
|
54
|
+
code: UnspecifiedErrorCode,
|
|
55
|
+
type: ErrorType.WalletError,
|
|
56
|
+
contextModule: 'turnkey-confirm-email-otp',
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Turnkey, TurnkeyIframeClient } from '@turnkey/sdk-browser';
|
|
2
|
+
import { TurnkeyMetadata } from '@injectivelabs/wallet-base';
|
|
3
|
+
import { HttpRestClient } from '@injectivelabs/utils';
|
|
4
|
+
export declare class TurnkeyWallet {
|
|
5
|
+
protected iframeClient: TurnkeyIframeClient | undefined;
|
|
6
|
+
protected turnkey: Turnkey | undefined;
|
|
7
|
+
protected client: HttpRestClient;
|
|
8
|
+
private metadata;
|
|
9
|
+
private accountMap;
|
|
10
|
+
setMetadata(metadata: Partial<TurnkeyMetadata>): void;
|
|
11
|
+
constructor(metadata: TurnkeyMetadata);
|
|
12
|
+
static getTurnkeyInstance(metadata: TurnkeyMetadata): Promise<{
|
|
13
|
+
turnkey: Turnkey;
|
|
14
|
+
iframeClient: TurnkeyIframeClient;
|
|
15
|
+
}>;
|
|
16
|
+
getTurnkey(): Promise<Turnkey>;
|
|
17
|
+
getIframeClient(): Promise<TurnkeyIframeClient>;
|
|
18
|
+
getSession(existingCredentialBundle?: string): Promise<{
|
|
19
|
+
session: import("@turnkey/sdk-browser").Session | undefined;
|
|
20
|
+
organizationId: string;
|
|
21
|
+
}>;
|
|
22
|
+
getAccounts(): Promise<string[]>;
|
|
23
|
+
getOrCreateAndGetAccount(address: string, organizationId?: string): Promise<{
|
|
24
|
+
address: import("abitype").Address;
|
|
25
|
+
nonceManager?: import("viem").NonceManager | undefined;
|
|
26
|
+
sign?: ((parameters: {
|
|
27
|
+
hash: import("viem").Hash;
|
|
28
|
+
}) => Promise<import("viem").Hex>) | undefined | undefined;
|
|
29
|
+
signAuthorization?: ((parameters: import("node_modules/viem/_types/types/authorization.js").AuthorizationRequest) => Promise<import("viem/accounts").SignAuthorizationReturnType>) | undefined | undefined;
|
|
30
|
+
signMessage: ({ message }: {
|
|
31
|
+
message: import("viem").SignableMessage;
|
|
32
|
+
}) => Promise<import("viem").Hex>;
|
|
33
|
+
signTransaction: <serializer extends import("viem").SerializeTransactionFn<import("viem").TransactionSerializable> = import("viem").SerializeTransactionFn<import("viem").TransactionSerializable>, transaction extends Parameters<serializer>[0] = Parameters<serializer>[0]>(transaction: transaction, options?: {
|
|
34
|
+
serializer?: serializer | undefined;
|
|
35
|
+
} | undefined) => Promise<import("viem").IsNarrowable<import("viem").TransactionSerialized<import("viem").GetTransactionType<transaction>>, import("viem").Hex> extends true ? import("viem").TransactionSerialized<import("viem").GetTransactionType<transaction>> : import("viem").Hex>;
|
|
36
|
+
signTypedData: <const typedData extends import("abitype").TypedData | Record<string, unknown>, primaryType extends keyof typedData | "EIP712Domain" = keyof typedData>(parameters: import("viem").TypedDataDefinition<typedData, primaryType>) => Promise<import("viem").Hex>;
|
|
37
|
+
publicKey: import("viem").Hex;
|
|
38
|
+
source: string;
|
|
39
|
+
type: "local";
|
|
40
|
+
}>;
|
|
41
|
+
injectAndRefresh(credentialBundle: string): Promise<void>;
|
|
42
|
+
private initFrame;
|
|
43
|
+
}
|