@sidhujag/sysweb3-keyring 1.0.627 → 2.0.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 +42 -0
- package/README.md +66 -0
- package/cjs/hardware-wallet-manager.js +302 -128
- package/cjs/hardware-wallet-manager.js.map +1 -1
- package/cjs/keyring-core.js +2605 -0
- package/cjs/keyring-core.js.map +1 -0
- package/cjs/keyring-manager.js +31 -2439
- 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/software-hd-account.js +23 -0
- package/cjs/software-hd-account.js.map +1 -0
- package/cjs/software.js +74 -0
- package/cjs/software.js.map +1 -0
- package/cjs/storage-core.js +227 -0
- package/cjs/storage-core.js.map +1 -0
- package/cjs/storage.js +15 -210
- package/cjs/storage.js.map +1 -1
- package/cjs/transactions/ethereum.js +176 -39
- package/cjs/transactions/ethereum.js.map +1 -1
- package/cjs/transactions/evm-local-signer.js +11 -1
- package/cjs/transactions/evm-local-signer.js.map +1 -1
- package/cjs/transactions/hardware-psbt.js +159 -0
- package/cjs/transactions/hardware-psbt.js.map +1 -0
- package/cjs/transactions/prepared-evm.js +196 -0
- package/cjs/transactions/prepared-evm.js.map +1 -0
- package/cjs/transactions/syscoin-core.js +651 -0
- package/cjs/transactions/syscoin-core.js.map +1 -0
- package/cjs/transactions/syscoin.js +8 -768
- package/cjs/transactions/syscoin.js.map +1 -1
- 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/types.js.map +1 -1
- 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 +55 -8
- package/types/hardware-wallet-manager.d.ts +12 -19
- package/types/keyring-core.d.ts +263 -0
- package/types/keyring-manager.d.ts +7 -224
- 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/software-hd-account.d.ts +16 -0
- package/types/software.d.ts +39 -0
- package/types/storage-core.d.ts +22 -0
- package/types/storage.d.ts +1 -4
- package/types/transactions/ethereum.d.ts +17 -7
- package/types/transactions/evm-local-signer.d.ts +3 -1
- package/types/transactions/hardware-psbt.d.ts +7 -0
- package/types/transactions/prepared-evm.d.ts +53 -0
- package/types/transactions/syscoin-core.d.ts +92 -0
- package/types/transactions/syscoin.d.ts +8 -67
- 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/types.d.ts +10 -0
- package/types/utils/psbt-account-scope.d.ts +1 -0
- package/cjs/transactions/__tests__/integration.test.js +0 -237
- package/cjs/transactions/__tests__/integration.test.js.map +0 -1
- package/cjs/transactions/__tests__/syscoin.test.js +0 -361
- package/cjs/transactions/__tests__/syscoin.test.js.map +0 -1
- package/types/transactions/__tests__/integration.test.d.ts +0 -1
- package/types/transactions/__tests__/syscoin.test.d.ts +0 -1
|
@@ -14,7 +14,38 @@ 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
|
+
});
|
|
20
|
+
const assertHardwareTransactionSender = (signedTx, expectedAddress) => {
|
|
21
|
+
if (transaction_1.Transaction.from(signedTx).from?.toLowerCase() !==
|
|
22
|
+
expectedAddress.toLowerCase()) {
|
|
23
|
+
throw Object.assign(new Error('Hardware signature does not match the approved account'), {
|
|
24
|
+
code: 'HARDWARE_ACCOUNT_MISMATCH',
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
};
|
|
17
28
|
const stripHexPrefix = (value) => value.startsWith('0x') || value.startsWith('0X') ? value.slice(2) : value;
|
|
29
|
+
// Connect returns hexadecimal signature fields; normalize their encoding
|
|
30
|
+
// without mutating the response or reparsing an already numeric recovery v.
|
|
31
|
+
const trezorSignature = (signature) => {
|
|
32
|
+
const { r, s, v } = signature;
|
|
33
|
+
if (![r, s].every((value) => /^(?:0x)?[0-9a-f]{64}$/i.test(value))) {
|
|
34
|
+
throw new Error('Invalid Trezor signature scalar encoding');
|
|
35
|
+
}
|
|
36
|
+
if (typeof v === 'string' && !/^(?:0x)?[0-9a-f]+$/i.test(v)) {
|
|
37
|
+
throw new Error('Invalid Trezor signature recovery value');
|
|
38
|
+
}
|
|
39
|
+
const recovery = typeof v === 'number' ? v : Number.parseInt(v, 16);
|
|
40
|
+
if (!Number.isSafeInteger(recovery) || recovery < 0) {
|
|
41
|
+
throw new Error('Invalid Trezor signature recovery value');
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
r: `0x${stripHexPrefix(r)}`,
|
|
45
|
+
s: `0x${stripHexPrefix(s)}`,
|
|
46
|
+
v: recovery,
|
|
47
|
+
};
|
|
48
|
+
};
|
|
18
49
|
const normalizeEthersOverrideValue = (value) => (0, ethers_v6_1.normalizeTxValue)(value);
|
|
19
50
|
const nonNegativeFeeQuantity = (value, label) => {
|
|
20
51
|
// Match the exported BigNumberish object contract without trusting a
|
|
@@ -131,7 +162,28 @@ class EthereumTransactions {
|
|
|
131
162
|
constructor(getNetwork, getDecryptedPrivateKey, getState, ledgerSigner, trezorSigner, captureSigningContext) {
|
|
132
163
|
// Allow manual override of gas parameters when automatic estimation fails
|
|
133
164
|
this.gasOverrides = {};
|
|
165
|
+
this.requireLedgerSigner = () => {
|
|
166
|
+
if (!this.ledgerSigner)
|
|
167
|
+
throw hardwareSignerUnavailable('Ledger');
|
|
168
|
+
return this.ledgerSigner;
|
|
169
|
+
};
|
|
170
|
+
this.requireTrezorSigner = () => {
|
|
171
|
+
if (!this.trezorSigner)
|
|
172
|
+
throw hardwareSignerUnavailable('Trezor');
|
|
173
|
+
return this.trezorSigner;
|
|
174
|
+
};
|
|
175
|
+
this.assertHardwareSignerAvailable = (targetAccount) => {
|
|
176
|
+
const state = this.getState();
|
|
177
|
+
const type = targetAccount?.type ?? state.activeAccountType;
|
|
178
|
+
const id = targetAccount?.id ?? state.activeAccountId;
|
|
179
|
+
const account = state.accounts[type]?.[id];
|
|
180
|
+
if (type === types_1.KeyringAccountType.Ledger || account?.isLedgerWallet)
|
|
181
|
+
this.requireLedgerSigner();
|
|
182
|
+
if (type === types_1.KeyringAccountType.Trezor || account?.isTrezorWallet)
|
|
183
|
+
this.requireTrezorSigner();
|
|
184
|
+
};
|
|
134
185
|
this.captureEvmSigningContext = () => {
|
|
186
|
+
this.assertHardwareSignerAvailable();
|
|
135
187
|
const { activeAccountType, activeAccountId, accounts, activeNetwork } = this.getState();
|
|
136
188
|
const selectedAccount = accounts[activeAccountType]?.[activeAccountId];
|
|
137
189
|
if (!selectedAccount)
|
|
@@ -192,9 +244,10 @@ class EthereumTransactions {
|
|
|
192
244
|
throw {
|
|
193
245
|
message: 'Decrypting for wrong address, change activeAccount maybe',
|
|
194
246
|
};
|
|
195
|
-
return await this.
|
|
247
|
+
return await this.requireLedgerSigner().evm.signTypedData({
|
|
196
248
|
version,
|
|
197
249
|
accountIndex: activeAccountId,
|
|
250
|
+
expectedAddress: activeAccount.address,
|
|
198
251
|
data: typedData,
|
|
199
252
|
});
|
|
200
253
|
};
|
|
@@ -203,7 +256,7 @@ class EthereumTransactions {
|
|
|
203
256
|
throw {
|
|
204
257
|
message: 'Decrypting for wrong address, change activeAccount maybe',
|
|
205
258
|
};
|
|
206
|
-
return await this.
|
|
259
|
+
return await this.requireTrezorSigner().signTypedData({
|
|
207
260
|
version,
|
|
208
261
|
address: addr,
|
|
209
262
|
data: typedData,
|
|
@@ -225,9 +278,9 @@ class EthereumTransactions {
|
|
|
225
278
|
const { activeAccountType } = this.getState();
|
|
226
279
|
switch (activeAccountType) {
|
|
227
280
|
case types_1.KeyringAccountType.Ledger:
|
|
228
|
-
return await this.
|
|
281
|
+
return await this.requireLedgerSigner().verifyUtxoAddress(accountIndex, currency, slip44);
|
|
229
282
|
case types_1.KeyringAccountType.Trezor:
|
|
230
|
-
return await this.
|
|
283
|
+
return await this.requireTrezorSigner().verifyUtxoAddress(accountIndex, currency, slip44);
|
|
231
284
|
default:
|
|
232
285
|
throw new Error('verifyUtxoAddress is only available for hardware wallet accounts');
|
|
233
286
|
}
|
|
@@ -284,8 +337,9 @@ class EthereumTransactions {
|
|
|
284
337
|
};
|
|
285
338
|
const signWithLedger = async () => {
|
|
286
339
|
try {
|
|
287
|
-
const response = await this.
|
|
340
|
+
const response = await this.requireLedgerSigner().evm.signPersonalMessage({
|
|
288
341
|
accountIndex: activeAccountId,
|
|
342
|
+
expectedAddress: activeAccount.address,
|
|
289
343
|
message: msg,
|
|
290
344
|
});
|
|
291
345
|
return response;
|
|
@@ -298,7 +352,7 @@ class EthereumTransactions {
|
|
|
298
352
|
try {
|
|
299
353
|
// For EVM networks, Trezor expects 'eth' regardless of the network's currency
|
|
300
354
|
const trezorCoin = activeNetwork.slip44 === 60 ? 'eth' : activeNetwork.currency;
|
|
301
|
-
const response = await this.
|
|
355
|
+
const response = await this.requireTrezorSigner().signMessage({
|
|
302
356
|
coin: trezorCoin,
|
|
303
357
|
address: activeAccount.address,
|
|
304
358
|
index: activeAccountId,
|
|
@@ -377,8 +431,9 @@ class EthereumTransactions {
|
|
|
377
431
|
// Message is plain text, convert to hex
|
|
378
432
|
messageForLedger = Buffer.from(msg, 'utf8').toString('hex');
|
|
379
433
|
}
|
|
380
|
-
const response = await this.
|
|
434
|
+
const response = await this.requireLedgerSigner().evm.signPersonalMessage({
|
|
381
435
|
accountIndex: activeAccountId,
|
|
436
|
+
expectedAddress: activeAccount.address,
|
|
382
437
|
message: messageForLedger,
|
|
383
438
|
});
|
|
384
439
|
return response;
|
|
@@ -401,7 +456,7 @@ class EthereumTransactions {
|
|
|
401
456
|
}
|
|
402
457
|
// For EVM networks, Trezor expects 'eth' regardless of the network's currency
|
|
403
458
|
const trezorCoin = activeNetwork.slip44 === 60 ? 'eth' : activeNetwork.currency;
|
|
404
|
-
const response = await this.
|
|
459
|
+
const response = await this.requireTrezorSigner().signMessage({
|
|
405
460
|
coin: trezorCoin,
|
|
406
461
|
address: activeAccount.address,
|
|
407
462
|
index: activeAccountId,
|
|
@@ -674,9 +729,52 @@ class EthereumTransactions {
|
|
|
674
729
|
(!Number.isSafeInteger(fallbackNonce) || fallbackNonce < 0)) {
|
|
675
730
|
throw new Error('Invalid cancellation fallback nonce');
|
|
676
731
|
}
|
|
732
|
+
const previewOnly = options.previewOnly === true;
|
|
733
|
+
const approvedMaximumFee = options.approvedMaximumFee;
|
|
734
|
+
if (!previewOnly &&
|
|
735
|
+
(typeof approvedMaximumFee !== 'string' ||
|
|
736
|
+
!/^(0|[1-9][0-9]{0,77})$/.test(approvedMaximumFee))) {
|
|
737
|
+
throw new Error('Cancellation fee approval required');
|
|
738
|
+
}
|
|
677
739
|
const assertHostContext = options.assertCurrentContext;
|
|
678
740
|
assertHostContext();
|
|
679
|
-
const
|
|
741
|
+
const state = this.getState();
|
|
742
|
+
const selectedType = state.activeAccountType;
|
|
743
|
+
const selectedId = state.activeAccountId;
|
|
744
|
+
const selectedAddress = state.accounts?.[selectedType]?.[selectedId]?.address;
|
|
745
|
+
const activeAccountType = options.targetAccount?.type ?? selectedType;
|
|
746
|
+
const activeAccountId = options.targetAccount?.id ?? selectedId;
|
|
747
|
+
const targetAccount = options.targetAccount
|
|
748
|
+
? { type: activeAccountType, id: activeAccountId }
|
|
749
|
+
: undefined;
|
|
750
|
+
const activeAccount = {
|
|
751
|
+
...state.accounts?.[activeAccountType]?.[activeAccountId],
|
|
752
|
+
};
|
|
753
|
+
const activeNetwork = { ...state.activeNetwork };
|
|
754
|
+
if (!selectedAddress ||
|
|
755
|
+
!activeAccount.address ||
|
|
756
|
+
(targetAccount && activeAccountType === types_1.KeyringAccountType.SmartAccount)) {
|
|
757
|
+
throw new Error('Cancellation signing account is unavailable');
|
|
758
|
+
}
|
|
759
|
+
if (!previewOnly)
|
|
760
|
+
this.assertHardwareSignerAvailable(targetAccount);
|
|
761
|
+
const provider = this.web3Provider;
|
|
762
|
+
const assertSession = this.captureSigningContext?.();
|
|
763
|
+
const assertKeyringContext = () => {
|
|
764
|
+
assertSession?.();
|
|
765
|
+
const current = this.getState();
|
|
766
|
+
if (current.activeAccountType !== selectedType ||
|
|
767
|
+
current.activeAccountId !== selectedId ||
|
|
768
|
+
current.accounts?.[selectedType]?.[selectedId]?.address?.toLowerCase() !== selectedAddress.toLowerCase() ||
|
|
769
|
+
current.accounts?.[activeAccountType]?.[activeAccountId]?.address?.toLowerCase() !== activeAccount.address.toLowerCase() ||
|
|
770
|
+
[current.activeNetwork, this.getNetwork()].some((selected) => selected.kind !== activeNetwork.kind ||
|
|
771
|
+
selected.chainId !== activeNetwork.chainId ||
|
|
772
|
+
selected.slip44 !== activeNetwork.slip44 ||
|
|
773
|
+
selected.url !== activeNetwork.url) ||
|
|
774
|
+
this.web3Provider !== provider) {
|
|
775
|
+
throw new Error('Wallet signing context changed');
|
|
776
|
+
}
|
|
777
|
+
};
|
|
680
778
|
const assertCurrent = () => {
|
|
681
779
|
assertHostContext();
|
|
682
780
|
assertKeyringContext();
|
|
@@ -798,6 +896,22 @@ class EthereumTransactions {
|
|
|
798
896
|
maxPriorityFeePerGas: bumpCancelFee(oldTxsGasValues.maxPriorityFeePerGas),
|
|
799
897
|
}),
|
|
800
898
|
};
|
|
899
|
+
const maximumFee = newGasValues.gasLimit.mul(isLegacy ? newGasValues.gasPrice : newGasValues.maxFeePerGas);
|
|
900
|
+
assertCurrent();
|
|
901
|
+
if (previewOnly)
|
|
902
|
+
return {
|
|
903
|
+
isCanceled: false,
|
|
904
|
+
error: false,
|
|
905
|
+
maximumFee: maximumFee.toString(),
|
|
906
|
+
};
|
|
907
|
+
if (maximumFee.gt(approvedMaximumFee))
|
|
908
|
+
throw new Error('Cancellation fee exceeds approval');
|
|
909
|
+
const assertApprovedEnvelope = (transaction) => {
|
|
910
|
+
const gas = nonNegativeFeeQuantity(transaction.gasLimit, 'cancellation gas limit');
|
|
911
|
+
const cap = nonNegativeFeeQuantity(isLegacy ? transaction.gasPrice : transaction.maxFeePerGas, 'cancellation maximum fee');
|
|
912
|
+
if (!gas.eq(42000) || gas.mul(cap).gt(approvedMaximumFee))
|
|
913
|
+
throw new Error('Cancellation fee exceeds approval');
|
|
914
|
+
};
|
|
801
915
|
// Base cancel transaction parameters (same for all wallet types)
|
|
802
916
|
const baseCancelTx = {
|
|
803
917
|
nonce: tx.nonce,
|
|
@@ -841,10 +955,12 @@ class EthereumTransactions {
|
|
|
841
955
|
chainId: activeNetwork.chainId,
|
|
842
956
|
type: 2, // Need explicit type for hardware wallet serialization
|
|
843
957
|
};
|
|
958
|
+
assertApprovedEnvelope(txFormattedForEthers);
|
|
844
959
|
const rawTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers);
|
|
845
|
-
const signature = await this.
|
|
960
|
+
const signature = await this.requireLedgerSigner().evm.signEVMTransaction({
|
|
846
961
|
rawTx: rawTx.replace('0x', ''),
|
|
847
962
|
accountIndex: activeAccountId,
|
|
963
|
+
expectedAddress: activeAccount.address,
|
|
848
964
|
});
|
|
849
965
|
assertCurrent();
|
|
850
966
|
const formattedSignature = {
|
|
@@ -855,6 +971,7 @@ class EthereumTransactions {
|
|
|
855
971
|
if (signature) {
|
|
856
972
|
const signedTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers, formattedSignature);
|
|
857
973
|
assertCurrent();
|
|
974
|
+
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
858
975
|
const transactionResponse = await provider.sendTransaction(signedTx);
|
|
859
976
|
return {
|
|
860
977
|
isCanceled: true,
|
|
@@ -908,7 +1025,8 @@ class EthereumTransactions {
|
|
|
908
1025
|
? formattedTx.maxPriorityFeePerGas
|
|
909
1026
|
: this.toHex0x(formattedTx.maxPriorityFeePerGas, 'maxPriorityFeePerGas');
|
|
910
1027
|
}
|
|
911
|
-
|
|
1028
|
+
assertApprovedEnvelope(txFormattedForTrezor);
|
|
1029
|
+
const signature = await this.requireTrezorSigner().signEthTransaction({
|
|
912
1030
|
coin: trezorCoin,
|
|
913
1031
|
tx: txFormattedForTrezor,
|
|
914
1032
|
index: activeAccountId.toString(),
|
|
@@ -916,8 +1034,9 @@ class EthereumTransactions {
|
|
|
916
1034
|
});
|
|
917
1035
|
assertCurrent();
|
|
918
1036
|
if (signature.success) {
|
|
919
|
-
const signedTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForTrezor, signature.payload);
|
|
1037
|
+
const signedTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForTrezor, trezorSignature(signature.payload));
|
|
920
1038
|
assertCurrent();
|
|
1039
|
+
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
921
1040
|
const transactionResponse = await provider.sendTransaction(signedTx);
|
|
922
1041
|
return {
|
|
923
1042
|
isCanceled: true,
|
|
@@ -942,11 +1061,11 @@ class EthereumTransactions {
|
|
|
942
1061
|
const cancelWithPrivateKey = async () => {
|
|
943
1062
|
try {
|
|
944
1063
|
assertCurrent();
|
|
945
|
-
const { address, decryptedPrivateKey } = this.getDecryptedPrivateKey();
|
|
1064
|
+
const { address, decryptedPrivateKey } = this.getDecryptedPrivateKey(targetAccount);
|
|
946
1065
|
if (address?.toLowerCase() !== activeAccount.address.toLowerCase()) {
|
|
947
1066
|
throw new Error('Wallet signing context changed');
|
|
948
1067
|
}
|
|
949
|
-
const transactionResponse = await (0, evm_local_signer_1.sendLocalEvmTransaction)(provider, decryptedPrivateKey, changedTxToCancel, assertCurrent, assertCurrent);
|
|
1068
|
+
const transactionResponse = await (0, evm_local_signer_1.sendLocalEvmTransaction)(provider, decryptedPrivateKey, changedTxToCancel, assertCurrent, assertCurrent, assertApprovedEnvelope);
|
|
950
1069
|
if (transactionResponse) {
|
|
951
1070
|
return {
|
|
952
1071
|
isCanceled: true,
|
|
@@ -1107,9 +1226,10 @@ class EthereumTransactions {
|
|
|
1107
1226
|
type: 2, // Need explicit type for hardware wallet serialization
|
|
1108
1227
|
};
|
|
1109
1228
|
const rawTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers);
|
|
1110
|
-
const signature = await this.
|
|
1229
|
+
const signature = await this.requireLedgerSigner().evm.signEVMTransaction({
|
|
1111
1230
|
rawTx: rawTx.replace('0x', ''),
|
|
1112
1231
|
accountIndex: activeAccountId,
|
|
1232
|
+
expectedAddress: activeAccount.address,
|
|
1113
1233
|
});
|
|
1114
1234
|
assertCurrent();
|
|
1115
1235
|
const formattedSignature = {
|
|
@@ -1120,6 +1240,7 @@ class EthereumTransactions {
|
|
|
1120
1240
|
if (signature) {
|
|
1121
1241
|
try {
|
|
1122
1242
|
const signedTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers, formattedSignature);
|
|
1243
|
+
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
1123
1244
|
assertBeforeBroadcast();
|
|
1124
1245
|
const finalTx = await provider.sendTransaction(signedTx);
|
|
1125
1246
|
return finalTx;
|
|
@@ -1180,7 +1301,7 @@ class EthereumTransactions {
|
|
|
1180
1301
|
};
|
|
1181
1302
|
break;
|
|
1182
1303
|
}
|
|
1183
|
-
const signature = await this.
|
|
1304
|
+
const signature = await this.requireTrezorSigner().signEthTransaction({
|
|
1184
1305
|
index: `${activeAccountId}`,
|
|
1185
1306
|
tx: txFormattedForTrezor,
|
|
1186
1307
|
coin: activeNetwork.currency,
|
|
@@ -1202,8 +1323,8 @@ class EthereumTransactions {
|
|
|
1202
1323
|
chainId: activeNetwork.chainId,
|
|
1203
1324
|
type: 2, // Need explicit type for hardware wallet serialization
|
|
1204
1325
|
};
|
|
1205
|
-
|
|
1206
|
-
|
|
1326
|
+
const signedTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers, trezorSignature(signature.payload));
|
|
1327
|
+
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
1207
1328
|
assertBeforeBroadcast();
|
|
1208
1329
|
const finalTx = await provider.sendTransaction(signedTx);
|
|
1209
1330
|
return finalTx;
|
|
@@ -1252,6 +1373,8 @@ class EthereumTransactions {
|
|
|
1252
1373
|
this.sendTransactionWithEditedFee = async (txHash, isLegacy = false, options = {}) => {
|
|
1253
1374
|
const { assertCurrentContext, validateOriginal, beforeBroadcast, approvedMaximumFee, } = options;
|
|
1254
1375
|
const previewOnly = options.previewOnly === true;
|
|
1376
|
+
if (!previewOnly)
|
|
1377
|
+
this.assertHardwareSignerAvailable(options.targetAccount);
|
|
1255
1378
|
if (!previewOnly &&
|
|
1256
1379
|
(typeof approvedMaximumFee !== 'string' ||
|
|
1257
1380
|
!/^\d{1,78}$/.test(approvedMaximumFee))) {
|
|
@@ -1366,7 +1489,6 @@ class EthereumTransactions {
|
|
|
1366
1489
|
newGasValues.maxPriorityFeePerGas.gt(newGasValues.maxFeePerGas))
|
|
1367
1490
|
throw new Error('Invalid replacement fee');
|
|
1368
1491
|
const maximumFee = newGasValues.gasLimit.mul(isLegacy ? newGasValues.gasPrice : newGasValues.maxFeePerGas);
|
|
1369
|
-
let adjustedValue = txValue;
|
|
1370
1492
|
if (isLikelyMaxSend && txValue.add(maximumFee).gt(currentBalance)) {
|
|
1371
1493
|
if (isContractCall) {
|
|
1372
1494
|
console.error('[SpeedUp] Cannot adjust value for contract call - rejecting speedup');
|
|
@@ -1377,16 +1499,19 @@ class EthereumTransactions {
|
|
|
1377
1499
|
message: 'Cannot speed up a likely max-send contract call; value cannot be adjusted to fit new gas',
|
|
1378
1500
|
};
|
|
1379
1501
|
}
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
:
|
|
1502
|
+
return {
|
|
1503
|
+
isSpeedUp: false,
|
|
1504
|
+
error: true,
|
|
1505
|
+
code: 'REPLACEMENT_VALUE_WOULD_CHANGE',
|
|
1506
|
+
message: 'Add funds before speeding up this transaction; the original amount will not be changed',
|
|
1507
|
+
};
|
|
1383
1508
|
}
|
|
1384
1509
|
const txWithEditedFee = {
|
|
1385
1510
|
chainId: activeNetwork.chainId,
|
|
1386
1511
|
from: tx.from,
|
|
1387
1512
|
to: tx.to,
|
|
1388
1513
|
nonce: tx.nonce,
|
|
1389
|
-
value:
|
|
1514
|
+
value: txValue,
|
|
1390
1515
|
data: txData,
|
|
1391
1516
|
gasLimit: newGasValues.gasLimit,
|
|
1392
1517
|
...(tx.accessList != null ? { accessList: tx.accessList } : {}),
|
|
@@ -1424,9 +1549,10 @@ class EthereumTransactions {
|
|
|
1424
1549
|
};
|
|
1425
1550
|
const rawTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers);
|
|
1426
1551
|
assertCurrent();
|
|
1427
|
-
const signature = await this.
|
|
1552
|
+
const signature = await this.requireLedgerSigner().evm.signEVMTransaction({
|
|
1428
1553
|
rawTx: rawTx.replace('0x', ''),
|
|
1429
1554
|
accountIndex: activeAccountId,
|
|
1555
|
+
expectedAddress: activeAccount.address,
|
|
1430
1556
|
});
|
|
1431
1557
|
const formattedSignature = {
|
|
1432
1558
|
r: `0x${signature.r}`,
|
|
@@ -1436,6 +1562,7 @@ class EthereumTransactions {
|
|
|
1436
1562
|
if (signature) {
|
|
1437
1563
|
const signedTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers, formattedSignature);
|
|
1438
1564
|
assertSignedSender(signedTx);
|
|
1565
|
+
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
1439
1566
|
assertBeforeBroadcast();
|
|
1440
1567
|
const transactionResponse = await provider.sendTransaction(signedTx);
|
|
1441
1568
|
return {
|
|
@@ -1505,15 +1632,16 @@ class EthereumTransactions {
|
|
|
1505
1632
|
: this.toHex0x(formattedTx.maxPriorityFeePerGas, 'maxPriorityFeePerGas');
|
|
1506
1633
|
}
|
|
1507
1634
|
assertCurrent();
|
|
1508
|
-
const signature = await this.
|
|
1635
|
+
const signature = await this.requireTrezorSigner().signEthTransaction({
|
|
1509
1636
|
coin: trezorCoin,
|
|
1510
1637
|
tx: txFormattedForTrezor,
|
|
1511
1638
|
index: activeAccountId.toString(),
|
|
1512
1639
|
slip44: activeNetwork.slip44,
|
|
1513
1640
|
});
|
|
1514
1641
|
if (signature.success) {
|
|
1515
|
-
const signedTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForTrezor, signature.payload);
|
|
1642
|
+
const signedTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForTrezor, trezorSignature(signature.payload));
|
|
1516
1643
|
assertSignedSender(signedTx);
|
|
1644
|
+
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
1517
1645
|
assertBeforeBroadcast();
|
|
1518
1646
|
const transactionResponse = await provider.sendTransaction(signedTx);
|
|
1519
1647
|
return {
|
|
@@ -1688,9 +1816,10 @@ class EthereumTransactions {
|
|
|
1688
1816
|
};
|
|
1689
1817
|
}
|
|
1690
1818
|
const rawTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers);
|
|
1691
|
-
const signature = await this.
|
|
1819
|
+
const signature = await this.requireLedgerSigner().evm.signEVMTransaction({
|
|
1692
1820
|
rawTx: rawTx.replace('0x', ''),
|
|
1693
1821
|
accountIndex: activeAccountId,
|
|
1822
|
+
expectedAddress: activeAccount.address,
|
|
1694
1823
|
});
|
|
1695
1824
|
assertCurrent();
|
|
1696
1825
|
const formattedSignature = {
|
|
@@ -1702,6 +1831,7 @@ class EthereumTransactions {
|
|
|
1702
1831
|
try {
|
|
1703
1832
|
const signedTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers, formattedSignature);
|
|
1704
1833
|
assertCurrent();
|
|
1834
|
+
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
1705
1835
|
const finalTx = await provider.sendTransaction(signedTx);
|
|
1706
1836
|
saveTrezorTx && saveTrezorTx(finalTx);
|
|
1707
1837
|
return finalTx;
|
|
@@ -1756,7 +1886,7 @@ class EthereumTransactions {
|
|
|
1756
1886
|
data: txData,
|
|
1757
1887
|
};
|
|
1758
1888
|
}
|
|
1759
|
-
const signature = await this.
|
|
1889
|
+
const signature = await this.requireTrezorSigner().signEthTransaction({
|
|
1760
1890
|
index: `${activeAccountId}`,
|
|
1761
1891
|
tx: txToBeSignedByTrezor,
|
|
1762
1892
|
coin: activeNetwork.currency,
|
|
@@ -1791,9 +1921,9 @@ class EthereumTransactions {
|
|
|
1791
1921
|
type: 2, // Need explicit type for hardware wallet serialization
|
|
1792
1922
|
};
|
|
1793
1923
|
}
|
|
1794
|
-
|
|
1795
|
-
const signedTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers, signature.payload);
|
|
1924
|
+
const signedTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers, trezorSignature(signature.payload));
|
|
1796
1925
|
assertCurrent();
|
|
1926
|
+
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
1797
1927
|
const finalTx = await provider.sendTransaction(signedTx);
|
|
1798
1928
|
saveTrezorTx && saveTrezorTx(finalTx);
|
|
1799
1929
|
return finalTx;
|
|
@@ -1909,9 +2039,10 @@ class EthereumTransactions {
|
|
|
1909
2039
|
};
|
|
1910
2040
|
}
|
|
1911
2041
|
const rawTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers);
|
|
1912
|
-
const signature = await this.
|
|
2042
|
+
const signature = await this.requireLedgerSigner().evm.signEVMTransaction({
|
|
1913
2043
|
rawTx: rawTx.replace('0x', ''),
|
|
1914
2044
|
accountIndex: activeAccountId,
|
|
2045
|
+
expectedAddress: activeAccount.address,
|
|
1915
2046
|
});
|
|
1916
2047
|
assertCurrent();
|
|
1917
2048
|
const formattedSignature = {
|
|
@@ -1923,6 +2054,7 @@ class EthereumTransactions {
|
|
|
1923
2054
|
try {
|
|
1924
2055
|
const signedTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers, formattedSignature);
|
|
1925
2056
|
assertCurrent();
|
|
2057
|
+
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
1926
2058
|
const finalTx = await provider.sendTransaction(signedTx);
|
|
1927
2059
|
return finalTx;
|
|
1928
2060
|
}
|
|
@@ -1978,7 +2110,7 @@ class EthereumTransactions {
|
|
|
1978
2110
|
}
|
|
1979
2111
|
// For EVM networks, Trezor expects 'eth' regardless of the network's currency
|
|
1980
2112
|
const trezorCoin = activeNetwork.slip44 === 60 ? 'eth' : activeNetwork.currency;
|
|
1981
|
-
const signature = await this.
|
|
2113
|
+
const signature = await this.requireTrezorSigner().signEthTransaction({
|
|
1982
2114
|
index: `${activeAccountId}`,
|
|
1983
2115
|
tx: txToBeSignedByTrezor,
|
|
1984
2116
|
coin: trezorCoin,
|
|
@@ -2013,9 +2145,9 @@ class EthereumTransactions {
|
|
|
2013
2145
|
type: 2, // Need explicit type for hardware wallet serialization
|
|
2014
2146
|
};
|
|
2015
2147
|
}
|
|
2016
|
-
|
|
2017
|
-
const signedTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers, signature.payload);
|
|
2148
|
+
const signedTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers, trezorSignature(signature.payload));
|
|
2018
2149
|
assertCurrent();
|
|
2150
|
+
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
2019
2151
|
const finalTx = await provider.sendTransaction(signedTx);
|
|
2020
2152
|
return finalTx;
|
|
2021
2153
|
}
|
|
@@ -2127,9 +2259,10 @@ class EthereumTransactions {
|
|
|
2127
2259
|
};
|
|
2128
2260
|
}
|
|
2129
2261
|
const rawTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers);
|
|
2130
|
-
const signature = await this.
|
|
2262
|
+
const signature = await this.requireLedgerSigner().evm.signEVMTransaction({
|
|
2131
2263
|
rawTx: rawTx.replace('0x', ''),
|
|
2132
2264
|
accountIndex: activeAccountId,
|
|
2265
|
+
expectedAddress: activeAccount.address,
|
|
2133
2266
|
});
|
|
2134
2267
|
assertCurrent();
|
|
2135
2268
|
const formattedSignature = {
|
|
@@ -2141,6 +2274,7 @@ class EthereumTransactions {
|
|
|
2141
2274
|
try {
|
|
2142
2275
|
const signedTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers, formattedSignature);
|
|
2143
2276
|
assertCurrent();
|
|
2277
|
+
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
2144
2278
|
const finalTx = await provider.sendTransaction(signedTx);
|
|
2145
2279
|
return finalTx;
|
|
2146
2280
|
}
|
|
@@ -2190,7 +2324,7 @@ class EthereumTransactions {
|
|
|
2190
2324
|
data: txData,
|
|
2191
2325
|
};
|
|
2192
2326
|
}
|
|
2193
|
-
const signature = await this.
|
|
2327
|
+
const signature = await this.requireTrezorSigner().signEthTransaction({
|
|
2194
2328
|
index: `${activeAccountId}`,
|
|
2195
2329
|
tx: txToBeSignedByTrezor,
|
|
2196
2330
|
coin: activeNetwork.currency,
|
|
@@ -2225,9 +2359,9 @@ class EthereumTransactions {
|
|
|
2225
2359
|
type: 2, // Need explicit type for hardware wallet serialization
|
|
2226
2360
|
};
|
|
2227
2361
|
}
|
|
2228
|
-
|
|
2229
|
-
const signedTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers, signature.payload);
|
|
2362
|
+
const signedTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers, trezorSignature(signature.payload));
|
|
2230
2363
|
assertCurrent();
|
|
2364
|
+
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
2231
2365
|
const finalTx = await provider.sendTransaction(signedTx);
|
|
2232
2366
|
return finalTx;
|
|
2233
2367
|
}
|
|
@@ -2403,7 +2537,10 @@ class EthereumTransactions {
|
|
|
2403
2537
|
};
|
|
2404
2538
|
};
|
|
2405
2539
|
this.getNetwork = getNetwork;
|
|
2406
|
-
this.getDecryptedPrivateKey =
|
|
2540
|
+
this.getDecryptedPrivateKey = (targetAccount) => {
|
|
2541
|
+
this.assertHardwareSignerAvailable(targetAccount);
|
|
2542
|
+
return getDecryptedPrivateKey(targetAccount);
|
|
2543
|
+
};
|
|
2407
2544
|
this.abortController = new AbortController();
|
|
2408
2545
|
// NOTE: Defer network access until vault state getter is initialized
|
|
2409
2546
|
// The web3Provider will be created lazily when first accessed via getters
|