@injectivelabs/wallet-ledger 1.15.0 → 1.15.2
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.d.ts +4 -0
- package/dist/cjs/index.js +24 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/strategy/Ledger/Base.d.ts +42 -0
- package/dist/cjs/strategy/Ledger/Base.js +245 -0
- package/dist/cjs/strategy/Ledger/LedgerLegacy.d.ts +5 -0
- package/dist/cjs/strategy/Ledger/LedgerLegacy.js +17 -0
- package/dist/cjs/strategy/Ledger/LedgerLive.d.ts +5 -0
- package/dist/cjs/strategy/Ledger/LedgerLive.js +17 -0
- package/dist/cjs/strategy/Ledger/hw/AccountManager.d.ts +21 -0
- package/dist/cjs/strategy/Ledger/hw/AccountManager.js +91 -0
- package/dist/cjs/strategy/Ledger/hw/index.d.ts +11 -0
- package/dist/cjs/strategy/Ledger/hw/index.js +65 -0
- package/dist/cjs/strategy/Ledger/utils.d.ts +2 -0
- package/dist/cjs/strategy/Ledger/utils.js +8 -0
- package/dist/cjs/strategy/LedgerCosmos/hw/AccountManager.d.ts +20 -0
- package/dist/cjs/strategy/LedgerCosmos/hw/AccountManager.js +69 -0
- package/dist/cjs/strategy/LedgerCosmos/hw/index.d.ts +11 -0
- package/dist/cjs/strategy/LedgerCosmos/hw/index.js +48 -0
- package/dist/cjs/strategy/LedgerCosmos/index.d.ts +36 -0
- package/dist/cjs/strategy/LedgerCosmos/index.js +159 -0
- package/dist/cjs/types.d.ts +17 -0
- package/dist/cjs/types.js +14 -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/Ledger/Base.d.ts +42 -0
- package/dist/esm/strategy/Ledger/Base.js +239 -0
- package/dist/esm/strategy/Ledger/LedgerLegacy.d.ts +5 -0
- package/dist/esm/strategy/Ledger/LedgerLegacy.js +10 -0
- package/dist/esm/strategy/Ledger/LedgerLive.d.ts +5 -0
- package/dist/esm/strategy/Ledger/LedgerLive.js +10 -0
- package/dist/esm/strategy/Ledger/hw/AccountManager.d.ts +21 -0
- package/dist/esm/strategy/Ledger/hw/AccountManager.js +85 -0
- package/dist/esm/strategy/Ledger/hw/index.d.ts +11 -0
- package/dist/esm/strategy/Ledger/hw/index.js +59 -0
- package/dist/esm/strategy/Ledger/utils.d.ts +2 -0
- package/dist/esm/strategy/Ledger/utils.js +3 -0
- package/dist/esm/strategy/LedgerCosmos/hw/AccountManager.d.ts +20 -0
- package/dist/esm/strategy/LedgerCosmos/hw/AccountManager.js +66 -0
- package/dist/esm/strategy/LedgerCosmos/hw/index.d.ts +11 -0
- package/dist/esm/strategy/LedgerCosmos/hw/index.js +42 -0
- package/dist/esm/strategy/LedgerCosmos/index.d.ts +36 -0
- package/dist/esm/strategy/LedgerCosmos/index.js +152 -0
- package/dist/esm/types.d.ts +17 -0
- package/dist/esm/types.js +11 -0
- package/package.json +6 -6
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { LedgerLive as LedgerLiveStrategy } from './strategy/Ledger/LedgerLive.js';
|
|
2
|
+
export { LedgerLegacy as LedgerLegacyStrategy } from './strategy/Ledger/LedgerLegacy.js';
|
|
3
|
+
export { LedgerCosmos as LedgerCosmosStrategy } from './strategy/LedgerCosmos/index.js';
|
|
4
|
+
export * from './types.js';
|
|
@@ -0,0 +1,24 @@
|
|
|
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.LedgerCosmosStrategy = exports.LedgerLegacyStrategy = exports.LedgerLiveStrategy = void 0;
|
|
18
|
+
var LedgerLive_js_1 = require("./strategy/Ledger/LedgerLive.js");
|
|
19
|
+
Object.defineProperty(exports, "LedgerLiveStrategy", { enumerable: true, get: function () { return LedgerLive_js_1.LedgerLive; } });
|
|
20
|
+
var LedgerLegacy_js_1 = require("./strategy/Ledger/LedgerLegacy.js");
|
|
21
|
+
Object.defineProperty(exports, "LedgerLegacyStrategy", { enumerable: true, get: function () { return LedgerLegacy_js_1.LedgerLegacy; } });
|
|
22
|
+
var index_js_1 = require("./strategy/LedgerCosmos/index.js");
|
|
23
|
+
Object.defineProperty(exports, "LedgerCosmosStrategy", { enumerable: true, get: function () { return index_js_1.LedgerCosmos; } });
|
|
24
|
+
__exportStar(require("./types.js"), exports);
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { AccountAddress, EthereumChainId } from '@injectivelabs/ts-types';
|
|
2
|
+
import { TxRaw, TxResponse, DirectSignResponse, AminoSignResponse } from '@injectivelabs/sdk-ts';
|
|
3
|
+
import { StdSignDoc, WalletDeviceType, BaseConcreteStrategy, SendTransactionOptions, ConcreteWalletStrategy, ConcreteEthereumWalletStrategyArgs } from '@injectivelabs/wallet-base';
|
|
4
|
+
import { LedgerDerivationPathType } from '../../types.js';
|
|
5
|
+
export default class LedgerBase extends BaseConcreteStrategy implements ConcreteWalletStrategy {
|
|
6
|
+
private baseDerivationPath;
|
|
7
|
+
private derivationPathType;
|
|
8
|
+
private ledger;
|
|
9
|
+
private ethereumOptions;
|
|
10
|
+
private alchemy;
|
|
11
|
+
constructor(args: ConcreteEthereumWalletStrategyArgs & {
|
|
12
|
+
derivationPathType: LedgerDerivationPathType;
|
|
13
|
+
});
|
|
14
|
+
getWalletDeviceType(): Promise<WalletDeviceType>;
|
|
15
|
+
enable(): Promise<boolean>;
|
|
16
|
+
disconnect(): Promise<void>;
|
|
17
|
+
getAddresses(): Promise<string[]>;
|
|
18
|
+
getSessionOrConfirm(address: AccountAddress): Promise<string>;
|
|
19
|
+
sendEthereumTransaction(txData: any, options: {
|
|
20
|
+
address: string;
|
|
21
|
+
ethereumChainId: EthereumChainId;
|
|
22
|
+
}): Promise<string>;
|
|
23
|
+
sendTransaction(transaction: TxRaw, options: SendTransactionOptions): Promise<TxResponse>;
|
|
24
|
+
signEip712TypedData(eip712json: string, address: AccountAddress): Promise<string>;
|
|
25
|
+
signAminoCosmosTransaction(_transaction: {
|
|
26
|
+
address: string;
|
|
27
|
+
signDoc: StdSignDoc;
|
|
28
|
+
}): Promise<AminoSignResponse>;
|
|
29
|
+
signCosmosTransaction(_transaction: {
|
|
30
|
+
txRaw: TxRaw;
|
|
31
|
+
accountNumber: number;
|
|
32
|
+
chainId: string;
|
|
33
|
+
address: string;
|
|
34
|
+
}): Promise<DirectSignResponse>;
|
|
35
|
+
signArbitrary(signer: AccountAddress, data: string | Uint8Array): Promise<string>;
|
|
36
|
+
getEthereumChainId(): Promise<string>;
|
|
37
|
+
getEthereumTransactionReceipt(txHash: string): Promise<string>;
|
|
38
|
+
getPubKey(): Promise<string>;
|
|
39
|
+
private signEthereumTransaction;
|
|
40
|
+
private getWalletForAddress;
|
|
41
|
+
private getAlchemy;
|
|
42
|
+
}
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
/* eslint-disable class-methods-use-this */
|
|
7
|
+
const ts_types_1 = require("@injectivelabs/ts-types");
|
|
8
|
+
const ethereumjs_util_1 = require("ethereumjs-util");
|
|
9
|
+
const common_1 = require("@ethereumjs/common");
|
|
10
|
+
const tx_1 = require("@ethereumjs/tx");
|
|
11
|
+
const ledgerhq_hw_app_eth_1 = require("@bangjelkoski/ledgerhq-hw-app-eth");
|
|
12
|
+
const exceptions_1 = require("@injectivelabs/exceptions");
|
|
13
|
+
const sdk_ts_1 = require("@injectivelabs/sdk-ts");
|
|
14
|
+
const wallet_base_1 = require("@injectivelabs/wallet-base");
|
|
15
|
+
const index_js_1 = __importDefault(require("./hw/index.js"));
|
|
16
|
+
const utils_js_1 = require("./utils.js");
|
|
17
|
+
const alchemy_sdk_1 = require("alchemy-sdk");
|
|
18
|
+
const getNetworkFromChainId = (chainId) => {
|
|
19
|
+
if (chainId === ts_types_1.EthereumChainId.Goerli) {
|
|
20
|
+
return common_1.Chain.Goerli;
|
|
21
|
+
}
|
|
22
|
+
if (chainId === ts_types_1.EthereumChainId.Sepolia) {
|
|
23
|
+
return common_1.Chain.Sepolia;
|
|
24
|
+
}
|
|
25
|
+
if (chainId === ts_types_1.EthereumChainId.Kovan) {
|
|
26
|
+
return common_1.Chain.Goerli;
|
|
27
|
+
}
|
|
28
|
+
return common_1.Chain.Mainnet;
|
|
29
|
+
};
|
|
30
|
+
class LedgerBase extends wallet_base_1.BaseConcreteStrategy {
|
|
31
|
+
baseDerivationPath;
|
|
32
|
+
derivationPathType;
|
|
33
|
+
ledger;
|
|
34
|
+
ethereumOptions;
|
|
35
|
+
alchemy;
|
|
36
|
+
constructor(args) {
|
|
37
|
+
super(args);
|
|
38
|
+
this.baseDerivationPath = wallet_base_1.DEFAULT_BASE_DERIVATION_PATH;
|
|
39
|
+
this.derivationPathType = args.derivationPathType;
|
|
40
|
+
this.ledger = new index_js_1.default();
|
|
41
|
+
this.ethereumOptions = args.ethereumOptions;
|
|
42
|
+
}
|
|
43
|
+
async getWalletDeviceType() {
|
|
44
|
+
return Promise.resolve(wallet_base_1.WalletDeviceType.Hardware);
|
|
45
|
+
}
|
|
46
|
+
async enable() {
|
|
47
|
+
return Promise.resolve(true);
|
|
48
|
+
}
|
|
49
|
+
async disconnect() {
|
|
50
|
+
this.ledger = await this.ledger.refresh();
|
|
51
|
+
}
|
|
52
|
+
async getAddresses() {
|
|
53
|
+
const { baseDerivationPath, derivationPathType } = this;
|
|
54
|
+
try {
|
|
55
|
+
const accountManager = await this.ledger.getAccountManager();
|
|
56
|
+
const wallets = await accountManager.getWallets(baseDerivationPath, derivationPathType);
|
|
57
|
+
return wallets.map((k) => k.address);
|
|
58
|
+
}
|
|
59
|
+
catch (e) {
|
|
60
|
+
throw new exceptions_1.LedgerException(new Error(e.message), {
|
|
61
|
+
code: exceptions_1.UnspecifiedErrorCode,
|
|
62
|
+
type: exceptions_1.ErrorType.WalletError,
|
|
63
|
+
contextModule: wallet_base_1.WalletAction.GetAccounts,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
async getSessionOrConfirm(address) {
|
|
68
|
+
return Promise.resolve(`0x${Buffer.from(`Confirmation for ${address} at time: ${Date.now()}`).toString('hex')}`);
|
|
69
|
+
}
|
|
70
|
+
async sendEthereumTransaction(txData, options) {
|
|
71
|
+
const signedTransaction = await this.signEthereumTransaction(txData, options);
|
|
72
|
+
try {
|
|
73
|
+
const alchemy = await this.getAlchemy();
|
|
74
|
+
const txReceipt = await alchemy.core.sendTransaction((0, ethereumjs_util_1.addHexPrefix)(signedTransaction.serialize().toString('hex')));
|
|
75
|
+
return txReceipt.hash;
|
|
76
|
+
}
|
|
77
|
+
catch (e) {
|
|
78
|
+
throw new exceptions_1.LedgerException(new Error(e.message), {
|
|
79
|
+
code: exceptions_1.UnspecifiedErrorCode,
|
|
80
|
+
type: exceptions_1.ErrorType.WalletError,
|
|
81
|
+
contextModule: wallet_base_1.WalletAction.SendEthereumTransaction,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
async sendTransaction(transaction, options) {
|
|
86
|
+
const { endpoints, txTimeout } = options;
|
|
87
|
+
if (!endpoints) {
|
|
88
|
+
throw new exceptions_1.WalletException(new Error('You have to pass endpoints.grpc within the options for using Ethereum native wallets'));
|
|
89
|
+
}
|
|
90
|
+
const txApi = new sdk_ts_1.TxGrpcApi(endpoints.grpc);
|
|
91
|
+
const response = await txApi.broadcast(transaction, { txTimeout });
|
|
92
|
+
if (response.code !== 0) {
|
|
93
|
+
throw new exceptions_1.TransactionException(new Error(response.rawLog), {
|
|
94
|
+
code: exceptions_1.UnspecifiedErrorCode,
|
|
95
|
+
contextCode: response.code,
|
|
96
|
+
contextModule: response.codespace,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
return response;
|
|
100
|
+
}
|
|
101
|
+
async signEip712TypedData(eip712json, address) {
|
|
102
|
+
const { derivationPath } = await this.getWalletForAddress(address);
|
|
103
|
+
const object = JSON.parse(eip712json);
|
|
104
|
+
try {
|
|
105
|
+
const ledger = await this.ledger.getInstance();
|
|
106
|
+
const result = await ledger.signEIP712HashedMessage(derivationPath, (0, ethereumjs_util_1.bufferToHex)((0, utils_js_1.domainHash)(object)), (0, ethereumjs_util_1.bufferToHex)((0, utils_js_1.messageHash)(object)));
|
|
107
|
+
const combined = `${result.r}${result.s}${result.v.toString(16)}`;
|
|
108
|
+
return combined.startsWith('0x') ? combined : `0x${combined}`;
|
|
109
|
+
}
|
|
110
|
+
catch (e) {
|
|
111
|
+
throw new exceptions_1.LedgerException(new Error(e.message), {
|
|
112
|
+
code: exceptions_1.UnspecifiedErrorCode,
|
|
113
|
+
type: exceptions_1.ErrorType.WalletError,
|
|
114
|
+
contextModule: wallet_base_1.WalletAction.SignTransaction,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
async signAminoCosmosTransaction(_transaction) {
|
|
119
|
+
throw new exceptions_1.WalletException(new Error('This wallet does not support signing Cosmos transactions'), {
|
|
120
|
+
code: exceptions_1.UnspecifiedErrorCode,
|
|
121
|
+
type: exceptions_1.ErrorType.WalletError,
|
|
122
|
+
contextModule: wallet_base_1.WalletAction.SendTransaction,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
// eslint-disable-next-line class-methods-use-this
|
|
126
|
+
async signCosmosTransaction(_transaction) {
|
|
127
|
+
throw new exceptions_1.WalletException(new Error('This wallet does not support signing Cosmos transactions'), {
|
|
128
|
+
code: exceptions_1.UnspecifiedErrorCode,
|
|
129
|
+
type: exceptions_1.ErrorType.WalletError,
|
|
130
|
+
contextModule: wallet_base_1.WalletAction.SendTransaction,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
async signArbitrary(signer, data) {
|
|
134
|
+
try {
|
|
135
|
+
const { derivationPath } = await this.getWalletForAddress(signer);
|
|
136
|
+
const ledger = await this.ledger.getInstance();
|
|
137
|
+
const result = await ledger.signPersonalMessage(derivationPath, Buffer.from((0, sdk_ts_1.toUtf8)(data), 'utf8').toString('hex'));
|
|
138
|
+
const combined = `${result.r}${result.s}${result.v.toString(16)}`;
|
|
139
|
+
return combined.startsWith('0x') ? combined : `0x${combined}`;
|
|
140
|
+
}
|
|
141
|
+
catch (e) {
|
|
142
|
+
throw new exceptions_1.LedgerException(new Error(e.message), {
|
|
143
|
+
code: exceptions_1.UnspecifiedErrorCode,
|
|
144
|
+
type: exceptions_1.ErrorType.WalletError,
|
|
145
|
+
contextModule: wallet_base_1.WalletAction.SignTransaction,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
async getEthereumChainId() {
|
|
150
|
+
const alchemy = await this.getAlchemy();
|
|
151
|
+
const alchemyProvider = await alchemy.config.getProvider();
|
|
152
|
+
return alchemyProvider.network.chainId.toString();
|
|
153
|
+
}
|
|
154
|
+
async getEthereumTransactionReceipt(txHash) {
|
|
155
|
+
return Promise.resolve(txHash);
|
|
156
|
+
}
|
|
157
|
+
// eslint-disable-next-line class-methods-use-this
|
|
158
|
+
async getPubKey() {
|
|
159
|
+
throw new exceptions_1.WalletException(new Error('You can only fetch PubKey from Cosmos native wallets'));
|
|
160
|
+
}
|
|
161
|
+
async signEthereumTransaction(txData, options) {
|
|
162
|
+
const alchemy = await this.getAlchemy();
|
|
163
|
+
const chainId = parseInt(options.ethereumChainId.toString(), 10);
|
|
164
|
+
const nonce = await alchemy.core.getTransactionCount(options.address);
|
|
165
|
+
const common = new common_1.Common({
|
|
166
|
+
chain: getNetworkFromChainId(chainId),
|
|
167
|
+
hardfork: common_1.Hardfork.London,
|
|
168
|
+
});
|
|
169
|
+
const eip1559TxData = {
|
|
170
|
+
from: txData.from,
|
|
171
|
+
data: txData.data,
|
|
172
|
+
to: txData.to,
|
|
173
|
+
nonce: (0, ethereumjs_util_1.addHexPrefix)(nonce.toString(16)),
|
|
174
|
+
gas: (0, ethereumjs_util_1.addHexPrefix)(txData.gas),
|
|
175
|
+
gasLimit: (0, ethereumjs_util_1.addHexPrefix)(txData.gas),
|
|
176
|
+
maxFeePerGas: (0, ethereumjs_util_1.addHexPrefix)(txData.gasPrice || txData.maxFeePerGas),
|
|
177
|
+
maxPriorityFeePerGas: (0, ethereumjs_util_1.addHexPrefix)(txData.maxPriorityFeePerGas || wallet_base_1.TIP_IN_GWEI.toString(16)),
|
|
178
|
+
};
|
|
179
|
+
const tx = tx_1.FeeMarketEIP1559Transaction.fromTxData(eip1559TxData, { common });
|
|
180
|
+
const msg = tx.getMessageToSign(false);
|
|
181
|
+
// const encodedMessage = msg
|
|
182
|
+
const encodedMessageHex = msg.toString('hex');
|
|
183
|
+
try {
|
|
184
|
+
const ledger = await this.ledger.getInstance();
|
|
185
|
+
const { derivationPath } = await this.getWalletForAddress(options.address);
|
|
186
|
+
const resolution = await ledgerhq_hw_app_eth_1.ledgerService.resolveTransaction(encodedMessageHex, {}, {});
|
|
187
|
+
const txSig = await ledger.signTransaction(derivationPath, encodedMessageHex, resolution);
|
|
188
|
+
const signedTxData = {
|
|
189
|
+
...eip1559TxData,
|
|
190
|
+
v: `0x${txSig.v}`,
|
|
191
|
+
r: `0x${txSig.r}`,
|
|
192
|
+
s: `0x${txSig.s}`,
|
|
193
|
+
};
|
|
194
|
+
return tx_1.FeeMarketEIP1559Transaction.fromTxData(signedTxData, {
|
|
195
|
+
common,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
catch (e) {
|
|
199
|
+
throw new exceptions_1.LedgerException(new Error(e.message), {
|
|
200
|
+
code: exceptions_1.UnspecifiedErrorCode,
|
|
201
|
+
type: exceptions_1.ErrorType.WalletError,
|
|
202
|
+
contextModule: wallet_base_1.WalletAction.SignEthereumTransaction,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
async getWalletForAddress(address) {
|
|
207
|
+
try {
|
|
208
|
+
const { baseDerivationPath, derivationPathType } = this;
|
|
209
|
+
const accountManager = await this.ledger.getAccountManager();
|
|
210
|
+
if (!accountManager.hasWalletForAddress(address)) {
|
|
211
|
+
for (let i = 0; i < wallet_base_1.DEFAULT_ADDRESS_SEARCH_LIMIT / wallet_base_1.DEFAULT_NUM_ADDRESSES_TO_FETCH; i += 1) {
|
|
212
|
+
await accountManager.getWallets(baseDerivationPath, derivationPathType);
|
|
213
|
+
if (accountManager.hasWalletForAddress(address)) {
|
|
214
|
+
return (await accountManager.getWalletForAddress(address));
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return (await accountManager.getWalletForAddress(address));
|
|
219
|
+
}
|
|
220
|
+
catch (e) {
|
|
221
|
+
throw new exceptions_1.LedgerException(new Error(e.message), {
|
|
222
|
+
code: exceptions_1.UnspecifiedErrorCode,
|
|
223
|
+
type: exceptions_1.ErrorType.WalletError,
|
|
224
|
+
contextModule: wallet_base_1.WalletAction.GetAccounts,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
async getAlchemy() {
|
|
229
|
+
if (this.alchemy) {
|
|
230
|
+
return this.alchemy;
|
|
231
|
+
}
|
|
232
|
+
const { rpcUrl, ethereumChainId } = this.ethereumOptions;
|
|
233
|
+
if (!rpcUrl) {
|
|
234
|
+
throw new exceptions_1.GeneralException(new Error('Please pass rpcUrl within the ethereumOptions'));
|
|
235
|
+
}
|
|
236
|
+
this.alchemy = new alchemy_sdk_1.Alchemy({
|
|
237
|
+
apiKey: (0, wallet_base_1.getKeyFromRpcUrl)(rpcUrl),
|
|
238
|
+
network: ethereumChainId === ts_types_1.EthereumChainId.Mainnet
|
|
239
|
+
? alchemy_sdk_1.Network.ETH_MAINNET
|
|
240
|
+
: alchemy_sdk_1.Network.ETH_SEPOLIA,
|
|
241
|
+
});
|
|
242
|
+
return this.alchemy;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
exports.default = LedgerBase;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.LedgerLegacy = void 0;
|
|
7
|
+
const types_js_1 = require("../../types.js");
|
|
8
|
+
const Base_js_1 = __importDefault(require("./Base.js"));
|
|
9
|
+
class LedgerLegacy extends Base_js_1.default {
|
|
10
|
+
constructor(args) {
|
|
11
|
+
super({
|
|
12
|
+
...args,
|
|
13
|
+
derivationPathType: types_js_1.LedgerDerivationPathType.LedgerMew,
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.LedgerLegacy = LedgerLegacy;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.LedgerLive = void 0;
|
|
7
|
+
const types_js_1 = require("../../types.js");
|
|
8
|
+
const Base_js_1 = __importDefault(require("./Base.js"));
|
|
9
|
+
class LedgerLive extends Base_js_1.default {
|
|
10
|
+
constructor(args) {
|
|
11
|
+
super({
|
|
12
|
+
...args,
|
|
13
|
+
derivationPathType: types_js_1.LedgerDerivationPathType.LedgerLive,
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.LedgerLive = LedgerLive;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { AccountAddress } from '@injectivelabs/ts-types';
|
|
2
|
+
import { Eth as EthereumApp } from '@bangjelkoski/ledgerhq-hw-app-eth';
|
|
3
|
+
import { LedgerDerivationPathType, LedgerWalletInfo } from '../../../types.js';
|
|
4
|
+
export default class AccountManager {
|
|
5
|
+
private wallets;
|
|
6
|
+
private ledger;
|
|
7
|
+
constructor(ledger: EthereumApp);
|
|
8
|
+
getWallets(baseDerivationPath: string, derivationPathType: LedgerDerivationPathType): Promise<LedgerWalletInfo[]>;
|
|
9
|
+
getLedgerDerivationPathBasedOnType: ({ fullBaseDerivationPath, derivationPathType, index, }: {
|
|
10
|
+
fullBaseDerivationPath: string;
|
|
11
|
+
derivationPathType: LedgerDerivationPathType;
|
|
12
|
+
index: number;
|
|
13
|
+
}) => string;
|
|
14
|
+
private getWalletsBasedOnIndex;
|
|
15
|
+
private hasWallets;
|
|
16
|
+
private hasWalletsInOffset;
|
|
17
|
+
private getOffset;
|
|
18
|
+
hasWalletForAddress(address: AccountAddress): boolean;
|
|
19
|
+
getWalletForAddress(address: AccountAddress): Promise<LedgerWalletInfo | undefined>;
|
|
20
|
+
reset(): void;
|
|
21
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const ethereumjs_util_1 = require("ethereumjs-util");
|
|
7
|
+
const hdkey_1 = __importDefault(require("hdkey"));
|
|
8
|
+
const types_js_1 = require("../../../types.js");
|
|
9
|
+
const wallet_base_1 = require("@injectivelabs/wallet-base");
|
|
10
|
+
const addressOfHDKey = (hdKey) => {
|
|
11
|
+
const shouldSanitizePublicKey = true;
|
|
12
|
+
const derivedPublicKey = hdKey.publicKey;
|
|
13
|
+
const ethereumAddressWithoutPrefix = (0, ethereumjs_util_1.publicToAddress)(derivedPublicKey, shouldSanitizePublicKey).toString('hex');
|
|
14
|
+
const address = (0, ethereumjs_util_1.addHexPrefix)(ethereumAddressWithoutPrefix);
|
|
15
|
+
return address;
|
|
16
|
+
};
|
|
17
|
+
class AccountManager {
|
|
18
|
+
wallets = [];
|
|
19
|
+
ledger;
|
|
20
|
+
constructor(ledger) {
|
|
21
|
+
this.ledger = ledger;
|
|
22
|
+
this.wallets = [];
|
|
23
|
+
}
|
|
24
|
+
async getWallets(baseDerivationPath, derivationPathType) {
|
|
25
|
+
const { start, end } = this.getOffset();
|
|
26
|
+
/**
|
|
27
|
+
* 1. Wallets are not yet fetched at all,
|
|
28
|
+
* 2. Wallets are not yet fetched for that offset
|
|
29
|
+
*/
|
|
30
|
+
if (!this.hasWallets() || !this.hasWalletsInOffset(start)) {
|
|
31
|
+
await this.getWalletsBasedOnIndex({
|
|
32
|
+
start,
|
|
33
|
+
end,
|
|
34
|
+
baseDerivationPath,
|
|
35
|
+
derivationPathType,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
return this.wallets.slice(start, end);
|
|
39
|
+
}
|
|
40
|
+
getLedgerDerivationPathBasedOnType = ({ fullBaseDerivationPath, derivationPathType, index, }) => {
|
|
41
|
+
if (derivationPathType === types_js_1.LedgerDerivationPathType.LedgerLive) {
|
|
42
|
+
return `${fullBaseDerivationPath}/${index}'/0/0`;
|
|
43
|
+
}
|
|
44
|
+
return `${fullBaseDerivationPath}/0'/${index}`;
|
|
45
|
+
};
|
|
46
|
+
async getWalletsBasedOnIndex({ start, end, baseDerivationPath, derivationPathType, }) {
|
|
47
|
+
for (let index = start; index < end; index += 1) {
|
|
48
|
+
const path = this.getLedgerDerivationPathBasedOnType({
|
|
49
|
+
fullBaseDerivationPath: baseDerivationPath,
|
|
50
|
+
derivationPathType,
|
|
51
|
+
index,
|
|
52
|
+
});
|
|
53
|
+
const result = await this.ledger.getAddress(path);
|
|
54
|
+
const hdKey = new hdkey_1.default();
|
|
55
|
+
hdKey.publicKey = Buffer.from(result.publicKey, 'hex');
|
|
56
|
+
hdKey.chainCode = Buffer.from(result.chainCode || '', 'hex');
|
|
57
|
+
const address = result.address || addressOfHDKey(hdKey);
|
|
58
|
+
this.wallets.push({
|
|
59
|
+
hdKey,
|
|
60
|
+
baseDerivationPath,
|
|
61
|
+
address: address.toLowerCase(),
|
|
62
|
+
derivationPath: path,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
hasWallets() {
|
|
67
|
+
return this.wallets.length > 0;
|
|
68
|
+
}
|
|
69
|
+
hasWalletsInOffset(offset) {
|
|
70
|
+
return this.wallets.length > offset;
|
|
71
|
+
}
|
|
72
|
+
getOffset() {
|
|
73
|
+
const totalWallets = this.wallets.length;
|
|
74
|
+
const nextBatchStart = totalWallets;
|
|
75
|
+
const nextBatchEnd = totalWallets + wallet_base_1.DEFAULT_NUM_ADDRESSES_TO_FETCH;
|
|
76
|
+
return {
|
|
77
|
+
start: nextBatchStart,
|
|
78
|
+
end: nextBatchEnd,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
hasWalletForAddress(address) {
|
|
82
|
+
return (this.wallets.find((wallet) => wallet.address.toLowerCase() === address.toLowerCase()) !== undefined);
|
|
83
|
+
}
|
|
84
|
+
async getWalletForAddress(address) {
|
|
85
|
+
return this.wallets.find((wallet) => wallet.address.toLowerCase() === address.toLowerCase());
|
|
86
|
+
}
|
|
87
|
+
reset() {
|
|
88
|
+
this.wallets = [];
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
exports.default = AccountManager;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Eth as EthereumApp } from '@bangjelkoski/ledgerhq-hw-app-eth';
|
|
2
|
+
import { Transport } from '@bangjelkoski/ledgerhq-hw-transport';
|
|
3
|
+
import AccountManager from './AccountManager.js';
|
|
4
|
+
export default class LedgerTransport {
|
|
5
|
+
private ledger;
|
|
6
|
+
private accountManager;
|
|
7
|
+
protected static getTransport(): Promise<Transport>;
|
|
8
|
+
getInstance(): Promise<EthereumApp>;
|
|
9
|
+
getAccountManager(): Promise<AccountManager>;
|
|
10
|
+
refresh(): Promise<LedgerTransport>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const ledgerhq_hw_transport_webhid_1 = require("@bangjelkoski/ledgerhq-hw-transport-webhid");
|
|
7
|
+
const ledgerhq_hw_transport_webusb_1 = require("@bangjelkoski/ledgerhq-hw-transport-webusb");
|
|
8
|
+
const ledgerhq_hw_app_eth_1 = require("@bangjelkoski/ledgerhq-hw-app-eth");
|
|
9
|
+
const exceptions_1 = require("@injectivelabs/exceptions");
|
|
10
|
+
const AccountManager_js_1 = __importDefault(require("./AccountManager.js"));
|
|
11
|
+
class LedgerTransport {
|
|
12
|
+
ledger = null;
|
|
13
|
+
accountManager = null;
|
|
14
|
+
static async getTransport() {
|
|
15
|
+
try {
|
|
16
|
+
if (await ledgerhq_hw_transport_webhid_1.TransportWebHID.isSupported()) {
|
|
17
|
+
const list = await ledgerhq_hw_transport_webhid_1.TransportWebHID.list();
|
|
18
|
+
if (list.length > 0 && list[0].opened) {
|
|
19
|
+
return new ledgerhq_hw_transport_webhid_1.TransportWebHID(list[0]);
|
|
20
|
+
}
|
|
21
|
+
const existing = await ledgerhq_hw_transport_webhid_1.TransportWebHID.openConnected().catch(() => null);
|
|
22
|
+
if (existing) {
|
|
23
|
+
return existing;
|
|
24
|
+
}
|
|
25
|
+
return await ledgerhq_hw_transport_webhid_1.TransportWebHID.request();
|
|
26
|
+
}
|
|
27
|
+
if (await ledgerhq_hw_transport_webusb_1.TransportWebUSB.isSupported()) {
|
|
28
|
+
const existing = await ledgerhq_hw_transport_webusb_1.TransportWebUSB.openConnected().catch(() => null);
|
|
29
|
+
if (existing) {
|
|
30
|
+
return existing;
|
|
31
|
+
}
|
|
32
|
+
return await ledgerhq_hw_transport_webusb_1.TransportWebUSB.request();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch (e) {
|
|
36
|
+
throw new exceptions_1.LedgerException(new Error(e.message));
|
|
37
|
+
}
|
|
38
|
+
return ledgerhq_hw_transport_webusb_1.TransportWebUSB.request();
|
|
39
|
+
}
|
|
40
|
+
async getInstance() {
|
|
41
|
+
if (!this.ledger) {
|
|
42
|
+
const transport = await LedgerTransport.getTransport();
|
|
43
|
+
this.ledger = new ledgerhq_hw_app_eth_1.Eth(transport);
|
|
44
|
+
transport.on('disconnect', () => {
|
|
45
|
+
this.ledger = null;
|
|
46
|
+
this.accountManager = null;
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
return this.ledger;
|
|
50
|
+
}
|
|
51
|
+
async getAccountManager() {
|
|
52
|
+
if (!this.accountManager) {
|
|
53
|
+
this.accountManager = new AccountManager_js_1.default(await this.getInstance());
|
|
54
|
+
}
|
|
55
|
+
return this.accountManager;
|
|
56
|
+
}
|
|
57
|
+
async refresh() {
|
|
58
|
+
if (!this.ledger) {
|
|
59
|
+
return new LedgerTransport();
|
|
60
|
+
}
|
|
61
|
+
this.ledger.transport.close();
|
|
62
|
+
return new LedgerTransport();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
exports.default = LedgerTransport;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.messageHash = exports.domainHash = void 0;
|
|
4
|
+
const eth_sig_util_1 = require("eth-sig-util");
|
|
5
|
+
const domainHash = (message) => eth_sig_util_1.TypedDataUtils.hashStruct('EIP712Domain', message.domain, message.types, true);
|
|
6
|
+
exports.domainHash = domainHash;
|
|
7
|
+
const messageHash = (message) => eth_sig_util_1.TypedDataUtils.hashStruct(message.primaryType, message.message, message.types, true);
|
|
8
|
+
exports.messageHash = messageHash;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { AccountAddress } from '@injectivelabs/ts-types';
|
|
2
|
+
import { Cosmos as CosmosApp } from '@bangjelkoski/ledgerhq-hw-app-cosmos';
|
|
3
|
+
import { LedgerWalletInfo } from '../../../types.js';
|
|
4
|
+
export default class AccountManager {
|
|
5
|
+
private wallets;
|
|
6
|
+
private ledger;
|
|
7
|
+
constructor(ledger: CosmosApp);
|
|
8
|
+
getWallets(baseDerivationPath: string): Promise<LedgerWalletInfo[]>;
|
|
9
|
+
getLedgerDerivationPathBasedOnType: ({ fullBaseDerivationPath, index, }: {
|
|
10
|
+
fullBaseDerivationPath: string;
|
|
11
|
+
index: number;
|
|
12
|
+
}) => string;
|
|
13
|
+
private getWalletsBasedOnIndex;
|
|
14
|
+
private hasWallets;
|
|
15
|
+
private hasWalletsInOffset;
|
|
16
|
+
private getOffset;
|
|
17
|
+
hasWalletForAddress(address: AccountAddress): boolean;
|
|
18
|
+
getWalletForAddress(address: AccountAddress): Promise<LedgerWalletInfo | undefined>;
|
|
19
|
+
reset(): void;
|
|
20
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const wallet_base_1 = require("@injectivelabs/wallet-base");
|
|
4
|
+
class AccountManager {
|
|
5
|
+
wallets = [];
|
|
6
|
+
ledger;
|
|
7
|
+
constructor(ledger) {
|
|
8
|
+
this.ledger = ledger;
|
|
9
|
+
this.wallets = [];
|
|
10
|
+
}
|
|
11
|
+
async getWallets(baseDerivationPath) {
|
|
12
|
+
const { start, end } = this.getOffset();
|
|
13
|
+
/**
|
|
14
|
+
* 1. Wallets are not yet fetched at all,
|
|
15
|
+
* 2. Wallets are not yet fetched for that offset
|
|
16
|
+
*/
|
|
17
|
+
if (!this.hasWallets() || !this.hasWalletsInOffset(start)) {
|
|
18
|
+
await this.getWalletsBasedOnIndex({
|
|
19
|
+
start,
|
|
20
|
+
end,
|
|
21
|
+
baseDerivationPath,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
return this.wallets.slice(start, end);
|
|
25
|
+
}
|
|
26
|
+
getLedgerDerivationPathBasedOnType = ({ fullBaseDerivationPath, index, }) => {
|
|
27
|
+
return `${fullBaseDerivationPath}/${index}'/0/0`;
|
|
28
|
+
};
|
|
29
|
+
async getWalletsBasedOnIndex({ start, end, baseDerivationPath, }) {
|
|
30
|
+
for (let index = start; index < end; index += 1) {
|
|
31
|
+
const path = this.getLedgerDerivationPathBasedOnType({
|
|
32
|
+
fullBaseDerivationPath: baseDerivationPath,
|
|
33
|
+
index,
|
|
34
|
+
});
|
|
35
|
+
const { address, publicKey } = await this.ledger.getAddress(path, 'inj');
|
|
36
|
+
this.wallets.push({
|
|
37
|
+
publicKey,
|
|
38
|
+
baseDerivationPath,
|
|
39
|
+
address: address.toLowerCase(),
|
|
40
|
+
derivationPath: path,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
hasWallets() {
|
|
45
|
+
return this.wallets.length > 0;
|
|
46
|
+
}
|
|
47
|
+
hasWalletsInOffset(offset) {
|
|
48
|
+
return this.wallets.length > offset;
|
|
49
|
+
}
|
|
50
|
+
getOffset() {
|
|
51
|
+
const totalWallets = this.wallets.length;
|
|
52
|
+
const nextBatchStart = totalWallets;
|
|
53
|
+
const nextBatchEnd = totalWallets + wallet_base_1.DEFAULT_NUM_ADDRESSES_TO_FETCH;
|
|
54
|
+
return {
|
|
55
|
+
start: nextBatchStart,
|
|
56
|
+
end: nextBatchEnd,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
hasWalletForAddress(address) {
|
|
60
|
+
return (this.wallets.find((wallet) => wallet.address.toLowerCase() === address.toLowerCase()) !== undefined);
|
|
61
|
+
}
|
|
62
|
+
async getWalletForAddress(address) {
|
|
63
|
+
return this.wallets.find((wallet) => wallet.address.toLowerCase() === address.toLowerCase());
|
|
64
|
+
}
|
|
65
|
+
reset() {
|
|
66
|
+
this.wallets = [];
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
exports.default = AccountManager;
|