@metamask-previews/wallet-cli 0.0.0-preview-b3db565c8 → 0.0.0-preview-8bfa290fb
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 +4 -8
- package/dist/commands/daemon/call.cjs +79 -0
- package/dist/commands/daemon/call.cjs.map +1 -0
- package/dist/commands/daemon/{call.d.ts → call.d.cts} +2 -2
- package/dist/commands/daemon/call.d.cts.map +1 -0
- package/dist/commands/daemon/call.d.mts +14 -0
- package/dist/commands/daemon/call.d.mts.map +1 -0
- package/dist/commands/daemon/{call.js → call.mjs} +31 -30
- package/dist/commands/daemon/call.mjs.map +1 -0
- package/dist/commands/daemon/list.cjs +48 -0
- package/dist/commands/daemon/list.cjs.map +1 -0
- package/dist/commands/daemon/{list.d.ts → list.d.cts} +2 -2
- package/dist/commands/daemon/list.d.cts.map +1 -0
- package/dist/commands/daemon/list.d.mts +7 -0
- package/dist/commands/daemon/list.d.mts.map +1 -0
- package/dist/commands/daemon/{list.js → list.mjs} +10 -9
- package/dist/commands/daemon/list.mjs.map +1 -0
- package/dist/commands/daemon/purge.cjs +58 -0
- package/dist/commands/daemon/purge.cjs.map +1 -0
- package/dist/commands/daemon/{purge.d.ts → purge.d.cts} +2 -2
- package/dist/commands/daemon/purge.d.cts.map +1 -0
- package/dist/commands/daemon/purge.d.mts +10 -0
- package/dist/commands/daemon/purge.d.mts.map +1 -0
- package/dist/commands/daemon/{purge.js → purge.mjs} +20 -19
- package/dist/commands/daemon/purge.mjs.map +1 -0
- package/dist/commands/daemon/start.cjs +52 -0
- package/dist/commands/daemon/{start.js.map → start.cjs.map} +1 -1
- package/dist/commands/daemon/{start.d.ts → start.d.cts} +2 -2
- package/dist/commands/daemon/start.d.cts.map +1 -0
- package/dist/commands/daemon/start.d.mts +12 -0
- package/dist/commands/daemon/start.d.mts.map +1 -0
- package/dist/commands/daemon/start.mjs +50 -0
- package/dist/commands/daemon/start.mjs.map +1 -0
- package/dist/commands/daemon/status.cjs +59 -0
- package/dist/commands/daemon/status.cjs.map +1 -0
- package/dist/commands/daemon/{status.d.ts → status.d.cts} +2 -2
- package/dist/commands/daemon/status.d.cts.map +1 -0
- package/dist/commands/daemon/status.d.mts +7 -0
- package/dist/commands/daemon/status.d.mts.map +1 -0
- package/dist/commands/daemon/{status.js → status.mjs} +11 -10
- package/dist/commands/daemon/status.mjs.map +1 -0
- package/dist/commands/daemon/stop.cjs +26 -0
- package/dist/commands/daemon/stop.cjs.map +1 -0
- package/dist/commands/daemon/{stop.d.ts → stop.d.cts} +2 -2
- package/dist/commands/daemon/stop.d.cts.map +1 -0
- package/dist/commands/daemon/stop.d.mts +7 -0
- package/dist/commands/daemon/stop.d.mts.map +1 -0
- package/dist/commands/daemon/{stop.js → stop.mjs} +10 -9
- package/dist/commands/daemon/stop.mjs.map +1 -0
- package/dist/commands/wallet/send.cjs +332 -0
- package/dist/commands/wallet/send.cjs.map +1 -0
- package/dist/commands/wallet/{send.d.ts → send.d.cts} +3 -3
- package/dist/commands/wallet/send.d.cts.map +1 -0
- package/dist/commands/wallet/send.d.mts +42 -0
- package/dist/commands/wallet/send.d.mts.map +1 -0
- package/dist/commands/wallet/{send.js → send.mjs} +123 -111
- package/dist/commands/wallet/send.mjs.map +1 -0
- package/dist/commands/wallet/unlock.cjs +75 -0
- package/dist/commands/wallet/unlock.cjs.map +1 -0
- package/dist/commands/wallet/{unlock.d.ts → unlock.d.cts} +2 -2
- package/dist/commands/wallet/unlock.d.cts.map +1 -0
- package/dist/commands/wallet/unlock.d.mts +11 -0
- package/dist/commands/wallet/unlock.d.mts.map +1 -0
- package/dist/commands/wallet/{unlock.js → unlock.mjs} +30 -29
- package/dist/commands/wallet/unlock.mjs.map +1 -0
- package/dist/daemon/auto-approval.cjs +86 -0
- package/dist/daemon/auto-approval.cjs.map +1 -0
- package/dist/daemon/{auto-approval.d.ts → auto-approval.d.cts} +3 -3
- package/dist/daemon/auto-approval.d.cts.map +1 -0
- package/dist/daemon/auto-approval.d.mts +22 -0
- package/dist/daemon/auto-approval.d.mts.map +1 -0
- package/dist/daemon/{auto-approval.js → auto-approval.mjs} +1 -1
- package/dist/daemon/auto-approval.mjs.map +1 -0
- package/dist/daemon/daemon-client.cjs +149 -0
- package/dist/daemon/daemon-client.cjs.map +1 -0
- package/dist/daemon/{daemon-client.d.ts → daemon-client.d.cts} +2 -2
- package/dist/daemon/daemon-client.d.cts.map +1 -0
- package/dist/daemon/daemon-client.d.mts +84 -0
- package/dist/daemon/daemon-client.d.mts.map +1 -0
- package/dist/daemon/{daemon-client.js → daemon-client.mjs} +8 -8
- package/dist/daemon/daemon-client.mjs.map +1 -0
- package/dist/daemon/daemon-entry.cjs +278 -0
- package/dist/daemon/daemon-entry.cjs.map +1 -0
- package/dist/daemon/daemon-entry.d.cts +2 -0
- package/dist/daemon/daemon-entry.d.cts.map +1 -0
- package/dist/daemon/daemon-entry.d.mts +2 -0
- package/dist/daemon/daemon-entry.d.mts.map +1 -0
- package/dist/daemon/{daemon-entry.js → daemon-entry.mjs} +12 -12
- package/dist/daemon/daemon-entry.mjs.map +1 -0
- package/dist/daemon/daemon-spawn.cjs +138 -0
- package/dist/daemon/daemon-spawn.cjs.map +1 -0
- package/dist/daemon/{daemon-spawn.d.ts → daemon-spawn.d.cts} +2 -2
- package/dist/daemon/daemon-spawn.d.cts.map +1 -0
- package/dist/daemon/daemon-spawn.d.mts +28 -0
- package/dist/daemon/daemon-spawn.d.mts.map +1 -0
- package/dist/daemon/{daemon-spawn.js → daemon-spawn.mjs} +7 -7
- package/dist/daemon/daemon-spawn.mjs.map +1 -0
- package/dist/daemon/data-dir.cjs +23 -0
- package/dist/daemon/data-dir.cjs.map +1 -0
- package/dist/daemon/{data-dir.d.ts → data-dir.d.cts} +1 -1
- package/dist/daemon/data-dir.d.cts.map +1 -0
- package/dist/daemon/data-dir.d.mts +14 -0
- package/dist/daemon/data-dir.d.mts.map +1 -0
- package/dist/daemon/{data-dir.js → data-dir.mjs} +3 -3
- package/dist/daemon/data-dir.mjs.map +1 -0
- package/dist/daemon/paths.cjs +20 -0
- package/dist/daemon/paths.cjs.map +1 -0
- package/dist/daemon/{paths.d.ts → paths.d.cts} +2 -2
- package/dist/daemon/paths.d.cts.map +1 -0
- package/dist/daemon/paths.d.mts +9 -0
- package/dist/daemon/paths.d.mts.map +1 -0
- package/dist/daemon/{paths.js → paths.mjs} +2 -2
- package/dist/daemon/paths.mjs.map +1 -0
- package/dist/daemon/prompts.cjs +55 -0
- package/dist/daemon/prompts.cjs.map +1 -0
- package/dist/daemon/{prompts.d.ts → prompts.d.cts} +1 -1
- package/dist/daemon/prompts.d.cts.map +1 -0
- package/dist/daemon/prompts.d.mts +31 -0
- package/dist/daemon/prompts.d.mts.map +1 -0
- package/dist/daemon/{prompts.js → prompts.mjs} +4 -4
- package/dist/daemon/prompts.mjs.map +1 -0
- package/dist/daemon/rpc-socket-server.cjs +284 -0
- package/dist/daemon/rpc-socket-server.cjs.map +1 -0
- package/dist/daemon/{rpc-socket-server.d.ts → rpc-socket-server.d.cts} +2 -2
- package/dist/daemon/rpc-socket-server.d.cts.map +1 -0
- package/dist/daemon/rpc-socket-server.d.mts +44 -0
- package/dist/daemon/rpc-socket-server.d.mts.map +1 -0
- package/dist/daemon/{rpc-socket-server.js → rpc-socket-server.mjs} +8 -8
- package/dist/daemon/rpc-socket-server.mjs.map +1 -0
- package/dist/daemon/secrets.cjs +137 -0
- package/dist/daemon/secrets.cjs.map +1 -0
- package/dist/daemon/{secrets.d.ts → secrets.d.cts} +1 -1
- package/dist/daemon/secrets.d.cts.map +1 -0
- package/dist/daemon/secrets.d.mts +72 -0
- package/dist/daemon/secrets.d.mts.map +1 -0
- package/dist/daemon/{secrets.js → secrets.mjs} +23 -11
- package/dist/daemon/secrets.mjs.map +1 -0
- package/dist/daemon/send-transaction.cjs +147 -0
- package/dist/daemon/send-transaction.cjs.map +1 -0
- package/dist/daemon/{send-transaction.d.ts → send-transaction.d.cts} +9 -9
- package/dist/daemon/send-transaction.d.cts.map +1 -0
- package/dist/daemon/send-transaction.d.mts +102 -0
- package/dist/daemon/send-transaction.d.mts.map +1 -0
- package/dist/daemon/{send-transaction.js → send-transaction.mjs} +3 -3
- package/dist/daemon/send-transaction.mjs.map +1 -0
- package/dist/daemon/socket-line.cjs +93 -0
- package/dist/daemon/socket-line.cjs.map +1 -0
- package/dist/daemon/{socket-line.d.ts → socket-line.d.cts} +5 -2
- package/dist/daemon/socket-line.d.cts.map +1 -0
- package/dist/daemon/socket-line.d.mts +21 -0
- package/dist/daemon/socket-line.d.mts.map +1 -0
- package/dist/daemon/{socket-line.js → socket-line.mjs} +1 -1
- package/dist/daemon/socket-line.mjs.map +1 -0
- package/dist/daemon/stop-daemon.cjs +117 -0
- package/dist/daemon/stop-daemon.cjs.map +1 -0
- package/dist/daemon/{stop-daemon.d.ts → stop-daemon.d.cts} +1 -1
- package/dist/daemon/stop-daemon.d.cts.map +1 -0
- package/dist/daemon/stop-daemon.d.mts +28 -0
- package/dist/daemon/stop-daemon.d.mts.map +1 -0
- package/dist/daemon/{stop-daemon.js → stop-daemon.mjs} +7 -7
- package/dist/daemon/stop-daemon.mjs.map +1 -0
- package/dist/daemon/types.cjs +20 -0
- package/dist/daemon/types.cjs.map +1 -0
- package/dist/daemon/{types.d.ts → types.d.cts} +4 -4
- package/dist/daemon/types.d.cts.map +1 -0
- package/dist/daemon/types.d.mts +94 -0
- package/dist/daemon/types.d.mts.map +1 -0
- package/dist/daemon/{types.js → types.mjs} +1 -1
- package/dist/daemon/types.mjs.map +1 -0
- package/dist/daemon/utils.cjs +172 -0
- package/dist/daemon/utils.cjs.map +1 -0
- package/dist/daemon/{utils.d.ts → utils.d.cts} +3 -2
- package/dist/daemon/utils.d.cts.map +1 -0
- package/dist/daemon/utils.d.mts +87 -0
- package/dist/daemon/utils.d.mts.map +1 -0
- package/dist/daemon/{utils.js → utils.mjs} +3 -3
- package/dist/daemon/utils.mjs.map +1 -0
- package/dist/daemon/wallet-factory.cjs +341 -0
- package/dist/daemon/wallet-factory.cjs.map +1 -0
- package/dist/daemon/{wallet-factory.d.ts → wallet-factory.d.cts} +4 -4
- package/dist/daemon/wallet-factory.d.cts.map +1 -0
- package/dist/daemon/wallet-factory.d.mts +64 -0
- package/dist/daemon/wallet-factory.d.mts.map +1 -0
- package/dist/daemon/{wallet-factory.js → wallet-factory.mjs} +12 -12
- package/dist/daemon/wallet-factory.mjs.map +1 -0
- package/dist/persistence/KeyValueStore.cjs +79 -0
- package/dist/persistence/KeyValueStore.cjs.map +1 -0
- package/dist/persistence/{KeyValueStore.d.ts → KeyValueStore.d.cts} +2 -2
- package/dist/persistence/KeyValueStore.d.cts.map +1 -0
- package/dist/persistence/KeyValueStore.d.mts +18 -0
- package/dist/persistence/KeyValueStore.d.mts.map +1 -0
- package/dist/persistence/KeyValueStore.mjs +79 -0
- package/dist/persistence/KeyValueStore.mjs.map +1 -0
- package/dist/persistence/persistence.cjs +204 -0
- package/dist/persistence/persistence.cjs.map +1 -0
- package/dist/persistence/{persistence.d.ts → persistence.d.cts} +5 -5
- package/dist/persistence/persistence.d.cts.map +1 -0
- package/dist/persistence/persistence.d.mts +45 -0
- package/dist/persistence/persistence.d.mts.map +1 -0
- package/dist/persistence/{persistence.js → persistence.mjs} +2 -2
- package/dist/persistence/persistence.mjs.map +1 -0
- package/dist/test/run-command.cjs +73 -0
- package/dist/test/run-command.cjs.map +1 -0
- package/dist/test/{run-command.d.ts → run-command.d.cts} +4 -4
- package/dist/test/run-command.d.cts.map +1 -0
- package/dist/test/run-command.d.mts +27 -0
- package/dist/test/run-command.d.mts.map +1 -0
- package/dist/test/{run-command.js → run-command.mjs} +3 -3
- package/dist/test/run-command.mjs.map +1 -0
- package/package.json +15 -19
- package/dist/commands/daemon/call.d.ts.map +0 -1
- package/dist/commands/daemon/call.js.map +0 -1
- package/dist/commands/daemon/list.d.ts.map +0 -1
- package/dist/commands/daemon/list.js.map +0 -1
- package/dist/commands/daemon/purge.d.ts.map +0 -1
- package/dist/commands/daemon/purge.js.map +0 -1
- package/dist/commands/daemon/start.d.ts.map +0 -1
- package/dist/commands/daemon/start.js +0 -49
- package/dist/commands/daemon/status.d.ts.map +0 -1
- package/dist/commands/daemon/status.js.map +0 -1
- package/dist/commands/daemon/stop.d.ts.map +0 -1
- package/dist/commands/daemon/stop.js.map +0 -1
- package/dist/commands/wallet/send.d.ts.map +0 -1
- package/dist/commands/wallet/send.js.map +0 -1
- package/dist/commands/wallet/unlock.d.ts.map +0 -1
- package/dist/commands/wallet/unlock.js.map +0 -1
- package/dist/daemon/auto-approval.d.ts.map +0 -1
- package/dist/daemon/auto-approval.js.map +0 -1
- package/dist/daemon/daemon-client.d.ts.map +0 -1
- package/dist/daemon/daemon-client.js.map +0 -1
- package/dist/daemon/daemon-entry.d.ts +0 -2
- package/dist/daemon/daemon-entry.d.ts.map +0 -1
- package/dist/daemon/daemon-entry.js.map +0 -1
- package/dist/daemon/daemon-spawn.d.ts.map +0 -1
- package/dist/daemon/daemon-spawn.js.map +0 -1
- package/dist/daemon/data-dir.d.ts.map +0 -1
- package/dist/daemon/data-dir.js.map +0 -1
- package/dist/daemon/paths.d.ts.map +0 -1
- package/dist/daemon/paths.js.map +0 -1
- package/dist/daemon/prompts.d.ts.map +0 -1
- package/dist/daemon/prompts.js.map +0 -1
- package/dist/daemon/rpc-socket-server.d.ts.map +0 -1
- package/dist/daemon/rpc-socket-server.js.map +0 -1
- package/dist/daemon/secrets.d.ts.map +0 -1
- package/dist/daemon/secrets.js.map +0 -1
- package/dist/daemon/send-transaction.d.ts.map +0 -1
- package/dist/daemon/send-transaction.js.map +0 -1
- package/dist/daemon/socket-line.d.ts.map +0 -1
- package/dist/daemon/socket-line.js.map +0 -1
- package/dist/daemon/stop-daemon.d.ts.map +0 -1
- package/dist/daemon/stop-daemon.js.map +0 -1
- package/dist/daemon/types.d.ts.map +0 -1
- package/dist/daemon/types.js.map +0 -1
- package/dist/daemon/utils.d.ts.map +0 -1
- package/dist/daemon/utils.js.map +0 -1
- package/dist/daemon/wallet-factory.d.ts.map +0 -1
- package/dist/daemon/wallet-factory.js.map +0 -1
- package/dist/persistence/KeyValueStore.d.ts.map +0 -1
- package/dist/persistence/KeyValueStore.js +0 -59
- package/dist/persistence/KeyValueStore.js.map +0 -1
- package/dist/persistence/persistence.d.ts.map +0 -1
- package/dist/persistence/persistence.js.map +0 -1
- package/dist/test/run-command.d.ts.map +0 -1
- package/dist/test/run-command.js.map +0 -1
|
@@ -1,11 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
1
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
2
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
3
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
4
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
|
+
};
|
|
6
|
+
var _WalletSend_instances, _WalletSend_dispatchSend;
|
|
7
|
+
import { is } from "@metamask/superstruct";
|
|
8
|
+
import { bigIntToHex, isJsonRpcFailure, toWei } from "@metamask/utils";
|
|
9
|
+
import { Command, Flags } from "@oclif/core";
|
|
10
|
+
import { sendCommand } from "../../daemon/daemon-client.mjs";
|
|
11
|
+
import { getDaemonPaths } from "../../daemon/paths.mjs";
|
|
12
|
+
import { confirmSend } from "../../daemon/prompts.mjs";
|
|
13
|
+
import { SendTransactionBroadcastResultStruct, SendTransactionDryRunResultStruct } from "../../daemon/send-transaction.mjs";
|
|
14
|
+
import { emptyToUndefined, formatJsonRpcError, makeDaemonConnectionError } from "../../daemon/utils.mjs";
|
|
9
15
|
const ETHER_DECIMALS = 18;
|
|
10
16
|
/**
|
|
11
17
|
* Fallback response timeout (ms) for the broadcast call. Broadcasting waits for
|
|
@@ -14,7 +20,7 @@ const ETHER_DECIMALS = 18;
|
|
|
14
20
|
* successful send look like a failure and tempt a duplicate re-send.
|
|
15
21
|
* `--timeout` overrides it.
|
|
16
22
|
*/
|
|
17
|
-
const BROADCAST_TIMEOUT_MS =
|
|
23
|
+
const BROADCAST_TIMEOUT_MS = 120000;
|
|
18
24
|
/**
|
|
19
25
|
* Convert a decimal ether amount to a `0x`-prefixed wei quantity.
|
|
20
26
|
*
|
|
@@ -42,61 +48,11 @@ export function parseEtherToWeiHex(amount) {
|
|
|
42
48
|
}
|
|
43
49
|
return bigIntToHex(toWei(trimmed, 'ether'));
|
|
44
50
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
static examples = [
|
|
51
|
-
'<%= config.bin %> wallet send --to 0xRecipient --value 0.01 --chain-id 0x1',
|
|
52
|
-
'<%= config.bin %> wallet send --to 0xRecipient --value 0.01 --network-client-id mainnet --yes',
|
|
53
|
-
'<%= config.bin %> wallet send --to 0xContract --data 0xabcdef --value 0 --chain-id 0x1 --dry-run',
|
|
54
|
-
];
|
|
55
|
-
static flags = {
|
|
56
|
-
to: Flags.string({
|
|
57
|
-
description: 'Recipient address (0x-prefixed)',
|
|
58
|
-
required: true,
|
|
59
|
-
}),
|
|
60
|
-
value: Flags.string({
|
|
61
|
-
description: 'Amount to send, in ether (e.g. 0.01). Defaults to 0.',
|
|
62
|
-
default: '0',
|
|
63
|
-
}),
|
|
64
|
-
from: Flags.string({
|
|
65
|
-
description: 'Sender address (0x-prefixed). Defaults to the selected account.',
|
|
66
|
-
}),
|
|
67
|
-
data: Flags.string({
|
|
68
|
-
description: 'Calldata as a 0x-prefixed hex string (for contract calls)',
|
|
69
|
-
}),
|
|
70
|
-
'network-client-id': Flags.string({
|
|
71
|
-
description: 'Network client to send on. Provide this or --chain-id, not both.',
|
|
72
|
-
}),
|
|
73
|
-
'chain-id': Flags.string({
|
|
74
|
-
description: 'Chain ID (0x-prefixed hex) to resolve to a network client. Provide this or --network-client-id, not both.',
|
|
75
|
-
}),
|
|
76
|
-
gas: Flags.string({
|
|
77
|
-
description: 'Gas limit override, as a 0x-prefixed hex quantity',
|
|
78
|
-
}),
|
|
79
|
-
'max-fee-per-gas': Flags.string({
|
|
80
|
-
description: 'maxFeePerGas override, as a 0x-prefixed hex wei quantity',
|
|
81
|
-
}),
|
|
82
|
-
'max-priority-fee-per-gas': Flags.string({
|
|
83
|
-
description: 'maxPriorityFeePerGas override, as a 0x-prefixed hex wei quantity',
|
|
84
|
-
}),
|
|
85
|
-
'gas-price': Flags.string({
|
|
86
|
-
description: 'Legacy gasPrice override, as a 0x-prefixed hex wei quantity',
|
|
87
|
-
}),
|
|
88
|
-
'dry-run': Flags.boolean({
|
|
89
|
-
description: 'Resolve the network client and sender and validate params, but do not broadcast.',
|
|
90
|
-
}),
|
|
91
|
-
yes: Flags.boolean({
|
|
92
|
-
char: 'y',
|
|
93
|
-
description: 'Skip the confirmation prompt and broadcast immediately.',
|
|
94
|
-
}),
|
|
95
|
-
timeout: Flags.integer({
|
|
96
|
-
char: 't',
|
|
97
|
-
description: 'Response timeout in milliseconds',
|
|
98
|
-
}),
|
|
99
|
-
};
|
|
51
|
+
class WalletSend extends Command {
|
|
52
|
+
constructor() {
|
|
53
|
+
super(...arguments);
|
|
54
|
+
_WalletSend_instances.add(this);
|
|
55
|
+
}
|
|
100
56
|
async run() {
|
|
101
57
|
const { flags } = await this.parse(WalletSend);
|
|
102
58
|
const networkClientId = emptyToUndefined(flags['network-client-id']);
|
|
@@ -150,7 +106,7 @@ export default class WalletSend extends Command {
|
|
|
150
106
|
// previews first so the confirmation shows (and then pins) the resolved
|
|
151
107
|
// sender/network; `--yes` skips straight to the broadcast.
|
|
152
108
|
if (flags['dry-run']) {
|
|
153
|
-
const preview = await this
|
|
109
|
+
const preview = await __classPrivateFieldGet(this, _WalletSend_instances, "m", _WalletSend_dispatchSend).call(this, {
|
|
154
110
|
socketPath,
|
|
155
111
|
params: { ...params, dryRun: true },
|
|
156
112
|
timeoutMs,
|
|
@@ -162,7 +118,7 @@ export default class WalletSend extends Command {
|
|
|
162
118
|
}
|
|
163
119
|
let resolved;
|
|
164
120
|
if (!flags.yes) {
|
|
165
|
-
const preview = await this
|
|
121
|
+
const preview = await __classPrivateFieldGet(this, _WalletSend_instances, "m", _WalletSend_dispatchSend).call(this, {
|
|
166
122
|
socketPath,
|
|
167
123
|
params: { ...params, dryRun: true },
|
|
168
124
|
timeoutMs,
|
|
@@ -198,7 +154,7 @@ export default class WalletSend extends Command {
|
|
|
198
154
|
networkClientId: resolved.networkClientId,
|
|
199
155
|
}
|
|
200
156
|
: params;
|
|
201
|
-
const result = await this
|
|
157
|
+
const result = await __classPrivateFieldGet(this, _WalletSend_instances, "m", _WalletSend_dispatchSend).call(this, {
|
|
202
158
|
socketPath,
|
|
203
159
|
params: broadcastParams,
|
|
204
160
|
timeoutMs: timeoutMs ?? BROADCAST_TIMEOUT_MS,
|
|
@@ -210,51 +166,107 @@ export default class WalletSend extends Command {
|
|
|
210
166
|
this.log(`Id: ${result.transactionId}`);
|
|
211
167
|
this.log(`Status: ${result.status}`);
|
|
212
168
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
this.error(
|
|
246
|
-
}
|
|
247
|
-
if (isJsonRpcFailure(response)) {
|
|
248
|
-
this.error(formatJsonRpcError(response.error));
|
|
249
|
-
}
|
|
250
|
-
const { result } = response;
|
|
251
|
-
if (!is(result, struct)) {
|
|
252
|
-
this.error(`The daemon returned an unexpected ${broadcast ? 'send' : 'dry-run'} ` +
|
|
253
|
-
'result. It may be running an incompatible version.');
|
|
169
|
+
}
|
|
170
|
+
_WalletSend_instances = new WeakSet(), _WalletSend_dispatchSend =
|
|
171
|
+
/**
|
|
172
|
+
* Send a `sendTransaction` RPC to the daemon and return its validated result,
|
|
173
|
+
* translating connection errors, broadcast timeouts, JSON-RPC failures, and
|
|
174
|
+
* unexpected payloads into command errors.
|
|
175
|
+
*
|
|
176
|
+
* @param options - Dispatch options.
|
|
177
|
+
* @param options.socketPath - The daemon Unix socket path.
|
|
178
|
+
* @param options.params - The `sendTransaction` params (with or without
|
|
179
|
+
* `dryRun`).
|
|
180
|
+
* @param options.timeoutMs - Optional response timeout in milliseconds.
|
|
181
|
+
* @param options.struct - Struct the `result` payload must satisfy; the
|
|
182
|
+
* return type is inferred from it.
|
|
183
|
+
* @param options.broadcast - Whether this is the real (fund-moving) broadcast.
|
|
184
|
+
* When true, a read timeout is reported with guidance that the send may
|
|
185
|
+
* already be in flight, so the user does not blindly re-send.
|
|
186
|
+
* @returns The validated `result` payload.
|
|
187
|
+
*/
|
|
188
|
+
async function _WalletSend_dispatchSend(options) {
|
|
189
|
+
const { socketPath, params, timeoutMs, struct, broadcast } = options;
|
|
190
|
+
let response;
|
|
191
|
+
try {
|
|
192
|
+
response = await sendCommand({
|
|
193
|
+
socketPath,
|
|
194
|
+
method: 'sendTransaction',
|
|
195
|
+
params,
|
|
196
|
+
...(timeoutMs === undefined ? {} : { timeoutMs }),
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
catch (error) {
|
|
200
|
+
if (broadcast && isReadTimeout(error)) {
|
|
201
|
+
this.error(broadcastTimeoutMessage());
|
|
254
202
|
}
|
|
255
|
-
|
|
203
|
+
this.error(makeDaemonConnectionError(error));
|
|
256
204
|
}
|
|
257
|
-
|
|
205
|
+
if (isJsonRpcFailure(response)) {
|
|
206
|
+
this.error(formatJsonRpcError(response.error));
|
|
207
|
+
}
|
|
208
|
+
const { result } = response;
|
|
209
|
+
if (!is(result, struct)) {
|
|
210
|
+
this.error(`The daemon returned an unexpected ${broadcast ? 'send' : 'dry-run'} ` +
|
|
211
|
+
'result. It may be running an incompatible version.');
|
|
212
|
+
}
|
|
213
|
+
return result;
|
|
214
|
+
};
|
|
215
|
+
WalletSend.description = 'Send a transaction through the daemon-hosted TransactionController. ' +
|
|
216
|
+
'Estimates gas automatically unless overridden, signs, broadcasts, and ' +
|
|
217
|
+
'prints the resulting transaction hash. The daemon auto-approves, so the ' +
|
|
218
|
+
'confirmation boundary is this command.';
|
|
219
|
+
WalletSend.examples = [
|
|
220
|
+
'<%= config.bin %> wallet send --to 0xRecipient --value 0.01 --chain-id 0x1',
|
|
221
|
+
'<%= config.bin %> wallet send --to 0xRecipient --value 0.01 --network-client-id mainnet --yes',
|
|
222
|
+
'<%= config.bin %> wallet send --to 0xContract --data 0xabcdef --value 0 --chain-id 0x1 --dry-run',
|
|
223
|
+
];
|
|
224
|
+
WalletSend.flags = {
|
|
225
|
+
to: Flags.string({
|
|
226
|
+
description: 'Recipient address (0x-prefixed)',
|
|
227
|
+
required: true,
|
|
228
|
+
}),
|
|
229
|
+
value: Flags.string({
|
|
230
|
+
description: 'Amount to send, in ether (e.g. 0.01). Defaults to 0.',
|
|
231
|
+
default: '0',
|
|
232
|
+
}),
|
|
233
|
+
from: Flags.string({
|
|
234
|
+
description: 'Sender address (0x-prefixed). Defaults to the selected account.',
|
|
235
|
+
}),
|
|
236
|
+
data: Flags.string({
|
|
237
|
+
description: 'Calldata as a 0x-prefixed hex string (for contract calls)',
|
|
238
|
+
}),
|
|
239
|
+
'network-client-id': Flags.string({
|
|
240
|
+
description: 'Network client to send on. Provide this or --chain-id, not both.',
|
|
241
|
+
}),
|
|
242
|
+
'chain-id': Flags.string({
|
|
243
|
+
description: 'Chain ID (0x-prefixed hex) to resolve to a network client. Provide this or --network-client-id, not both.',
|
|
244
|
+
}),
|
|
245
|
+
gas: Flags.string({
|
|
246
|
+
description: 'Gas limit override, as a 0x-prefixed hex quantity',
|
|
247
|
+
}),
|
|
248
|
+
'max-fee-per-gas': Flags.string({
|
|
249
|
+
description: 'maxFeePerGas override, as a 0x-prefixed hex wei quantity',
|
|
250
|
+
}),
|
|
251
|
+
'max-priority-fee-per-gas': Flags.string({
|
|
252
|
+
description: 'maxPriorityFeePerGas override, as a 0x-prefixed hex wei quantity',
|
|
253
|
+
}),
|
|
254
|
+
'gas-price': Flags.string({
|
|
255
|
+
description: 'Legacy gasPrice override, as a 0x-prefixed hex wei quantity',
|
|
256
|
+
}),
|
|
257
|
+
'dry-run': Flags.boolean({
|
|
258
|
+
description: 'Resolve the network client and sender and validate params, but do not broadcast.',
|
|
259
|
+
}),
|
|
260
|
+
yes: Flags.boolean({
|
|
261
|
+
char: 'y',
|
|
262
|
+
description: 'Skip the confirmation prompt and broadcast immediately.',
|
|
263
|
+
}),
|
|
264
|
+
timeout: Flags.integer({
|
|
265
|
+
char: 't',
|
|
266
|
+
description: 'Response timeout in milliseconds',
|
|
267
|
+
}),
|
|
268
|
+
};
|
|
269
|
+
export default WalletSend;
|
|
258
270
|
/**
|
|
259
271
|
* Whether an error is the daemon-client socket read timeout. It carries no
|
|
260
272
|
* errno code, so its message is the only signal.
|
|
@@ -313,4 +325,4 @@ function formatPlan(plan, etherAmount, extras) {
|
|
|
313
325
|
}
|
|
314
326
|
return lines.join('\n');
|
|
315
327
|
}
|
|
316
|
-
//# sourceMappingURL=send.
|
|
328
|
+
//# sourceMappingURL=send.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"send.mjs","sourceRoot":"","sources":["../../../src/commands/wallet/send.ts"],"names":[],"mappings":"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","sourcesContent":["import { is } from '@metamask/superstruct';\nimport type { Struct } from '@metamask/superstruct';\nimport { bigIntToHex, isJsonRpcFailure, toWei } from '@metamask/utils';\nimport type { Hex, Json, JsonRpcParams } from '@metamask/utils';\nimport { Command, Flags } from '@oclif/core';\n\nimport { sendCommand } from '../../daemon/daemon-client.js';\nimport { getDaemonPaths } from '../../daemon/paths.js';\nimport { confirmSend } from '../../daemon/prompts.js';\nimport {\n SendTransactionBroadcastResultStruct,\n SendTransactionDryRunResultStruct,\n} from '../../daemon/send-transaction.js';\nimport type { SendTransactionDryRunResult } from '../../daemon/send-transaction.js';\nimport {\n emptyToUndefined,\n formatJsonRpcError,\n makeDaemonConnectionError,\n} from '../../daemon/utils.js';\n\nconst ETHER_DECIMALS = 18;\n\n/**\n * Fallback response timeout (ms) for the broadcast call. Broadcasting waits for\n * signing and `eth_sendRawTransaction` server-side, which can far outlast the\n * 30s default used for cheap RPCs; too short a timeout would make a slow but\n * successful send look like a failure and tempt a duplicate re-send.\n * `--timeout` overrides it.\n */\nconst BROADCAST_TIMEOUT_MS = 120_000;\n\n/**\n * The transaction fields shown in the confirmation preview that the daemon\n * does not echo back (they are the raw `--data` / gas overrides the user\n * passed, so the CLI supplies them for display).\n */\ntype PlanExtras = {\n data?: string | undefined;\n gas?: string | undefined;\n maxFeePerGas?: string | undefined;\n maxPriorityFeePerGas?: string | undefined;\n gasPrice?: string | undefined;\n};\n\n/**\n * Convert a decimal ether amount to a `0x`-prefixed wei quantity.\n *\n * The fixed-point conversion is delegated to `@metamask/utils`' `toWei` rather\n * than re-deriving the wei math here. The daemon's `sendTransaction` boundary\n * expects canonical hex wei; this is where the human-friendly `--value` (ether)\n * is turned into it.\n *\n * `toWei` silently accepts negatives and throws opaque messages on other\n * malformed input, so the value is guarded up front for a clear error and a\n * strictly non-negative amount.\n *\n * @param amount - A non-negative decimal ether amount (e.g. `\"0.1\"`, `\"1\"`).\n * @returns The equivalent wei as a `0x`-prefixed hex string.\n * @throws If `amount` is not a non-negative decimal or has more than 18\n * fractional digits.\n */\nexport function parseEtherToWeiHex(amount: string): Hex {\n const trimmed = amount.trim();\n if (!/^\\d+(?:\\.\\d+)?$/u.test(trimmed)) {\n throw new Error(\n `Invalid value \"${amount}\": expected a non-negative decimal amount of ether (e.g. 0.1).`,\n );\n }\n\n if ((trimmed.split('.')[1] ?? '').length > ETHER_DECIMALS) {\n throw new Error(\n `Invalid value \"${amount}\": ether has at most ${ETHER_DECIMALS} decimal places.`,\n );\n }\n\n return bigIntToHex(toWei(trimmed, 'ether'));\n}\n\nexport default class WalletSend extends Command {\n static override description =\n 'Send a transaction through the daemon-hosted TransactionController. ' +\n 'Estimates gas automatically unless overridden, signs, broadcasts, and ' +\n 'prints the resulting transaction hash. The daemon auto-approves, so the ' +\n 'confirmation boundary is this command.';\n\n static override examples = [\n '<%= config.bin %> wallet send --to 0xRecipient --value 0.01 --chain-id 0x1',\n '<%= config.bin %> wallet send --to 0xRecipient --value 0.01 --network-client-id mainnet --yes',\n '<%= config.bin %> wallet send --to 0xContract --data 0xabcdef --value 0 --chain-id 0x1 --dry-run',\n ];\n\n static override flags = {\n to: Flags.string({\n description: 'Recipient address (0x-prefixed)',\n required: true,\n }),\n value: Flags.string({\n description: 'Amount to send, in ether (e.g. 0.01). Defaults to 0.',\n default: '0',\n }),\n from: Flags.string({\n description:\n 'Sender address (0x-prefixed). Defaults to the selected account.',\n }),\n data: Flags.string({\n description: 'Calldata as a 0x-prefixed hex string (for contract calls)',\n }),\n 'network-client-id': Flags.string({\n description:\n 'Network client to send on. Provide this or --chain-id, not both.',\n }),\n 'chain-id': Flags.string({\n description:\n 'Chain ID (0x-prefixed hex) to resolve to a network client. Provide this or --network-client-id, not both.',\n }),\n gas: Flags.string({\n description: 'Gas limit override, as a 0x-prefixed hex quantity',\n }),\n 'max-fee-per-gas': Flags.string({\n description: 'maxFeePerGas override, as a 0x-prefixed hex wei quantity',\n }),\n 'max-priority-fee-per-gas': Flags.string({\n description:\n 'maxPriorityFeePerGas override, as a 0x-prefixed hex wei quantity',\n }),\n 'gas-price': Flags.string({\n description:\n 'Legacy gasPrice override, as a 0x-prefixed hex wei quantity',\n }),\n 'dry-run': Flags.boolean({\n description:\n 'Resolve the network client and sender and validate params, but do not broadcast.',\n }),\n yes: Flags.boolean({\n char: 'y',\n description: 'Skip the confirmation prompt and broadcast immediately.',\n }),\n timeout: Flags.integer({\n char: 't',\n description: 'Response timeout in milliseconds',\n }),\n };\n\n public async run(): Promise<void> {\n const { flags } = await this.parse(WalletSend);\n\n const networkClientId = emptyToUndefined(flags['network-client-id']);\n const chainId = emptyToUndefined(flags['chain-id']);\n if ((networkClientId === undefined) === (chainId === undefined)) {\n this.error('Provide exactly one of --network-client-id or --chain-id.');\n }\n\n let value: string;\n try {\n value = parseEtherToWeiHex(flags.value);\n } catch (error) {\n // `parseEtherToWeiHex` only ever throws `Error`.\n this.error((error as Error).message);\n }\n\n // Everything except the network selector. The selector is added per call:\n // a confirmed broadcast pins the `networkClientId` the preview resolved\n // rather than re-sending `--chain-id` and re-resolving it.\n const baseParams: Record<string, Json> = {\n to: flags.to,\n value,\n ...(flags.from ? { from: flags.from } : {}),\n ...(flags.data ? { data: flags.data } : {}),\n ...(flags.gas ? { gas: flags.gas } : {}),\n ...(flags['max-fee-per-gas']\n ? { maxFeePerGas: flags['max-fee-per-gas'] }\n : {}),\n ...(flags['max-priority-fee-per-gas']\n ? { maxPriorityFeePerGas: flags['max-priority-fee-per-gas'] }\n : {}),\n ...(flags['gas-price'] ? { gasPrice: flags['gas-price'] } : {}),\n };\n // Exactly one selector is defined (guarded above); guard each spread by its\n // own `undefined` check so the object never carries an `undefined` value.\n const params: Record<string, Json> = {\n ...baseParams,\n ...(networkClientId === undefined ? {} : { networkClientId }),\n ...(chainId === undefined ? {} : { chainId }),\n };\n const planExtras: PlanExtras = {\n data: flags.data,\n gas: flags.gas,\n maxFeePerGas: flags['max-fee-per-gas'],\n maxPriorityFeePerGas: flags['max-priority-fee-per-gas'],\n gasPrice: flags['gas-price'],\n };\n\n const { socketPath } = getDaemonPaths(this.config.dataDir);\n const timeoutMs = flags.timeout;\n\n // A `dryRun` resolves the sender and network client server-side without\n // broadcasting. `--dry-run` stops after previewing; an interactive run\n // previews first so the confirmation shows (and then pins) the resolved\n // sender/network; `--yes` skips straight to the broadcast.\n if (flags['dry-run']) {\n const preview = await this.#dispatchSend({\n socketPath,\n params: { ...params, dryRun: true },\n timeoutMs,\n struct: SendTransactionDryRunResultStruct,\n broadcast: false,\n });\n this.log(formatPlan(preview, flags.value, planExtras));\n return;\n }\n\n let resolved: SendTransactionDryRunResult | undefined;\n if (!flags.yes) {\n const preview = await this.#dispatchSend({\n socketPath,\n params: { ...params, dryRun: true },\n timeoutMs,\n struct: SendTransactionDryRunResultStruct,\n broadcast: false,\n });\n\n let confirmed: boolean;\n try {\n confirmed = await confirmSend(\n formatPlan(preview, flags.value, planExtras),\n );\n } catch (error) {\n // Ctrl+C at the prompt (@inquirer/core's ExitPromptError) is a clean\n // abort, not a failure; anything else should surface.\n if (error instanceof Error && error.name === 'ExitPromptError') {\n this.log('Aborted.');\n return;\n }\n throw error;\n }\n if (!confirmed) {\n this.log('Aborted.');\n return;\n }\n resolved = preview;\n }\n\n // Broadcast the exact sender/network the user reviewed (when they confirmed\n // a preview), so what is signed matches what was shown. `--yes` skips the\n // preview, so there it re-resolves server-side from `params`.\n const broadcastParams: Record<string, Json> = resolved\n ? {\n ...baseParams,\n from: resolved.from,\n networkClientId: resolved.networkClientId,\n }\n : params;\n\n const result = await this.#dispatchSend({\n socketPath,\n params: broadcastParams,\n timeoutMs: timeoutMs ?? BROADCAST_TIMEOUT_MS,\n struct: SendTransactionBroadcastResultStruct,\n broadcast: true,\n });\n this.log('Transaction broadcast.');\n this.log(`Hash: ${result.transactionHash}`);\n this.log(`Id: ${result.transactionId}`);\n this.log(`Status: ${result.status}`);\n }\n\n /**\n * Send a `sendTransaction` RPC to the daemon and return its validated result,\n * translating connection errors, broadcast timeouts, JSON-RPC failures, and\n * unexpected payloads into command errors.\n *\n * @param options - Dispatch options.\n * @param options.socketPath - The daemon Unix socket path.\n * @param options.params - The `sendTransaction` params (with or without\n * `dryRun`).\n * @param options.timeoutMs - Optional response timeout in milliseconds.\n * @param options.struct - Struct the `result` payload must satisfy; the\n * return type is inferred from it.\n * @param options.broadcast - Whether this is the real (fund-moving) broadcast.\n * When true, a read timeout is reported with guidance that the send may\n * already be in flight, so the user does not blindly re-send.\n * @returns The validated `result` payload.\n */\n async #dispatchSend<Value>(options: {\n socketPath: string;\n params: JsonRpcParams;\n timeoutMs: number | undefined;\n struct: Struct<Value>;\n broadcast: boolean;\n }): Promise<Value> {\n const { socketPath, params, timeoutMs, struct, broadcast } = options;\n let response;\n try {\n response = await sendCommand({\n socketPath,\n method: 'sendTransaction',\n params,\n ...(timeoutMs === undefined ? {} : { timeoutMs }),\n });\n } catch (error) {\n if (broadcast && isReadTimeout(error)) {\n this.error(broadcastTimeoutMessage());\n }\n this.error(makeDaemonConnectionError(error));\n }\n\n if (isJsonRpcFailure(response)) {\n this.error(formatJsonRpcError(response.error));\n }\n\n const { result } = response;\n if (!is(result, struct)) {\n this.error(\n `The daemon returned an unexpected ${broadcast ? 'send' : 'dry-run'} ` +\n 'result. It may be running an incompatible version.',\n );\n }\n return result;\n }\n}\n\n/**\n * Whether an error is the daemon-client socket read timeout. It carries no\n * errno code, so its message is the only signal.\n *\n * @param error - The caught value.\n * @returns True if it is the read timeout.\n */\nfunction isReadTimeout(error: unknown): boolean {\n return error instanceof Error && error.message === 'Socket read timed out';\n}\n\n/**\n * The message shown when the broadcast call times out. A send is not\n * idempotent, and the daemon may still be broadcasting after the client gives\n * up waiting, so this warns against a blind re-run rather than reading as a\n * plain connection failure.\n *\n * @returns The user-facing guidance.\n */\nfunction broadcastTimeoutMessage(): string {\n return (\n 'The daemon did not respond in time, but your transaction may still be ' +\n 'broadcasting. Do NOT re-run this command — you could send it twice. ' +\n 'Check `mm daemon status`, the daemon log, or your account on-chain to ' +\n 'confirm, then use --timeout to wait longer if needed.'\n );\n}\n\n/**\n * Format a dry-run plan for display (and as the confirmation prompt body).\n *\n * @param plan - The dry-run result returned by the daemon.\n * @param etherAmount - The original `--value` (ether), shown alongside the\n * resolved wei so the user sees the human amount they typed.\n * @param extras - The `--data` / gas overrides the daemon does not echo back,\n * shown so the user confirms exactly what will be sent.\n * @returns A multi-line summary of the transaction to be sent.\n */\nfunction formatPlan(\n plan: SendTransactionDryRunResult,\n etherAmount: string,\n extras: PlanExtras,\n): string {\n const lines = [\n 'About to send:',\n ` To: ${plan.to}`,\n ` From: ${plan.from}`,\n ` Value: ${etherAmount} ETH (${plan.value} wei)`,\n ` Network: ${plan.networkClientId}`,\n ];\n if (extras.data) {\n lines.push(` Data: ${extras.data}`);\n }\n const gasParts = [\n extras.gas ? `gas=${extras.gas}` : undefined,\n extras.maxFeePerGas ? `maxFeePerGas=${extras.maxFeePerGas}` : undefined,\n extras.maxPriorityFeePerGas\n ? `maxPriorityFeePerGas=${extras.maxPriorityFeePerGas}`\n : undefined,\n extras.gasPrice ? `gasPrice=${extras.gasPrice}` : undefined,\n ].filter((part): part is string => part !== undefined);\n if (gasParts.length > 0) {\n lines.push(` Gas: ${gasParts.join(', ')}`);\n }\n return lines.join('\\n');\n}\n"]}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("@metamask/utils");
|
|
4
|
+
const core_1 = require("@oclif/core");
|
|
5
|
+
const daemon_client_js_1 = require("../../daemon/daemon-client.cjs");
|
|
6
|
+
const paths_js_1 = require("../../daemon/paths.cjs");
|
|
7
|
+
const prompts_js_1 = require("../../daemon/prompts.cjs");
|
|
8
|
+
const utils_js_1 = require("../../daemon/utils.cjs");
|
|
9
|
+
class WalletUnlock extends core_1.Command {
|
|
10
|
+
async run() {
|
|
11
|
+
const { flags } = await this.parse(WalletUnlock);
|
|
12
|
+
const { timeout: timeoutMs } = flags;
|
|
13
|
+
// `emptyToUndefined` collapses `--password ''` and `MM_WALLET_PASSWORD=''`
|
|
14
|
+
// to undefined so the prompt fires instead of sending an empty string.
|
|
15
|
+
const flagPassword = (0, utils_js_1.emptyToUndefined)(flags.password);
|
|
16
|
+
let password;
|
|
17
|
+
try {
|
|
18
|
+
password = flagPassword ?? (await (0, prompts_js_1.promptPassword)());
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
// Only swallow ExitPromptError (@inquirer/core's Ctrl+C signal); any
|
|
22
|
+
// other rejection (import failure, internal prompt crash) should surface.
|
|
23
|
+
if (error instanceof Error && error.name === 'ExitPromptError') {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
throw error;
|
|
27
|
+
}
|
|
28
|
+
const { socketPath } = (0, paths_js_1.getDaemonPaths)(this.config.dataDir);
|
|
29
|
+
let response;
|
|
30
|
+
try {
|
|
31
|
+
response = await (0, daemon_client_js_1.sendCommand)({
|
|
32
|
+
socketPath,
|
|
33
|
+
method: 'call',
|
|
34
|
+
params: ['KeyringController:submitPassword', password],
|
|
35
|
+
...(timeoutMs === undefined ? {} : { timeoutMs }),
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
this.error((0, utils_js_1.makeDaemonConnectionError)(error));
|
|
40
|
+
}
|
|
41
|
+
if ((0, utils_1.isJsonRpcFailure)(response)) {
|
|
42
|
+
const { code, message, data } = response.error;
|
|
43
|
+
// `isJsonRpcFailure` already validates that `data` is JSON, so
|
|
44
|
+
// `JSON.stringify` cannot throw here.
|
|
45
|
+
const dataSuffix = data === undefined || data === null
|
|
46
|
+
? ''
|
|
47
|
+
: ` data=${JSON.stringify(data)}`;
|
|
48
|
+
this.error(`Failed to unlock: ${message} (code ${String(code)})${dataSuffix}`);
|
|
49
|
+
}
|
|
50
|
+
this.log('Wallet unlocked.');
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
WalletUnlock.description = 'Unlock the wallet (submits the password to KeyringController). ' +
|
|
54
|
+
'Use this after `mm daemon start` was run without `--password`, or ' +
|
|
55
|
+
'after the keyring was locked via `KeyringController:setLocked`.';
|
|
56
|
+
WalletUnlock.examples = [
|
|
57
|
+
'<%= config.bin %> wallet unlock --password <pw>',
|
|
58
|
+
'MM_WALLET_PASSWORD=<pw> <%= config.bin %> wallet unlock',
|
|
59
|
+
'<%= config.bin %> wallet unlock # prompts interactively',
|
|
60
|
+
];
|
|
61
|
+
WalletUnlock.flags = {
|
|
62
|
+
password: core_1.Flags.string({
|
|
63
|
+
description: 'Wallet password (testing only — use MM_WALLET_PASSWORD env var in production). ' +
|
|
64
|
+
'When omitted, the command prompts interactively.',
|
|
65
|
+
env: 'MM_WALLET_PASSWORD',
|
|
66
|
+
required: false,
|
|
67
|
+
}),
|
|
68
|
+
timeout: core_1.Flags.integer({
|
|
69
|
+
char: 't',
|
|
70
|
+
description: 'Response timeout in milliseconds',
|
|
71
|
+
required: false,
|
|
72
|
+
}),
|
|
73
|
+
};
|
|
74
|
+
exports.default = WalletUnlock;
|
|
75
|
+
//# sourceMappingURL=unlock.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unlock.cjs","sourceRoot":"","sources":["../../../src/commands/wallet/unlock.ts"],"names":[],"mappings":";;AAAA,2CAAmD;AACnD,sCAA6C;AAE7C,qEAA4D;AAC5D,qDAAuD;AACvD,yDAAyD;AACzD,qDAG+B;AAE/B,MAAqB,YAAa,SAAQ,cAAO;IA2BxC,KAAK,CAAC,GAAG;QACd,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACjD,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;QAErC,2EAA2E;QAC3E,uEAAuE;QACvE,MAAM,YAAY,GAAG,IAAA,2BAAgB,EAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACtD,IAAI,QAAgB,CAAC;QACrB,IAAI,CAAC;YACH,QAAQ,GAAG,YAAY,IAAI,CAAC,MAAM,IAAA,2BAAc,GAAE,CAAC,CAAC;QACtD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,qEAAqE;YACrE,0EAA0E;YAC1E,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;gBAC/D,OAAO;YACT,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;QAED,MAAM,EAAE,UAAU,EAAE,GAAG,IAAA,yBAAc,EAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAE3D,IAAI,QAAQ,CAAC;QACb,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,IAAA,8BAAW,EAAC;gBAC3B,UAAU;gBACV,MAAM,EAAE,MAAM;gBACd,MAAM,EAAE,CAAC,kCAAkC,EAAE,QAAQ,CAAC;gBACtD,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC;aAClD,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,IAAA,oCAAyB,EAAC,KAAK,CAAC,CAAC,CAAC;QAC/C,CAAC;QAED,IAAI,IAAA,wBAAgB,EAAC,QAAQ,CAAC,EAAE,CAAC;YAC/B,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC;YAC/C,+DAA+D;YAC/D,sCAAsC;YACtC,MAAM,UAAU,GACd,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI;gBACjC,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;YACtC,IAAI,CAAC,KAAK,CACR,qBAAqB,OAAO,UAAU,MAAM,CAAC,IAAI,CAAC,IAAI,UAAU,EAAE,CACnE,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAC/B,CAAC;;AAzEe,wBAAW,GACzB,iEAAiE;IACjE,oEAAoE;IACpE,iEAAiE,CAAC;AAEpD,qBAAQ,GAAG;IACzB,iDAAiD;IACjD,yDAAyD;IACzD,2DAA2D;CAC5D,CAAC;AAEc,kBAAK,GAAG;IACtB,QAAQ,EAAE,YAAK,CAAC,MAAM,CAAC;QACrB,WAAW,EACT,iFAAiF;YACjF,kDAAkD;QACpD,GAAG,EAAE,oBAAoB;QACzB,QAAQ,EAAE,KAAK;KAChB,CAAC;IACF,OAAO,EAAE,YAAK,CAAC,OAAO,CAAC;QACrB,IAAI,EAAE,GAAG;QACT,WAAW,EAAE,kCAAkC;QAC/C,QAAQ,EAAE,KAAK;KAChB,CAAC;CACH,CAAC;kBAzBiB,YAAY","sourcesContent":["import { isJsonRpcFailure } from '@metamask/utils';\nimport { Command, Flags } from '@oclif/core';\n\nimport { sendCommand } from '../../daemon/daemon-client.js';\nimport { getDaemonPaths } from '../../daemon/paths.js';\nimport { promptPassword } from '../../daemon/prompts.js';\nimport {\n emptyToUndefined,\n makeDaemonConnectionError,\n} from '../../daemon/utils.js';\n\nexport default class WalletUnlock extends Command {\n static override description =\n 'Unlock the wallet (submits the password to KeyringController). ' +\n 'Use this after `mm daemon start` was run without `--password`, or ' +\n 'after the keyring was locked via `KeyringController:setLocked`.';\n\n static override examples = [\n '<%= config.bin %> wallet unlock --password <pw>',\n 'MM_WALLET_PASSWORD=<pw> <%= config.bin %> wallet unlock',\n '<%= config.bin %> wallet unlock # prompts interactively',\n ];\n\n static override flags = {\n password: Flags.string({\n description:\n 'Wallet password (testing only — use MM_WALLET_PASSWORD env var in production). ' +\n 'When omitted, the command prompts interactively.',\n env: 'MM_WALLET_PASSWORD',\n required: false,\n }),\n timeout: Flags.integer({\n char: 't',\n description: 'Response timeout in milliseconds',\n required: false,\n }),\n };\n\n public async run(): Promise<void> {\n const { flags } = await this.parse(WalletUnlock);\n const { timeout: timeoutMs } = flags;\n\n // `emptyToUndefined` collapses `--password ''` and `MM_WALLET_PASSWORD=''`\n // to undefined so the prompt fires instead of sending an empty string.\n const flagPassword = emptyToUndefined(flags.password);\n let password: string;\n try {\n password = flagPassword ?? (await promptPassword());\n } catch (error) {\n // Only swallow ExitPromptError (@inquirer/core's Ctrl+C signal); any\n // other rejection (import failure, internal prompt crash) should surface.\n if (error instanceof Error && error.name === 'ExitPromptError') {\n return;\n }\n throw error;\n }\n\n const { socketPath } = getDaemonPaths(this.config.dataDir);\n\n let response;\n try {\n response = await sendCommand({\n socketPath,\n method: 'call',\n params: ['KeyringController:submitPassword', password],\n ...(timeoutMs === undefined ? {} : { timeoutMs }),\n });\n } catch (error) {\n this.error(makeDaemonConnectionError(error));\n }\n\n if (isJsonRpcFailure(response)) {\n const { code, message, data } = response.error;\n // `isJsonRpcFailure` already validates that `data` is JSON, so\n // `JSON.stringify` cannot throw here.\n const dataSuffix =\n data === undefined || data === null\n ? ''\n : ` data=${JSON.stringify(data)}`;\n this.error(\n `Failed to unlock: ${message} (code ${String(code)})${dataSuffix}`,\n );\n }\n\n this.log('Wallet unlocked.');\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Command } from
|
|
1
|
+
import { Command } from "@oclif/core";
|
|
2
2
|
export default class WalletUnlock extends Command {
|
|
3
3
|
static description: string;
|
|
4
4
|
static examples: string[];
|
|
@@ -8,4 +8,4 @@ export default class WalletUnlock extends Command {
|
|
|
8
8
|
};
|
|
9
9
|
run(): Promise<void>;
|
|
10
10
|
}
|
|
11
|
-
//# sourceMappingURL=unlock.d.
|
|
11
|
+
//# sourceMappingURL=unlock.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unlock.d.cts","sourceRoot":"","sources":["../../../src/commands/wallet/unlock.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAS,oBAAoB;AAU7C,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,OAAO;IAC/C,OAAgB,WAAW,SAGyC;IAEpE,OAAgB,QAAQ,WAItB;IAEF,OAAgB,KAAK;;;MAanB;IAEW,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAgDlC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Command } from "@oclif/core";
|
|
2
|
+
export default class WalletUnlock extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
password: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
+
timeout: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
+
};
|
|
9
|
+
run(): Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=unlock.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unlock.d.mts","sourceRoot":"","sources":["../../../src/commands/wallet/unlock.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAS,oBAAoB;AAU7C,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,OAAO;IAC/C,OAAgB,WAAW,SAGyC;IAEpE,OAAgB,QAAQ,WAItB;IAEF,OAAgB,KAAK;;;MAanB;IAEW,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAgDlC"}
|
|
@@ -1,31 +1,10 @@
|
|
|
1
|
-
import { isJsonRpcFailure } from
|
|
2
|
-
import { Command, Flags } from
|
|
3
|
-
import { sendCommand } from
|
|
4
|
-
import { getDaemonPaths } from
|
|
5
|
-
import { promptPassword } from
|
|
6
|
-
import { emptyToUndefined, makeDaemonConnectionError
|
|
7
|
-
|
|
8
|
-
static description = 'Unlock the wallet (submits the password to KeyringController). ' +
|
|
9
|
-
'Use this after `mm daemon start` was run without `--password`, or ' +
|
|
10
|
-
'after the keyring was locked via `KeyringController:setLocked`.';
|
|
11
|
-
static examples = [
|
|
12
|
-
'<%= config.bin %> wallet unlock --password <pw>',
|
|
13
|
-
'MM_WALLET_PASSWORD=<pw> <%= config.bin %> wallet unlock',
|
|
14
|
-
'<%= config.bin %> wallet unlock # prompts interactively',
|
|
15
|
-
];
|
|
16
|
-
static flags = {
|
|
17
|
-
password: Flags.string({
|
|
18
|
-
description: 'Wallet password (testing only — use MM_WALLET_PASSWORD env var in production). ' +
|
|
19
|
-
'When omitted, the command prompts interactively.',
|
|
20
|
-
env: 'MM_WALLET_PASSWORD',
|
|
21
|
-
required: false,
|
|
22
|
-
}),
|
|
23
|
-
timeout: Flags.integer({
|
|
24
|
-
char: 't',
|
|
25
|
-
description: 'Response timeout in milliseconds',
|
|
26
|
-
required: false,
|
|
27
|
-
}),
|
|
28
|
-
};
|
|
1
|
+
import { isJsonRpcFailure } from "@metamask/utils";
|
|
2
|
+
import { Command, Flags } from "@oclif/core";
|
|
3
|
+
import { sendCommand } from "../../daemon/daemon-client.mjs";
|
|
4
|
+
import { getDaemonPaths } from "../../daemon/paths.mjs";
|
|
5
|
+
import { promptPassword } from "../../daemon/prompts.mjs";
|
|
6
|
+
import { emptyToUndefined, makeDaemonConnectionError } from "../../daemon/utils.mjs";
|
|
7
|
+
class WalletUnlock extends Command {
|
|
29
8
|
async run() {
|
|
30
9
|
const { flags } = await this.parse(WalletUnlock);
|
|
31
10
|
const { timeout: timeoutMs } = flags;
|
|
@@ -69,4 +48,26 @@ export default class WalletUnlock extends Command {
|
|
|
69
48
|
this.log('Wallet unlocked.');
|
|
70
49
|
}
|
|
71
50
|
}
|
|
72
|
-
|
|
51
|
+
WalletUnlock.description = 'Unlock the wallet (submits the password to KeyringController). ' +
|
|
52
|
+
'Use this after `mm daemon start` was run without `--password`, or ' +
|
|
53
|
+
'after the keyring was locked via `KeyringController:setLocked`.';
|
|
54
|
+
WalletUnlock.examples = [
|
|
55
|
+
'<%= config.bin %> wallet unlock --password <pw>',
|
|
56
|
+
'MM_WALLET_PASSWORD=<pw> <%= config.bin %> wallet unlock',
|
|
57
|
+
'<%= config.bin %> wallet unlock # prompts interactively',
|
|
58
|
+
];
|
|
59
|
+
WalletUnlock.flags = {
|
|
60
|
+
password: Flags.string({
|
|
61
|
+
description: 'Wallet password (testing only — use MM_WALLET_PASSWORD env var in production). ' +
|
|
62
|
+
'When omitted, the command prompts interactively.',
|
|
63
|
+
env: 'MM_WALLET_PASSWORD',
|
|
64
|
+
required: false,
|
|
65
|
+
}),
|
|
66
|
+
timeout: Flags.integer({
|
|
67
|
+
char: 't',
|
|
68
|
+
description: 'Response timeout in milliseconds',
|
|
69
|
+
required: false,
|
|
70
|
+
}),
|
|
71
|
+
};
|
|
72
|
+
export default WalletUnlock;
|
|
73
|
+
//# sourceMappingURL=unlock.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unlock.mjs","sourceRoot":"","sources":["../../../src/commands/wallet/unlock.ts"],"names":[],"mappings":"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","sourcesContent":["import { isJsonRpcFailure } from '@metamask/utils';\nimport { Command, Flags } from '@oclif/core';\n\nimport { sendCommand } from '../../daemon/daemon-client.js';\nimport { getDaemonPaths } from '../../daemon/paths.js';\nimport { promptPassword } from '../../daemon/prompts.js';\nimport {\n emptyToUndefined,\n makeDaemonConnectionError,\n} from '../../daemon/utils.js';\n\nexport default class WalletUnlock extends Command {\n static override description =\n 'Unlock the wallet (submits the password to KeyringController). ' +\n 'Use this after `mm daemon start` was run without `--password`, or ' +\n 'after the keyring was locked via `KeyringController:setLocked`.';\n\n static override examples = [\n '<%= config.bin %> wallet unlock --password <pw>',\n 'MM_WALLET_PASSWORD=<pw> <%= config.bin %> wallet unlock',\n '<%= config.bin %> wallet unlock # prompts interactively',\n ];\n\n static override flags = {\n password: Flags.string({\n description:\n 'Wallet password (testing only — use MM_WALLET_PASSWORD env var in production). ' +\n 'When omitted, the command prompts interactively.',\n env: 'MM_WALLET_PASSWORD',\n required: false,\n }),\n timeout: Flags.integer({\n char: 't',\n description: 'Response timeout in milliseconds',\n required: false,\n }),\n };\n\n public async run(): Promise<void> {\n const { flags } = await this.parse(WalletUnlock);\n const { timeout: timeoutMs } = flags;\n\n // `emptyToUndefined` collapses `--password ''` and `MM_WALLET_PASSWORD=''`\n // to undefined so the prompt fires instead of sending an empty string.\n const flagPassword = emptyToUndefined(flags.password);\n let password: string;\n try {\n password = flagPassword ?? (await promptPassword());\n } catch (error) {\n // Only swallow ExitPromptError (@inquirer/core's Ctrl+C signal); any\n // other rejection (import failure, internal prompt crash) should surface.\n if (error instanceof Error && error.name === 'ExitPromptError') {\n return;\n }\n throw error;\n }\n\n const { socketPath } = getDaemonPaths(this.config.dataDir);\n\n let response;\n try {\n response = await sendCommand({\n socketPath,\n method: 'call',\n params: ['KeyringController:submitPassword', password],\n ...(timeoutMs === undefined ? {} : { timeoutMs }),\n });\n } catch (error) {\n this.error(makeDaemonConnectionError(error));\n }\n\n if (isJsonRpcFailure(response)) {\n const { code, message, data } = response.error;\n // `isJsonRpcFailure` already validates that `data` is JSON, so\n // `JSON.stringify` cannot throw here.\n const dataSuffix =\n data === undefined || data === null\n ? ''\n : ` data=${JSON.stringify(data)}`;\n this.error(\n `Failed to unlock: ${message} (code ${String(code)})${dataSuffix}`,\n );\n }\n\n this.log('Wallet unlocked.');\n }\n}\n"]}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.subscribeToAutoApproval = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Subscribe the daemon to auto-accept every pending approval request.
|
|
6
|
+
*
|
|
7
|
+
* Without this, any `ApprovalController:addRequest` call hangs forever on a
|
|
8
|
+
* headless daemon. **Everything is approved without a prompt** — trust boundary
|
|
9
|
+
* is the `0600` same-user socket. A scoped policy is tracked in
|
|
10
|
+
* {@link https://github.com/MetaMask/core/issues/9513}.
|
|
11
|
+
*
|
|
12
|
+
* The `inFlight` guard makes accepting each id idempotent: `acceptRequest`
|
|
13
|
+
* deletes the request on resolve, which itself re-emits `stateChanged`. Without
|
|
14
|
+
* it the same id would be accepted twice and the second accept would reject.
|
|
15
|
+
* Both sync throws and async rejections are logged and swallowed so one bad
|
|
16
|
+
* request cannot crash the daemon or wedge the subscription.
|
|
17
|
+
*
|
|
18
|
+
* @param messenger - The wallet root messenger.
|
|
19
|
+
* @param log - Optional logger for accept failures. Defaults to `console.error`.
|
|
20
|
+
* @returns A function that unsubscribes the auto-approval handler.
|
|
21
|
+
*/
|
|
22
|
+
function subscribeToAutoApproval(messenger, log) {
|
|
23
|
+
const logFn = log ??
|
|
24
|
+
((message) => {
|
|
25
|
+
console.error(message);
|
|
26
|
+
});
|
|
27
|
+
const inFlight = new Set();
|
|
28
|
+
const logFailure = (id, error) => {
|
|
29
|
+
logFn(`Failed to auto-accept approval request ${id}: ${String(error)}`);
|
|
30
|
+
};
|
|
31
|
+
const acceptRequest = (id) => {
|
|
32
|
+
if (inFlight.has(id)) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
inFlight.add(id);
|
|
36
|
+
try {
|
|
37
|
+
messenger
|
|
38
|
+
.call('ApprovalController:acceptRequest', id)
|
|
39
|
+
.catch((error) => logFailure(id, error))
|
|
40
|
+
.finally(() => inFlight.delete(id));
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
// Synchronous throw means the Promise chain above was never built
|
|
44
|
+
// (no .catch/.finally attached), so clean up the in-flight guard here.
|
|
45
|
+
// The error is intentionally suppressed — a race-condition reject must
|
|
46
|
+
// not crash the daemon or permanently wedge the subscription.
|
|
47
|
+
inFlight.delete(id);
|
|
48
|
+
logFailure(id, error);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
const handler = (state) => {
|
|
52
|
+
for (const id of Object.keys(state.pendingApprovals)) {
|
|
53
|
+
acceptRequest(id);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
return subscribeToApprovalStateChanged(messenger, handler);
|
|
57
|
+
}
|
|
58
|
+
exports.subscribeToAutoApproval = subscribeToAutoApproval;
|
|
59
|
+
/**
|
|
60
|
+
* Subscribe a handler to `ApprovalController:stateChanged`.
|
|
61
|
+
*
|
|
62
|
+
* `ApprovalControllerEvents` only declares `ApprovalController:stateChange`
|
|
63
|
+
* (via `ControllerStateChangeEvent`), not the non-deprecated
|
|
64
|
+
* `ApprovalController:stateChanged` variant that `BaseController` publishes at
|
|
65
|
+
* runtime. This helper localizes the unavoidable cast — using the same
|
|
66
|
+
* technique as `subscribeToStateChanged` in the persistence layer — behind a
|
|
67
|
+
* typed {@link ApprovalStateChangeHandler}, keeping the `state` payload
|
|
68
|
+
* compile-checked at the call site instead of erased by a statement-level
|
|
69
|
+
* `@ts-expect-error`.
|
|
70
|
+
*
|
|
71
|
+
* TODO: Remove this cast once `ApprovalControllerEvents` includes
|
|
72
|
+
* `ControllerStateChangedEvent` (`:stateChanged`), matching the union already
|
|
73
|
+
* exported by `BaseController`.
|
|
74
|
+
*
|
|
75
|
+
* @param messenger - The wallet root messenger.
|
|
76
|
+
* @param handler - The state-change handler to register.
|
|
77
|
+
* @returns A function that unsubscribes the handler.
|
|
78
|
+
*/
|
|
79
|
+
function subscribeToApprovalStateChanged(messenger, handler) {
|
|
80
|
+
const subscriber = messenger;
|
|
81
|
+
subscriber.subscribe('ApprovalController:stateChanged', handler);
|
|
82
|
+
return () => {
|
|
83
|
+
subscriber.unsubscribe('ApprovalController:stateChanged', handler);
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=auto-approval.cjs.map
|