@sidhujag/sysweb3-keyring 2.1.7 → 2.1.9
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 +12 -0
- package/cjs/hardware-transaction-authority.js +15 -11
- package/cjs/hardware-transaction-authority.js.map +1 -1
- package/cjs/hardware-wallet-manager.js +74 -119
- package/cjs/hardware-wallet-manager.js.map +1 -1
- package/cjs/hardware-wallet-types.js +16 -0
- package/cjs/hardware-wallet-types.js.map +1 -0
- package/cjs/host-keyring.js +32 -0
- package/cjs/host-keyring.js.map +1 -0
- package/cjs/index.js +1 -0
- package/cjs/index.js.map +1 -1
- package/cjs/keyring-core.js +96 -61
- package/cjs/keyring-core.js.map +1 -1
- package/cjs/keyring-manager.js +15 -16
- package/cjs/keyring-manager.js.map +1 -1
- package/cjs/ledger/host-types.js.map +1 -1
- package/cjs/ledger/index.js +24 -4
- package/cjs/ledger/index.js.map +1 -1
- package/cjs/ledger-hardware.js +15 -0
- package/cjs/ledger-hardware.js.map +1 -0
- package/cjs/software.js +6 -25
- package/cjs/software.js.map +1 -1
- package/cjs/transactions/ethereum.js +371 -494
- package/cjs/transactions/ethereum.js.map +1 -1
- package/cjs/transactions/evm-submission-failure.js +73 -0
- package/cjs/transactions/evm-submission-failure.js.map +1 -0
- package/cjs/transactions/evm-submission.js +35 -61
- package/cjs/transactions/evm-submission.js.map +1 -1
- package/cjs/transactions/ledger-signing.js +52 -0
- package/cjs/transactions/ledger-signing.js.map +1 -0
- package/cjs/transactions/prepared-evm.js +24 -1
- package/cjs/transactions/prepared-evm.js.map +1 -1
- package/cjs/transactions/trezor-signing.js +90 -0
- package/cjs/transactions/trezor-signing.js.map +1 -0
- package/cjs/trezor/connect.js +238 -243
- package/cjs/trezor/connect.js.map +1 -1
- package/cjs/trezor/host-types.js +19 -0
- package/cjs/trezor/host-types.js.map +1 -0
- package/cjs/trezor/index.js +75 -23
- package/cjs/trezor/index.js.map +1 -1
- package/cjs/trezor/webextension-host.js +118 -0
- package/cjs/trezor/webextension-host.js.map +1 -0
- package/cjs/trezor-hardware.js +16 -0
- package/cjs/trezor-hardware.js.map +1 -0
- package/cjs/types.js.map +1 -1
- package/esm/hardware-transaction-authority.js +14 -11
- package/esm/hardware-transaction-authority.js.map +1 -1
- package/esm/hardware-wallet-manager.js +20 -32
- package/esm/hardware-wallet-manager.js.map +1 -1
- package/esm/hardware-wallet-types.js +13 -0
- package/esm/hardware-wallet-types.js.map +1 -0
- package/esm/keyring-core.js +98 -63
- package/esm/keyring-core.js.map +1 -1
- package/esm/ledger/dmk-host.js +2 -0
- package/esm/ledger/dmk-host.js.map +1 -1
- package/esm/ledger/dmk-session.js +73 -8
- package/esm/ledger/dmk-session.js.map +1 -1
- package/esm/ledger/host-types.js.map +1 -1
- package/esm/ledger/index.js +22 -2
- package/esm/ledger/index.js.map +1 -1
- package/esm/transactions/ethereum.js +372 -495
- package/esm/transactions/ethereum.js.map +1 -1
- package/esm/transactions/evm-submission-failure.js +68 -0
- package/esm/transactions/evm-submission-failure.js.map +1 -0
- package/esm/transactions/evm-submission.js +32 -59
- package/esm/transactions/evm-submission.js.map +1 -1
- package/esm/transactions/ledger-signing.js +49 -0
- package/esm/transactions/ledger-signing.js.map +1 -0
- package/esm/transactions/prepared-evm.js +23 -1
- package/esm/transactions/prepared-evm.js.map +1 -1
- package/esm/transactions/trezor-signing.js +87 -0
- package/esm/transactions/trezor-signing.js.map +1 -0
- package/esm/trezor/connect.js +236 -209
- package/esm/trezor/connect.js.map +1 -1
- package/esm/trezor/host-types.js +16 -0
- package/esm/trezor/host-types.js.map +1 -0
- package/esm/trezor/index.js +74 -22
- package/esm/trezor/index.js.map +1 -1
- package/esm/types.js.map +1 -1
- package/package.json +61 -1
- package/types/hardware-transaction-authority.d.ts +1 -0
- package/types/hardware-wallet-manager.d.ts +6 -22
- package/types/hardware-wallet-types.d.ts +21 -0
- package/types/host-keyring.d.ts +16 -0
- package/types/index.d.ts +1 -0
- package/types/keyring-core.d.ts +12 -4
- package/types/keyring-manager.d.ts +5 -3
- package/types/ledger/dmk-host.d.ts +2 -0
- package/types/ledger/dmk-session.d.ts +9 -0
- package/types/ledger/host-types.d.ts +2 -0
- package/types/ledger/index.d.ts +3 -1
- package/types/ledger-hardware.d.ts +5 -0
- package/types/software.d.ts +2 -16
- package/types/transactions/ethereum.d.ts +11 -1
- package/types/transactions/evm-submission-failure.d.ts +11 -0
- package/types/transactions/evm-submission.d.ts +6 -8
- package/types/transactions/ledger-signing.d.ts +13 -0
- package/types/transactions/prepared-evm.d.ts +12 -0
- package/types/transactions/trezor-signing.d.ts +13 -0
- package/types/trezor/connect.d.ts +11 -9
- package/types/trezor/host-types.d.ts +25 -0
- package/types/trezor/index.d.ts +7 -7
- package/types/trezor/webextension-host.d.ts +7 -0
- package/types/trezor-hardware.d.ts +6 -0
- package/types/types.d.ts +16 -4
|
@@ -7,6 +7,7 @@ exports.EthereumTransactions = void 0;
|
|
|
7
7
|
const eth_sig_util_1 = require("@metamask/eth-sig-util");
|
|
8
8
|
const sysweb3_network_1 = require("@sidhujag/sysweb3-network");
|
|
9
9
|
const sysweb3_utils_1 = require("@sidhujag/sysweb3-utils");
|
|
10
|
+
const address_1 = require("ethers/address");
|
|
10
11
|
const transaction_1 = require("ethers/transaction");
|
|
11
12
|
const utils_1 = require("ethers/utils");
|
|
12
13
|
const omit_1 = __importDefault(require("lodash/omit"));
|
|
@@ -15,9 +16,12 @@ const evm_fees_1 = require("../evm-fees");
|
|
|
15
16
|
const providers_1 = require("../providers");
|
|
16
17
|
const types_1 = require("../types");
|
|
17
18
|
const evm_cancellation_1 = require("./evm-cancellation");
|
|
19
|
+
const evm_envelope_1 = require("./evm-envelope");
|
|
18
20
|
const evm_local_signer_1 = require("./evm-local-signer");
|
|
19
21
|
const evm_submission_1 = require("./evm-submission");
|
|
22
|
+
const ledger_signing_1 = require("./ledger-signing");
|
|
20
23
|
const prepared_evm_1 = require("./prepared-evm");
|
|
24
|
+
const trezor_signing_1 = require("./trezor-signing");
|
|
21
25
|
const derivation_paths_1 = require("../utils/derivation-paths");
|
|
22
26
|
const hardwareSignerUnavailable = (hardware) => Object.assign(new Error(`${hardware} signer is unavailable in this host`), {
|
|
23
27
|
code: 'HARDWARE_SIGNER_UNAVAILABLE',
|
|
@@ -35,26 +39,6 @@ const stripHexPrefix = (value) => {
|
|
|
35
39
|
? value.slice(2)
|
|
36
40
|
: value;
|
|
37
41
|
};
|
|
38
|
-
// Connect returns hexadecimal signature fields; normalize their encoding
|
|
39
|
-
// without mutating the response or reparsing an already numeric recovery v.
|
|
40
|
-
const trezorSignature = (signature) => {
|
|
41
|
-
const { r, s, v } = signature;
|
|
42
|
-
if (![r, s].every((value) => /^(?:0x)?[0-9a-f]{64}$/i.test(value))) {
|
|
43
|
-
throw new Error('Invalid Trezor signature scalar encoding');
|
|
44
|
-
}
|
|
45
|
-
if (typeof v === 'string' && !/^(?:0x)?[0-9a-f]+$/i.test(v)) {
|
|
46
|
-
throw new Error('Invalid Trezor signature recovery value');
|
|
47
|
-
}
|
|
48
|
-
const recovery = typeof v === 'number' ? v : Number.parseInt(v, 16);
|
|
49
|
-
if (!Number.isSafeInteger(recovery) || recovery < 0) {
|
|
50
|
-
throw new Error('Invalid Trezor signature recovery value');
|
|
51
|
-
}
|
|
52
|
-
return {
|
|
53
|
-
r: `0x${stripHexPrefix(r)}`,
|
|
54
|
-
s: `0x${stripHexPrefix(s)}`,
|
|
55
|
-
v: recovery,
|
|
56
|
-
};
|
|
57
|
-
};
|
|
58
42
|
const normalizeEthersOverrideValue = (value) => (0, ethers_v6_1.normalizeTxValue)(value);
|
|
59
43
|
// The same protocol bound applies to software and external-device envelopes.
|
|
60
44
|
// Keep this at serialization as well as before handing a request to a device.
|
|
@@ -160,7 +144,7 @@ class EthereumTransactions {
|
|
|
160
144
|
}
|
|
161
145
|
return () => assertSynchronousOriginalValidation(guard(), 'Signing context guard must be synchronous');
|
|
162
146
|
};
|
|
163
|
-
this.
|
|
147
|
+
this.captureEvmAccountContext = (target) => {
|
|
164
148
|
this.assertHardwareSignerAvailable(target);
|
|
165
149
|
const state = this.getState();
|
|
166
150
|
const selectedType = state.activeAccountType;
|
|
@@ -174,7 +158,6 @@ class EthereumTransactions {
|
|
|
174
158
|
const account = { address: selectedAccount.address };
|
|
175
159
|
const network = { ...state.activeNetwork };
|
|
176
160
|
const assertSession = this.captureSessionGuard();
|
|
177
|
-
const provider = this.web3Provider;
|
|
178
161
|
const assertCurrent = () => {
|
|
179
162
|
assertSession();
|
|
180
163
|
const current = this.getState();
|
|
@@ -188,8 +171,7 @@ class EthereumTransactions {
|
|
|
188
171
|
[current.activeNetwork, this.getNetwork()].some((selected) => selected.kind !== network.kind ||
|
|
189
172
|
selected.chainId !== network.chainId ||
|
|
190
173
|
selected.slip44 !== network.slip44 ||
|
|
191
|
-
selected.url !== network.url)
|
|
192
|
-
this.web3Provider !== provider)
|
|
174
|
+
selected.url !== network.url))
|
|
193
175
|
throw new Error('Wallet signing context changed');
|
|
194
176
|
};
|
|
195
177
|
assertCurrent();
|
|
@@ -198,10 +180,20 @@ class EthereumTransactions {
|
|
|
198
180
|
activeAccountType,
|
|
199
181
|
activeAccountId,
|
|
200
182
|
activeNetwork: network,
|
|
201
|
-
provider,
|
|
202
183
|
assertCurrent,
|
|
203
184
|
};
|
|
204
185
|
};
|
|
186
|
+
this.captureEvmSigningContext = (target) => {
|
|
187
|
+
const context = this.captureEvmAccountContext(target);
|
|
188
|
+
const provider = this.web3Provider;
|
|
189
|
+
const assertCurrent = () => {
|
|
190
|
+
context.assertCurrent();
|
|
191
|
+
if (this.web3Provider !== provider)
|
|
192
|
+
throw new Error('Wallet signing context changed');
|
|
193
|
+
};
|
|
194
|
+
assertCurrent();
|
|
195
|
+
return { ...context, provider, assertCurrent };
|
|
196
|
+
};
|
|
205
197
|
this.captureSubmission = (operation, account, type, id, network, assertCurrent, details = {}) => {
|
|
206
198
|
if (!this.captureSubmissionLifecycle)
|
|
207
199
|
throw new TypeError('A durable EVM submission lifecycle is required');
|
|
@@ -302,10 +294,51 @@ class EthereumTransactions {
|
|
|
302
294
|
throw error;
|
|
303
295
|
}
|
|
304
296
|
};
|
|
305
|
-
this.ethSign = async (params) => {
|
|
306
|
-
const
|
|
307
|
-
|
|
308
|
-
|
|
297
|
+
this.ethSign = async (params, input) => {
|
|
298
|
+
const selected = this.captureEvmAccountContext();
|
|
299
|
+
if (!Array.isArray(params) || params.length !== 2)
|
|
300
|
+
throw new Error('Invalid digest request');
|
|
301
|
+
const first = Object.getOwnPropertyDescriptor(params, '0');
|
|
302
|
+
const second = Object.getOwnPropertyDescriptor(params, '1');
|
|
303
|
+
if (!first ||
|
|
304
|
+
!second ||
|
|
305
|
+
!('value' in first) ||
|
|
306
|
+
!('value' in second) ||
|
|
307
|
+
typeof first.value !== 'string' ||
|
|
308
|
+
typeof second.value !== 'string')
|
|
309
|
+
throw new Error('Invalid digest request');
|
|
310
|
+
params = [first.value, second.value];
|
|
311
|
+
const options = (0, evm_envelope_1.readEvmOwnData)(input, [
|
|
312
|
+
'selectedAccount',
|
|
313
|
+
'targetAccount',
|
|
314
|
+
'assertCurrent',
|
|
315
|
+
]);
|
|
316
|
+
const selectedAccount = (0, prepared_evm_1.snapshotEvmSigningIdentity)(options.selectedAccount);
|
|
317
|
+
const targetAccount = (0, prepared_evm_1.snapshotEvmSigningIdentity)(options.targetAccount);
|
|
318
|
+
const hostGuard = (0, prepared_evm_1.preparedEvmGuard)({
|
|
319
|
+
assertCurrent: options.assertCurrent,
|
|
320
|
+
});
|
|
321
|
+
const target = {
|
|
322
|
+
id: targetAccount.id,
|
|
323
|
+
type: targetAccount.type,
|
|
324
|
+
};
|
|
325
|
+
const context = this.captureEvmAccountContext(target);
|
|
326
|
+
const assertCurrent = () => {
|
|
327
|
+
hostGuard();
|
|
328
|
+
selected.assertCurrent();
|
|
329
|
+
context.assertCurrent();
|
|
330
|
+
if (selected.activeAccountId !== selectedAccount.id ||
|
|
331
|
+
selected.activeAccountType !== selectedAccount.type ||
|
|
332
|
+
(0, address_1.getAddress)(selected.activeAccount.address) !==
|
|
333
|
+
selectedAccount.expectedAddress ||
|
|
334
|
+
(0, address_1.getAddress)(context.activeAccount.address) !==
|
|
335
|
+
targetAccount.expectedAddress ||
|
|
336
|
+
targetAccount.type === 'SmartAccount')
|
|
337
|
+
throw new Error('EVM digest signing context changed');
|
|
338
|
+
};
|
|
339
|
+
assertCurrent();
|
|
340
|
+
const { address, decryptedPrivateKey } = this.getDecryptedPrivateKey(target);
|
|
341
|
+
const { activeAccountId, activeAccountType, activeNetwork, activeAccount } = context;
|
|
309
342
|
// Validate that the derived address matches the active account to prevent race conditions
|
|
310
343
|
if (address.toLowerCase() !== activeAccount.address.toLowerCase()) {
|
|
311
344
|
throw {
|
|
@@ -374,14 +407,19 @@ class EthereumTransactions {
|
|
|
374
407
|
throw error;
|
|
375
408
|
}
|
|
376
409
|
};
|
|
410
|
+
let signature;
|
|
377
411
|
switch (activeAccountType) {
|
|
378
412
|
case types_1.KeyringAccountType.Trezor:
|
|
379
|
-
|
|
413
|
+
signature = await signWithTrezor();
|
|
414
|
+
break;
|
|
380
415
|
case types_1.KeyringAccountType.Ledger:
|
|
381
|
-
|
|
416
|
+
signature = await signWithLedger();
|
|
417
|
+
break;
|
|
382
418
|
default:
|
|
383
|
-
|
|
419
|
+
signature = sign();
|
|
384
420
|
}
|
|
421
|
+
assertCurrent();
|
|
422
|
+
return signature;
|
|
385
423
|
};
|
|
386
424
|
this.signPersonalMessage = async (params) => {
|
|
387
425
|
const { address, decryptedPrivateKey } = this.getDecryptedPrivateKey();
|
|
@@ -951,33 +989,18 @@ class EthereumTransactions {
|
|
|
951
989
|
const rawTx = serializeTransaction(txFormattedForEthers);
|
|
952
990
|
if (retained)
|
|
953
991
|
assertCancellationEnvelope(rawTx);
|
|
954
|
-
const
|
|
955
|
-
|
|
992
|
+
const { rawTransaction: signedTx } = await (0, ledger_signing_1.signLedgerEvmTransaction)(this.requireLedgerSigner(), {
|
|
993
|
+
unsignedTransaction: rawTx,
|
|
956
994
|
accountIndex: activeAccountId,
|
|
957
995
|
expectedAddress: activeAccount.address,
|
|
958
996
|
}, await this.authorizeHardwareTransaction(provider, assertCurrent));
|
|
959
997
|
assertCurrent();
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
998
|
+
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
999
|
+
const transactionResponse = await this.submitSignedHardwareTransaction(provider, signedTx, ({ rawTransaction, admit }) => admit(() => provider.sendTransaction(rawTransaction)), submission, undefined, rawTx);
|
|
1000
|
+
return {
|
|
1001
|
+
isCanceled: true,
|
|
1002
|
+
transaction: transactionResponse,
|
|
964
1003
|
};
|
|
965
|
-
if (signature) {
|
|
966
|
-
const signedTx = serializeTransaction(txFormattedForEthers, formattedSignature);
|
|
967
|
-
assertCurrent();
|
|
968
|
-
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
969
|
-
const transactionResponse = await this.submitSignedHardwareTransaction(provider, signedTx, ({ rawTransaction, admit }) => admit(() => provider.sendTransaction(rawTransaction)), submission, undefined, rawTx);
|
|
970
|
-
return {
|
|
971
|
-
isCanceled: true,
|
|
972
|
-
transaction: transactionResponse,
|
|
973
|
-
};
|
|
974
|
-
}
|
|
975
|
-
else {
|
|
976
|
-
return {
|
|
977
|
-
isCanceled: false,
|
|
978
|
-
error: true,
|
|
979
|
-
};
|
|
980
|
-
}
|
|
981
1004
|
}
|
|
982
1005
|
catch (error) {
|
|
983
1006
|
return {
|
|
@@ -1025,29 +1048,20 @@ class EthereumTransactions {
|
|
|
1025
1048
|
const expectedUnsignedTransaction = serializeTransaction(txFormattedForTrezor);
|
|
1026
1049
|
if (retained)
|
|
1027
1050
|
assertCancellationEnvelope(expectedUnsignedTransaction);
|
|
1028
|
-
const
|
|
1051
|
+
const { rawTransaction: signedTx } = await (0, trezor_signing_1.signTrezorEvmTransaction)(this.requireTrezorSigner(), {
|
|
1052
|
+
accountIndex: activeAccountId,
|
|
1029
1053
|
coin: trezorCoin,
|
|
1030
|
-
|
|
1031
|
-
index: activeAccountId.toString(),
|
|
1054
|
+
expectedAddress: activeAccount.address,
|
|
1032
1055
|
slip44: activeNetwork.slip44,
|
|
1056
|
+
unsignedTransaction: expectedUnsignedTransaction,
|
|
1033
1057
|
}, await this.authorizeHardwareTransaction(provider, assertCurrent));
|
|
1034
1058
|
assertCurrent();
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
isCanceled: true,
|
|
1042
|
-
transaction: transactionResponse,
|
|
1043
|
-
};
|
|
1044
|
-
}
|
|
1045
|
-
else {
|
|
1046
|
-
return {
|
|
1047
|
-
isCanceled: false,
|
|
1048
|
-
error: true,
|
|
1049
|
-
};
|
|
1050
|
-
}
|
|
1059
|
+
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
1060
|
+
const transactionResponse = await this.submitSignedHardwareTransaction(provider, signedTx, ({ rawTransaction, admit }) => admit(() => provider.sendTransaction(rawTransaction)), submission, undefined, expectedUnsignedTransaction);
|
|
1061
|
+
return {
|
|
1062
|
+
isCanceled: true,
|
|
1063
|
+
transaction: transactionResponse,
|
|
1064
|
+
};
|
|
1051
1065
|
}
|
|
1052
1066
|
catch (error) {
|
|
1053
1067
|
return {
|
|
@@ -1108,12 +1122,21 @@ class EthereumTransactions {
|
|
|
1108
1122
|
typeof options !== 'object' ||
|
|
1109
1123
|
Array.isArray(options) ||
|
|
1110
1124
|
(options.mode !== 'reviewed-native' &&
|
|
1125
|
+
options.mode !== 'reviewed-generic' &&
|
|
1111
1126
|
options.mode !== 'specialized') ||
|
|
1112
1127
|
typeof options.assertCurrent !== 'function')
|
|
1113
1128
|
throw new Error('Explicit transaction approval is required');
|
|
1114
1129
|
// Capture once; later caller mutations cannot replace this invocation's
|
|
1115
1130
|
// admission decision while chain checks or device approval are pending.
|
|
1116
1131
|
const { assertCurrent: assertHostCurrent, mode, walletNonce } = options;
|
|
1132
|
+
const reviewId = mode === 'reviewed-generic' ? options.reviewId : undefined;
|
|
1133
|
+
if (mode === 'reviewed-generic' &&
|
|
1134
|
+
(typeof reviewId !== 'string' ||
|
|
1135
|
+
!/^[A-Za-z0-9_-]{1,128}$/.test(reviewId) ||
|
|
1136
|
+
walletNonce === undefined))
|
|
1137
|
+
throw new Error('An issued fee review and approved nonce are required');
|
|
1138
|
+
const selectedAccount = (0, prepared_evm_1.snapshotEvmSigningIdentity)(options.selectedAccount);
|
|
1139
|
+
const targetAccount = (0, prepared_evm_1.snapshotEvmSigningIdentity)(options.targetAccount);
|
|
1117
1140
|
const nonceApproval = walletNonce === undefined ? undefined : { ...walletNonce };
|
|
1118
1141
|
const assertApproved = () => {
|
|
1119
1142
|
const result = assertHostCurrent();
|
|
@@ -1125,14 +1148,14 @@ class EthereumTransactions {
|
|
|
1125
1148
|
assertApproved();
|
|
1126
1149
|
return await this.sendFormattedTransactionInternal(params, isLegacy, () => {
|
|
1127
1150
|
broadcastAttempted = true;
|
|
1128
|
-
}, assertApproved, mode, nonceApproval);
|
|
1151
|
+
}, assertApproved, mode, nonceApproval, selectedAccount, targetAccount, reviewId);
|
|
1129
1152
|
}
|
|
1130
1153
|
catch (error) {
|
|
1131
1154
|
// A broadcast transport error may mean the node accepted the signed
|
|
1132
1155
|
// transaction. Derive this marker from this invocation, never RPC data.
|
|
1133
1156
|
const submissionError = Object.assign(new Error(error instanceof Error ? error.message : String(error)), error, {
|
|
1134
1157
|
transactionNotBroadcast: !broadcastAttempted ||
|
|
1135
|
-
(0, evm_submission_1.evmSubmissionFailure)(error)
|
|
1158
|
+
(0, evm_submission_1.evmSubmissionFailure)(error)?.transactionNotBroadcast === true,
|
|
1136
1159
|
});
|
|
1137
1160
|
if (error instanceof Error) {
|
|
1138
1161
|
submissionError.name = error.name;
|
|
@@ -1142,19 +1165,60 @@ class EthereumTransactions {
|
|
|
1142
1165
|
throw submissionError;
|
|
1143
1166
|
}
|
|
1144
1167
|
};
|
|
1145
|
-
this.sendFormattedTransactionInternal = async (input, isLegacy, beforeBroadcast, assertHostCurrent, mode, walletNonce) => {
|
|
1168
|
+
this.sendFormattedTransactionInternal = async (input, isLegacy, beforeBroadcast, assertHostCurrent, mode, walletNonce, selectedIdentity, targetIdentity, reviewId) => {
|
|
1146
1169
|
// Hardware approval may outlive the selected account, network or unlocked
|
|
1147
1170
|
// session. Keep immutable identities and one provider for this invocation.
|
|
1148
|
-
const
|
|
1171
|
+
const selectedContext = this.captureEvmAccountContext();
|
|
1172
|
+
const targetAccount = {
|
|
1173
|
+
id: targetIdentity.id,
|
|
1174
|
+
type: targetIdentity.type,
|
|
1175
|
+
};
|
|
1176
|
+
if (targetAccount.type === types_1.KeyringAccountType.SmartAccount)
|
|
1177
|
+
throw new Error('Invalid EVM payer');
|
|
1178
|
+
const { activeAccount, activeAccountType, activeAccountId, activeNetwork, provider, assertCurrent: assertKeyringCurrent, } = this.captureEvmSigningContext(targetAccount);
|
|
1149
1179
|
const assertSigningCurrent = () => {
|
|
1150
1180
|
assertHostCurrent();
|
|
1181
|
+
selectedContext.assertCurrent();
|
|
1151
1182
|
assertKeyringCurrent();
|
|
1183
|
+
if (selectedContext.activeAccountId !== selectedIdentity.id ||
|
|
1184
|
+
selectedContext.activeAccountType !== selectedIdentity.type ||
|
|
1185
|
+
(0, address_1.getAddress)(selectedContext.activeAccount.address) !==
|
|
1186
|
+
selectedIdentity.expectedAddress ||
|
|
1187
|
+
(0, address_1.getAddress)(activeAccount.address) !== targetIdentity.expectedAddress)
|
|
1188
|
+
throw new Error('EVM payer approval context changed');
|
|
1152
1189
|
};
|
|
1190
|
+
assertSigningCurrent();
|
|
1191
|
+
// Generic reviewed calls keep the exact prepared envelope, including
|
|
1192
|
+
// contract creation, calldata and access lists, through existing signers.
|
|
1193
|
+
const reviewed = mode === 'reviewed-generic'
|
|
1194
|
+
? (0, evm_envelope_1.snapshotPreparedEvmTransaction)(input)
|
|
1195
|
+
: undefined;
|
|
1196
|
+
if (reviewed) {
|
|
1197
|
+
if (reviewed.from !== targetIdentity.expectedAddress ||
|
|
1198
|
+
reviewed.chainId !== String(activeNetwork.chainId) ||
|
|
1199
|
+
reviewed.nonce !== String(walletNonce?.nonce) ||
|
|
1200
|
+
(isLegacy !== undefined && isLegacy !== (reviewed.type === 0)) ||
|
|
1201
|
+
(this.gasOverrides.minGasLimit &&
|
|
1202
|
+
BigInt(reviewed.gasLimit) < this.gasOverrides.minGasLimit.toBigInt()))
|
|
1203
|
+
throw new Error('Reviewed EVM transaction does not match its approval');
|
|
1204
|
+
input = reviewed;
|
|
1205
|
+
isLegacy = reviewed.type === 0;
|
|
1206
|
+
}
|
|
1153
1207
|
const assertBeforeBroadcast = () => {
|
|
1154
1208
|
assertCurrent();
|
|
1155
1209
|
beforeBroadcast();
|
|
1156
1210
|
};
|
|
1157
|
-
const submission = this.captureSubmission('send', activeAccount, activeAccountType, activeAccountId, activeNetwork, assertSigningCurrent, {
|
|
1211
|
+
const submission = this.captureSubmission('send', activeAccount, activeAccountType, activeAccountId, activeNetwork, assertSigningCurrent, {
|
|
1212
|
+
walletNonce,
|
|
1213
|
+
...(reviewed
|
|
1214
|
+
? {
|
|
1215
|
+
review: {
|
|
1216
|
+
id: reviewId,
|
|
1217
|
+
unsignedHash: transaction_1.Transaction.from((0, evm_envelope_1.serializePreparedEvmTransaction)(reviewed)).unsignedHash,
|
|
1218
|
+
},
|
|
1219
|
+
}
|
|
1220
|
+
: {}),
|
|
1221
|
+
});
|
|
1158
1222
|
const assertCurrent = submission.assertCurrent;
|
|
1159
1223
|
const approvedNonce = submission.context.walletNonce?.nonce;
|
|
1160
1224
|
const assertApprovedNonce = (nonce) => {
|
|
@@ -1163,6 +1227,7 @@ class EthereumTransactions {
|
|
|
1163
1227
|
};
|
|
1164
1228
|
if (mode === 'reviewed-native') {
|
|
1165
1229
|
const { transaction } = (0, prepared_evm_1.snapshotPreparedEvmRequest)({
|
|
1230
|
+
selectedAccount: selectedIdentity,
|
|
1166
1231
|
account: {
|
|
1167
1232
|
id: activeAccountId,
|
|
1168
1233
|
type: activeAccountType,
|
|
@@ -1193,7 +1258,7 @@ class EthereumTransactions {
|
|
|
1193
1258
|
assertCurrent();
|
|
1194
1259
|
if (this.gasOverrides.minGasLimit !== minimum)
|
|
1195
1260
|
throw new Error('Reviewed native gas policy changed');
|
|
1196
|
-
const { address, decryptedPrivateKey } = this.getDecryptedPrivateKey();
|
|
1261
|
+
const { address, decryptedPrivateKey } = this.getDecryptedPrivateKey(targetAccount);
|
|
1197
1262
|
if (address.toLowerCase() !== transaction.from.toLowerCase())
|
|
1198
1263
|
throw new Error('Reviewed native signer does not match the approved account');
|
|
1199
1264
|
assertCurrent();
|
|
@@ -1206,6 +1271,9 @@ class EthereumTransactions {
|
|
|
1206
1271
|
if (!params || typeof params !== 'object' || Array.isArray(params))
|
|
1207
1272
|
throw new TypeError('Invalid EVM transaction request');
|
|
1208
1273
|
const supplied = { ...params };
|
|
1274
|
+
if (supplied.from !== undefined &&
|
|
1275
|
+
(0, address_1.getAddress)(supplied.from) !== targetIdentity.expectedAddress)
|
|
1276
|
+
throw new Error('EVM transaction sender does not match the approved payer');
|
|
1209
1277
|
// Validate original scalar spellings before conversion. Normalization's
|
|
1210
1278
|
// permissive zero coercion must not bypass the bounded wire parser.
|
|
1211
1279
|
for (const field of [
|
|
@@ -1258,7 +1326,8 @@ class EthereumTransactions {
|
|
|
1258
1326
|
const validateEip1559Fees = () => {
|
|
1259
1327
|
const maximum = nonNegativeFeeQuantity(params.maxFeePerGas, 'maximum fee');
|
|
1260
1328
|
const priority = nonNegativeFeeQuantity(params.maxPriorityFeePerGas, 'priority fee');
|
|
1261
|
-
if (maximum.isZero() ||
|
|
1329
|
+
if ((mode !== 'reviewed-generic' && maximum.isZero()) ||
|
|
1330
|
+
priority.gt(maximum))
|
|
1262
1331
|
throw new Error('Invalid EIP-1559 fees');
|
|
1263
1332
|
params.maxFeePerGas = maximum;
|
|
1264
1333
|
params.maxPriorityFeePerGas = priority;
|
|
@@ -1269,7 +1338,9 @@ class EthereumTransactions {
|
|
|
1269
1338
|
validateEip1559Fees();
|
|
1270
1339
|
// Only apply a minimum gas limit when a network-specific override is set.
|
|
1271
1340
|
// Otherwise keep the user/dapp-approved gas limit unchanged.
|
|
1272
|
-
if (
|
|
1341
|
+
if (mode !== 'reviewed-generic' &&
|
|
1342
|
+
params.gasLimit != null &&
|
|
1343
|
+
this.gasOverrides.minGasLimit) {
|
|
1273
1344
|
const minGasLimit = this.gasOverrides.minGasLimit;
|
|
1274
1345
|
const currentGasLimit = ethers_v6_1.BigNumber.from(params.gasLimit);
|
|
1275
1346
|
if (currentGasLimit.lt(minGasLimit)) {
|
|
@@ -1340,31 +1411,15 @@ class EthereumTransactions {
|
|
|
1340
1411
|
type: 2, // Need explicit type for hardware wallet serialization
|
|
1341
1412
|
};
|
|
1342
1413
|
const rawTx = serializeTransaction(txFormattedForEthers);
|
|
1343
|
-
const
|
|
1344
|
-
|
|
1414
|
+
const { rawTransaction: signedTx } = await (0, ledger_signing_1.signLedgerEvmTransaction)(this.requireLedgerSigner(), {
|
|
1415
|
+
unsignedTransaction: rawTx,
|
|
1345
1416
|
accountIndex: activeAccountId,
|
|
1346
1417
|
expectedAddress: activeAccount.address,
|
|
1347
1418
|
}, await this.authorizeHardwareTransaction(provider, assertCurrent));
|
|
1348
1419
|
assertCurrent();
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
v: parseInt(signature.v, 16),
|
|
1353
|
-
};
|
|
1354
|
-
if (signature) {
|
|
1355
|
-
try {
|
|
1356
|
-
const signedTx = serializeTransaction(txFormattedForEthers, formattedSignature);
|
|
1357
|
-
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
1358
|
-
const finalTx = await this.submitSignedHardwareTransaction(provider, signedTx, ({ rawTransaction, admit }) => admit(() => provider.sendTransaction(rawTransaction)), submission, assertBeforeBroadcast, rawTx);
|
|
1359
|
-
return finalTx;
|
|
1360
|
-
}
|
|
1361
|
-
catch (error) {
|
|
1362
|
-
throw error;
|
|
1363
|
-
}
|
|
1364
|
-
}
|
|
1365
|
-
else {
|
|
1366
|
-
throw new Error(`Transaction Signature Failed. Error: ${signature}`);
|
|
1367
|
-
}
|
|
1420
|
+
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
1421
|
+
const finalTx = await this.submitSignedHardwareTransaction(provider, signedTx, ({ rawTransaction, admit }) => admit(() => provider.sendTransaction(rawTransaction)), submission, assertBeforeBroadcast, rawTx);
|
|
1422
|
+
return finalTx;
|
|
1368
1423
|
};
|
|
1369
1424
|
const sendEVMTrezorTransaction = async () => {
|
|
1370
1425
|
assertCurrent();
|
|
@@ -1421,44 +1476,21 @@ class EthereumTransactions {
|
|
|
1421
1476
|
...txFormattedForTrezor,
|
|
1422
1477
|
type: isLegacy ? 0 : 2,
|
|
1423
1478
|
});
|
|
1424
|
-
const
|
|
1425
|
-
|
|
1426
|
-
tx: txFormattedForTrezor,
|
|
1479
|
+
const { rawTransaction: signedTx } = await (0, trezor_signing_1.signTrezorEvmTransaction)(this.requireTrezorSigner(), {
|
|
1480
|
+
accountIndex: activeAccountId,
|
|
1427
1481
|
coin: activeNetwork.currency,
|
|
1482
|
+
expectedAddress: activeAccount.address,
|
|
1428
1483
|
slip44: activeNetwork.slip44,
|
|
1484
|
+
unsignedTransaction: expectedUnsignedTransaction,
|
|
1429
1485
|
}, await this.authorizeHardwareTransaction(provider, assertCurrent));
|
|
1430
1486
|
assertCurrent();
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
? {
|
|
1435
|
-
...formatParams,
|
|
1436
|
-
nonce: transactionNonce,
|
|
1437
|
-
chainId: activeNetwork.chainId,
|
|
1438
|
-
type: 0, // Force Type 0 for legacy
|
|
1439
|
-
}
|
|
1440
|
-
: {
|
|
1441
|
-
...formatParams,
|
|
1442
|
-
nonce: transactionNonce,
|
|
1443
|
-
chainId: activeNetwork.chainId,
|
|
1444
|
-
type: 2, // Need explicit type for hardware wallet serialization
|
|
1445
|
-
};
|
|
1446
|
-
const signedTx = serializeTransaction(txFormattedForEthers, trezorSignature(signature.payload));
|
|
1447
|
-
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
1448
|
-
const finalTx = await this.submitSignedHardwareTransaction(provider, signedTx, ({ rawTransaction, admit }) => admit(() => provider.sendTransaction(rawTransaction)), submission, assertBeforeBroadcast, expectedUnsignedTransaction);
|
|
1449
|
-
return finalTx;
|
|
1450
|
-
}
|
|
1451
|
-
catch (error) {
|
|
1452
|
-
throw error;
|
|
1453
|
-
}
|
|
1454
|
-
}
|
|
1455
|
-
else {
|
|
1456
|
-
throw new Error(`Transaction Signature Failed. Error: ${signature}`);
|
|
1457
|
-
}
|
|
1487
|
+
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
1488
|
+
const finalTx = await this.submitSignedHardwareTransaction(provider, signedTx, ({ rawTransaction, admit }) => admit(() => provider.sendTransaction(rawTransaction)), submission, assertBeforeBroadcast, expectedUnsignedTransaction);
|
|
1489
|
+
return finalTx;
|
|
1458
1490
|
};
|
|
1459
1491
|
const sendEVMTransaction = async () => {
|
|
1460
1492
|
assertCurrent();
|
|
1461
|
-
const { address, decryptedPrivateKey } = this.getDecryptedPrivateKey();
|
|
1493
|
+
const { address, decryptedPrivateKey } = this.getDecryptedPrivateKey(targetAccount);
|
|
1462
1494
|
// Validate that we have the correct private key for the active account to prevent race conditions
|
|
1463
1495
|
// This is critical for transaction security during account switches
|
|
1464
1496
|
if (address.toLowerCase() !== activeAccount.address.toLowerCase()) {
|
|
@@ -1715,32 +1747,18 @@ class EthereumTransactions {
|
|
|
1715
1747
|
};
|
|
1716
1748
|
const rawTx = serializeTransaction(txFormattedForEthers);
|
|
1717
1749
|
assertCurrent();
|
|
1718
|
-
const
|
|
1719
|
-
|
|
1750
|
+
const { rawTransaction: signedTx } = await (0, ledger_signing_1.signLedgerEvmTransaction)(this.requireLedgerSigner(), {
|
|
1751
|
+
unsignedTransaction: rawTx,
|
|
1720
1752
|
accountIndex: activeAccountId,
|
|
1721
1753
|
expectedAddress: activeAccount.address,
|
|
1722
1754
|
}, await this.authorizeHardwareTransaction(provider, assertCurrent));
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1755
|
+
assertSignedSender(signedTx);
|
|
1756
|
+
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
1757
|
+
const transactionResponse = await this.submitSignedHardwareTransaction(provider, signedTx, ({ rawTransaction, admit }) => admit(() => provider.sendTransaction(rawTransaction)), submission, assertBeforeBroadcast, rawTx);
|
|
1758
|
+
return {
|
|
1759
|
+
isSpeedUp: true,
|
|
1760
|
+
transaction: transactionResponse,
|
|
1727
1761
|
};
|
|
1728
|
-
if (signature) {
|
|
1729
|
-
const signedTx = serializeTransaction(txFormattedForEthers, formattedSignature);
|
|
1730
|
-
assertSignedSender(signedTx);
|
|
1731
|
-
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
1732
|
-
const transactionResponse = await this.submitSignedHardwareTransaction(provider, signedTx, ({ rawTransaction, admit }) => admit(() => provider.sendTransaction(rawTransaction)), submission, assertBeforeBroadcast, rawTx);
|
|
1733
|
-
return {
|
|
1734
|
-
isSpeedUp: true,
|
|
1735
|
-
transaction: transactionResponse,
|
|
1736
|
-
};
|
|
1737
|
-
}
|
|
1738
|
-
else {
|
|
1739
|
-
return {
|
|
1740
|
-
isSpeedUp: false,
|
|
1741
|
-
error: true,
|
|
1742
|
-
};
|
|
1743
|
-
}
|
|
1744
1762
|
}
|
|
1745
1763
|
catch (error) {
|
|
1746
1764
|
console.error('[SpeedUp] Failed to send replacement transaction with Ledger:', error);
|
|
@@ -1800,28 +1818,20 @@ class EthereumTransactions {
|
|
|
1800
1818
|
assertCurrent();
|
|
1801
1819
|
assertTransactionGasLimit(txFormattedForTrezor);
|
|
1802
1820
|
const expectedUnsignedTransaction = serializeTransaction(txFormattedForTrezor);
|
|
1803
|
-
const
|
|
1821
|
+
const { rawTransaction: signedTx } = await (0, trezor_signing_1.signTrezorEvmTransaction)(this.requireTrezorSigner(), {
|
|
1822
|
+
accountIndex: activeAccountId,
|
|
1804
1823
|
coin: trezorCoin,
|
|
1805
|
-
|
|
1806
|
-
index: activeAccountId.toString(),
|
|
1824
|
+
expectedAddress: activeAccount.address,
|
|
1807
1825
|
slip44: activeNetwork.slip44,
|
|
1826
|
+
unsignedTransaction: expectedUnsignedTransaction,
|
|
1808
1827
|
}, await this.authorizeHardwareTransaction(provider, assertCurrent));
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
transaction: transactionResponse,
|
|
1817
|
-
};
|
|
1818
|
-
}
|
|
1819
|
-
else {
|
|
1820
|
-
return {
|
|
1821
|
-
isSpeedUp: false,
|
|
1822
|
-
error: true,
|
|
1823
|
-
};
|
|
1824
|
-
}
|
|
1828
|
+
assertSignedSender(signedTx);
|
|
1829
|
+
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
1830
|
+
const transactionResponse = await this.submitSignedHardwareTransaction(provider, signedTx, ({ rawTransaction, admit }) => admit(() => provider.sendTransaction(rawTransaction)), submission, assertBeforeBroadcast, expectedUnsignedTransaction);
|
|
1831
|
+
return {
|
|
1832
|
+
isSpeedUp: true,
|
|
1833
|
+
transaction: transactionResponse,
|
|
1834
|
+
};
|
|
1825
1835
|
}
|
|
1826
1836
|
catch (error) {
|
|
1827
1837
|
console.error('[SpeedUp] Failed to send replacement transaction with Trezor:', error);
|
|
@@ -1953,73 +1963,51 @@ class EthereumTransactions {
|
|
|
1953
1963
|
};
|
|
1954
1964
|
const sendERC20TokenOnLedger = async () => {
|
|
1955
1965
|
assertCurrent();
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
type: 0,
|
|
1973
|
-
};
|
|
1974
|
-
}
|
|
1975
|
-
else {
|
|
1976
|
-
txFormattedForEthers = {
|
|
1977
|
-
to: tokenAddress,
|
|
1978
|
-
value: '0x0',
|
|
1979
|
-
gasLimit: gasLimit,
|
|
1980
|
-
maxFeePerGas,
|
|
1981
|
-
maxPriorityFeePerGas,
|
|
1982
|
-
data: txData,
|
|
1983
|
-
nonce,
|
|
1984
|
-
chainId: activeNetwork.chainId,
|
|
1985
|
-
type: 2, // Need explicit type for hardware wallet serialization
|
|
1986
|
-
};
|
|
1987
|
-
}
|
|
1988
|
-
const rawTx = serializeTransaction(txFormattedForEthers);
|
|
1989
|
-
const signature = await this.requireLedgerSigner().evm.signEVMTransaction({
|
|
1990
|
-
rawTx: rawTx.replace('0x', ''),
|
|
1991
|
-
accountIndex: activeAccountId,
|
|
1992
|
-
expectedAddress: activeAccount.address,
|
|
1993
|
-
}, await this.authorizeHardwareTransaction(provider, assertCurrent, signal));
|
|
1994
|
-
assertCurrent();
|
|
1995
|
-
const formattedSignature = {
|
|
1996
|
-
r: `0x${signature.r}`,
|
|
1997
|
-
s: `0x${signature.s}`,
|
|
1998
|
-
v: parseInt(signature.v, 16),
|
|
1966
|
+
const _contract = new ethers_v6_1.Contract(tokenAddress, (0, sysweb3_utils_1.getErc20Abi)(), provider);
|
|
1967
|
+
const txData = _contract.interface.encodeFunctionData('transfer', [
|
|
1968
|
+
receiver,
|
|
1969
|
+
exactTokenAmount,
|
|
1970
|
+
]);
|
|
1971
|
+
let txFormattedForEthers;
|
|
1972
|
+
if (isLegacy) {
|
|
1973
|
+
txFormattedForEthers = {
|
|
1974
|
+
to: tokenAddress,
|
|
1975
|
+
value: '0x0',
|
|
1976
|
+
gasLimit: gasLimit,
|
|
1977
|
+
gasPrice,
|
|
1978
|
+
data: txData,
|
|
1979
|
+
nonce,
|
|
1980
|
+
chainId: activeNetwork.chainId,
|
|
1981
|
+
type: 0,
|
|
1999
1982
|
};
|
|
2000
|
-
if (signature) {
|
|
2001
|
-
try {
|
|
2002
|
-
const signedTx = serializeTransaction(txFormattedForEthers, formattedSignature);
|
|
2003
|
-
assertCurrent();
|
|
2004
|
-
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
2005
|
-
const finalTx = await this.submitSignedHardwareTransaction(provider, signedTx, async ({ rawTransaction, admit }) => {
|
|
2006
|
-
const response = await admit(() => provider.sendTransaction(rawTransaction));
|
|
2007
|
-
saveTrezorTx && saveTrezorTx(response);
|
|
2008
|
-
return response;
|
|
2009
|
-
}, submission, undefined, rawTx);
|
|
2010
|
-
return finalTx;
|
|
2011
|
-
}
|
|
2012
|
-
catch (error) {
|
|
2013
|
-
throw error;
|
|
2014
|
-
}
|
|
2015
|
-
}
|
|
2016
|
-
else {
|
|
2017
|
-
throw new Error(`Transaction Signature Failed. Error: ${signature}`);
|
|
2018
|
-
}
|
|
2019
1983
|
}
|
|
2020
|
-
|
|
2021
|
-
|
|
1984
|
+
else {
|
|
1985
|
+
txFormattedForEthers = {
|
|
1986
|
+
to: tokenAddress,
|
|
1987
|
+
value: '0x0',
|
|
1988
|
+
gasLimit: gasLimit,
|
|
1989
|
+
maxFeePerGas,
|
|
1990
|
+
maxPriorityFeePerGas,
|
|
1991
|
+
data: txData,
|
|
1992
|
+
nonce,
|
|
1993
|
+
chainId: activeNetwork.chainId,
|
|
1994
|
+
type: 2, // Need explicit type for hardware wallet serialization
|
|
1995
|
+
};
|
|
2022
1996
|
}
|
|
1997
|
+
const rawTx = serializeTransaction(txFormattedForEthers);
|
|
1998
|
+
const { rawTransaction: signedTx } = await (0, ledger_signing_1.signLedgerEvmTransaction)(this.requireLedgerSigner(), {
|
|
1999
|
+
unsignedTransaction: rawTx,
|
|
2000
|
+
accountIndex: activeAccountId,
|
|
2001
|
+
expectedAddress: activeAccount.address,
|
|
2002
|
+
}, await this.authorizeHardwareTransaction(provider, assertCurrent, signal));
|
|
2003
|
+
assertCurrent();
|
|
2004
|
+
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
2005
|
+
const finalTx = await this.submitSignedHardwareTransaction(provider, signedTx, async ({ rawTransaction, admit }) => {
|
|
2006
|
+
const response = await admit(() => provider.sendTransaction(rawTransaction));
|
|
2007
|
+
saveTrezorTx && saveTrezorTx(response);
|
|
2008
|
+
return response;
|
|
2009
|
+
}, submission, undefined, rawTx);
|
|
2010
|
+
return finalTx;
|
|
2023
2011
|
};
|
|
2024
2012
|
const sendERC20TokenOnTrezor = async () => {
|
|
2025
2013
|
assertCurrent();
|
|
@@ -2058,58 +2046,21 @@ class EthereumTransactions {
|
|
|
2058
2046
|
...txToBeSignedByTrezor,
|
|
2059
2047
|
type: isLegacy ? 0 : 2,
|
|
2060
2048
|
});
|
|
2061
|
-
const
|
|
2062
|
-
|
|
2063
|
-
tx: txToBeSignedByTrezor,
|
|
2049
|
+
const { rawTransaction: signedTx } = await (0, trezor_signing_1.signTrezorEvmTransaction)(this.requireTrezorSigner(), {
|
|
2050
|
+
accountIndex: activeAccountId,
|
|
2064
2051
|
coin: activeNetwork.currency,
|
|
2052
|
+
expectedAddress: activeAccount.address,
|
|
2065
2053
|
slip44: activeNetwork.slip44,
|
|
2054
|
+
unsignedTransaction: expectedUnsignedTransaction,
|
|
2066
2055
|
}, await this.authorizeHardwareTransaction(provider, assertCurrent, signal));
|
|
2067
2056
|
assertCurrent();
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
gasLimit: gasLimit,
|
|
2076
|
-
gasPrice,
|
|
2077
|
-
data: txData,
|
|
2078
|
-
nonce,
|
|
2079
|
-
chainId: activeNetwork.chainId,
|
|
2080
|
-
type: 0,
|
|
2081
|
-
};
|
|
2082
|
-
}
|
|
2083
|
-
else {
|
|
2084
|
-
txFormattedForEthers = {
|
|
2085
|
-
to: tokenAddress,
|
|
2086
|
-
value: '0x0',
|
|
2087
|
-
gasLimit: gasLimit,
|
|
2088
|
-
maxFeePerGas,
|
|
2089
|
-
maxPriorityFeePerGas,
|
|
2090
|
-
data: txData,
|
|
2091
|
-
nonce,
|
|
2092
|
-
chainId: activeNetwork.chainId,
|
|
2093
|
-
type: 2, // Need explicit type for hardware wallet serialization
|
|
2094
|
-
};
|
|
2095
|
-
}
|
|
2096
|
-
const signedTx = serializeTransaction(txFormattedForEthers, trezorSignature(signature.payload));
|
|
2097
|
-
assertCurrent();
|
|
2098
|
-
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
2099
|
-
const finalTx = await this.submitSignedHardwareTransaction(provider, signedTx, async ({ rawTransaction, admit }) => {
|
|
2100
|
-
const response = await admit(() => provider.sendTransaction(rawTransaction));
|
|
2101
|
-
saveTrezorTx && saveTrezorTx(response);
|
|
2102
|
-
return response;
|
|
2103
|
-
}, submission, undefined, expectedUnsignedTransaction);
|
|
2104
|
-
return finalTx;
|
|
2105
|
-
}
|
|
2106
|
-
catch (error) {
|
|
2107
|
-
throw error;
|
|
2108
|
-
}
|
|
2109
|
-
}
|
|
2110
|
-
else {
|
|
2111
|
-
throw new Error(`Transaction Signature Failed. Error: ${signature}`);
|
|
2112
|
-
}
|
|
2057
|
+
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
2058
|
+
const finalTx = await this.submitSignedHardwareTransaction(provider, signedTx, async ({ rawTransaction, admit }) => {
|
|
2059
|
+
const response = await admit(() => provider.sendTransaction(rawTransaction));
|
|
2060
|
+
saveTrezorTx && saveTrezorTx(response);
|
|
2061
|
+
return response;
|
|
2062
|
+
}, submission, undefined, expectedUnsignedTransaction);
|
|
2063
|
+
return finalTx;
|
|
2113
2064
|
}
|
|
2114
2065
|
catch (error) {
|
|
2115
2066
|
throw error;
|
|
@@ -2180,70 +2131,48 @@ class EthereumTransactions {
|
|
|
2180
2131
|
};
|
|
2181
2132
|
const sendERC721TokenOnLedger = async () => {
|
|
2182
2133
|
assertCurrent();
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
type: 0,
|
|
2201
|
-
};
|
|
2202
|
-
}
|
|
2203
|
-
else {
|
|
2204
|
-
txFormattedForEthers = {
|
|
2205
|
-
to: tokenAddress,
|
|
2206
|
-
value: '0x0',
|
|
2207
|
-
gasLimit,
|
|
2208
|
-
maxFeePerGas,
|
|
2209
|
-
maxPriorityFeePerGas,
|
|
2210
|
-
data: txData,
|
|
2211
|
-
nonce,
|
|
2212
|
-
chainId: activeNetwork.chainId,
|
|
2213
|
-
type: 2, // Need explicit type for hardware wallet serialization
|
|
2214
|
-
};
|
|
2215
|
-
}
|
|
2216
|
-
const rawTx = serializeTransaction(txFormattedForEthers);
|
|
2217
|
-
const signature = await this.requireLedgerSigner().evm.signEVMTransaction({
|
|
2218
|
-
rawTx: rawTx.replace('0x', ''),
|
|
2219
|
-
accountIndex: activeAccountId,
|
|
2220
|
-
expectedAddress: activeAccount.address,
|
|
2221
|
-
}, await this.authorizeHardwareTransaction(provider, assertCurrent, signal));
|
|
2222
|
-
assertCurrent();
|
|
2223
|
-
const formattedSignature = {
|
|
2224
|
-
r: `0x${signature.r}`,
|
|
2225
|
-
s: `0x${signature.s}`,
|
|
2226
|
-
v: parseInt(signature.v, 16),
|
|
2134
|
+
const _contract = new ethers_v6_1.Contract(tokenAddress, (0, sysweb3_utils_1.getErc21Abi)(), provider);
|
|
2135
|
+
const txData = _contract.interface.encodeFunctionData('transferFrom', [
|
|
2136
|
+
activeAccountAddress,
|
|
2137
|
+
receiver,
|
|
2138
|
+
normalizedTokenId,
|
|
2139
|
+
]);
|
|
2140
|
+
let txFormattedForEthers;
|
|
2141
|
+
if (isLegacy) {
|
|
2142
|
+
txFormattedForEthers = {
|
|
2143
|
+
to: tokenAddress,
|
|
2144
|
+
value: '0x0',
|
|
2145
|
+
gasLimit,
|
|
2146
|
+
gasPrice,
|
|
2147
|
+
data: txData,
|
|
2148
|
+
nonce,
|
|
2149
|
+
chainId: activeNetwork.chainId,
|
|
2150
|
+
type: 0,
|
|
2227
2151
|
};
|
|
2228
|
-
if (signature) {
|
|
2229
|
-
try {
|
|
2230
|
-
const signedTx = serializeTransaction(txFormattedForEthers, formattedSignature);
|
|
2231
|
-
assertCurrent();
|
|
2232
|
-
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
2233
|
-
const finalTx = await this.submitSignedHardwareTransaction(provider, signedTx, ({ rawTransaction, admit }) => admit(() => provider.sendTransaction(rawTransaction)), submission, undefined, rawTx);
|
|
2234
|
-
return finalTx;
|
|
2235
|
-
}
|
|
2236
|
-
catch (error) {
|
|
2237
|
-
throw error;
|
|
2238
|
-
}
|
|
2239
|
-
}
|
|
2240
|
-
else {
|
|
2241
|
-
throw new Error(`Transaction Signature Failed. Error: ${signature}`);
|
|
2242
|
-
}
|
|
2243
2152
|
}
|
|
2244
|
-
|
|
2245
|
-
|
|
2153
|
+
else {
|
|
2154
|
+
txFormattedForEthers = {
|
|
2155
|
+
to: tokenAddress,
|
|
2156
|
+
value: '0x0',
|
|
2157
|
+
gasLimit,
|
|
2158
|
+
maxFeePerGas,
|
|
2159
|
+
maxPriorityFeePerGas,
|
|
2160
|
+
data: txData,
|
|
2161
|
+
nonce,
|
|
2162
|
+
chainId: activeNetwork.chainId,
|
|
2163
|
+
type: 2, // Need explicit type for hardware wallet serialization
|
|
2164
|
+
};
|
|
2246
2165
|
}
|
|
2166
|
+
const rawTx = serializeTransaction(txFormattedForEthers);
|
|
2167
|
+
const { rawTransaction: signedTx } = await (0, ledger_signing_1.signLedgerEvmTransaction)(this.requireLedgerSigner(), {
|
|
2168
|
+
unsignedTransaction: rawTx,
|
|
2169
|
+
accountIndex: activeAccountId,
|
|
2170
|
+
expectedAddress: activeAccount.address,
|
|
2171
|
+
}, await this.authorizeHardwareTransaction(provider, assertCurrent, signal));
|
|
2172
|
+
assertCurrent();
|
|
2173
|
+
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
2174
|
+
const finalTx = await this.submitSignedHardwareTransaction(provider, signedTx, ({ rawTransaction, admit }) => admit(() => provider.sendTransaction(rawTransaction)), submission, undefined, rawTx);
|
|
2175
|
+
return finalTx;
|
|
2247
2176
|
};
|
|
2248
2177
|
const sendERC721TokenOnTrezor = async () => {
|
|
2249
2178
|
assertCurrent();
|
|
@@ -2286,55 +2215,17 @@ class EthereumTransactions {
|
|
|
2286
2215
|
...txToBeSignedByTrezor,
|
|
2287
2216
|
type: isLegacy ? 0 : 2,
|
|
2288
2217
|
});
|
|
2289
|
-
const
|
|
2290
|
-
|
|
2291
|
-
tx: txToBeSignedByTrezor,
|
|
2218
|
+
const { rawTransaction: signedTx } = await (0, trezor_signing_1.signTrezorEvmTransaction)(this.requireTrezorSigner(), {
|
|
2219
|
+
accountIndex: activeAccountId,
|
|
2292
2220
|
coin: trezorCoin,
|
|
2221
|
+
expectedAddress: activeAccount.address,
|
|
2293
2222
|
slip44: activeNetwork.slip44,
|
|
2223
|
+
unsignedTransaction: expectedUnsignedTransaction,
|
|
2294
2224
|
}, await this.authorizeHardwareTransaction(provider, assertCurrent, signal));
|
|
2295
2225
|
assertCurrent();
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
if (isLegacy) {
|
|
2300
|
-
txFormattedForEthers = {
|
|
2301
|
-
to: tokenAddress,
|
|
2302
|
-
value: '0x0',
|
|
2303
|
-
gasLimit,
|
|
2304
|
-
gasPrice,
|
|
2305
|
-
data: txData,
|
|
2306
|
-
nonce,
|
|
2307
|
-
chainId: activeNetwork.chainId,
|
|
2308
|
-
type: 0,
|
|
2309
|
-
};
|
|
2310
|
-
}
|
|
2311
|
-
else {
|
|
2312
|
-
txFormattedForEthers = {
|
|
2313
|
-
to: tokenAddress,
|
|
2314
|
-
value: '0x0',
|
|
2315
|
-
gasLimit,
|
|
2316
|
-
maxFeePerGas,
|
|
2317
|
-
maxPriorityFeePerGas,
|
|
2318
|
-
data: txData,
|
|
2319
|
-
nonce,
|
|
2320
|
-
chainId: activeNetwork.chainId,
|
|
2321
|
-
type: 2, // Need explicit type for hardware wallet serialization
|
|
2322
|
-
};
|
|
2323
|
-
}
|
|
2324
|
-
const signedTx = serializeTransaction(txFormattedForEthers, trezorSignature(signature.payload));
|
|
2325
|
-
assertCurrent();
|
|
2326
|
-
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
2327
|
-
const finalTx = await this.submitSignedHardwareTransaction(provider, signedTx, ({ rawTransaction, admit }) => admit(() => provider.sendTransaction(rawTransaction)), submission, undefined, expectedUnsignedTransaction);
|
|
2328
|
-
return finalTx;
|
|
2329
|
-
}
|
|
2330
|
-
catch (error) {
|
|
2331
|
-
console.log({ error });
|
|
2332
|
-
throw error;
|
|
2333
|
-
}
|
|
2334
|
-
}
|
|
2335
|
-
else {
|
|
2336
|
-
throw new Error(`Transaction Signature Failed. Error: ${signature}`);
|
|
2337
|
-
}
|
|
2226
|
+
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
2227
|
+
const finalTx = await this.submitSignedHardwareTransaction(provider, signedTx, ({ rawTransaction, admit }) => admit(() => provider.sendTransaction(rawTransaction)), submission, undefined, expectedUnsignedTransaction);
|
|
2228
|
+
return finalTx;
|
|
2338
2229
|
}
|
|
2339
2230
|
catch (error) {
|
|
2340
2231
|
console.log({ errorDois: error });
|
|
@@ -2410,66 +2301,44 @@ class EthereumTransactions {
|
|
|
2410
2301
|
};
|
|
2411
2302
|
const sendERC1155TokenOnLedger = async () => {
|
|
2412
2303
|
assertCurrent();
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
type: 0,
|
|
2427
|
-
};
|
|
2428
|
-
}
|
|
2429
|
-
else {
|
|
2430
|
-
txFormattedForEthers = {
|
|
2431
|
-
to: tokenAddress,
|
|
2432
|
-
value: '0x0',
|
|
2433
|
-
gasLimit,
|
|
2434
|
-
maxFeePerGas,
|
|
2435
|
-
maxPriorityFeePerGas,
|
|
2436
|
-
data: txData,
|
|
2437
|
-
nonce,
|
|
2438
|
-
chainId: activeNetwork.chainId,
|
|
2439
|
-
type: 2, // Need explicit type for hardware wallet serialization
|
|
2440
|
-
};
|
|
2441
|
-
}
|
|
2442
|
-
const rawTx = serializeTransaction(txFormattedForEthers);
|
|
2443
|
-
const signature = await this.requireLedgerSigner().evm.signEVMTransaction({
|
|
2444
|
-
rawTx: rawTx.replace('0x', ''),
|
|
2445
|
-
accountIndex: activeAccountId,
|
|
2446
|
-
expectedAddress: activeAccount.address,
|
|
2447
|
-
}, await this.authorizeHardwareTransaction(provider, assertCurrent, signal));
|
|
2448
|
-
assertCurrent();
|
|
2449
|
-
const formattedSignature = {
|
|
2450
|
-
r: `0x${signature.r}`,
|
|
2451
|
-
s: `0x${signature.s}`,
|
|
2452
|
-
v: parseInt(signature.v, 16),
|
|
2304
|
+
const _contract = new ethers_v6_1.Contract(tokenAddress, (0, sysweb3_utils_1.getErc55Abi)(), provider);
|
|
2305
|
+
const txData = _contract.interface.encodeFunctionData('safeTransferFrom', [activeAccountAddress, receiver, normalizedTokenId, amount, '0x']);
|
|
2306
|
+
let txFormattedForEthers;
|
|
2307
|
+
if (isLegacy) {
|
|
2308
|
+
txFormattedForEthers = {
|
|
2309
|
+
to: tokenAddress,
|
|
2310
|
+
value: '0x0',
|
|
2311
|
+
gasLimit,
|
|
2312
|
+
gasPrice,
|
|
2313
|
+
data: txData,
|
|
2314
|
+
nonce,
|
|
2315
|
+
chainId: activeNetwork.chainId,
|
|
2316
|
+
type: 0,
|
|
2453
2317
|
};
|
|
2454
|
-
if (signature) {
|
|
2455
|
-
try {
|
|
2456
|
-
const signedTx = serializeTransaction(txFormattedForEthers, formattedSignature);
|
|
2457
|
-
assertCurrent();
|
|
2458
|
-
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
2459
|
-
const finalTx = await this.submitSignedHardwareTransaction(provider, signedTx, ({ rawTransaction, admit }) => admit(() => provider.sendTransaction(rawTransaction)), submission, undefined, rawTx);
|
|
2460
|
-
return finalTx;
|
|
2461
|
-
}
|
|
2462
|
-
catch (error) {
|
|
2463
|
-
throw error;
|
|
2464
|
-
}
|
|
2465
|
-
}
|
|
2466
|
-
else {
|
|
2467
|
-
throw new Error(`Transaction Signature Failed. Error: ${signature}`);
|
|
2468
|
-
}
|
|
2469
2318
|
}
|
|
2470
|
-
|
|
2471
|
-
|
|
2319
|
+
else {
|
|
2320
|
+
txFormattedForEthers = {
|
|
2321
|
+
to: tokenAddress,
|
|
2322
|
+
value: '0x0',
|
|
2323
|
+
gasLimit,
|
|
2324
|
+
maxFeePerGas,
|
|
2325
|
+
maxPriorityFeePerGas,
|
|
2326
|
+
data: txData,
|
|
2327
|
+
nonce,
|
|
2328
|
+
chainId: activeNetwork.chainId,
|
|
2329
|
+
type: 2, // Need explicit type for hardware wallet serialization
|
|
2330
|
+
};
|
|
2472
2331
|
}
|
|
2332
|
+
const rawTx = serializeTransaction(txFormattedForEthers);
|
|
2333
|
+
const { rawTransaction: signedTx } = await (0, ledger_signing_1.signLedgerEvmTransaction)(this.requireLedgerSigner(), {
|
|
2334
|
+
unsignedTransaction: rawTx,
|
|
2335
|
+
accountIndex: activeAccountId,
|
|
2336
|
+
expectedAddress: activeAccount.address,
|
|
2337
|
+
}, await this.authorizeHardwareTransaction(provider, assertCurrent, signal));
|
|
2338
|
+
assertCurrent();
|
|
2339
|
+
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
2340
|
+
const finalTx = await this.submitSignedHardwareTransaction(provider, signedTx, ({ rawTransaction, admit }) => admit(() => provider.sendTransaction(rawTransaction)), submission, undefined, rawTx);
|
|
2341
|
+
return finalTx;
|
|
2473
2342
|
};
|
|
2474
2343
|
const sendERC1155TokenOnTrezor = async () => {
|
|
2475
2344
|
assertCurrent();
|
|
@@ -2505,55 +2374,17 @@ class EthereumTransactions {
|
|
|
2505
2374
|
...txToBeSignedByTrezor,
|
|
2506
2375
|
type: isLegacy ? 0 : 2,
|
|
2507
2376
|
});
|
|
2508
|
-
const
|
|
2509
|
-
|
|
2510
|
-
tx: txToBeSignedByTrezor,
|
|
2377
|
+
const { rawTransaction: signedTx } = await (0, trezor_signing_1.signTrezorEvmTransaction)(this.requireTrezorSigner(), {
|
|
2378
|
+
accountIndex: activeAccountId,
|
|
2511
2379
|
coin: activeNetwork.currency,
|
|
2380
|
+
expectedAddress: activeAccount.address,
|
|
2512
2381
|
slip44: activeNetwork.slip44,
|
|
2382
|
+
unsignedTransaction: expectedUnsignedTransaction,
|
|
2513
2383
|
}, await this.authorizeHardwareTransaction(provider, assertCurrent, signal));
|
|
2514
2384
|
assertCurrent();
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
if (isLegacy) {
|
|
2519
|
-
txFormattedForEthers = {
|
|
2520
|
-
to: tokenAddress,
|
|
2521
|
-
value: '0x0',
|
|
2522
|
-
gasLimit,
|
|
2523
|
-
gasPrice,
|
|
2524
|
-
data: txData,
|
|
2525
|
-
nonce,
|
|
2526
|
-
chainId: activeNetwork.chainId,
|
|
2527
|
-
type: 0,
|
|
2528
|
-
};
|
|
2529
|
-
}
|
|
2530
|
-
else {
|
|
2531
|
-
txFormattedForEthers = {
|
|
2532
|
-
to: tokenAddress,
|
|
2533
|
-
value: '0x0',
|
|
2534
|
-
gasLimit,
|
|
2535
|
-
maxFeePerGas,
|
|
2536
|
-
maxPriorityFeePerGas,
|
|
2537
|
-
data: txData,
|
|
2538
|
-
nonce,
|
|
2539
|
-
chainId: activeNetwork.chainId,
|
|
2540
|
-
type: 2, // Need explicit type for hardware wallet serialization
|
|
2541
|
-
};
|
|
2542
|
-
}
|
|
2543
|
-
const signedTx = serializeTransaction(txFormattedForEthers, trezorSignature(signature.payload));
|
|
2544
|
-
assertCurrent();
|
|
2545
|
-
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
2546
|
-
const finalTx = await this.submitSignedHardwareTransaction(provider, signedTx, ({ rawTransaction, admit }) => admit(() => provider.sendTransaction(rawTransaction)), submission, undefined, expectedUnsignedTransaction);
|
|
2547
|
-
return finalTx;
|
|
2548
|
-
}
|
|
2549
|
-
catch (error) {
|
|
2550
|
-
console.log({ error });
|
|
2551
|
-
throw error;
|
|
2552
|
-
}
|
|
2553
|
-
}
|
|
2554
|
-
else {
|
|
2555
|
-
throw new Error(`Transaction Signature Failed. Error: ${signature}`);
|
|
2556
|
-
}
|
|
2385
|
+
assertHardwareTransactionSender(signedTx, activeAccount.address);
|
|
2386
|
+
const finalTx = await this.submitSignedHardwareTransaction(provider, signedTx, ({ rawTransaction, admit }) => admit(() => provider.sendTransaction(rawTransaction)), submission, undefined, expectedUnsignedTransaction);
|
|
2387
|
+
return finalTx;
|
|
2557
2388
|
}
|
|
2558
2389
|
catch (error) {
|
|
2559
2390
|
console.log({ error });
|
|
@@ -2791,6 +2622,52 @@ class EthereumTransactions {
|
|
|
2791
2622
|
console.log('[EthereumTransactions] Deferring provider initialization:', error?.message || error);
|
|
2792
2623
|
}
|
|
2793
2624
|
}
|
|
2625
|
+
signPreparedEvmTransaction(input, options) {
|
|
2626
|
+
const selected = this.captureEvmAccountContext();
|
|
2627
|
+
const request = (0, prepared_evm_1.snapshotPreparedEvmRequest)(input);
|
|
2628
|
+
const target = {
|
|
2629
|
+
id: request.account.id,
|
|
2630
|
+
type: request.account.type,
|
|
2631
|
+
};
|
|
2632
|
+
const context = this.captureEvmAccountContext(target);
|
|
2633
|
+
const hostGuard = (0, prepared_evm_1.preparedEvmGuard)(options);
|
|
2634
|
+
const targetRecord = this.getState().accounts[target.type]?.[target.id];
|
|
2635
|
+
const encryptedKey = targetRecord?.xprv;
|
|
2636
|
+
const assertCurrent = () => {
|
|
2637
|
+
selected.assertCurrent();
|
|
2638
|
+
context.assertCurrent();
|
|
2639
|
+
const live = this.getState().accounts[target.type]?.[target.id];
|
|
2640
|
+
if (!live ||
|
|
2641
|
+
live.id !== target.id ||
|
|
2642
|
+
live.isSmartAccount ||
|
|
2643
|
+
live.isLedgerWallet ||
|
|
2644
|
+
live.isTrezorWallet ||
|
|
2645
|
+
typeof encryptedKey !== 'string' ||
|
|
2646
|
+
!encryptedKey ||
|
|
2647
|
+
live.xprv !== encryptedKey ||
|
|
2648
|
+
selected.activeAccountId !== request.selectedAccount.id ||
|
|
2649
|
+
selected.activeAccountType !== request.selectedAccount.type ||
|
|
2650
|
+
(0, address_1.getAddress)(selected.activeAccount.address) !==
|
|
2651
|
+
request.selectedAccount.expectedAddress ||
|
|
2652
|
+
(0, address_1.getAddress)(context.activeAccount.address) !==
|
|
2653
|
+
request.account.expectedAddress ||
|
|
2654
|
+
context.activeNetwork.kind !== 'ethereum' ||
|
|
2655
|
+
context.activeNetwork.slip44 !== 60 ||
|
|
2656
|
+
String(context.activeNetwork.chainId) !== request.network.chainId ||
|
|
2657
|
+
context.activeNetwork.url !== request.network.url)
|
|
2658
|
+
throw new Error('Prepared EVM signing context changed or is unsupported');
|
|
2659
|
+
};
|
|
2660
|
+
assertCurrent();
|
|
2661
|
+
hostGuard();
|
|
2662
|
+
assertCurrent();
|
|
2663
|
+
const key = this.getDecryptedPrivateKey(target);
|
|
2664
|
+
if ((0, address_1.getAddress)(key.address) !== request.account.expectedAddress)
|
|
2665
|
+
throw new Error('Prepared EVM signer address mismatch');
|
|
2666
|
+
const { signed } = (0, prepared_evm_1.signPreparedEvmEnvelope)(request.transaction, key.decryptedPrivateKey);
|
|
2667
|
+
hostGuard();
|
|
2668
|
+
assertCurrent();
|
|
2669
|
+
return signed;
|
|
2670
|
+
}
|
|
2794
2671
|
setWeb3Provider(network) {
|
|
2795
2672
|
this.abortController.abort();
|
|
2796
2673
|
this.abortController = new AbortController();
|