@sidhujag/sysweb3-keyring 1.0.626 → 1.0.628

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.
Files changed (40) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/cjs/keyring-core.js +2512 -0
  3. package/cjs/keyring-core.js.map +1 -0
  4. package/cjs/keyring-manager.js +23 -2437
  5. package/cjs/keyring-manager.js.map +1 -1
  6. package/cjs/software.js +58 -0
  7. package/cjs/software.js.map +1 -0
  8. package/cjs/storage-core.js +227 -0
  9. package/cjs/storage-core.js.map +1 -0
  10. package/cjs/storage.js +15 -210
  11. package/cjs/storage.js.map +1 -1
  12. package/cjs/transactions/ethereum.js +121 -29
  13. package/cjs/transactions/ethereum.js.map +1 -1
  14. package/cjs/transactions/evm-local-signer.js +11 -1
  15. package/cjs/transactions/evm-local-signer.js.map +1 -1
  16. package/cjs/transactions/hardware-psbt.js +167 -0
  17. package/cjs/transactions/hardware-psbt.js.map +1 -0
  18. package/cjs/transactions/syscoin-core.js +651 -0
  19. package/cjs/transactions/syscoin-core.js.map +1 -0
  20. package/cjs/transactions/syscoin.js +8 -768
  21. package/cjs/transactions/syscoin.js.map +1 -1
  22. package/cjs/types.js.map +1 -1
  23. package/package.json +38 -4
  24. package/types/keyring-core.d.ts +257 -0
  25. package/types/keyring-manager.d.ts +5 -223
  26. package/types/software.d.ts +23 -0
  27. package/types/storage-core.d.ts +22 -0
  28. package/types/storage.d.ts +1 -4
  29. package/types/transactions/ethereum.d.ts +16 -6
  30. package/types/transactions/evm-local-signer.d.ts +3 -1
  31. package/types/transactions/hardware-psbt.d.ts +7 -0
  32. package/types/transactions/syscoin-core.d.ts +92 -0
  33. package/types/transactions/syscoin.d.ts +8 -67
  34. package/types/types.d.ts +10 -0
  35. package/cjs/transactions/__tests__/integration.test.js +0 -237
  36. package/cjs/transactions/__tests__/integration.test.js.map +0 -1
  37. package/cjs/transactions/__tests__/syscoin.test.js +0 -361
  38. package/cjs/transactions/__tests__/syscoin.test.js.map +0 -1
  39. package/types/transactions/__tests__/integration.test.d.ts +0 -1
  40. package/types/transactions/__tests__/syscoin.test.d.ts +0 -1
package/cjs/storage.js CHANGED
@@ -1,215 +1,20 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getDecryptedVault = exports.setEncryptedVault = exports.VaultAuthenticationError = void 0;
3
+ exports.VaultAuthenticationError = exports.getDecryptedVault = exports.setEncryptedVault = void 0;
7
4
  const sysweb3_core_1 = require("@sidhujag/sysweb3-core");
8
- const crypto_js_1 = __importDefault(require("crypto-js"));
5
+ const storage_core_1 = require("./storage-core");
6
+ // Preserve the legacy process-wide storage authority. Host-isolated consumers
7
+ // import storage-core directly and supply their own asynchronous storage port.
9
8
  const storage = sysweb3_core_1.sysweb3Di.getStateStorageDb();
10
- // Simple async mutex implementation to prevent concurrent vault operations
11
- class AsyncMutex {
12
- constructor() {
13
- this.mutex = Promise.resolve();
14
- }
15
- async runExclusive(callback) {
16
- const oldMutex = this.mutex;
17
- let release;
18
- this.mutex = new Promise((resolve) => {
19
- release = resolve;
20
- });
21
- await oldMutex;
22
- try {
23
- return await callback();
24
- }
25
- finally {
26
- release();
27
- }
28
- }
29
- }
30
- const vaultMutex = new AsyncMutex();
31
- const isHex = (s) => /^[0-9a-fA-F]+$/.test(s);
32
- const hexToBytes = (hex) => {
33
- const clean = (hex || '').trim();
34
- if (!isHex(clean) || clean.length % 2 !== 0) {
35
- throw new Error('Invalid hex string');
36
- }
37
- const out = new Uint8Array(clean.length / 2);
38
- for (let i = 0; i < out.length; i++) {
39
- out[i] = parseInt(clean.slice(i * 2, i * 2 + 2), 16);
40
- }
41
- return out;
42
- };
43
- const bytesToHex = (bytes) => {
44
- const u8 = new Uint8Array(bytes);
45
- let hex = '';
46
- for (let i = 0; i < u8.length; i++) {
47
- hex += u8[i].toString(16).padStart(2, '0');
48
- }
49
- return hex;
50
- };
51
- const maybeParseGcmEnvelope = (raw) => {
52
- if (!raw || typeof raw !== 'string')
53
- return null;
54
- if (!raw.trim().startsWith('{'))
55
- return null;
56
- try {
57
- const parsed = JSON.parse(raw);
58
- if (parsed &&
59
- parsed.v === 4 &&
60
- parsed.alg === 'A256GCM' &&
61
- typeof parsed.iv === 'string' &&
62
- typeof parsed.ct === 'string') {
63
- return parsed;
64
- }
65
- return null;
66
- }
67
- catch {
68
- return null;
69
- }
70
- };
71
- const encryptVaultWebCrypto = async (plaintextJson, keyHex) => {
72
- const subtle = globalThis.crypto.subtle;
73
- const iv = new Uint8Array(12);
74
- globalThis.crypto.getRandomValues(iv);
75
- const keyBytes = hexToBytes(keyHex);
76
- if (keyBytes.length !== 32) {
77
- throw new Error('Vault key must be 32 bytes (hex length 64)');
78
- }
79
- const key = await subtle.importKey('raw', keyBytes, { name: 'AES-GCM' }, false, ['encrypt']);
80
- const pt = new TextEncoder().encode(plaintextJson);
81
- const ct = await subtle.encrypt({ name: 'AES-GCM', iv: iv }, key, pt);
82
- return {
83
- v: 4,
84
- alg: 'A256GCM',
85
- iv: bytesToHex(iv.buffer),
86
- ct: bytesToHex(ct),
87
- };
88
- };
89
- class VaultAuthenticationError extends Error {
90
- constructor() {
91
- super('Failed to decrypt vault - invalid password or corrupted data');
92
- this.code = 'INVALID_PASSWORD';
93
- this.name = 'VaultAuthenticationError';
94
- }
95
- }
96
- exports.VaultAuthenticationError = VaultAuthenticationError;
97
- const invalidPasswordError = () => new VaultAuthenticationError();
98
- const decryptVaultWebCrypto = async (envelope, keyHex) => {
99
- const subtle = globalThis?.crypto?.subtle;
100
- if (!subtle) {
101
- throw new Error('WebCrypto is required to decrypt this vault');
102
- }
103
- const keyBytes = hexToBytes(keyHex);
104
- if (keyBytes.length !== 32) {
105
- throw new Error('Vault key must be 32 bytes (hex length 64)');
106
- }
107
- const key = await subtle.importKey('raw', keyBytes, { name: 'AES-GCM' }, false, ['decrypt']);
108
- const ivBytes = hexToBytes(envelope.iv);
109
- const ctBytes = hexToBytes(envelope.ct);
110
- if (ivBytes.length !== 12 || ctBytes.length < 16) {
111
- throw new Error('Invalid encrypted vault format');
112
- }
113
- let pt;
114
- try {
115
- pt = await subtle.decrypt({ name: 'AES-GCM', iv: ivBytes }, key, ctBytes);
116
- }
117
- catch (error) {
118
- // Only a failed authentication tag is a password/ciphertext failure.
119
- // Key import and other platform exceptions must remain operational.
120
- if (error?.name === 'OperationError') {
121
- throw invalidPasswordError();
122
- }
123
- throw error;
124
- }
125
- return new TextDecoder().decode(pt);
126
- };
127
- // Single vault for all networks - stores the mnemonic and can derive accounts for any slip44
128
- const setEncryptedVault = async (decryptedVault, pwd, freshVaultKeys) => {
129
- return vaultMutex.runExclusive(async () => {
130
- const plaintext = JSON.stringify(decryptedVault);
131
- // Writes never downgrade to unauthenticated passphrase AES. Legacy CBC
132
- // remains readable below, but missing WebCrypto is an operational failure.
133
- const canUseWebCrypto = !!globalThis?.crypto?.subtle &&
134
- !!globalThis?.crypto?.getRandomValues;
135
- if (!canUseWebCrypto) {
136
- throw new Error('WebCrypto is required for vault encryption');
137
- }
138
- if (typeof pwd !== 'string' || !isHex(pwd) || pwd.length !== 64) {
139
- throw new Error('Vault key must be 32 bytes (hex length 64)');
140
- }
141
- const envelope = await encryptVaultWebCrypto(plaintext, pwd);
142
- const toStore = JSON.stringify(envelope);
143
- if (freshVaultKeys) {
144
- // The backend primitive (or native storage Web Lock) covers both the
145
- // absence check and batch commit across independently bundled contexts.
146
- const created = await storage.createManyIfAbsent({
147
- 'vault-keys': freshVaultKeys,
148
- vault: toStore,
149
- });
150
- if (!created)
151
- throw new Error('Cannot initialize a new vault over existing wallet storage');
152
- }
153
- else {
154
- // Existing vault updates retain their migration-specific write ordering.
155
- await storage.set('vault', toStore);
156
- }
157
- });
158
- };
159
- exports.setEncryptedVault = setEncryptedVault;
160
- const getDecryptedVault = async (pwd, legacyPassword) => {
161
- return vaultMutex.runExclusive(async () => {
162
- // Always use single 'vault' key
163
- const vault = await storage.get('vault');
164
- if (!vault) {
165
- throw new Error('Vault not found');
166
- }
167
- // Prefer WebCrypto AES-GCM when the stored vault is in v4 envelope format.
168
- const maybeEnvelope = maybeParseGcmEnvelope(vault);
169
- if (!maybeEnvelope &&
170
- typeof vault === 'string' &&
171
- vault.trim().startsWith('{')) {
172
- // Legacy CBC vaults are base64. A JSON-shaped record must be a valid
173
- // GCM envelope rather than being misreported as a password failure.
174
- throw new Error('Invalid encrypted vault format');
175
- }
176
- let decryptedVault;
177
- if (maybeEnvelope) {
178
- decryptedVault = await decryptVaultWebCrypto(maybeEnvelope, pwd);
179
- }
180
- else {
181
- // Legacy CryptoJS passphrase-AES vault (v3 and older v4 canary).
182
- // An interrupted migration can already have written CBC with the
183
- // derived key while the metadata still selects the legacy password.
184
- for (const candidateKey of new Set([legacyPassword ?? pwd, pwd])) {
185
- let plaintext;
186
- try {
187
- plaintext = crypto_js_1.default.AES.decrypt(vault, candidateKey).toString(crypto_js_1.default.enc.Utf8);
188
- }
189
- catch (error) {
190
- if (error?.message === 'Malformed UTF-8 data')
191
- continue;
192
- throw error;
193
- }
194
- if (!plaintext)
195
- continue;
196
- try {
197
- return JSON.parse(plaintext);
198
- }
199
- catch (error) {
200
- // CBC has no authentication tag; invalid plaintext is the only
201
- // available indication of a bad password/ciphertext.
202
- if (!(error instanceof SyntaxError))
203
- throw error;
204
- }
205
- }
206
- throw invalidPasswordError();
207
- }
208
- if (!decryptedVault) {
209
- throw invalidPasswordError();
210
- }
211
- return JSON.parse(decryptedVault);
212
- });
213
- };
214
- exports.getDecryptedVault = getDecryptedVault;
9
+ const persistence = (0, storage_core_1.createVaultPersistence)({
10
+ get: async (key) => storage.get(key),
11
+ set: async (key, value) => {
12
+ await storage.set(key, value);
13
+ },
14
+ createManyIfAbsent: async (items) => storage.createManyIfAbsent(items),
15
+ });
16
+ exports.setEncryptedVault = persistence.setEncryptedVault;
17
+ exports.getDecryptedVault = persistence.getDecryptedVault;
18
+ var storage_core_2 = require("./storage-core");
19
+ Object.defineProperty(exports, "VaultAuthenticationError", { enumerable: true, get: function () { return storage_core_2.VaultAuthenticationError; } });
215
20
  //# sourceMappingURL=storage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/storage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/storage.ts"],"names":[],"mappings":";;;AAAA,yDAAmD;AAEnD,iDAAwD;AAExD,8EAA8E;AAC9E,+EAA+E;AAC/E,MAAM,OAAO,GAAG,wBAAS,CAAC,iBAAiB,EAAE,CAAC;AAC9C,MAAM,WAAW,GAAG,IAAA,qCAAsB,EAAC;IACzC,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;IACpC,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE;QACxB,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAChC,CAAC;IACD,kBAAkB,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,kBAAkB,CAAC,KAAK,CAAC;CACvE,CAAC,CAAC;AAEU,QAAA,iBAAiB,GAAG,WAAW,CAAC,iBAAiB,CAAC;AAClD,QAAA,iBAAiB,GAAG,WAAW,CAAC,iBAAiB,CAAC;AAC/D,+CAA0D;AAAjD,wHAAA,wBAAwB,OAAA"}
@@ -14,6 +14,9 @@ const providers_1 = require("../providers");
14
14
  const types_1 = require("../types");
15
15
  const evm_local_signer_1 = require("./evm-local-signer");
16
16
  const derivation_paths_1 = require("../utils/derivation-paths");
17
+ const hardwareSignerUnavailable = (hardware) => Object.assign(new Error(`${hardware} signer is unavailable in this host`), {
18
+ code: 'HARDWARE_SIGNER_UNAVAILABLE',
19
+ });
17
20
  const stripHexPrefix = (value) => value.startsWith('0x') || value.startsWith('0X') ? value.slice(2) : value;
18
21
  const normalizeEthersOverrideValue = (value) => (0, ethers_v6_1.normalizeTxValue)(value);
19
22
  const nonNegativeFeeQuantity = (value, label) => {
@@ -131,7 +134,28 @@ class EthereumTransactions {
131
134
  constructor(getNetwork, getDecryptedPrivateKey, getState, ledgerSigner, trezorSigner, captureSigningContext) {
132
135
  // Allow manual override of gas parameters when automatic estimation fails
133
136
  this.gasOverrides = {};
137
+ this.requireLedgerSigner = () => {
138
+ if (!this.ledgerSigner)
139
+ throw hardwareSignerUnavailable('Ledger');
140
+ return this.ledgerSigner;
141
+ };
142
+ this.requireTrezorSigner = () => {
143
+ if (!this.trezorSigner)
144
+ throw hardwareSignerUnavailable('Trezor');
145
+ return this.trezorSigner;
146
+ };
147
+ this.assertHardwareSignerAvailable = (targetAccount) => {
148
+ const state = this.getState();
149
+ const type = targetAccount?.type ?? state.activeAccountType;
150
+ const id = targetAccount?.id ?? state.activeAccountId;
151
+ const account = state.accounts[type]?.[id];
152
+ if (type === types_1.KeyringAccountType.Ledger || account?.isLedgerWallet)
153
+ this.requireLedgerSigner();
154
+ if (type === types_1.KeyringAccountType.Trezor || account?.isTrezorWallet)
155
+ this.requireTrezorSigner();
156
+ };
134
157
  this.captureEvmSigningContext = () => {
158
+ this.assertHardwareSignerAvailable();
135
159
  const { activeAccountType, activeAccountId, accounts, activeNetwork } = this.getState();
136
160
  const selectedAccount = accounts[activeAccountType]?.[activeAccountId];
137
161
  if (!selectedAccount)
@@ -192,7 +216,7 @@ class EthereumTransactions {
192
216
  throw {
193
217
  message: 'Decrypting for wrong address, change activeAccount maybe',
194
218
  };
195
- return await this.ledgerSigner.evm.signTypedData({
219
+ return await this.requireLedgerSigner().evm.signTypedData({
196
220
  version,
197
221
  accountIndex: activeAccountId,
198
222
  data: typedData,
@@ -203,7 +227,7 @@ class EthereumTransactions {
203
227
  throw {
204
228
  message: 'Decrypting for wrong address, change activeAccount maybe',
205
229
  };
206
- return await this.trezorSigner.signTypedData({
230
+ return await this.requireTrezorSigner().signTypedData({
207
231
  version,
208
232
  address: addr,
209
233
  data: typedData,
@@ -225,9 +249,9 @@ class EthereumTransactions {
225
249
  const { activeAccountType } = this.getState();
226
250
  switch (activeAccountType) {
227
251
  case types_1.KeyringAccountType.Ledger:
228
- return await this.ledgerSigner.verifyUtxoAddress(accountIndex, currency, slip44);
252
+ return await this.requireLedgerSigner().verifyUtxoAddress(accountIndex, currency, slip44);
229
253
  case types_1.KeyringAccountType.Trezor:
230
- return await this.trezorSigner.verifyUtxoAddress(accountIndex, currency, slip44);
254
+ return await this.requireTrezorSigner().verifyUtxoAddress(accountIndex, currency, slip44);
231
255
  default:
232
256
  throw new Error('verifyUtxoAddress is only available for hardware wallet accounts');
233
257
  }
@@ -284,7 +308,7 @@ class EthereumTransactions {
284
308
  };
285
309
  const signWithLedger = async () => {
286
310
  try {
287
- const response = await this.ledgerSigner.evm.signPersonalMessage({
311
+ const response = await this.requireLedgerSigner().evm.signPersonalMessage({
288
312
  accountIndex: activeAccountId,
289
313
  message: msg,
290
314
  });
@@ -298,7 +322,7 @@ class EthereumTransactions {
298
322
  try {
299
323
  // For EVM networks, Trezor expects 'eth' regardless of the network's currency
300
324
  const trezorCoin = activeNetwork.slip44 === 60 ? 'eth' : activeNetwork.currency;
301
- const response = await this.trezorSigner.signMessage({
325
+ const response = await this.requireTrezorSigner().signMessage({
302
326
  coin: trezorCoin,
303
327
  address: activeAccount.address,
304
328
  index: activeAccountId,
@@ -377,7 +401,7 @@ class EthereumTransactions {
377
401
  // Message is plain text, convert to hex
378
402
  messageForLedger = Buffer.from(msg, 'utf8').toString('hex');
379
403
  }
380
- const response = await this.ledgerSigner.evm.signPersonalMessage({
404
+ const response = await this.requireLedgerSigner().evm.signPersonalMessage({
381
405
  accountIndex: activeAccountId,
382
406
  message: messageForLedger,
383
407
  });
@@ -401,7 +425,7 @@ class EthereumTransactions {
401
425
  }
402
426
  // For EVM networks, Trezor expects 'eth' regardless of the network's currency
403
427
  const trezorCoin = activeNetwork.slip44 === 60 ? 'eth' : activeNetwork.currency;
404
- const response = await this.trezorSigner.signMessage({
428
+ const response = await this.requireTrezorSigner().signMessage({
405
429
  coin: trezorCoin,
406
430
  address: activeAccount.address,
407
431
  index: activeAccountId,
@@ -674,9 +698,52 @@ class EthereumTransactions {
674
698
  (!Number.isSafeInteger(fallbackNonce) || fallbackNonce < 0)) {
675
699
  throw new Error('Invalid cancellation fallback nonce');
676
700
  }
701
+ const previewOnly = options.previewOnly === true;
702
+ const approvedMaximumFee = options.approvedMaximumFee;
703
+ if (!previewOnly &&
704
+ (typeof approvedMaximumFee !== 'string' ||
705
+ !/^(0|[1-9][0-9]{0,77})$/.test(approvedMaximumFee))) {
706
+ throw new Error('Cancellation fee approval required');
707
+ }
677
708
  const assertHostContext = options.assertCurrentContext;
678
709
  assertHostContext();
679
- const { activeAccount, activeAccountType, activeAccountId, activeNetwork, provider, assertCurrent: assertKeyringContext, } = this.captureEvmSigningContext();
710
+ const state = this.getState();
711
+ const selectedType = state.activeAccountType;
712
+ const selectedId = state.activeAccountId;
713
+ const selectedAddress = state.accounts?.[selectedType]?.[selectedId]?.address;
714
+ const activeAccountType = options.targetAccount?.type ?? selectedType;
715
+ const activeAccountId = options.targetAccount?.id ?? selectedId;
716
+ const targetAccount = options.targetAccount
717
+ ? { type: activeAccountType, id: activeAccountId }
718
+ : undefined;
719
+ const activeAccount = {
720
+ ...state.accounts?.[activeAccountType]?.[activeAccountId],
721
+ };
722
+ const activeNetwork = { ...state.activeNetwork };
723
+ if (!selectedAddress ||
724
+ !activeAccount.address ||
725
+ (targetAccount && activeAccountType === types_1.KeyringAccountType.SmartAccount)) {
726
+ throw new Error('Cancellation signing account is unavailable');
727
+ }
728
+ if (!previewOnly)
729
+ this.assertHardwareSignerAvailable(targetAccount);
730
+ const provider = this.web3Provider;
731
+ const assertSession = this.captureSigningContext?.();
732
+ const assertKeyringContext = () => {
733
+ assertSession?.();
734
+ const current = this.getState();
735
+ if (current.activeAccountType !== selectedType ||
736
+ current.activeAccountId !== selectedId ||
737
+ current.accounts?.[selectedType]?.[selectedId]?.address?.toLowerCase() !== selectedAddress.toLowerCase() ||
738
+ current.accounts?.[activeAccountType]?.[activeAccountId]?.address?.toLowerCase() !== activeAccount.address.toLowerCase() ||
739
+ [current.activeNetwork, this.getNetwork()].some((selected) => selected.kind !== activeNetwork.kind ||
740
+ selected.chainId !== activeNetwork.chainId ||
741
+ selected.slip44 !== activeNetwork.slip44 ||
742
+ selected.url !== activeNetwork.url) ||
743
+ this.web3Provider !== provider) {
744
+ throw new Error('Wallet signing context changed');
745
+ }
746
+ };
680
747
  const assertCurrent = () => {
681
748
  assertHostContext();
682
749
  assertKeyringContext();
@@ -798,6 +865,22 @@ class EthereumTransactions {
798
865
  maxPriorityFeePerGas: bumpCancelFee(oldTxsGasValues.maxPriorityFeePerGas),
799
866
  }),
800
867
  };
868
+ const maximumFee = newGasValues.gasLimit.mul(isLegacy ? newGasValues.gasPrice : newGasValues.maxFeePerGas);
869
+ assertCurrent();
870
+ if (previewOnly)
871
+ return {
872
+ isCanceled: false,
873
+ error: false,
874
+ maximumFee: maximumFee.toString(),
875
+ };
876
+ if (maximumFee.gt(approvedMaximumFee))
877
+ throw new Error('Cancellation fee exceeds approval');
878
+ const assertApprovedEnvelope = (transaction) => {
879
+ const gas = nonNegativeFeeQuantity(transaction.gasLimit, 'cancellation gas limit');
880
+ const cap = nonNegativeFeeQuantity(isLegacy ? transaction.gasPrice : transaction.maxFeePerGas, 'cancellation maximum fee');
881
+ if (!gas.eq(42000) || gas.mul(cap).gt(approvedMaximumFee))
882
+ throw new Error('Cancellation fee exceeds approval');
883
+ };
801
884
  // Base cancel transaction parameters (same for all wallet types)
802
885
  const baseCancelTx = {
803
886
  nonce: tx.nonce,
@@ -841,8 +924,9 @@ class EthereumTransactions {
841
924
  chainId: activeNetwork.chainId,
842
925
  type: 2, // Need explicit type for hardware wallet serialization
843
926
  };
927
+ assertApprovedEnvelope(txFormattedForEthers);
844
928
  const rawTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers);
845
- const signature = await this.ledgerSigner.evm.signEVMTransaction({
929
+ const signature = await this.requireLedgerSigner().evm.signEVMTransaction({
846
930
  rawTx: rawTx.replace('0x', ''),
847
931
  accountIndex: activeAccountId,
848
932
  });
@@ -908,7 +992,8 @@ class EthereumTransactions {
908
992
  ? formattedTx.maxPriorityFeePerGas
909
993
  : this.toHex0x(formattedTx.maxPriorityFeePerGas, 'maxPriorityFeePerGas');
910
994
  }
911
- const signature = await this.trezorSigner.signEthTransaction({
995
+ assertApprovedEnvelope(txFormattedForTrezor);
996
+ const signature = await this.requireTrezorSigner().signEthTransaction({
912
997
  coin: trezorCoin,
913
998
  tx: txFormattedForTrezor,
914
999
  index: activeAccountId.toString(),
@@ -942,11 +1027,11 @@ class EthereumTransactions {
942
1027
  const cancelWithPrivateKey = async () => {
943
1028
  try {
944
1029
  assertCurrent();
945
- const { address, decryptedPrivateKey } = this.getDecryptedPrivateKey();
1030
+ const { address, decryptedPrivateKey } = this.getDecryptedPrivateKey(targetAccount);
946
1031
  if (address?.toLowerCase() !== activeAccount.address.toLowerCase()) {
947
1032
  throw new Error('Wallet signing context changed');
948
1033
  }
949
- const transactionResponse = await (0, evm_local_signer_1.sendLocalEvmTransaction)(provider, decryptedPrivateKey, changedTxToCancel, assertCurrent, assertCurrent);
1034
+ const transactionResponse = await (0, evm_local_signer_1.sendLocalEvmTransaction)(provider, decryptedPrivateKey, changedTxToCancel, assertCurrent, assertCurrent, assertApprovedEnvelope);
950
1035
  if (transactionResponse) {
951
1036
  return {
952
1037
  isCanceled: true,
@@ -1107,7 +1192,7 @@ class EthereumTransactions {
1107
1192
  type: 2, // Need explicit type for hardware wallet serialization
1108
1193
  };
1109
1194
  const rawTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers);
1110
- const signature = await this.ledgerSigner.evm.signEVMTransaction({
1195
+ const signature = await this.requireLedgerSigner().evm.signEVMTransaction({
1111
1196
  rawTx: rawTx.replace('0x', ''),
1112
1197
  accountIndex: activeAccountId,
1113
1198
  });
@@ -1180,7 +1265,7 @@ class EthereumTransactions {
1180
1265
  };
1181
1266
  break;
1182
1267
  }
1183
- const signature = await this.trezorSigner.signEthTransaction({
1268
+ const signature = await this.requireTrezorSigner().signEthTransaction({
1184
1269
  index: `${activeAccountId}`,
1185
1270
  tx: txFormattedForTrezor,
1186
1271
  coin: activeNetwork.currency,
@@ -1252,6 +1337,8 @@ class EthereumTransactions {
1252
1337
  this.sendTransactionWithEditedFee = async (txHash, isLegacy = false, options = {}) => {
1253
1338
  const { assertCurrentContext, validateOriginal, beforeBroadcast, approvedMaximumFee, } = options;
1254
1339
  const previewOnly = options.previewOnly === true;
1340
+ if (!previewOnly)
1341
+ this.assertHardwareSignerAvailable(options.targetAccount);
1255
1342
  if (!previewOnly &&
1256
1343
  (typeof approvedMaximumFee !== 'string' ||
1257
1344
  !/^\d{1,78}$/.test(approvedMaximumFee))) {
@@ -1366,7 +1453,6 @@ class EthereumTransactions {
1366
1453
  newGasValues.maxPriorityFeePerGas.gt(newGasValues.maxFeePerGas))
1367
1454
  throw new Error('Invalid replacement fee');
1368
1455
  const maximumFee = newGasValues.gasLimit.mul(isLegacy ? newGasValues.gasPrice : newGasValues.maxFeePerGas);
1369
- let adjustedValue = txValue;
1370
1456
  if (isLikelyMaxSend && txValue.add(maximumFee).gt(currentBalance)) {
1371
1457
  if (isContractCall) {
1372
1458
  console.error('[SpeedUp] Cannot adjust value for contract call - rejecting speedup');
@@ -1377,16 +1463,19 @@ class EthereumTransactions {
1377
1463
  message: 'Cannot speed up a likely max-send contract call; value cannot be adjusted to fit new gas',
1378
1464
  };
1379
1465
  }
1380
- adjustedValue = currentBalance.gt(maximumFee)
1381
- ? currentBalance.sub(maximumFee)
1382
- : ethers_v6_1.Zero;
1466
+ return {
1467
+ isSpeedUp: false,
1468
+ error: true,
1469
+ code: 'REPLACEMENT_VALUE_WOULD_CHANGE',
1470
+ message: 'Add funds before speeding up this transaction; the original amount will not be changed',
1471
+ };
1383
1472
  }
1384
1473
  const txWithEditedFee = {
1385
1474
  chainId: activeNetwork.chainId,
1386
1475
  from: tx.from,
1387
1476
  to: tx.to,
1388
1477
  nonce: tx.nonce,
1389
- value: adjustedValue,
1478
+ value: txValue,
1390
1479
  data: txData,
1391
1480
  gasLimit: newGasValues.gasLimit,
1392
1481
  ...(tx.accessList != null ? { accessList: tx.accessList } : {}),
@@ -1424,7 +1513,7 @@ class EthereumTransactions {
1424
1513
  };
1425
1514
  const rawTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers);
1426
1515
  assertCurrent();
1427
- const signature = await this.ledgerSigner.evm.signEVMTransaction({
1516
+ const signature = await this.requireLedgerSigner().evm.signEVMTransaction({
1428
1517
  rawTx: rawTx.replace('0x', ''),
1429
1518
  accountIndex: activeAccountId,
1430
1519
  });
@@ -1505,7 +1594,7 @@ class EthereumTransactions {
1505
1594
  : this.toHex0x(formattedTx.maxPriorityFeePerGas, 'maxPriorityFeePerGas');
1506
1595
  }
1507
1596
  assertCurrent();
1508
- const signature = await this.trezorSigner.signEthTransaction({
1597
+ const signature = await this.requireTrezorSigner().signEthTransaction({
1509
1598
  coin: trezorCoin,
1510
1599
  tx: txFormattedForTrezor,
1511
1600
  index: activeAccountId.toString(),
@@ -1688,7 +1777,7 @@ class EthereumTransactions {
1688
1777
  };
1689
1778
  }
1690
1779
  const rawTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers);
1691
- const signature = await this.ledgerSigner.evm.signEVMTransaction({
1780
+ const signature = await this.requireLedgerSigner().evm.signEVMTransaction({
1692
1781
  rawTx: rawTx.replace('0x', ''),
1693
1782
  accountIndex: activeAccountId,
1694
1783
  });
@@ -1756,7 +1845,7 @@ class EthereumTransactions {
1756
1845
  data: txData,
1757
1846
  };
1758
1847
  }
1759
- const signature = await this.trezorSigner.signEthTransaction({
1848
+ const signature = await this.requireTrezorSigner().signEthTransaction({
1760
1849
  index: `${activeAccountId}`,
1761
1850
  tx: txToBeSignedByTrezor,
1762
1851
  coin: activeNetwork.currency,
@@ -1909,7 +1998,7 @@ class EthereumTransactions {
1909
1998
  };
1910
1999
  }
1911
2000
  const rawTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers);
1912
- const signature = await this.ledgerSigner.evm.signEVMTransaction({
2001
+ const signature = await this.requireLedgerSigner().evm.signEVMTransaction({
1913
2002
  rawTx: rawTx.replace('0x', ''),
1914
2003
  accountIndex: activeAccountId,
1915
2004
  });
@@ -1978,7 +2067,7 @@ class EthereumTransactions {
1978
2067
  }
1979
2068
  // For EVM networks, Trezor expects 'eth' regardless of the network's currency
1980
2069
  const trezorCoin = activeNetwork.slip44 === 60 ? 'eth' : activeNetwork.currency;
1981
- const signature = await this.trezorSigner.signEthTransaction({
2070
+ const signature = await this.requireTrezorSigner().signEthTransaction({
1982
2071
  index: `${activeAccountId}`,
1983
2072
  tx: txToBeSignedByTrezor,
1984
2073
  coin: trezorCoin,
@@ -2127,7 +2216,7 @@ class EthereumTransactions {
2127
2216
  };
2128
2217
  }
2129
2218
  const rawTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers);
2130
- const signature = await this.ledgerSigner.evm.signEVMTransaction({
2219
+ const signature = await this.requireLedgerSigner().evm.signEVMTransaction({
2131
2220
  rawTx: rawTx.replace('0x', ''),
2132
2221
  accountIndex: activeAccountId,
2133
2222
  });
@@ -2190,7 +2279,7 @@ class EthereumTransactions {
2190
2279
  data: txData,
2191
2280
  };
2192
2281
  }
2193
- const signature = await this.trezorSigner.signEthTransaction({
2282
+ const signature = await this.requireTrezorSigner().signEthTransaction({
2194
2283
  index: `${activeAccountId}`,
2195
2284
  tx: txToBeSignedByTrezor,
2196
2285
  coin: activeNetwork.currency,
@@ -2403,7 +2492,10 @@ class EthereumTransactions {
2403
2492
  };
2404
2493
  };
2405
2494
  this.getNetwork = getNetwork;
2406
- this.getDecryptedPrivateKey = getDecryptedPrivateKey;
2495
+ this.getDecryptedPrivateKey = (targetAccount) => {
2496
+ this.assertHardwareSignerAvailable(targetAccount);
2497
+ return getDecryptedPrivateKey(targetAccount);
2498
+ };
2407
2499
  this.abortController = new AbortController();
2408
2500
  // NOTE: Defer network access until vault state getter is initialized
2409
2501
  // The web3Provider will be created lazily when first accessed via getters