@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
package/README.md
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# 🌟 Injective Protocol - Turnkey Wallet Strategy
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@injectivelabs/wallet-turnkey)
|
|
4
|
+
[](https://www.npmjs.com/package/@injectivelabs/wallet-turnkey)
|
|
5
|
+
[]()
|
|
6
|
+
|
|
7
|
+
_Package to use Turnkey Wallet on Injective via the wallet strategy._
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 📚 Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
yarn add @injectivelabs/wallet-turnkey
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 📖 Documentation
|
|
20
|
+
|
|
21
|
+
Injective's wallet packages are intended to make it easy for developers to choose exactly what wallets - and subsequent dependencies - they
|
|
22
|
+
want to include in their projects.
|
|
23
|
+
|
|
24
|
+
Regardless of which wallet package(s) you choose to use you must also have `@injectivelabs/wallet-core` and `@injectivelabs/wallet-base`
|
|
25
|
+
installed. These contain all of the types and core wallet functionality, with the separate wallet packages only providing the necessary
|
|
26
|
+
dependencies and implementations for their specific wallets.
|
|
27
|
+
|
|
28
|
+
Here's a brief example of how to use this package to send 1 INJ.:
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { Wallet } from '@injectivelabs/wallet-base';
|
|
32
|
+
import { BaseWalletStrategy, MsgBroadcaster } from '@injectivelabs/wallet-core';
|
|
33
|
+
import { TurnkeyWallet } from '@injectivelabs/wallet-turnkey';
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
const strategyArgs: WalletStrategyArguments = {
|
|
37
|
+
chainId: ChainId.Mainnet,
|
|
38
|
+
wallet: Wallet.Turnkey,
|
|
39
|
+
strategies: {
|
|
40
|
+
[Wallet.Turnkey]: new TurnkeyWallet({
|
|
41
|
+
onStatusChange(status) {
|
|
42
|
+
turnkeyStatus.value = status
|
|
43
|
+
},
|
|
44
|
+
chainId: injectiveClients.chainId,
|
|
45
|
+
ethereumOptions: {
|
|
46
|
+
ethereumChainId: injectiveClients.ethereumChainId!,
|
|
47
|
+
},
|
|
48
|
+
metadata: {
|
|
49
|
+
turnkeyAuthIframeContainerId,
|
|
50
|
+
defaultOrganizationId: import.meta.env
|
|
51
|
+
.VITE_TURNKEY_DEFAULT_ORGANIZATION_ID,
|
|
52
|
+
apiBaseUrl: 'https://api.turnkey.com',
|
|
53
|
+
},
|
|
54
|
+
})
|
|
55
|
+
},
|
|
56
|
+
}
|
|
57
|
+
const walletStrategy = new BaseWalletStrategy(strategyArgs)
|
|
58
|
+
|
|
59
|
+
const msgBroadcaster = new MsgBroadcaster({
|
|
60
|
+
walletStrategy,
|
|
61
|
+
simulateTx: true,
|
|
62
|
+
network: Network.Mainnet,
|
|
63
|
+
ethereumChainId: injectiveClients.ethereumChainId!,
|
|
64
|
+
endpoints: injectiveClients.endpoints,
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
const sendTX = async () => {
|
|
68
|
+
const injectiveAddress = 'someInjectiveAddress'
|
|
69
|
+
|
|
70
|
+
const message = MsgSend.fromJSON({
|
|
71
|
+
srcInjectiveAddress: injectiveAddress,
|
|
72
|
+
dstInjectiveAddress: injectiveAddress,
|
|
73
|
+
amount: {
|
|
74
|
+
amount: '1',
|
|
75
|
+
denom: 'inj',
|
|
76
|
+
},
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
return await msgBroadcaster.broadcast({ msgs: message })
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const result = await sendTX()
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Read more and find example usages on our [WalletStrategy Docs](https://docs.ts.injective.network/wallet/wallet-wallet-strategy)
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## 📜 Contribution
|
|
90
|
+
|
|
91
|
+
**Contribution guides and practices will be available once there is a stable foundation of the whole package set within the `injective-ts` repo.**
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## ⛑ Support
|
|
96
|
+
|
|
97
|
+
Reach out to us at one of the following places!
|
|
98
|
+
|
|
99
|
+
- Website at <a href="https://injective.com" target="_blank">`injective.com`</a>
|
|
100
|
+
- Twitter at <a href="https://twitter.com/Injective_" target="_blank">`@Injective`</a>
|
|
101
|
+
- Discord at <a href="https://discord.com/invite/NK4qdbv" target="_blank">`Discord`</a>
|
|
102
|
+
- Telegram at <a href="https://t.me/joininjective" target="_blank">`Telegram`</a>
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## 🔓 License
|
|
107
|
+
|
|
108
|
+
Copyright © 2021 - 2022 Injective Labs Inc. (https://injectivelabs.org/)
|
|
109
|
+
|
|
110
|
+
<a href="https://iili.io/mNneZN.md.png"><img src="https://iili.io/mNneZN.md.png" style="width: 300px; max-width: 100%; height: auto" />
|
|
111
|
+
|
|
112
|
+
Originally released by Injective Labs Inc. under: <br />
|
|
113
|
+
Apache License <br />
|
|
114
|
+
Version 2.0, January 2004 <br />
|
|
115
|
+
http://www.apache.org/licenses/
|
|
116
|
+
|
|
117
|
+
<p> </p>
|
|
118
|
+
<div align="center">
|
|
119
|
+
<sub><em>Powering the future of decentralized finance.</em></sub>
|
|
120
|
+
</div>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.TurnkeyOauthWalletStrategy = exports.TurnkeyOtpWalletStrategy = void 0;
|
|
18
|
+
var otp_js_1 = require("./strategy/strategy/otp.js");
|
|
19
|
+
Object.defineProperty(exports, "TurnkeyOtpWalletStrategy", { enumerable: true, get: function () { return otp_js_1.TurnkeyOtpWalletStrategy; } });
|
|
20
|
+
var oauth_js_1 = require("./strategy/strategy/oauth.js");
|
|
21
|
+
Object.defineProperty(exports, "TurnkeyOauthWalletStrategy", { enumerable: true, get: function () { return oauth_js_1.TurnkeyOauthWalletStrategy; } });
|
|
22
|
+
__exportStar(require("./strategy/strategy/base.js"), exports);
|
|
23
|
+
__exportStar(require("./strategy/turnkey/turnkey.js"), exports);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TURNKEY_OTP_VERIFY_PATH = exports.TURNKEY_OTP_INIT_PATH = exports.TURNKEY_OTP_PATH = exports.TURNKEY_OAUTH_PATH = void 0;
|
|
4
|
+
exports.TURNKEY_OAUTH_PATH = 'turnkey/oauth';
|
|
5
|
+
exports.TURNKEY_OTP_PATH = 'turnkey/otp';
|
|
6
|
+
exports.TURNKEY_OTP_INIT_PATH = `${exports.TURNKEY_OTP_PATH}/init`;
|
|
7
|
+
exports.TURNKEY_OTP_VERIFY_PATH = `${exports.TURNKEY_OTP_PATH}/verify`;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { TxRaw, AminoSignResponse, DirectSignResponse } from '@injectivelabs/sdk-ts';
|
|
2
|
+
import { HttpRestClient } from '@injectivelabs/utils';
|
|
3
|
+
import { AccountAddress, EthereumChainId } from '@injectivelabs/ts-types';
|
|
4
|
+
import { StdSignDoc, TurnkeyProvider, WalletDeviceType, type WalletMetadata, BaseConcreteStrategy, ConcreteWalletStrategy, SendTransactionOptions, ConcreteEthereumWalletStrategyArgs } from '@injectivelabs/wallet-base';
|
|
5
|
+
import { TurnkeyWallet } from '../turnkey/turnkey.js';
|
|
6
|
+
import { TurnkeyIframeClient } from '@turnkey/sdk-browser';
|
|
7
|
+
export declare class BaseTurnkeyWalletStrategy extends BaseConcreteStrategy implements ConcreteWalletStrategy {
|
|
8
|
+
turnkeyWallet: TurnkeyWallet | undefined;
|
|
9
|
+
turnkeyProvider: TurnkeyProvider;
|
|
10
|
+
client: HttpRestClient;
|
|
11
|
+
constructor(args: ConcreteEthereumWalletStrategyArgs & {
|
|
12
|
+
provider: TurnkeyProvider;
|
|
13
|
+
apiServerEndpoint?: string;
|
|
14
|
+
});
|
|
15
|
+
getWalletDeviceType(): Promise<WalletDeviceType>;
|
|
16
|
+
setMetadata(metadata?: {
|
|
17
|
+
turnkey?: Partial<WalletMetadata['turnkey']>;
|
|
18
|
+
}): void;
|
|
19
|
+
private setOrganizationId;
|
|
20
|
+
enable(): Promise<boolean>;
|
|
21
|
+
disconnect(): Promise<void>;
|
|
22
|
+
getAddresses(): Promise<string[]>;
|
|
23
|
+
getSessionOrConfirm(): Promise<string>;
|
|
24
|
+
sendEthereumTransaction(_transaction: unknown, _options: {
|
|
25
|
+
address: AccountAddress;
|
|
26
|
+
ethereumChainId: EthereumChainId;
|
|
27
|
+
}): Promise<string>;
|
|
28
|
+
sendTransaction(transaction: TxRaw, options: SendTransactionOptions): Promise<any>;
|
|
29
|
+
signEip712TypedData(eip712json: string, address: AccountAddress): Promise<string>;
|
|
30
|
+
signCosmosTransaction(_transaction: {
|
|
31
|
+
txRaw: TxRaw;
|
|
32
|
+
accountNumber: number;
|
|
33
|
+
chainId: string;
|
|
34
|
+
address: string;
|
|
35
|
+
}): Promise<DirectSignResponse>;
|
|
36
|
+
signAminoCosmosTransaction(_transaction: {
|
|
37
|
+
address: string;
|
|
38
|
+
signDoc: StdSignDoc;
|
|
39
|
+
}): Promise<AminoSignResponse>;
|
|
40
|
+
signArbitrary(_signer: AccountAddress, _data: string | Uint8Array): Promise<string>;
|
|
41
|
+
getEthereumChainId(): Promise<string>;
|
|
42
|
+
getEthereumTransactionReceipt(_txHash: string): Promise<string>;
|
|
43
|
+
getPubKey(): Promise<string>;
|
|
44
|
+
getIframeClient(): Promise<TurnkeyIframeClient>;
|
|
45
|
+
private getTurnkeyWallet;
|
|
46
|
+
private getOrganizationId;
|
|
47
|
+
}
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BaseTurnkeyWalletStrategy = void 0;
|
|
4
|
+
/* eslint-disable class-methods-use-this */
|
|
5
|
+
const exceptions_1 = require("@injectivelabs/exceptions");
|
|
6
|
+
const sdk_ts_1 = require("@injectivelabs/sdk-ts");
|
|
7
|
+
const utils_1 = require("@injectivelabs/utils");
|
|
8
|
+
const wallet_base_1 = require("@injectivelabs/wallet-base");
|
|
9
|
+
const turnkey_js_1 = require("../turnkey/turnkey.js");
|
|
10
|
+
const types_js_1 = require("../types.js");
|
|
11
|
+
const otp_js_1 = require("../turnkey/otp.js");
|
|
12
|
+
const oauth_js_1 = require("../turnkey/oauth.js");
|
|
13
|
+
const sdk_browser_1 = require("@turnkey/sdk-browser");
|
|
14
|
+
const viem_1 = require("viem");
|
|
15
|
+
const utils_js_1 = require("../../utils.js");
|
|
16
|
+
class BaseTurnkeyWalletStrategy extends wallet_base_1.BaseConcreteStrategy {
|
|
17
|
+
turnkeyWallet;
|
|
18
|
+
turnkeyProvider;
|
|
19
|
+
client;
|
|
20
|
+
constructor(args) {
|
|
21
|
+
super(args);
|
|
22
|
+
this.turnkeyProvider = args.provider;
|
|
23
|
+
const endpoint = args.apiServerEndpoint || this.metadata?.turnkey?.apiServerEndpoint;
|
|
24
|
+
if (!endpoint) {
|
|
25
|
+
throw new exceptions_1.WalletException(new Error('apiServerEndpoint is required'));
|
|
26
|
+
}
|
|
27
|
+
this.client = new utils_1.HttpRestClient(endpoint);
|
|
28
|
+
}
|
|
29
|
+
async getWalletDeviceType() {
|
|
30
|
+
return Promise.resolve(wallet_base_1.WalletDeviceType.Browser);
|
|
31
|
+
}
|
|
32
|
+
setMetadata(metadata) {
|
|
33
|
+
if (metadata?.turnkey) {
|
|
34
|
+
this.metadata = {
|
|
35
|
+
...this.metadata,
|
|
36
|
+
turnkey: {
|
|
37
|
+
...this.metadata?.turnkey,
|
|
38
|
+
...metadata.turnkey,
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//? This is here specifically because we have to ensure we set the organizationId on TurnkeyWallet as well
|
|
44
|
+
setOrganizationId(organizationId) {
|
|
45
|
+
this.setMetadata({ turnkey: { organizationId } });
|
|
46
|
+
this.turnkeyWallet?.setMetadata({ organizationId });
|
|
47
|
+
}
|
|
48
|
+
async enable() {
|
|
49
|
+
const turnkeyWallet = await this.getTurnkeyWallet();
|
|
50
|
+
try {
|
|
51
|
+
const session = await turnkeyWallet.getSession();
|
|
52
|
+
if (session.session) {
|
|
53
|
+
// User is already logged in, we don't need to do anything in the next steps
|
|
54
|
+
if (this.metadata?.turnkey) {
|
|
55
|
+
this.metadata.turnkey.session = session.session;
|
|
56
|
+
}
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
return !!(await turnkeyWallet.getIframeClient());
|
|
60
|
+
}
|
|
61
|
+
catch (e) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
async disconnect() {
|
|
66
|
+
const turnkeyWallet = await this.getTurnkeyWallet();
|
|
67
|
+
const turnkey = await turnkeyWallet.getTurnkey();
|
|
68
|
+
const isUserLoggedIn = await turnkey.getSession();
|
|
69
|
+
if (!isUserLoggedIn) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
await turnkey.logout();
|
|
73
|
+
}
|
|
74
|
+
async getAddresses() {
|
|
75
|
+
const turnkeyWallet = await this.getTurnkeyWallet();
|
|
76
|
+
const organizationId = await this.getOrganizationId();
|
|
77
|
+
// CHeck if the user is already connected
|
|
78
|
+
const session = await turnkeyWallet.getSession();
|
|
79
|
+
if (!session.session) {
|
|
80
|
+
const iframeClient = await turnkeyWallet.getIframeClient();
|
|
81
|
+
// Check the provider type and perform auth step accordingly
|
|
82
|
+
if (this.turnkeyProvider === wallet_base_1.TurnkeyProvider.Email) {
|
|
83
|
+
if (!this.metadata?.turnkey?.otpId) {
|
|
84
|
+
throw new exceptions_1.WalletException(new Error('OTP ID is required'));
|
|
85
|
+
}
|
|
86
|
+
if (!this.metadata?.turnkey?.otpCode) {
|
|
87
|
+
throw new exceptions_1.WalletException(new Error('OTP code is required'));
|
|
88
|
+
}
|
|
89
|
+
const result = await otp_js_1.TurnkeyOtpWallet.confirmEmailOTP({
|
|
90
|
+
iframeClient,
|
|
91
|
+
organizationId,
|
|
92
|
+
client: this.client,
|
|
93
|
+
otpCode: this.metadata?.turnkey?.otpCode,
|
|
94
|
+
emailOTPId: this.metadata?.turnkey?.otpId,
|
|
95
|
+
});
|
|
96
|
+
if (result?.credentialBundle) {
|
|
97
|
+
this.metadata.turnkey.credentialBundle = result.credentialBundle;
|
|
98
|
+
await turnkeyWallet.injectAndRefresh(result.credentialBundle);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
if (!this.metadata?.turnkey?.oidcToken) {
|
|
103
|
+
throw new exceptions_1.WalletException(new Error('Oidc token is required'));
|
|
104
|
+
}
|
|
105
|
+
const result = await oauth_js_1.TurnkeyOauthWallet.oauthLogin({
|
|
106
|
+
client: this.client,
|
|
107
|
+
iframeClient,
|
|
108
|
+
oidcToken: this.metadata?.turnkey?.oidcToken,
|
|
109
|
+
providerName: this.turnkeyProvider.toString(),
|
|
110
|
+
});
|
|
111
|
+
if (result?.credentialBundle) {
|
|
112
|
+
this.metadata.turnkey.organizationId = result.organizationId;
|
|
113
|
+
this.metadata.turnkey.credentialBundle = result.credentialBundle;
|
|
114
|
+
await turnkeyWallet.injectAndRefresh(result.credentialBundle);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
try {
|
|
119
|
+
return await turnkeyWallet.getAccounts();
|
|
120
|
+
}
|
|
121
|
+
catch (e) {
|
|
122
|
+
if (e.contextCode === types_js_1.TurnkeyErrorCodes.UserLoggedOut) {
|
|
123
|
+
await this.disconnect();
|
|
124
|
+
throw e;
|
|
125
|
+
}
|
|
126
|
+
throw new exceptions_1.WalletException(new Error(e.message), {
|
|
127
|
+
code: exceptions_1.UnspecifiedErrorCode,
|
|
128
|
+
type: exceptions_1.ErrorType.WalletError,
|
|
129
|
+
contextModule: wallet_base_1.WalletAction.GetAccounts,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
async getSessionOrConfirm() {
|
|
134
|
+
const { turnkeyProvider, metadata, client } = this;
|
|
135
|
+
const turnkeyWallet = await this.getTurnkeyWallet();
|
|
136
|
+
const iframeClient = await turnkeyWallet.getIframeClient();
|
|
137
|
+
const session = await turnkeyWallet.getSession();
|
|
138
|
+
if (
|
|
139
|
+
// If either of these values exist on the metadata, then we want to proceed with the login flow
|
|
140
|
+
!this.metadata?.turnkey?.email &&
|
|
141
|
+
!this.metadata?.turnkey?.oidcToken &&
|
|
142
|
+
session.session?.token) {
|
|
143
|
+
await iframeClient.injectCredentialBundle(session.session?.token);
|
|
144
|
+
this.setOrganizationId(session.organizationId);
|
|
145
|
+
await iframeClient.refreshSession({
|
|
146
|
+
sessionType: sdk_browser_1.SessionType.READ_WRITE,
|
|
147
|
+
targetPublicKey: iframeClient.iframePublicKey,
|
|
148
|
+
expirationSeconds: '900',
|
|
149
|
+
});
|
|
150
|
+
return session.session.token;
|
|
151
|
+
}
|
|
152
|
+
if (turnkeyProvider === wallet_base_1.TurnkeyProvider.Email) {
|
|
153
|
+
if (!metadata?.turnkey?.email) {
|
|
154
|
+
throw new exceptions_1.WalletException(new Error('Email is required'));
|
|
155
|
+
}
|
|
156
|
+
const result = await otp_js_1.TurnkeyOtpWallet.initEmailOTP({
|
|
157
|
+
client,
|
|
158
|
+
iframeClient,
|
|
159
|
+
email: metadata.turnkey.email,
|
|
160
|
+
otpInitPath: metadata.turnkey.otpInitPath,
|
|
161
|
+
});
|
|
162
|
+
if (result?.organizationId && this.metadata?.turnkey) {
|
|
163
|
+
this.metadata.turnkey.organizationId = result.organizationId;
|
|
164
|
+
}
|
|
165
|
+
if (result?.otpId && this.metadata?.turnkey) {
|
|
166
|
+
this.metadata.turnkey.otpId = result.otpId;
|
|
167
|
+
}
|
|
168
|
+
return result?.otpId || '';
|
|
169
|
+
}
|
|
170
|
+
if ([wallet_base_1.TurnkeyProvider.Google, wallet_base_1.TurnkeyProvider.Apple].includes(turnkeyProvider)) {
|
|
171
|
+
if (metadata?.turnkey?.oidcToken) {
|
|
172
|
+
const oauthResult = await oauth_js_1.TurnkeyOauthWallet.oauthLogin({
|
|
173
|
+
client,
|
|
174
|
+
iframeClient,
|
|
175
|
+
oidcToken: metadata.turnkey.oidcToken,
|
|
176
|
+
providerName: turnkeyProvider.toString(),
|
|
177
|
+
oauthLoginPath: metadata.turnkey.oauthLoginPath,
|
|
178
|
+
});
|
|
179
|
+
if (oauthResult?.credentialBundle) {
|
|
180
|
+
await turnkeyWallet.injectAndRefresh(oauthResult.credentialBundle);
|
|
181
|
+
}
|
|
182
|
+
if (oauthResult?.credentialBundle) {
|
|
183
|
+
const session = await turnkeyWallet.getSession();
|
|
184
|
+
if (this.metadata?.turnkey && session.organizationId) {
|
|
185
|
+
this.metadata.turnkey.organizationId = session.organizationId;
|
|
186
|
+
}
|
|
187
|
+
return oauthResult.credentialBundle;
|
|
188
|
+
}
|
|
189
|
+
throw new exceptions_1.WalletException(new Error('Oauth result not found'));
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
const nonce = await oauth_js_1.TurnkeyOauthWallet.generateOAuthNonce(iframeClient);
|
|
193
|
+
if (!metadata?.turnkey?.googleClientId ||
|
|
194
|
+
!metadata?.turnkey?.googleRedirectUri) {
|
|
195
|
+
throw new exceptions_1.WalletException(new Error('googleClientId and googleRedirectUri are required'));
|
|
196
|
+
}
|
|
197
|
+
if (turnkeyProvider === wallet_base_1.TurnkeyProvider.Google) {
|
|
198
|
+
return (0, utils_js_1.generateGoogleUrl)({
|
|
199
|
+
nonce,
|
|
200
|
+
clientId: metadata.turnkey.googleClientId,
|
|
201
|
+
redirectUri: metadata.turnkey.googleRedirectUri,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
//? When we add Apple support, we might also want to return the URL as well
|
|
205
|
+
return nonce;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return '';
|
|
209
|
+
}
|
|
210
|
+
async sendEthereumTransaction(_transaction, _options) {
|
|
211
|
+
throw new exceptions_1.WalletException(new Error('sendEthereumTransaction is not supported. Turnkey only supports sending cosmos transactions'), {
|
|
212
|
+
code: exceptions_1.UnspecifiedErrorCode,
|
|
213
|
+
context: wallet_base_1.WalletAction.SendEthereumTransaction,
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
async sendTransaction(transaction, options) {
|
|
217
|
+
const { endpoints, txTimeout } = options;
|
|
218
|
+
if (!endpoints) {
|
|
219
|
+
throw new exceptions_1.WalletException(new Error('You have to pass endpoints.grpc within the options for using Turnkey wallet'));
|
|
220
|
+
}
|
|
221
|
+
const txApi = new sdk_ts_1.TxGrpcApi(endpoints.grpc);
|
|
222
|
+
const response = await txApi.broadcast(transaction, { txTimeout });
|
|
223
|
+
if (response.code !== 0) {
|
|
224
|
+
throw new exceptions_1.TransactionException(new Error(response.rawLog), {
|
|
225
|
+
code: exceptions_1.UnspecifiedErrorCode,
|
|
226
|
+
contextCode: response.code,
|
|
227
|
+
contextModule: response.codespace,
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
return response;
|
|
231
|
+
}
|
|
232
|
+
async signEip712TypedData(eip712json, address) {
|
|
233
|
+
const turnkeyWallet = await this.getTurnkeyWallet();
|
|
234
|
+
const organizationId = await this.getOrganizationId();
|
|
235
|
+
//? Turnkey expects the case sensitive address and the current impl of getChecksumAddress from sdk-ts doesn't play nice with browser envs
|
|
236
|
+
const checksumAddress = (0, viem_1.getAddress)(address);
|
|
237
|
+
const account = await turnkeyWallet.getOrCreateAndGetAccount(checksumAddress, organizationId);
|
|
238
|
+
if (!account) {
|
|
239
|
+
throw new exceptions_1.WalletException(new Error('Turnkey account not found'));
|
|
240
|
+
}
|
|
241
|
+
let parsedData;
|
|
242
|
+
try {
|
|
243
|
+
parsedData = JSON.parse(eip712json);
|
|
244
|
+
}
|
|
245
|
+
catch (e) {
|
|
246
|
+
throw new exceptions_1.WalletException(new Error('Failed to parse EIP-712 data: Invalid JSON format'), {
|
|
247
|
+
code: exceptions_1.UnspecifiedErrorCode,
|
|
248
|
+
type: exceptions_1.ErrorType.WalletError,
|
|
249
|
+
contextModule: wallet_base_1.WalletAction.SignTransaction,
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
const signature = await account.signTypedData(parsedData);
|
|
253
|
+
return signature;
|
|
254
|
+
}
|
|
255
|
+
// eslint-disable-next-line class-methods-use-this
|
|
256
|
+
async signCosmosTransaction(_transaction) {
|
|
257
|
+
throw new exceptions_1.WalletException(new Error('This wallet does not support signing Cosmos transactions'), {
|
|
258
|
+
code: exceptions_1.UnspecifiedErrorCode,
|
|
259
|
+
type: exceptions_1.ErrorType.WalletError,
|
|
260
|
+
contextModule: wallet_base_1.WalletAction.SignTransaction,
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
async signAminoCosmosTransaction(_transaction) {
|
|
264
|
+
throw new exceptions_1.WalletException(new Error('This wallet does not support signAminoCosmosTransaction'), {
|
|
265
|
+
code: exceptions_1.UnspecifiedErrorCode,
|
|
266
|
+
type: exceptions_1.ErrorType.WalletError,
|
|
267
|
+
contextModule: wallet_base_1.WalletAction.SignTransaction,
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
async signArbitrary(_signer, _data) {
|
|
271
|
+
throw new exceptions_1.WalletException(new Error('This wallet does not support signArbitrary'), {
|
|
272
|
+
code: exceptions_1.UnspecifiedErrorCode,
|
|
273
|
+
type: exceptions_1.ErrorType.WalletError,
|
|
274
|
+
contextModule: wallet_base_1.WalletAction.SignTransaction,
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
async getEthereumChainId() {
|
|
278
|
+
throw new exceptions_1.CosmosWalletException(new Error('getEthereumChainId is not supported on Turnkey wallet'), {
|
|
279
|
+
code: exceptions_1.UnspecifiedErrorCode,
|
|
280
|
+
context: wallet_base_1.WalletAction.GetChainId,
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
async getEthereumTransactionReceipt(_txHash) {
|
|
284
|
+
throw new exceptions_1.CosmosWalletException(new Error('getEthereumTransactionReceipt is not supported on Turnkey'), {
|
|
285
|
+
code: exceptions_1.UnspecifiedErrorCode,
|
|
286
|
+
type: exceptions_1.ErrorType.WalletError,
|
|
287
|
+
context: wallet_base_1.WalletAction.GetEthereumTransactionReceipt,
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
// eslint-disable-next-line class-methods-use-this
|
|
291
|
+
async getPubKey() {
|
|
292
|
+
throw new exceptions_1.WalletException(new Error('You can only fetch PubKey from Cosmos native wallets'));
|
|
293
|
+
}
|
|
294
|
+
async getIframeClient() {
|
|
295
|
+
const turnkeyWallet = await this.getTurnkeyWallet();
|
|
296
|
+
return turnkeyWallet.getIframeClient();
|
|
297
|
+
}
|
|
298
|
+
async getTurnkeyWallet() {
|
|
299
|
+
const { metadata } = this;
|
|
300
|
+
if (!this.turnkeyWallet) {
|
|
301
|
+
if (!metadata?.turnkey) {
|
|
302
|
+
throw new exceptions_1.WalletException(new Error('Turnkey metadata is required'));
|
|
303
|
+
}
|
|
304
|
+
if (!metadata.turnkey.apiBaseUrl) {
|
|
305
|
+
throw new exceptions_1.WalletException(new Error('Turnkey apiBaseUrl is required'));
|
|
306
|
+
}
|
|
307
|
+
if (!metadata.turnkey.apiServerEndpoint) {
|
|
308
|
+
throw new exceptions_1.WalletException(new Error('Turnkey apiServerEndpoint is required'));
|
|
309
|
+
}
|
|
310
|
+
if (!metadata.turnkey.defaultOrganizationId) {
|
|
311
|
+
throw new exceptions_1.WalletException(new Error('Turnkey defaultOrganizationId is required'));
|
|
312
|
+
}
|
|
313
|
+
this.turnkeyWallet = new turnkey_js_1.TurnkeyWallet(metadata.turnkey);
|
|
314
|
+
}
|
|
315
|
+
return this.turnkeyWallet;
|
|
316
|
+
}
|
|
317
|
+
async getOrganizationId() {
|
|
318
|
+
const { metadata } = this;
|
|
319
|
+
const organizationId = metadata?.turnkey?.organizationId ||
|
|
320
|
+
metadata?.turnkey?.defaultOrganizationId;
|
|
321
|
+
if (!organizationId) {
|
|
322
|
+
throw new exceptions_1.WalletException(new Error('Organization ID is required'));
|
|
323
|
+
}
|
|
324
|
+
return organizationId;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
exports.BaseTurnkeyWalletStrategy = BaseTurnkeyWalletStrategy;
|
|
@@ -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,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TurnkeyOauthWalletStrategy = void 0;
|
|
4
|
+
const base_js_1 = require("./base.js");
|
|
5
|
+
const wallet_base_1 = require("@injectivelabs/wallet-base");
|
|
6
|
+
class TurnkeyOauthWalletStrategy extends base_js_1.BaseTurnkeyWalletStrategy {
|
|
7
|
+
constructor(args) {
|
|
8
|
+
super({
|
|
9
|
+
...args,
|
|
10
|
+
provider: wallet_base_1.TurnkeyProvider.Google,
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
exports.TurnkeyOauthWalletStrategy = TurnkeyOauthWalletStrategy;
|
|
@@ -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,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TurnkeyOtpWalletStrategy = void 0;
|
|
4
|
+
const base_js_1 = require("./base.js");
|
|
5
|
+
const wallet_base_1 = require("@injectivelabs/wallet-base");
|
|
6
|
+
class TurnkeyOtpWalletStrategy extends base_js_1.BaseTurnkeyWalletStrategy {
|
|
7
|
+
constructor(args) {
|
|
8
|
+
super({
|
|
9
|
+
...args,
|
|
10
|
+
provider: wallet_base_1.TurnkeyProvider.Email,
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
exports.TurnkeyOtpWalletStrategy = TurnkeyOtpWalletStrategy;
|
|
@@ -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,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TurnkeyOauthWallet = void 0;
|
|
4
|
+
const exceptions_1 = require("@injectivelabs/exceptions");
|
|
5
|
+
const sdk_ts_1 = require("@injectivelabs/sdk-ts");
|
|
6
|
+
const consts_js_1 = require("../consts.js");
|
|
7
|
+
class TurnkeyOauthWallet {
|
|
8
|
+
static async generateOAuthNonce(iframeClient) {
|
|
9
|
+
try {
|
|
10
|
+
const targetPublicKey = iframeClient.iframePublicKey;
|
|
11
|
+
if (!targetPublicKey) {
|
|
12
|
+
throw new exceptions_1.WalletException(new Error('Target public key not found'));
|
|
13
|
+
}
|
|
14
|
+
return Array.from((0, sdk_ts_1.sha256)(new TextEncoder().encode(targetPublicKey)))
|
|
15
|
+
.map((b) => b.toString(16).padStart(2, '0'))
|
|
16
|
+
.join('');
|
|
17
|
+
}
|
|
18
|
+
catch (e) {
|
|
19
|
+
throw new exceptions_1.WalletException(new Error(e.message), {
|
|
20
|
+
code: exceptions_1.UnspecifiedErrorCode,
|
|
21
|
+
type: exceptions_1.ErrorType.WalletError,
|
|
22
|
+
contextModule: 'turnkey-generate-oauth-nonce',
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
static async oauthLogin(args) {
|
|
27
|
+
const { client, iframeClient } = args;
|
|
28
|
+
const path = args.oauthLoginPath || consts_js_1.TURNKEY_OAUTH_PATH;
|
|
29
|
+
try {
|
|
30
|
+
const targetPublicKey = iframeClient.iframePublicKey;
|
|
31
|
+
if (!targetPublicKey) {
|
|
32
|
+
throw new exceptions_1.WalletException(new Error('Target public key not found'));
|
|
33
|
+
}
|
|
34
|
+
// client.$post is undefined, resorting to this for now
|
|
35
|
+
const response = await client.post(path, {
|
|
36
|
+
targetPublicKey,
|
|
37
|
+
oidcToken: args.oidcToken,
|
|
38
|
+
providerName: args.providerName,
|
|
39
|
+
});
|
|
40
|
+
return response.data;
|
|
41
|
+
}
|
|
42
|
+
catch (e) {
|
|
43
|
+
throw new exceptions_1.WalletException(new Error(e.message), {
|
|
44
|
+
code: exceptions_1.UnspecifiedErrorCode,
|
|
45
|
+
type: exceptions_1.ErrorType.WalletError,
|
|
46
|
+
contextModule: 'turnkey-oauth-login',
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exports.TurnkeyOauthWallet = TurnkeyOauthWallet;
|