@sidhujag/sysweb3-keyring 1.0.628 → 2.1.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/CHANGELOG.md +30 -0
- package/README.md +174 -0
- package/cjs/bip84-native.js +8 -0
- package/cjs/bip84-native.js.map +1 -0
- package/cjs/hardware-wallet-manager.js +302 -128
- package/cjs/hardware-wallet-manager.js.map +1 -1
- package/cjs/keyring-core.js +319 -0
- package/cjs/keyring-core.js.map +1 -1
- package/cjs/keyring-manager.js +9 -3
- package/cjs/keyring-manager.js.map +1 -1
- package/cjs/ledger/bitcoin_client/lib/appClient.js.map +1 -1
- package/cjs/ledger/host-types.js +10 -0
- package/cjs/ledger/host-types.js.map +1 -0
- package/cjs/ledger/index.js +243 -447
- package/cjs/ledger/index.js.map +1 -1
- package/cjs/ledger/prepare-psbt.js +177 -0
- package/cjs/ledger/prepare-psbt.js.map +1 -0
- package/cjs/public-bip84.js +157 -0
- package/cjs/public-bip84.js.map +1 -0
- package/cjs/software-hd-account.js +23 -0
- package/cjs/software-hd-account.js.map +1 -0
- package/cjs/software-utxo-account.js +12 -0
- package/cjs/software-utxo-account.js.map +1 -0
- package/cjs/software.js +24 -0
- package/cjs/software.js.map +1 -1
- package/cjs/transactions/bip84-native-plan.js +481 -0
- package/cjs/transactions/bip84-native-plan.js.map +1 -0
- package/cjs/transactions/ethereum.js +55 -10
- package/cjs/transactions/ethereum.js.map +1 -1
- package/cjs/transactions/hardware-psbt.js +36 -44
- package/cjs/transactions/hardware-psbt.js.map +1 -1
- package/cjs/transactions/prepared-bip84.js +214 -0
- package/cjs/transactions/prepared-bip84.js.map +1 -0
- package/cjs/transactions/prepared-evm.js +197 -0
- package/cjs/transactions/prepared-evm.js.map +1 -0
- package/cjs/trezor/connect.js +243 -0
- package/cjs/trezor/connect.js.map +1 -0
- package/cjs/trezor/index.js +96 -58
- package/cjs/trezor/index.js.map +1 -1
- package/cjs/trezor/witness.js +25 -0
- package/cjs/trezor/witness.js.map +1 -0
- package/cjs/utils/psbt-account-scope.js +5 -3
- package/cjs/utils/psbt-account-scope.js.map +1 -1
- package/esm/errorUtils.js +72 -0
- package/esm/errorUtils.js.map +1 -0
- package/esm/ethers-v6.js +207 -0
- package/esm/ethers-v6.js.map +1 -0
- package/esm/hardware-wallet-manager.js +643 -0
- package/esm/hardware-wallet-manager.js.map +1 -0
- package/esm/ledger/bitcoin_client/lib/appClient.js +279 -0
- package/esm/ledger/bitcoin_client/lib/appClient.js.map +1 -0
- package/esm/ledger/bitcoin_client/lib/bip32.js +49 -0
- package/esm/ledger/bitcoin_client/lib/bip32.js.map +1 -0
- package/esm/ledger/bitcoin_client/lib/buffertools.js +119 -0
- package/esm/ledger/bitcoin_client/lib/buffertools.js.map +1 -0
- package/esm/ledger/bitcoin_client/lib/clientCommands.js +269 -0
- package/esm/ledger/bitcoin_client/lib/clientCommands.js.map +1 -0
- package/esm/ledger/bitcoin_client/lib/merkelizedPsbt.js +50 -0
- package/esm/ledger/bitcoin_client/lib/merkelizedPsbt.js.map +1 -0
- package/esm/ledger/bitcoin_client/lib/merkle.js +111 -0
- package/esm/ledger/bitcoin_client/lib/merkle.js.map +1 -0
- package/esm/ledger/bitcoin_client/lib/merkleMap.js +42 -0
- package/esm/ledger/bitcoin_client/lib/merkleMap.js.map +1 -0
- package/esm/ledger/bitcoin_client/lib/policy.js +68 -0
- package/esm/ledger/bitcoin_client/lib/policy.js.map +1 -0
- package/esm/ledger/bitcoin_client/lib/psbtv2.js +645 -0
- package/esm/ledger/bitcoin_client/lib/psbtv2.js.map +1 -0
- package/esm/ledger/bitcoin_client/lib/varint.js +108 -0
- package/esm/ledger/bitcoin_client/lib/varint.js.map +1 -0
- package/esm/ledger/consts.js +4 -0
- package/esm/ledger/consts.js.map +1 -0
- package/esm/ledger/dmk-evm.js +258 -0
- package/esm/ledger/dmk-evm.js.map +1 -0
- package/esm/ledger/dmk-session.js +264 -0
- package/esm/ledger/dmk-session.js.map +1 -0
- package/esm/ledger/dmk-utxo.js +279 -0
- package/esm/ledger/dmk-utxo.js.map +1 -0
- package/esm/ledger/host-types.js +5 -0
- package/esm/ledger/host-types.js.map +1 -0
- package/esm/ledger/index.js +268 -0
- package/esm/ledger/index.js.map +1 -0
- package/esm/ledger/prepare-psbt.js +141 -0
- package/esm/ledger/prepare-psbt.js.map +1 -0
- package/esm/ledger/types.js +2 -0
- package/esm/ledger/types.js.map +1 -0
- package/esm/ledger-host.js +36 -0
- package/esm/ledger-host.js.map +1 -0
- package/esm/private-records.js +153 -0
- package/esm/private-records.js.map +1 -0
- package/esm/providers.js +588 -0
- package/esm/providers.js.map +1 -0
- package/esm/signers.js +28 -0
- package/esm/signers.js.map +1 -0
- package/esm/trezor/connect.js +206 -0
- package/esm/trezor/connect.js.map +1 -0
- package/esm/trezor/index.js +876 -0
- package/esm/trezor/index.js.map +1 -0
- package/esm/trezor/witness.js +21 -0
- package/esm/trezor/witness.js.map +1 -0
- package/esm/types.js +17 -0
- package/esm/types.js.map +1 -0
- package/esm/utils/derivation-paths.js +109 -0
- package/esm/utils/derivation-paths.js.map +1 -0
- package/esm/utils/psbt-account-scope.js +310 -0
- package/esm/utils/psbt-account-scope.js.map +1 -0
- package/package.json +34 -9
- package/types/bip84-native.d.ts +3 -0
- package/types/hardware-wallet-manager.d.ts +12 -19
- package/types/keyring-core.d.ts +14 -0
- package/types/keyring-manager.d.ts +2 -1
- package/types/ledger/bitcoin_client/lib/appClient.d.ts +6 -3
- package/types/ledger/dmk-evm.d.ts +8 -0
- package/types/ledger/dmk-session.d.ts +60 -0
- package/types/ledger/dmk-utxo.d.ts +26 -0
- package/types/ledger/host-types.d.ts +131 -0
- package/types/ledger/index.d.ts +21 -58
- package/types/ledger/prepare-psbt.d.ts +3 -0
- package/types/ledger/types.d.ts +3 -0
- package/types/ledger-host.d.ts +7 -0
- package/types/public-bip84.d.ts +39 -0
- package/types/software-hd-account.d.ts +16 -0
- package/types/software-utxo-account.d.ts +13 -0
- package/types/software.d.ts +26 -0
- package/types/transactions/bip84-native-plan.d.ts +83 -0
- package/types/transactions/ethereum.d.ts +1 -1
- package/types/transactions/prepared-bip84.d.ts +27 -0
- package/types/transactions/prepared-evm.d.ts +53 -0
- package/types/trezor/connect.d.ts +42 -0
- package/types/trezor/index.d.ts +22 -4
- package/types/trezor/witness.d.ts +3 -0
- package/types/utils/psbt-account-scope.d.ts +1 -0
|
@@ -0,0 +1,643 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import { ledgerCancelledError, ledgerHostError } from './ledger/host-types';
|
|
3
|
+
import TrezorConnect, { subscribeTrezorEvents } from './trezor/connect';
|
|
4
|
+
export var HardwareWalletType;
|
|
5
|
+
(function (HardwareWalletType) {
|
|
6
|
+
HardwareWalletType["LEDGER"] = "ledger";
|
|
7
|
+
HardwareWalletType["TREZOR"] = "trezor";
|
|
8
|
+
})(HardwareWalletType || (HardwareWalletType = {}));
|
|
9
|
+
export var ConnectionStatus;
|
|
10
|
+
(function (ConnectionStatus) {
|
|
11
|
+
ConnectionStatus["DISCONNECTED"] = "disconnected";
|
|
12
|
+
ConnectionStatus["CONNECTING"] = "connecting";
|
|
13
|
+
ConnectionStatus["CONNECTED"] = "connected";
|
|
14
|
+
ConnectionStatus["ERROR"] = "error";
|
|
15
|
+
})(ConnectionStatus || (ConnectionStatus = {}));
|
|
16
|
+
/**
|
|
17
|
+
* Hardware Wallet Manager with connection pooling, status monitoring, and error recovery
|
|
18
|
+
*/
|
|
19
|
+
export class HardwareWalletManager extends EventEmitter {
|
|
20
|
+
constructor(ledgerHost) {
|
|
21
|
+
super();
|
|
22
|
+
this.ledgerHost = ledgerHost;
|
|
23
|
+
this.connectionPool = new Map();
|
|
24
|
+
this.statusMonitorInterval = null;
|
|
25
|
+
this.lifecycleGeneration = 0;
|
|
26
|
+
this.IDLE_TIMEOUT = 5 * 60 * 1000; // 5 minutes
|
|
27
|
+
this.STATUS_CHECK_INTERVAL = 5000; // 5 seconds
|
|
28
|
+
this.retryConfig = {
|
|
29
|
+
maxRetries: 3,
|
|
30
|
+
baseDelay: 1000, // 1 second
|
|
31
|
+
maxDelay: 10000, // 10 seconds
|
|
32
|
+
backoffMultiplier: 2,
|
|
33
|
+
};
|
|
34
|
+
this.observeTrezor();
|
|
35
|
+
this.startStatusMonitoring();
|
|
36
|
+
}
|
|
37
|
+
observeTrezor() {
|
|
38
|
+
if (this.unsubscribeTrezor)
|
|
39
|
+
return;
|
|
40
|
+
this.unsubscribeTrezor = subscribeTrezorEvents((event) => {
|
|
41
|
+
if (event.type === 'disconnected') {
|
|
42
|
+
// Our pre-init disposal and Connect initialization invalidate the
|
|
43
|
+
// adapter too. Keep this attempt owned until it settles or is revoked.
|
|
44
|
+
if (this.connectionPool.get('trezor-default')?.status ===
|
|
45
|
+
ConnectionStatus.CONNECTING)
|
|
46
|
+
return;
|
|
47
|
+
this.handleDisconnect('trezor-default', HardwareWalletType.TREZOR);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
/** Raw transports are deliberately unavailable through the semantic host boundary. */
|
|
52
|
+
async getLedgerConnection() {
|
|
53
|
+
throw ledgerHostError('HARDWARE_SIGNER_UNAVAILABLE', 'Ledger requires a semantic LedgerHost; raw Ledger transports are not supported');
|
|
54
|
+
}
|
|
55
|
+
async initializeLedger() {
|
|
56
|
+
const host = this.ledgerHost;
|
|
57
|
+
if (!host) {
|
|
58
|
+
throw ledgerHostError('HARDWARE_SIGNER_UNAVAILABLE', 'A semantic LedgerHost is required to connect Ledger');
|
|
59
|
+
}
|
|
60
|
+
if (this.destruction)
|
|
61
|
+
throw ledgerCancelledError();
|
|
62
|
+
this.startStatusMonitoring();
|
|
63
|
+
const key = `${HardwareWalletType.LEDGER}-default`;
|
|
64
|
+
if (host.getStatus().connected) {
|
|
65
|
+
const existing = this.connectionPool.get(key);
|
|
66
|
+
if (existing)
|
|
67
|
+
existing.lastActivity = Date.now();
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (this.ledgerInitialization)
|
|
71
|
+
return this.ledgerInitialization;
|
|
72
|
+
const generation = this.lifecycleGeneration;
|
|
73
|
+
const entry = {
|
|
74
|
+
status: ConnectionStatus.CONNECTING,
|
|
75
|
+
lastActivity: Date.now(),
|
|
76
|
+
retryCount: 0,
|
|
77
|
+
};
|
|
78
|
+
this.connectionPool.set(key, entry);
|
|
79
|
+
const isCurrent = () => generation === this.lifecycleGeneration &&
|
|
80
|
+
this.connectionPool.get(key) === entry &&
|
|
81
|
+
!this.destruction;
|
|
82
|
+
const assertCurrent = () => {
|
|
83
|
+
if (!isCurrent())
|
|
84
|
+
throw ledgerCancelledError();
|
|
85
|
+
};
|
|
86
|
+
// Install the shared promise before any observer can re-enter this method.
|
|
87
|
+
const pending = Promise.resolve().then(async () => {
|
|
88
|
+
assertCurrent();
|
|
89
|
+
this.emit('connectionAttempt', {
|
|
90
|
+
type: HardwareWalletType.LEDGER,
|
|
91
|
+
attempt: 1,
|
|
92
|
+
maxAttempts: 1,
|
|
93
|
+
});
|
|
94
|
+
assertCurrent();
|
|
95
|
+
// Device selection happens in the visible host, never by a background chooser.
|
|
96
|
+
await host.connect({ useGrantedDevices: true });
|
|
97
|
+
assertCurrent();
|
|
98
|
+
if (!host.getStatus().connected)
|
|
99
|
+
throw ledgerHostError('HARDWARE_SIGNER_UNAVAILABLE', 'Connect a Ledger device in the Ledger window');
|
|
100
|
+
entry.status = ConnectionStatus.CONNECTED;
|
|
101
|
+
entry.lastActivity = Date.now();
|
|
102
|
+
this.emit('connected', { type: HardwareWalletType.LEDGER });
|
|
103
|
+
assertCurrent();
|
|
104
|
+
});
|
|
105
|
+
this.ledgerInitialization = pending;
|
|
106
|
+
try {
|
|
107
|
+
await pending;
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
if (isCurrent()) {
|
|
111
|
+
entry.status = ConnectionStatus.ERROR;
|
|
112
|
+
entry.error = error;
|
|
113
|
+
this.emit('connectionFailed', {
|
|
114
|
+
type: HardwareWalletType.LEDGER,
|
|
115
|
+
error: entry.error.message,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
throw error;
|
|
119
|
+
}
|
|
120
|
+
finally {
|
|
121
|
+
if (this.ledgerInitialization === pending)
|
|
122
|
+
this.ledgerInitialization = undefined;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Initialize Trezor with retry logic
|
|
127
|
+
*/
|
|
128
|
+
async initializeTrezor() {
|
|
129
|
+
if (this.destruction) {
|
|
130
|
+
throw Object.assign(new Error('Trezor connection is closing'), {
|
|
131
|
+
code: 'Method_Interrupted',
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
const generation = this.lifecycleGeneration;
|
|
135
|
+
this.observeTrezor();
|
|
136
|
+
this.startStatusMonitoring();
|
|
137
|
+
const key = `${HardwareWalletType.TREZOR}-default`;
|
|
138
|
+
const existing = this.connectionPool.get(key);
|
|
139
|
+
if (existing?.status === ConnectionStatus.CONNECTED) {
|
|
140
|
+
existing.lastActivity = Date.now();
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
// Check if we're already trying to connect
|
|
144
|
+
if (this.trezorInitialization ||
|
|
145
|
+
existing?.status === ConnectionStatus.CONNECTING) {
|
|
146
|
+
console.log('[HardwareWalletManager] Trezor connection already in progress');
|
|
147
|
+
// Wait a bit and check again
|
|
148
|
+
await this.delay(1000);
|
|
149
|
+
if (generation !== this.lifecycleGeneration || this.destruction)
|
|
150
|
+
return false;
|
|
151
|
+
const updated = this.connectionPool.get(key);
|
|
152
|
+
return updated?.status === ConnectionStatus.CONNECTED || false;
|
|
153
|
+
}
|
|
154
|
+
const owner = {};
|
|
155
|
+
this.trezorInitialization = owner;
|
|
156
|
+
try {
|
|
157
|
+
return await this.initializeTrezorWithRetry(key, owner, generation);
|
|
158
|
+
}
|
|
159
|
+
finally {
|
|
160
|
+
if (this.trezorInitialization === owner)
|
|
161
|
+
this.trezorInitialization = undefined;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Initialize Trezor with exponential backoff retry
|
|
166
|
+
*/
|
|
167
|
+
async initializeTrezorWithRetry(key, owner, generation) {
|
|
168
|
+
const entry = {
|
|
169
|
+
status: ConnectionStatus.CONNECTING,
|
|
170
|
+
lastActivity: Date.now(),
|
|
171
|
+
retryCount: 0,
|
|
172
|
+
};
|
|
173
|
+
this.connectionPool.set(key, entry);
|
|
174
|
+
const isCurrent = () => generation === this.lifecycleGeneration &&
|
|
175
|
+
this.trezorInitialization === owner &&
|
|
176
|
+
this.connectionPool.get(key) === entry &&
|
|
177
|
+
!this.destruction;
|
|
178
|
+
let lastError;
|
|
179
|
+
// Reduce retry attempts for Trezor to prevent repeated popups
|
|
180
|
+
const trezorRetryConfig = {
|
|
181
|
+
...this.retryConfig,
|
|
182
|
+
maxRetries: 1, // Only retry once for Trezor
|
|
183
|
+
};
|
|
184
|
+
for (let attempt = 0; attempt <= trezorRetryConfig.maxRetries; attempt++) {
|
|
185
|
+
if (!isCurrent())
|
|
186
|
+
return false;
|
|
187
|
+
try {
|
|
188
|
+
this.emit('connectionAttempt', {
|
|
189
|
+
type: HardwareWalletType.TREZOR,
|
|
190
|
+
attempt: attempt + 1,
|
|
191
|
+
maxAttempts: trezorRetryConfig.maxRetries + 1,
|
|
192
|
+
});
|
|
193
|
+
if (!isCurrent())
|
|
194
|
+
return false;
|
|
195
|
+
// Dispose the previous Suite connection before initialization
|
|
196
|
+
try {
|
|
197
|
+
await TrezorConnect.dispose();
|
|
198
|
+
}
|
|
199
|
+
catch (disposeError) {
|
|
200
|
+
console.log('[HardwareWalletManager] Dispose error (safe to ignore):', disposeError);
|
|
201
|
+
}
|
|
202
|
+
if (!isCurrent())
|
|
203
|
+
return false;
|
|
204
|
+
await TrezorConnect.init({
|
|
205
|
+
manifest: {
|
|
206
|
+
appName: 'Pali Wallet',
|
|
207
|
+
appUrl: 'https://paliwallet.com/',
|
|
208
|
+
email: 'support@syscoin.org',
|
|
209
|
+
},
|
|
210
|
+
debug: false, // Disable debug mode to prevent extra logs
|
|
211
|
+
// Connect chooses Suite Desktop, then the supported Suite Web fallback.
|
|
212
|
+
coreMode: 'auto',
|
|
213
|
+
});
|
|
214
|
+
if (!isCurrent())
|
|
215
|
+
return false;
|
|
216
|
+
entry.status = ConnectionStatus.CONNECTED;
|
|
217
|
+
entry.retryCount = 0;
|
|
218
|
+
entry.error = undefined;
|
|
219
|
+
this.emit('connected', { type: HardwareWalletType.TREZOR });
|
|
220
|
+
return isCurrent();
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
// Teardown or a newer owner revoked this attempt. Its continuation
|
|
224
|
+
// must not mutate status, retry, or dispose the newer connection.
|
|
225
|
+
if (!isCurrent())
|
|
226
|
+
return false;
|
|
227
|
+
lastError = error;
|
|
228
|
+
if (lastError.code === 'HARDWARE_SIGNER_BUSY') {
|
|
229
|
+
entry.status = ConnectionStatus.ERROR;
|
|
230
|
+
entry.error = lastError;
|
|
231
|
+
this.emit('connectionFailed', {
|
|
232
|
+
type: HardwareWalletType.TREZOR,
|
|
233
|
+
error: lastError.message,
|
|
234
|
+
});
|
|
235
|
+
throw lastError;
|
|
236
|
+
}
|
|
237
|
+
if (lastError.code === 'HARDWARE_SIGNER_UNAVAILABLE')
|
|
238
|
+
break;
|
|
239
|
+
// Check if already initialized - this is actually OK
|
|
240
|
+
if (lastError.message.includes('TrezorConnect has been already initialized')) {
|
|
241
|
+
// Instead of just marking as connected, verify the connection
|
|
242
|
+
try {
|
|
243
|
+
// Test the connection with a simple call
|
|
244
|
+
const testResponse = await TrezorConnect.getFeatures();
|
|
245
|
+
if (!isCurrent())
|
|
246
|
+
return false;
|
|
247
|
+
if (testResponse.success) {
|
|
248
|
+
entry.status = ConnectionStatus.CONNECTED;
|
|
249
|
+
entry.retryCount = 0;
|
|
250
|
+
entry.error = undefined;
|
|
251
|
+
this.emit('connected', { type: HardwareWalletType.TREZOR });
|
|
252
|
+
return isCurrent();
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
catch (testError) {
|
|
256
|
+
console.log('[HardwareWalletManager] Trezor test connection failed:', testError);
|
|
257
|
+
}
|
|
258
|
+
if (!isCurrent())
|
|
259
|
+
return false;
|
|
260
|
+
// If test failed, dispose and retry
|
|
261
|
+
try {
|
|
262
|
+
await TrezorConnect.dispose();
|
|
263
|
+
if (!isCurrent())
|
|
264
|
+
return false;
|
|
265
|
+
await this.delay(500);
|
|
266
|
+
}
|
|
267
|
+
catch (disposeError) {
|
|
268
|
+
console.log('[HardwareWalletManager] Error disposing for retry:', disposeError);
|
|
269
|
+
}
|
|
270
|
+
if (!isCurrent())
|
|
271
|
+
return false;
|
|
272
|
+
}
|
|
273
|
+
entry.retryCount = attempt + 1;
|
|
274
|
+
entry.error = lastError;
|
|
275
|
+
// Check for specific Trezor errors
|
|
276
|
+
if (lastError.message.includes('device is already in use') ||
|
|
277
|
+
lastError.message.includes('Device is being used in another window')) {
|
|
278
|
+
console.log('[HardwareWalletManager] Trezor device is in use by another application');
|
|
279
|
+
// Try to dispose and reinitialize
|
|
280
|
+
try {
|
|
281
|
+
await TrezorConnect.dispose();
|
|
282
|
+
if (!isCurrent())
|
|
283
|
+
return false;
|
|
284
|
+
await this.delay(2000); // Wait 2 seconds before retry
|
|
285
|
+
}
|
|
286
|
+
catch (disposeError) {
|
|
287
|
+
console.log('[HardwareWalletManager] Error during dispose:', disposeError);
|
|
288
|
+
}
|
|
289
|
+
if (!isCurrent())
|
|
290
|
+
return false;
|
|
291
|
+
}
|
|
292
|
+
// Don't retry if user cancelled
|
|
293
|
+
if (this.isUserCancellationError(lastError)) {
|
|
294
|
+
console.log('[HardwareWalletManager] User cancelled Trezor connection');
|
|
295
|
+
break; // Exit retry loop
|
|
296
|
+
}
|
|
297
|
+
if (attempt < trezorRetryConfig.maxRetries) {
|
|
298
|
+
const delay = this.calculateBackoffDelay(attempt);
|
|
299
|
+
this.emit('retrying', {
|
|
300
|
+
type: HardwareWalletType.TREZOR,
|
|
301
|
+
attempt: attempt + 1,
|
|
302
|
+
nextRetryIn: delay,
|
|
303
|
+
error: lastError.message,
|
|
304
|
+
});
|
|
305
|
+
await this.delay(delay);
|
|
306
|
+
if (!isCurrent())
|
|
307
|
+
return false;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
if (!isCurrent())
|
|
312
|
+
return false;
|
|
313
|
+
entry.status = ConnectionStatus.ERROR;
|
|
314
|
+
this.emit('connectionFailed', {
|
|
315
|
+
type: HardwareWalletType.TREZOR,
|
|
316
|
+
error: lastError?.message,
|
|
317
|
+
});
|
|
318
|
+
if (!isCurrent())
|
|
319
|
+
return false;
|
|
320
|
+
// Clean up on failure
|
|
321
|
+
try {
|
|
322
|
+
await TrezorConnect.dispose();
|
|
323
|
+
}
|
|
324
|
+
catch (disposeError) {
|
|
325
|
+
console.log('[HardwareWalletManager] Failed to dispose on error:', disposeError);
|
|
326
|
+
}
|
|
327
|
+
return false;
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Handle device disconnect
|
|
331
|
+
*/
|
|
332
|
+
handleDisconnect(key, type) {
|
|
333
|
+
const entry = this.connectionPool.get(key);
|
|
334
|
+
if (entry) {
|
|
335
|
+
entry.status = ConnectionStatus.DISCONNECTED;
|
|
336
|
+
this.emit('disconnected', { type });
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Start real-time status monitoring
|
|
341
|
+
*/
|
|
342
|
+
startStatusMonitoring() {
|
|
343
|
+
if (this.statusMonitorInterval) {
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
this.statusMonitorInterval = setInterval(() => {
|
|
347
|
+
this.checkAllConnections();
|
|
348
|
+
}, this.STATUS_CHECK_INTERVAL);
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Check all connections and clean up idle ones
|
|
352
|
+
*/
|
|
353
|
+
async checkAllConnections() {
|
|
354
|
+
const generation = this.lifecycleGeneration;
|
|
355
|
+
const isCurrent = () => generation === this.lifecycleGeneration && !this.destruction;
|
|
356
|
+
if (!isCurrent())
|
|
357
|
+
return;
|
|
358
|
+
const now = Date.now();
|
|
359
|
+
const statuses = [];
|
|
360
|
+
for (const [key, entry] of this.connectionPool.entries()) {
|
|
361
|
+
if (!isCurrent())
|
|
362
|
+
return;
|
|
363
|
+
const type = key.startsWith(HardwareWalletType.LEDGER)
|
|
364
|
+
? HardwareWalletType.LEDGER
|
|
365
|
+
: HardwareWalletType.TREZOR;
|
|
366
|
+
if (type === HardwareWalletType.LEDGER &&
|
|
367
|
+
entry.status === ConnectionStatus.CONNECTED &&
|
|
368
|
+
!this.ledgerHost?.getStatus().connected) {
|
|
369
|
+
this.handleDisconnect(key, type);
|
|
370
|
+
}
|
|
371
|
+
// Clean up idle connections
|
|
372
|
+
if (entry.status === ConnectionStatus.CONNECTED &&
|
|
373
|
+
now - entry.lastActivity > this.IDLE_TIMEOUT) {
|
|
374
|
+
await this.closeConnection(key, entry);
|
|
375
|
+
if (!isCurrent())
|
|
376
|
+
return;
|
|
377
|
+
continue;
|
|
378
|
+
}
|
|
379
|
+
// Build status
|
|
380
|
+
const status = {
|
|
381
|
+
type,
|
|
382
|
+
status: entry.status,
|
|
383
|
+
connected: entry.status === ConnectionStatus.CONNECTED,
|
|
384
|
+
lastSeen: entry.lastActivity,
|
|
385
|
+
error: entry.error?.message,
|
|
386
|
+
};
|
|
387
|
+
statuses.push(status);
|
|
388
|
+
}
|
|
389
|
+
if (isCurrent())
|
|
390
|
+
this.emit('statusUpdate', statuses);
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Get current status of all hardware wallets
|
|
394
|
+
*/
|
|
395
|
+
getStatus() {
|
|
396
|
+
const statuses = [];
|
|
397
|
+
// Check Ledger
|
|
398
|
+
const ledgerEntry = this.connectionPool.get(`${HardwareWalletType.LEDGER}-default`);
|
|
399
|
+
const ledgerConnected = !this.destruction && this.ledgerHost?.getStatus().connected === true;
|
|
400
|
+
statuses.push({
|
|
401
|
+
type: HardwareWalletType.LEDGER,
|
|
402
|
+
status: this.destruction
|
|
403
|
+
? ConnectionStatus.DISCONNECTED
|
|
404
|
+
: ledgerConnected
|
|
405
|
+
? ConnectionStatus.CONNECTED
|
|
406
|
+
: ledgerEntry?.status === ConnectionStatus.CONNECTING
|
|
407
|
+
? ConnectionStatus.CONNECTING
|
|
408
|
+
: ledgerEntry?.status === ConnectionStatus.ERROR
|
|
409
|
+
? ConnectionStatus.ERROR
|
|
410
|
+
: ConnectionStatus.DISCONNECTED,
|
|
411
|
+
connected: ledgerConnected,
|
|
412
|
+
lastSeen: ledgerEntry?.lastActivity,
|
|
413
|
+
error: ledgerEntry?.error?.message,
|
|
414
|
+
});
|
|
415
|
+
// Check Trezor
|
|
416
|
+
const trezorEntry = this.connectionPool.get(`${HardwareWalletType.TREZOR}-default`);
|
|
417
|
+
statuses.push({
|
|
418
|
+
type: HardwareWalletType.TREZOR,
|
|
419
|
+
status: trezorEntry?.status || ConnectionStatus.DISCONNECTED,
|
|
420
|
+
connected: trezorEntry?.status === ConnectionStatus.CONNECTED,
|
|
421
|
+
lastSeen: trezorEntry?.lastActivity,
|
|
422
|
+
error: trezorEntry?.error?.message,
|
|
423
|
+
});
|
|
424
|
+
return statuses;
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Check if a specific device is connected
|
|
428
|
+
*/
|
|
429
|
+
isConnected(type) {
|
|
430
|
+
if (type === HardwareWalletType.LEDGER)
|
|
431
|
+
return (!this.destruction && this.ledgerHost?.getStatus().connected === true);
|
|
432
|
+
const key = `${type}-default`;
|
|
433
|
+
const entry = this.connectionPool.get(key);
|
|
434
|
+
return entry?.status === ConnectionStatus.CONNECTED;
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Ensure connection before operation
|
|
438
|
+
*/
|
|
439
|
+
async ensureConnection(type) {
|
|
440
|
+
if (type === HardwareWalletType.LEDGER) {
|
|
441
|
+
await this.initializeLedger();
|
|
442
|
+
}
|
|
443
|
+
else if (type === HardwareWalletType.TREZOR) {
|
|
444
|
+
const initialized = await this.initializeTrezor();
|
|
445
|
+
if (!initialized) {
|
|
446
|
+
throw new Error('Failed to initialize Trezor');
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Close a specific connection
|
|
452
|
+
*/
|
|
453
|
+
async closeConnection(key, entry = this.connectionPool.get(key)) {
|
|
454
|
+
if (!entry || this.connectionPool.get(key) !== entry)
|
|
455
|
+
return;
|
|
456
|
+
// Handle Trezor connections
|
|
457
|
+
if (key.startsWith(HardwareWalletType.TREZOR)) {
|
|
458
|
+
try {
|
|
459
|
+
await TrezorConnect.dispose();
|
|
460
|
+
}
|
|
461
|
+
catch (error) {
|
|
462
|
+
console.error('Error disposing Trezor:', error);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
if (key.startsWith(HardwareWalletType.LEDGER)) {
|
|
466
|
+
try {
|
|
467
|
+
await this.ledgerHost?.disconnect();
|
|
468
|
+
}
|
|
469
|
+
catch (error) {
|
|
470
|
+
console.error('Error disconnecting Ledger host:', error);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
if (this.connectionPool.get(key) === entry)
|
|
474
|
+
this.connectionPool.delete(key);
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Close all connections and stop monitoring
|
|
478
|
+
*/
|
|
479
|
+
destroy() {
|
|
480
|
+
if (this.destruction)
|
|
481
|
+
return this.destruction;
|
|
482
|
+
// Revoke pending initialization synchronously, before closing any transport.
|
|
483
|
+
this.lifecycleGeneration++;
|
|
484
|
+
this.trezorInitialization = undefined;
|
|
485
|
+
this.ledgerInitialization = undefined;
|
|
486
|
+
this.unsubscribeTrezor?.();
|
|
487
|
+
this.unsubscribeTrezor = undefined;
|
|
488
|
+
// Stop monitoring
|
|
489
|
+
if (this.statusMonitorInterval) {
|
|
490
|
+
clearInterval(this.statusMonitorInterval);
|
|
491
|
+
this.statusMonitorInterval = null;
|
|
492
|
+
}
|
|
493
|
+
const entries = [...this.connectionPool.entries()];
|
|
494
|
+
const trezor = this.connectionPool.get('trezor-default');
|
|
495
|
+
if (trezor)
|
|
496
|
+
trezor.status = ConnectionStatus.DISCONNECTED;
|
|
497
|
+
let resolve;
|
|
498
|
+
let reject;
|
|
499
|
+
const destruction = new Promise((done, failed) => {
|
|
500
|
+
resolve = done;
|
|
501
|
+
reject = failed;
|
|
502
|
+
});
|
|
503
|
+
this.destruction = destruction;
|
|
504
|
+
// Revoke Trezor first, then Ledger in this same call stack. Awaiting either
|
|
505
|
+
// cleanup before revoking the other could admit an already-queued response.
|
|
506
|
+
const trezorCleanup = entries
|
|
507
|
+
.filter(([key]) => key.startsWith(HardwareWalletType.TREZOR))
|
|
508
|
+
.map(([key, entry]) => this.closeConnection(key, entry));
|
|
509
|
+
let ledgerCleanup;
|
|
510
|
+
try {
|
|
511
|
+
ledgerCleanup = Promise.resolve(this.ledgerHost?.disconnect()).catch((error) => {
|
|
512
|
+
console.error('Error disconnecting Ledger host:', error);
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
catch (error) {
|
|
516
|
+
console.error('Error disconnecting Ledger host:', error);
|
|
517
|
+
ledgerCleanup = Promise.resolve();
|
|
518
|
+
}
|
|
519
|
+
const close = async () => {
|
|
520
|
+
try {
|
|
521
|
+
await Promise.all([...trezorCleanup, ledgerCleanup]);
|
|
522
|
+
for (const [key, entry] of entries) {
|
|
523
|
+
if (this.connectionPool.get(key) === entry)
|
|
524
|
+
this.connectionPool.delete(key);
|
|
525
|
+
}
|
|
526
|
+
this.removeAllListeners();
|
|
527
|
+
}
|
|
528
|
+
finally {
|
|
529
|
+
if (this.destruction === destruction)
|
|
530
|
+
this.destruction = undefined;
|
|
531
|
+
}
|
|
532
|
+
};
|
|
533
|
+
void close().then(resolve, reject);
|
|
534
|
+
return destruction;
|
|
535
|
+
}
|
|
536
|
+
/**
|
|
537
|
+
* Calculate exponential backoff delay
|
|
538
|
+
*/
|
|
539
|
+
calculateBackoffDelay(attempt) {
|
|
540
|
+
const delay = Math.min(this.retryConfig.baseDelay *
|
|
541
|
+
Math.pow(this.retryConfig.backoffMultiplier, attempt), this.retryConfig.maxDelay);
|
|
542
|
+
// Add jitter (±20%)
|
|
543
|
+
const jitter = delay * 0.2 * (Math.random() - 0.5);
|
|
544
|
+
return Math.round(delay + jitter);
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* Delay helper
|
|
548
|
+
*/
|
|
549
|
+
delay(ms) {
|
|
550
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* Retry an operation with exponential backoff
|
|
554
|
+
*/
|
|
555
|
+
async retryOperation(operation, operationName, customRetryConfig) {
|
|
556
|
+
const config = { ...this.retryConfig, ...customRetryConfig };
|
|
557
|
+
let lastError;
|
|
558
|
+
for (let attempt = 0; attempt <= config.maxRetries; attempt++) {
|
|
559
|
+
try {
|
|
560
|
+
return await operation();
|
|
561
|
+
}
|
|
562
|
+
catch (error) {
|
|
563
|
+
lastError = error;
|
|
564
|
+
// Do not retry on explicit user cancellations (Ledger/Trezor)
|
|
565
|
+
if (this.isUserCancellationError(lastError)) {
|
|
566
|
+
throw lastError;
|
|
567
|
+
}
|
|
568
|
+
if (attempt < config.maxRetries) {
|
|
569
|
+
const delay = this.calculateBackoffDelay(attempt);
|
|
570
|
+
this.emit('operationRetry', {
|
|
571
|
+
operation: operationName,
|
|
572
|
+
attempt: attempt + 1,
|
|
573
|
+
nextRetryIn: delay,
|
|
574
|
+
error: lastError.message,
|
|
575
|
+
});
|
|
576
|
+
await this.delay(delay);
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
throw new Error(`${operationName} failed after ${config.maxRetries + 1} attempts: ${lastError?.message || 'Unknown error'}`);
|
|
581
|
+
}
|
|
582
|
+
/**
|
|
583
|
+
* Detects common user-cancellation errors to avoid pointless retries
|
|
584
|
+
*/
|
|
585
|
+
isUserCancellationError(err) {
|
|
586
|
+
const message = (err?.message || '').toLowerCase();
|
|
587
|
+
const name = err?.name || '';
|
|
588
|
+
const statusCode = err?.statusCode;
|
|
589
|
+
const code = err?.code;
|
|
590
|
+
if (code === 'HARDWARE_REQUEST_CANCELLED' ||
|
|
591
|
+
code === 'HARDWARE_CLEAR_SIGNING_UNAVAILABLE' ||
|
|
592
|
+
code === 'HARDWARE_ACCOUNT_MISMATCH' ||
|
|
593
|
+
code === 'LEDGER_INVALID_REQUEST' ||
|
|
594
|
+
code === 'LEDGER_INVALID_RESPONSE' ||
|
|
595
|
+
code === 'LEDGER_INVALID_SIGNATURE' ||
|
|
596
|
+
code === 'HARDWARE_SIGNER_UNAVAILABLE' ||
|
|
597
|
+
code === 'HARDWARE_SIGNER_BUSY' ||
|
|
598
|
+
code === 'Method_Cancel' ||
|
|
599
|
+
code === 'Method_Interrupted' ||
|
|
600
|
+
code === 'Method_PermissionsNotGranted' ||
|
|
601
|
+
code === 'Method_Unsupported' ||
|
|
602
|
+
code === 'Method_UnsupportedCoinForHost' ||
|
|
603
|
+
code === 'Device_Disconnected' ||
|
|
604
|
+
code === 'Device_NotFound' ||
|
|
605
|
+
code === 'Device_CallInProgress' ||
|
|
606
|
+
code === 'Transport_Missing' ||
|
|
607
|
+
code === 'Desktop_ConnectionMissing' ||
|
|
608
|
+
code === 'Browser_LocalNetworkPermissionMissing')
|
|
609
|
+
return true;
|
|
610
|
+
// Ledger: 0x6985 (Conditions of use not satisfied) on rejection
|
|
611
|
+
if (statusCode === 0x6985)
|
|
612
|
+
return true;
|
|
613
|
+
// Message-based heuristics across vendors
|
|
614
|
+
if (message.includes('0x6985') ||
|
|
615
|
+
(message.includes('condition') &&
|
|
616
|
+
message.includes('not') &&
|
|
617
|
+
message.includes('satisf')) ||
|
|
618
|
+
message.includes('not allowed') ||
|
|
619
|
+
message.includes('permission denied') ||
|
|
620
|
+
message.includes('permissions not granted') ||
|
|
621
|
+
message.includes('user rejected') ||
|
|
622
|
+
message.includes('denied by the user') ||
|
|
623
|
+
message.includes('failure_actioncancelled') ||
|
|
624
|
+
message.includes('denied') ||
|
|
625
|
+
message.includes('rejected') ||
|
|
626
|
+
message.includes('refused') ||
|
|
627
|
+
message.includes('cancelled') ||
|
|
628
|
+
message.includes('canceled') ||
|
|
629
|
+
message.includes('popup closed')) {
|
|
630
|
+
return true;
|
|
631
|
+
}
|
|
632
|
+
// Name-based checks (align with frontend utilities)
|
|
633
|
+
if (name === 'NotAllowedError' ||
|
|
634
|
+
name === 'AbortError' ||
|
|
635
|
+
name === 'UserCancel' ||
|
|
636
|
+
name === 'TransportError' ||
|
|
637
|
+
name === 'DOMException') {
|
|
638
|
+
return true;
|
|
639
|
+
}
|
|
640
|
+
return false;
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
//# sourceMappingURL=hardware-wallet-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hardware-wallet-manager.js","sourceRoot":"","sources":["../../src/hardware-wallet-manager.ts"],"names":[],"mappings":"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"}
|