hodl-wallet 2.0.8 → 2.2.0
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 +1 -1
- package/browser/index.d.ts +1 -0
- package/browser/index.js +1 -0
- package/browser/package.json +5 -0
- package/dist/app/account.d.ts +7 -0
- package/dist/app/account.js +248 -0
- package/dist/app/account.js.map +1 -0
- package/dist/app/format.d.ts +3 -0
- package/dist/app/format.js +27 -0
- package/dist/app/format.js.map +1 -0
- package/dist/app/index.d.ts +8 -0
- package/dist/app/index.js +7 -0
- package/dist/app/index.js.map +1 -0
- package/dist/app/menu.d.ts +12 -0
- package/dist/app/menu.js +78 -0
- package/dist/app/menu.js.map +1 -0
- package/dist/app/output.d.ts +15 -0
- package/dist/app/output.js +81 -0
- package/dist/app/output.js.map +1 -0
- package/dist/app/session.d.ts +105 -0
- package/dist/app/session.js +2 -0
- package/dist/app/session.js.map +1 -0
- package/dist/app/transfer.d.ts +3 -0
- package/dist/app/transfer.js +144 -0
- package/dist/app/transfer.js.map +1 -0
- package/dist/app/ui.d.ts +60 -0
- package/dist/app/ui.js +15 -0
- package/dist/app/ui.js.map +1 -0
- package/dist/browser-core.d.ts +15 -0
- package/dist/browser-core.js +11 -0
- package/dist/browser-core.js.map +1 -0
- package/dist/environment-node.d.ts +2 -0
- package/dist/environment-node.js +8 -0
- package/dist/environment-node.js.map +1 -0
- package/dist/environment.d.ts +2 -0
- package/dist/environment.js +8 -0
- package/dist/environment.js.map +1 -0
- package/dist/index.js +24 -1096
- package/dist/index.js.map +1 -1
- package/dist/network/lib/BaseNetwork.d.ts +3 -1
- package/dist/network/lib/BaseNetwork.js +8 -0
- package/dist/network/lib/BaseNetwork.js.map +1 -1
- package/dist/network/lib/BitcoinNetwork.d.ts +4 -1
- package/dist/network/lib/BitcoinNetwork.js +32 -22
- package/dist/network/lib/BitcoinNetwork.js.map +1 -1
- package/dist/network/lib/Web3Network.d.ts +3 -1
- package/dist/network/lib/Web3Network.js +34 -33
- package/dist/network/lib/Web3Network.js.map +1 -1
- package/dist/network/types.d.ts +5 -1
- package/dist/node-session.d.ts +51 -0
- package/dist/node-session.js +410 -0
- package/dist/node-session.js.map +1 -0
- package/dist/persist.d.ts +8 -1
- package/dist/persist.js +48 -42
- package/dist/persist.js.map +1 -1
- package/dist/sensitive-data.d.ts +2 -0
- package/dist/sensitive-data.js +21 -0
- package/dist/sensitive-data.js.map +1 -0
- package/dist/swap/config.d.ts +2 -2
- package/dist/swap/routes.d.ts +4 -4
- package/dist/swap/service.d.ts +3 -3
- package/dist/swap/service.js +14 -14
- package/dist/swap/service.js.map +1 -1
- package/dist/transfer-service.d.ts +3 -2
- package/dist/transfer-service.js +37 -12
- package/dist/transfer-service.js.map +1 -1
- package/dist/ui-inquirer.d.ts +30 -0
- package/dist/ui-inquirer.js +62 -0
- package/dist/ui-inquirer.js.map +1 -0
- package/dist/wallet-store.d.ts +11 -0
- package/dist/wallet-store.js +2 -0
- package/dist/wallet-store.js.map +1 -0
- package/package.json +13 -1
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import os from 'os';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import Persist from './persist.js';
|
|
5
|
+
import { TransferService } from './transfer-service.js';
|
|
6
|
+
import { NetworkRegistry, networkStorageName } from './network-registry.js';
|
|
7
|
+
import { SwapService } from './swap/service.js';
|
|
8
|
+
import { routeForNetwork } from './swap/routes.js';
|
|
9
|
+
import { startSwapMenu } from './swap/ui.js';
|
|
10
|
+
import { errorMessage } from './app/format.js';
|
|
11
|
+
import { showError } from './app/output.js';
|
|
12
|
+
function isNetworkUsageEntry(value) {
|
|
13
|
+
return (typeof value === 'object' &&
|
|
14
|
+
value !== null &&
|
|
15
|
+
!Array.isArray(value) &&
|
|
16
|
+
typeof value.count === 'number');
|
|
17
|
+
}
|
|
18
|
+
async function askEncryptionKey(ui) {
|
|
19
|
+
return ui.password({ message: 'Password:' });
|
|
20
|
+
}
|
|
21
|
+
/** The encrypted profile in ~/.HODL as a wallet session. Prompts only through the Ui it is given. */
|
|
22
|
+
export class NodeSession {
|
|
23
|
+
capabilities = { replaceAccount: true, balanceHistory: true, switchNetworkFirst: false };
|
|
24
|
+
transfers;
|
|
25
|
+
contacts;
|
|
26
|
+
db;
|
|
27
|
+
selectedNetwork;
|
|
28
|
+
networkInstance;
|
|
29
|
+
networkUsage;
|
|
30
|
+
databaseExisted;
|
|
31
|
+
profileLock;
|
|
32
|
+
hodlDir;
|
|
33
|
+
constructor(encryptionKey, profileLock) {
|
|
34
|
+
const hodlDir = path.join(os.homedir(), '.HODL');
|
|
35
|
+
this.hodlDir = hodlDir;
|
|
36
|
+
if (!fs.existsSync(hodlDir)) {
|
|
37
|
+
fs.mkdirSync(hodlDir, { recursive: true, mode: 0o700 });
|
|
38
|
+
}
|
|
39
|
+
fs.chmodSync(hodlDir, 0o700);
|
|
40
|
+
this.databaseExisted = fs.existsSync(path.join(hodlDir, 'persist.json'));
|
|
41
|
+
this.profileLock = profileLock;
|
|
42
|
+
try {
|
|
43
|
+
this.db = new Persist({ path: hodlDir, encryptionKey });
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
this.profileLock.release();
|
|
47
|
+
throw error;
|
|
48
|
+
}
|
|
49
|
+
this.networkInstance = null;
|
|
50
|
+
this.selectedNetwork = null;
|
|
51
|
+
this.networkUsage = {};
|
|
52
|
+
this.transfers = this.transferPort();
|
|
53
|
+
this.contacts = this.contactsPort();
|
|
54
|
+
}
|
|
55
|
+
get plugin() { return this.selectedNetwork; }
|
|
56
|
+
get network() { return this.networkInstance; }
|
|
57
|
+
async connect() {
|
|
58
|
+
await this.db.connect();
|
|
59
|
+
this.securePersistFile();
|
|
60
|
+
}
|
|
61
|
+
hasStoredDatabase() {
|
|
62
|
+
return this.databaseExisted;
|
|
63
|
+
}
|
|
64
|
+
async start() {
|
|
65
|
+
const rawNetworkUsage = await this.db.get('networkUsage') || {};
|
|
66
|
+
// Validate and clean networkUsage data
|
|
67
|
+
this.networkUsage = {};
|
|
68
|
+
for (const [networkName, usage] of Object.entries(rawNetworkUsage)) {
|
|
69
|
+
if (typeof usage === 'number') {
|
|
70
|
+
// Old format - convert to new format
|
|
71
|
+
this.networkUsage[networkName] = {
|
|
72
|
+
count: usage,
|
|
73
|
+
lastUsed: 0
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
else if (isNetworkUsageEntry(usage)) {
|
|
77
|
+
// Valid new format
|
|
78
|
+
this.networkUsage[networkName] = {
|
|
79
|
+
count: usage.count,
|
|
80
|
+
lastUsed: usage.lastUsed || 0
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
// Skip corrupted entries (they'll be recreated when needed)
|
|
84
|
+
}
|
|
85
|
+
const networkPlugins = this.networks();
|
|
86
|
+
if (networkPlugins.length === 0) {
|
|
87
|
+
throw new Error('No valid network plugins found.');
|
|
88
|
+
}
|
|
89
|
+
// The most recently used network
|
|
90
|
+
await this.selectNetwork(networkPlugins[0]);
|
|
91
|
+
}
|
|
92
|
+
/** Most recently used first. */
|
|
93
|
+
networks() {
|
|
94
|
+
return new NetworkRegistry().list().sort((a, b) => {
|
|
95
|
+
const aUsage = this.networkUsage[networkStorageName(a)];
|
|
96
|
+
const bUsage = this.networkUsage[networkStorageName(b)];
|
|
97
|
+
// Handle old format (number) vs new format (object)
|
|
98
|
+
const aLastUsed = typeof aUsage === 'object' ? aUsage.lastUsed || 0 : 0;
|
|
99
|
+
const bLastUsed = typeof bUsage === 'object' ? bUsage.lastUsed || 0 : 0;
|
|
100
|
+
// If neither has lastUsed timestamp, sort by old count format
|
|
101
|
+
if (aLastUsed === 0 && bLastUsed === 0) {
|
|
102
|
+
const aCount = typeof aUsage === 'number' ? aUsage : (aUsage?.count || 0);
|
|
103
|
+
const bCount = typeof bUsage === 'number' ? bUsage : (bUsage?.count || 0);
|
|
104
|
+
return bCount - aCount;
|
|
105
|
+
}
|
|
106
|
+
return bLastUsed - aLastUsed;
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
async selectNetwork(selectedNetwork) {
|
|
110
|
+
// Update usage info for the selected network
|
|
111
|
+
// Handle migration from old format (number) to new format (object)
|
|
112
|
+
const currentUsage = this.networkUsage[networkStorageName(selectedNetwork)];
|
|
113
|
+
if (!currentUsage || typeof currentUsage === 'number' || typeof currentUsage !== 'object' || currentUsage === null || Array.isArray(currentUsage)) {
|
|
114
|
+
// Old format (number), doesn't exist, or corrupted data - create new object
|
|
115
|
+
this.networkUsage[networkStorageName(selectedNetwork)] = {
|
|
116
|
+
count: typeof currentUsage === 'number' ? currentUsage + 1 : 1,
|
|
117
|
+
lastUsed: Date.now()
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
else if (isNetworkUsageEntry(currentUsage)) {
|
|
121
|
+
// New format (object) - update values
|
|
122
|
+
currentUsage.count = (currentUsage.count || 0) + 1;
|
|
123
|
+
currentUsage.lastUsed = Date.now();
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
this.networkUsage[networkStorageName(selectedNetwork)] = {
|
|
127
|
+
count: 1,
|
|
128
|
+
lastUsed: Date.now()
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
await this.db.set('networkUsage', this.networkUsage);
|
|
132
|
+
this.selectedNetwork = selectedNetwork;
|
|
133
|
+
this.networkInstance = new selectedNetwork.NetworkClass(selectedNetwork);
|
|
134
|
+
this.networkInstance.name = selectedNetwork.name;
|
|
135
|
+
}
|
|
136
|
+
async setAccount(account) {
|
|
137
|
+
if (!account) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
await this.db.set('account', this.network.constructor.name, account);
|
|
141
|
+
if (account.mnemonic) {
|
|
142
|
+
await this.db.set('mnemonic', account.mnemonic);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
async getAccount() {
|
|
146
|
+
const account = await this.db.get('account', this.network.constructor.name);
|
|
147
|
+
return account ?? null;
|
|
148
|
+
}
|
|
149
|
+
async address() {
|
|
150
|
+
return this.db.get('account', this.network.constructor.name, 'address');
|
|
151
|
+
}
|
|
152
|
+
async getMnemonic() {
|
|
153
|
+
return await this.db.get('mnemonic') ?? null;
|
|
154
|
+
}
|
|
155
|
+
async hasMnemonic() {
|
|
156
|
+
return Boolean(await this.getMnemonic());
|
|
157
|
+
}
|
|
158
|
+
async hasAccount() {
|
|
159
|
+
return typeof await this.db.get('account', this.network.constructor.name, 'address') === 'string';
|
|
160
|
+
}
|
|
161
|
+
async createAccount(kind) {
|
|
162
|
+
if (kind === 'existing-mnemonic') {
|
|
163
|
+
await this.setAccount(await this.network.accountFromMnemonic((await this.getMnemonic())));
|
|
164
|
+
}
|
|
165
|
+
else if (kind === 'random') {
|
|
166
|
+
await this.setAccount(await this.network.createAccount());
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
await this.setAccount(await this.network.createAccountFromMnemonic(kind));
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
async importMnemonic(mnemonic) {
|
|
173
|
+
const account = await this.network.accountFromMnemonic(mnemonic);
|
|
174
|
+
await this.setAccount(account);
|
|
175
|
+
Persist.clearSensitiveData(account);
|
|
176
|
+
}
|
|
177
|
+
async importPrivateKey(privateKey) {
|
|
178
|
+
await this.setAccount(await this.network.privateKeyToAccount(privateKey));
|
|
179
|
+
}
|
|
180
|
+
async accountDetails() {
|
|
181
|
+
const account = await this.getAccount();
|
|
182
|
+
if (!account)
|
|
183
|
+
return null;
|
|
184
|
+
const mnemonic = await this.getMnemonic();
|
|
185
|
+
const details = {
|
|
186
|
+
address: await this.address(),
|
|
187
|
+
privateKey: account.privateKey,
|
|
188
|
+
...(mnemonic ? { mnemonic } : {})
|
|
189
|
+
};
|
|
190
|
+
Persist.clearSensitiveData(account);
|
|
191
|
+
return details;
|
|
192
|
+
}
|
|
193
|
+
async tokenBalances() {
|
|
194
|
+
return this.network.getTokenBalances(await this.address());
|
|
195
|
+
}
|
|
196
|
+
async sentTransfers() {
|
|
197
|
+
const address = await this.address();
|
|
198
|
+
const history = await this.db.values('transactions', address, this.selectedNetwork.nativeToken) || [];
|
|
199
|
+
const legacyHistoryKey = this.selectedNetwork.id === 'op'
|
|
200
|
+
? 'OP'
|
|
201
|
+
: this.selectedNetwork.id === 'arb'
|
|
202
|
+
? 'ARB'
|
|
203
|
+
: null;
|
|
204
|
+
if (legacyHistoryKey) {
|
|
205
|
+
const legacyHistory = await this.db.values('transactions', address, legacyHistoryKey) || [];
|
|
206
|
+
history.push(...legacyHistory);
|
|
207
|
+
history.sort((a, b) => a.timestamp.localeCompare(b.timestamp));
|
|
208
|
+
}
|
|
209
|
+
const transfers = await this.transferService().list();
|
|
210
|
+
for (const transfer of transfers.filter(item => item.from === address)) {
|
|
211
|
+
const existing = history.find(item => item.hash === transfer.transactionHash);
|
|
212
|
+
if (existing)
|
|
213
|
+
existing.status = transfer.status;
|
|
214
|
+
else
|
|
215
|
+
history.push({
|
|
216
|
+
timestamp: transfer.createdAt, recipient: transfer.to, token: transfer.asset,
|
|
217
|
+
amount: transfer.amount, hash: transfer.transactionHash, status: transfer.status
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
history.sort((a, b) => a.timestamp.localeCompare(b.timestamp));
|
|
221
|
+
const sent = [];
|
|
222
|
+
for (const tx of history) {
|
|
223
|
+
sent.push({
|
|
224
|
+
timestamp: tx.timestamp, recipient: tx.recipient, contact: await this.contactName(tx.recipient),
|
|
225
|
+
token: tx.token, amount: tx.amount, balance: tx.balance, status: tx.status,
|
|
226
|
+
url: this.selectedNetwork.explorer + tx.hash
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
return sent;
|
|
230
|
+
}
|
|
231
|
+
importActions() {
|
|
232
|
+
return [{ name: 'Import HODL File', run: ui => this.importHODLFile(ui) }];
|
|
233
|
+
}
|
|
234
|
+
exportActions() {
|
|
235
|
+
return [{ name: 'Export HODL File', run: ui => this.exportHODLFile(ui) }];
|
|
236
|
+
}
|
|
237
|
+
menuActions() {
|
|
238
|
+
return routeForNetwork(this.selectedNetwork.id) ? [{ name: 'Swap', run: () => this.swapFunds() }] : [];
|
|
239
|
+
}
|
|
240
|
+
async close() {
|
|
241
|
+
try {
|
|
242
|
+
await this.db.dispose();
|
|
243
|
+
}
|
|
244
|
+
finally {
|
|
245
|
+
this.securePersistFile();
|
|
246
|
+
this.profileLock.release();
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
get storageNetworkName() { return networkStorageName(this.selectedNetwork); }
|
|
250
|
+
transferService() {
|
|
251
|
+
return new TransferService(this.db, this.selectedNetwork, this.network);
|
|
252
|
+
}
|
|
253
|
+
transferPort() {
|
|
254
|
+
return {
|
|
255
|
+
pending: async () => (await this.transferService().list())
|
|
256
|
+
.filter(transfer => !['confirmed', 'failed'].includes(transfer.status))
|
|
257
|
+
.map(transfer => ({
|
|
258
|
+
requestId: transfer.requestId, to: transfer.to, asset: transfer.asset,
|
|
259
|
+
amount: transfer.amount, status: transfer.status
|
|
260
|
+
})),
|
|
261
|
+
preview: async ({ to, asset }) => {
|
|
262
|
+
const preview = await this.transferService().send({ wallet: 'default', to, asset, amount: 'max', dryRun: true });
|
|
263
|
+
return { amount: preview.amount, fee: preview.fee };
|
|
264
|
+
},
|
|
265
|
+
send: (draft, requestId) => this.transferService().send({
|
|
266
|
+
wallet: 'default', to: draft.to, asset: draft.asset, amount: draft.amount, requestId, dryRun: false
|
|
267
|
+
}),
|
|
268
|
+
record: async (result, draft) => {
|
|
269
|
+
const balance = (await this.network.getAssetBalance(result.from, draft.asset)).amount;
|
|
270
|
+
await this.addToTransactions(draft.to, draft.asset, result.amount, result.transactionHash, balance);
|
|
271
|
+
return {
|
|
272
|
+
timestamp: new Date(), recipient: draft.to, contact: await this.contactName(draft.to),
|
|
273
|
+
token: draft.asset, amount: result.amount, balance,
|
|
274
|
+
url: this.selectedNetwork.explorer + result.transactionHash
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
contactsPort() {
|
|
280
|
+
return {
|
|
281
|
+
list: async () => {
|
|
282
|
+
const contacts = await this.db.entries('contact', this.storageNetworkName) || [];
|
|
283
|
+
return contacts.map(([address, data]) => ({ address, name: data.name }));
|
|
284
|
+
},
|
|
285
|
+
get: async (address) => (await this.db.get('contact', this.storageNetworkName, address))?.name,
|
|
286
|
+
set: async (address, name) => { await this.db.set('contact', this.storageNetworkName, address, 'name', name); },
|
|
287
|
+
delete: async (address) => { await this.db.del('contact', this.storageNetworkName, address); },
|
|
288
|
+
clear: async () => { await this.db.del('contact'); }
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
async contactName(address) {
|
|
292
|
+
return this.contacts.get(address);
|
|
293
|
+
}
|
|
294
|
+
async addToTransactions(recipient, token, amount, hash, balance) {
|
|
295
|
+
const transaction = {
|
|
296
|
+
timestamp: new Date().toISOString(),
|
|
297
|
+
recipient,
|
|
298
|
+
token,
|
|
299
|
+
amount,
|
|
300
|
+
hash,
|
|
301
|
+
balance
|
|
302
|
+
};
|
|
303
|
+
const address = await this.address();
|
|
304
|
+
const history = await this.db.values('transactions', address, this.selectedNetwork.nativeToken) || [];
|
|
305
|
+
if (!history.some(entry => entry.hash === hash)) {
|
|
306
|
+
await this.db.add('transactions', address, this.selectedNetwork.nativeToken, transaction);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
async swapFunds() {
|
|
310
|
+
const route = routeForNetwork(this.selectedNetwork.id);
|
|
311
|
+
if (!route)
|
|
312
|
+
throw new Error('No swap route for the selected network.');
|
|
313
|
+
await startSwapMenu(new SwapService(this.db, { routeId: route.id }));
|
|
314
|
+
}
|
|
315
|
+
securePersistFile() {
|
|
316
|
+
const persistPath = path.join(this.hodlDir, 'persist.json');
|
|
317
|
+
if (fs.existsSync(persistPath)) {
|
|
318
|
+
fs.chmodSync(persistPath, 0o600);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
async exportHODLFile(ui) {
|
|
322
|
+
const address = await this.address();
|
|
323
|
+
const defaultFileName = `${address.slice(-6).toUpperCase()}`;
|
|
324
|
+
let fileName = await ui.input({
|
|
325
|
+
message: 'Enter the name for the HODL file:',
|
|
326
|
+
default: defaultFileName
|
|
327
|
+
});
|
|
328
|
+
fileName += '.HODL';
|
|
329
|
+
const encryptionKey = await askEncryptionKey(ui);
|
|
330
|
+
if (!this.db.matchesPassword(encryptionKey)) {
|
|
331
|
+
showError(ui, 'Failed to export HODL file.', 'The password is incorrect.');
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
const data = await this.db.get();
|
|
335
|
+
try {
|
|
336
|
+
const encryptedData = Persist.encrypt(data, encryptionKey);
|
|
337
|
+
fs.writeFileSync(fileName, encryptedData);
|
|
338
|
+
}
|
|
339
|
+
finally {
|
|
340
|
+
Persist.clearSensitiveData(data);
|
|
341
|
+
}
|
|
342
|
+
ui.table({ head: ['HODL File Exported'], tone: 'green', rows: [[`File saved as: ${fileName}`]] });
|
|
343
|
+
}
|
|
344
|
+
async importHODLFile(ui) {
|
|
345
|
+
// Scan current directory for .HODL files
|
|
346
|
+
const currentDir = process.cwd();
|
|
347
|
+
let hodlFiles = [];
|
|
348
|
+
try {
|
|
349
|
+
const files = fs.readdirSync(currentDir);
|
|
350
|
+
hodlFiles = files.filter(file => file.endsWith('.HODL'));
|
|
351
|
+
}
|
|
352
|
+
catch (error) {
|
|
353
|
+
console.error('Error reading directory:', errorMessage(error));
|
|
354
|
+
}
|
|
355
|
+
// Create file options array for autocomplete
|
|
356
|
+
const fileOptions = hodlFiles.map(file => ({
|
|
357
|
+
name: file,
|
|
358
|
+
value: path.join(currentDir, file)
|
|
359
|
+
}));
|
|
360
|
+
// Use autocomplete pattern similar to transferFunds
|
|
361
|
+
const filePath = await ui.autocomplete({
|
|
362
|
+
message: 'HODL file path:',
|
|
363
|
+
source: input => {
|
|
364
|
+
const filenameOptions = fileOptions
|
|
365
|
+
.filter(entry => entry.name.toLowerCase().includes(input.toLowerCase()) || entry.value.toLowerCase().includes(input.toLowerCase()))
|
|
366
|
+
.map(entry => ({
|
|
367
|
+
name: entry.name,
|
|
368
|
+
value: entry.value
|
|
369
|
+
}));
|
|
370
|
+
// Put path options first, then filename options, then manual input
|
|
371
|
+
return [{ name: input, value: input }, ...filenameOptions];
|
|
372
|
+
}
|
|
373
|
+
});
|
|
374
|
+
// If user leaves empty, skip the operation
|
|
375
|
+
if (!filePath || filePath.trim() === '') {
|
|
376
|
+
return false;
|
|
377
|
+
}
|
|
378
|
+
// Validate the file path
|
|
379
|
+
if (!filePath.endsWith('.HODL')) {
|
|
380
|
+
showError(ui, 'File must have .HODL extension');
|
|
381
|
+
return false;
|
|
382
|
+
}
|
|
383
|
+
if (!fs.existsSync(filePath)) {
|
|
384
|
+
showError(ui, 'File not found.');
|
|
385
|
+
return false;
|
|
386
|
+
}
|
|
387
|
+
const encryptedData = fs.readFileSync(filePath, 'utf8');
|
|
388
|
+
if (!Persist.isCurrentFormat(encryptedData)) {
|
|
389
|
+
showError(ui, 'Unsupported HODL file.', 'Files saved in the legacy format can no longer be imported.');
|
|
390
|
+
return false;
|
|
391
|
+
}
|
|
392
|
+
const encryptionKey = await askEncryptionKey(ui);
|
|
393
|
+
let importedData;
|
|
394
|
+
try {
|
|
395
|
+
importedData = Persist.decrypt(encryptedData, encryptionKey);
|
|
396
|
+
await this.db.set(importedData);
|
|
397
|
+
const account = await this.getAccount();
|
|
398
|
+
Persist.clearSensitiveData(account);
|
|
399
|
+
return Boolean(account);
|
|
400
|
+
}
|
|
401
|
+
catch (error) {
|
|
402
|
+
showError(ui, 'Failed to import HODL file.', 'The password is incorrect.');
|
|
403
|
+
return false;
|
|
404
|
+
}
|
|
405
|
+
finally {
|
|
406
|
+
Persist.clearSensitiveData(importedData);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
//# sourceMappingURL=node-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-session.js","sourceRoot":"","sources":["../node-session.ts"],"names":[],"mappings":"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"}
|
package/dist/persist.d.ts
CHANGED
|
@@ -1,20 +1,27 @@
|
|
|
1
1
|
import Deepbase from 'deepbase';
|
|
2
|
+
import type { WalletStore } from './wallet-store.js';
|
|
2
3
|
type PersistOptions = {
|
|
3
4
|
path: string;
|
|
4
5
|
encryptionKey: string;
|
|
5
6
|
};
|
|
6
7
|
type EncryptionKey = string | Buffer;
|
|
7
|
-
declare class Persist extends Deepbase {
|
|
8
|
+
declare class Persist extends Deepbase implements WalletStore {
|
|
8
9
|
private readonly encryptionKey;
|
|
9
10
|
private readonly memoryKey;
|
|
10
11
|
private disposed;
|
|
11
12
|
private readonly storagePath;
|
|
12
13
|
constructor(opts: PersistOptions);
|
|
13
14
|
flush(): Promise<void>;
|
|
15
|
+
/** Whether the password is the one this profile is encrypted with. */
|
|
16
|
+
matchesPassword(password: string): boolean;
|
|
14
17
|
dispose(): Promise<void>;
|
|
15
18
|
static clearSensitiveData(value: unknown): void;
|
|
16
19
|
static encrypt(obj: unknown, encryptionKey: EncryptionKey): string;
|
|
20
|
+
static isCurrentFormat(encryptedData: string): boolean;
|
|
21
|
+
/** Only the current format. Profiles saved before it are read with decryptProfile. */
|
|
17
22
|
static decrypt(encryptedData: string, encryptionKey: EncryptionKey): unknown;
|
|
23
|
+
/** The stored profile, migrating one saved in the legacy format; it is rewritten as v2 on the next save. */
|
|
24
|
+
static decryptProfile(encryptedData: string, encryptionKey: EncryptionKey): unknown;
|
|
18
25
|
static decryptLegacy(encryptedData: string, encryptionKey: EncryptionKey): unknown;
|
|
19
26
|
static evpBytesToKey(password: Buffer, salt: Buffer, keyLen: number, ivLen: number): {
|
|
20
27
|
key: Buffer;
|
package/dist/persist.js
CHANGED
|
@@ -2,12 +2,12 @@ import Deepbase from 'deepbase';
|
|
|
2
2
|
import crypto from 'node:crypto';
|
|
3
3
|
import fs from 'node:fs';
|
|
4
4
|
import path from 'node:path';
|
|
5
|
+
import { clearSensitiveData, isSensitiveField } from './sensitive-data.js';
|
|
5
6
|
const ALGORITHM = 'aes-256-gcm';
|
|
6
7
|
const KEY_LENGTH = 32;
|
|
7
8
|
const IV_LENGTH = 12;
|
|
8
9
|
const SALT_LENGTH = 16;
|
|
9
10
|
const SEALED_SECRET_VERSION = 1;
|
|
10
|
-
const SENSITIVE_FIELDS = new Set(['privateKey', 'mnemonic', 'rawTransaction']);
|
|
11
11
|
class Persist extends Deepbase {
|
|
12
12
|
encryptionKey;
|
|
13
13
|
memoryKey;
|
|
@@ -21,7 +21,7 @@ class Persist extends Deepbase {
|
|
|
21
21
|
name: 'persist',
|
|
22
22
|
path: opts.path,
|
|
23
23
|
stringify: (obj) => Persist.encrypt(obj, encryptionKey),
|
|
24
|
-
parse: (encryptedData) => Persist.
|
|
24
|
+
parse: (encryptedData) => Persist.decryptProfile(encryptedData, encryptionKey),
|
|
25
25
|
encodeForMemory: (value, path) => Persist.transformSecrets(value, path, secret => Persist.sealSecret(secret, memoryKey)),
|
|
26
26
|
decodeFromMemory: (value, path) => Persist.transformSecrets(value, path, secret => Persist.unsealSecret(secret, memoryKey))
|
|
27
27
|
});
|
|
@@ -46,6 +46,16 @@ class Persist extends Deepbase {
|
|
|
46
46
|
fs.closeSync(directory);
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
+
/** Whether the password is the one this profile is encrypted with. */
|
|
50
|
+
matchesPassword(password) {
|
|
51
|
+
const candidate = Buffer.from(password, 'utf8');
|
|
52
|
+
try {
|
|
53
|
+
return candidate.length === this.encryptionKey.length && crypto.timingSafeEqual(candidate, this.encryptionKey);
|
|
54
|
+
}
|
|
55
|
+
finally {
|
|
56
|
+
candidate.fill(0);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
49
59
|
async dispose() {
|
|
50
60
|
if (this.disposed) {
|
|
51
61
|
return;
|
|
@@ -60,21 +70,7 @@ class Persist extends Deepbase {
|
|
|
60
70
|
}
|
|
61
71
|
}
|
|
62
72
|
static clearSensitiveData(value) {
|
|
63
|
-
|
|
64
|
-
value.forEach(item => Persist.clearSensitiveData(item));
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
if (!Persist.isRecord(value)) {
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
for (const [key, item] of Object.entries(value)) {
|
|
71
|
-
if (SENSITIVE_FIELDS.has(key)) {
|
|
72
|
-
value[key] = '';
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
Persist.clearSensitiveData(item);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
73
|
+
clearSensitiveData(value);
|
|
78
74
|
}
|
|
79
75
|
static encrypt(obj, encryptionKey) {
|
|
80
76
|
const salt = crypto.randomBytes(SALT_LENGTH);
|
|
@@ -96,31 +92,41 @@ class Persist extends Deepbase {
|
|
|
96
92
|
serialized?.fill(0);
|
|
97
93
|
}
|
|
98
94
|
}
|
|
99
|
-
static
|
|
95
|
+
static isCurrentFormat(encryptedData) {
|
|
100
96
|
const parts = encryptedData.split(':');
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
97
|
+
return parts[0] === 'v2' && parts.length === 5;
|
|
98
|
+
}
|
|
99
|
+
/** Only the current format. Profiles saved before it are read with decryptProfile. */
|
|
100
|
+
static decrypt(encryptedData, encryptionKey) {
|
|
101
|
+
if (!Persist.isCurrentFormat(encryptedData)) {
|
|
102
|
+
throw new Error('Unsupported encrypted payload format');
|
|
103
|
+
}
|
|
104
|
+
const [, saltHex, ivHex, authTagHex, encryptedHex] = encryptedData.split(':');
|
|
105
|
+
const salt = Buffer.from(saltHex, 'hex');
|
|
106
|
+
const iv = Buffer.from(ivHex, 'hex');
|
|
107
|
+
const authTag = Buffer.from(authTagHex, 'hex');
|
|
108
|
+
const encrypted = Buffer.from(encryptedHex, 'hex');
|
|
109
|
+
const key = crypto.scryptSync(encryptionKey, salt, KEY_LENGTH);
|
|
110
|
+
let decrypted;
|
|
111
|
+
try {
|
|
112
|
+
const decipher = crypto.createDecipheriv(ALGORITHM, key, iv);
|
|
113
|
+
decipher.setAuthTag(authTag);
|
|
114
|
+
decrypted = Buffer.concat([
|
|
115
|
+
decipher.update(encrypted),
|
|
116
|
+
decipher.final()
|
|
117
|
+
]);
|
|
118
|
+
return JSON.parse(decrypted.toString('utf8'));
|
|
119
|
+
}
|
|
120
|
+
finally {
|
|
121
|
+
key.fill(0);
|
|
122
|
+
decrypted?.fill(0);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/** The stored profile, migrating one saved in the legacy format; it is rewritten as v2 on the next save. */
|
|
126
|
+
static decryptProfile(encryptedData, encryptionKey) {
|
|
127
|
+
return Persist.isCurrentFormat(encryptedData)
|
|
128
|
+
? Persist.decrypt(encryptedData, encryptionKey)
|
|
129
|
+
: Persist.decryptLegacy(encryptedData, encryptionKey);
|
|
124
130
|
}
|
|
125
131
|
static decryptLegacy(encryptedData, encryptionKey) {
|
|
126
132
|
const [, encrypted] = encryptedData.split(':');
|
|
@@ -181,7 +187,7 @@ class Persist extends Deepbase {
|
|
|
181
187
|
}
|
|
182
188
|
static isSensitivePath(path) {
|
|
183
189
|
const field = path.at(-1);
|
|
184
|
-
return field !== undefined &&
|
|
190
|
+
return field !== undefined && isSensitiveField(field);
|
|
185
191
|
}
|
|
186
192
|
static isRecord(value) {
|
|
187
193
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
package/dist/persist.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"persist.js","sourceRoot":"","sources":["../persist.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"persist.js","sourceRoot":"","sources":["../persist.ts"],"names":[],"mappings":"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"}
|