@metamask-previews/wallet-cli 0.0.0-preview-2dc3d26a4 → 0.0.0-preview-aa202ec10
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 +3 -0
- package/README.md +11 -1
- package/dist/commands/wallet/send.cjs +332 -0
- package/dist/commands/wallet/send.cjs.map +1 -0
- package/dist/commands/wallet/send.d.cts +42 -0
- 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.mjs +328 -0
- package/dist/commands/wallet/send.mjs.map +1 -0
- package/dist/daemon/daemon-entry.cjs +4 -0
- package/dist/daemon/daemon-entry.cjs.map +1 -1
- package/dist/daemon/daemon-entry.mjs +4 -0
- package/dist/daemon/daemon-entry.mjs.map +1 -1
- package/dist/daemon/prompts.cjs +19 -1
- package/dist/daemon/prompts.cjs.map +1 -1
- package/dist/daemon/prompts.d.cts +11 -0
- package/dist/daemon/prompts.d.cts.map +1 -1
- package/dist/daemon/prompts.d.mts +11 -0
- package/dist/daemon/prompts.d.mts.map +1 -1
- package/dist/daemon/prompts.mjs +17 -0
- package/dist/daemon/prompts.mjs.map +1 -1
- package/dist/daemon/send-transaction.cjs +147 -0
- package/dist/daemon/send-transaction.cjs.map +1 -0
- package/dist/daemon/send-transaction.d.cts +102 -0
- 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.mjs +143 -0
- package/dist/daemon/send-transaction.mjs.map +1 -0
- package/package.json +4 -1
package/dist/daemon/prompts.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.promptPassword = exports.confirmPurge = void 0;
|
|
3
|
+
exports.promptPassword = exports.confirmSend = exports.confirmPurge = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Ask the user to confirm the destructive `daemon purge` operation.
|
|
6
6
|
*
|
|
@@ -18,6 +18,24 @@ async function confirmPurge() {
|
|
|
18
18
|
});
|
|
19
19
|
}
|
|
20
20
|
exports.confirmPurge = confirmPurge;
|
|
21
|
+
/**
|
|
22
|
+
* Ask the user to confirm broadcasting a transaction. Used by `mm wallet send`
|
|
23
|
+
* when neither `--yes` nor `--dry-run` was passed. Same dynamic-import +
|
|
24
|
+
* ESM-interop pattern as {@link confirmPurge}. Defaults to `false` so an
|
|
25
|
+
* accidental bare Enter never broadcasts.
|
|
26
|
+
*
|
|
27
|
+
* @param summary - A human-readable description of the transaction to send
|
|
28
|
+
* (recipient, amount, network), shown above the prompt.
|
|
29
|
+
* @returns True if the user confirmed.
|
|
30
|
+
*/
|
|
31
|
+
async function confirmSend(summary) {
|
|
32
|
+
const { default: confirm } = await import("@inquirer/confirm");
|
|
33
|
+
return confirm({
|
|
34
|
+
message: `${summary}\nBroadcast this transaction?`,
|
|
35
|
+
default: false,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
exports.confirmSend = confirmSend;
|
|
21
39
|
/**
|
|
22
40
|
* Prompt the user for the wallet password, with input masked. Used by
|
|
23
41
|
* `mm wallet unlock` when the user did not pass `--password` or set the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.cjs","sourceRoot":"","sources":["../../src/daemon/prompts.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;GAQG;AACI,KAAK,UAAU,YAAY;IAChC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,qBAAqB,CAAC;IAC/D,OAAO,OAAO,CAAC;QACb,OAAO,EAAE,2DAA2D;QACpE,OAAO,EAAE,KAAK;KACf,CAAC,CAAC;AACL,CAAC;AAND,oCAMC;AAED;;;;;;;GAOG;AACI,KAAK,UAAU,cAAc;IAClC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,sBAAsB,CAAC;IACjE,OAAO,QAAQ,CAAC;QACd,OAAO,EAAE,kBAAkB;QAC3B,IAAI,EAAE,IAAI;KACX,CAAC,CAAC;AACL,CAAC;AAND,wCAMC","sourcesContent":["/**\n * Ask the user to confirm the destructive `daemon purge` operation.\n *\n * Wraps `@inquirer/confirm` in a dynamic import so this CommonJS-compiled\n * package can interop with that ESM-only dependency, and so tests can mock\n * the prompt without going through jest's ESM mock machinery.\n *\n * @returns True if the user confirmed.\n */\nexport async function confirmPurge(): Promise<boolean> {\n const { default: confirm } = await import('@inquirer/confirm');\n return confirm({\n message: 'This will stop the daemon and delete all state. Continue?',\n default: false,\n });\n}\n\n/**\n * Prompt the user for the wallet password, with input masked. Used by\n * `mm wallet unlock` when the user did not pass `--password` or set the\n * `MM_WALLET_PASSWORD` env var. Same dynamic-import + ESM-interop pattern\n * as {@link confirmPurge}.\n *\n * @returns The password the user typed.\n */\nexport async function promptPassword(): Promise<string> {\n const { default: password } = await import('@inquirer/password');\n return password({\n message: 'Wallet password:',\n mask: true,\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"prompts.cjs","sourceRoot":"","sources":["../../src/daemon/prompts.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;GAQG;AACI,KAAK,UAAU,YAAY;IAChC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,qBAAqB,CAAC;IAC/D,OAAO,OAAO,CAAC;QACb,OAAO,EAAE,2DAA2D;QACpE,OAAO,EAAE,KAAK;KACf,CAAC,CAAC;AACL,CAAC;AAND,oCAMC;AAED;;;;;;;;;GASG;AACI,KAAK,UAAU,WAAW,CAAC,OAAe;IAC/C,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,qBAAqB,CAAC;IAC/D,OAAO,OAAO,CAAC;QACb,OAAO,EAAE,GAAG,OAAO,+BAA+B;QAClD,OAAO,EAAE,KAAK;KACf,CAAC,CAAC;AACL,CAAC;AAND,kCAMC;AAED;;;;;;;GAOG;AACI,KAAK,UAAU,cAAc;IAClC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,sBAAsB,CAAC;IACjE,OAAO,QAAQ,CAAC;QACd,OAAO,EAAE,kBAAkB;QAC3B,IAAI,EAAE,IAAI;KACX,CAAC,CAAC;AACL,CAAC;AAND,wCAMC","sourcesContent":["/**\n * Ask the user to confirm the destructive `daemon purge` operation.\n *\n * Wraps `@inquirer/confirm` in a dynamic import so this CommonJS-compiled\n * package can interop with that ESM-only dependency, and so tests can mock\n * the prompt without going through jest's ESM mock machinery.\n *\n * @returns True if the user confirmed.\n */\nexport async function confirmPurge(): Promise<boolean> {\n const { default: confirm } = await import('@inquirer/confirm');\n return confirm({\n message: 'This will stop the daemon and delete all state. Continue?',\n default: false,\n });\n}\n\n/**\n * Ask the user to confirm broadcasting a transaction. Used by `mm wallet send`\n * when neither `--yes` nor `--dry-run` was passed. Same dynamic-import +\n * ESM-interop pattern as {@link confirmPurge}. Defaults to `false` so an\n * accidental bare Enter never broadcasts.\n *\n * @param summary - A human-readable description of the transaction to send\n * (recipient, amount, network), shown above the prompt.\n * @returns True if the user confirmed.\n */\nexport async function confirmSend(summary: string): Promise<boolean> {\n const { default: confirm } = await import('@inquirer/confirm');\n return confirm({\n message: `${summary}\\nBroadcast this transaction?`,\n default: false,\n });\n}\n\n/**\n * Prompt the user for the wallet password, with input masked. Used by\n * `mm wallet unlock` when the user did not pass `--password` or set the\n * `MM_WALLET_PASSWORD` env var. Same dynamic-import + ESM-interop pattern\n * as {@link confirmPurge}.\n *\n * @returns The password the user typed.\n */\nexport async function promptPassword(): Promise<string> {\n const { default: password } = await import('@inquirer/password');\n return password({\n message: 'Wallet password:',\n mask: true,\n });\n}\n"]}
|
|
@@ -8,6 +8,17 @@
|
|
|
8
8
|
* @returns True if the user confirmed.
|
|
9
9
|
*/
|
|
10
10
|
export declare function confirmPurge(): Promise<boolean>;
|
|
11
|
+
/**
|
|
12
|
+
* Ask the user to confirm broadcasting a transaction. Used by `mm wallet send`
|
|
13
|
+
* when neither `--yes` nor `--dry-run` was passed. Same dynamic-import +
|
|
14
|
+
* ESM-interop pattern as {@link confirmPurge}. Defaults to `false` so an
|
|
15
|
+
* accidental bare Enter never broadcasts.
|
|
16
|
+
*
|
|
17
|
+
* @param summary - A human-readable description of the transaction to send
|
|
18
|
+
* (recipient, amount, network), shown above the prompt.
|
|
19
|
+
* @returns True if the user confirmed.
|
|
20
|
+
*/
|
|
21
|
+
export declare function confirmSend(summary: string): Promise<boolean>;
|
|
11
22
|
/**
|
|
12
23
|
* Prompt the user for the wallet password, with input masked. Used by
|
|
13
24
|
* `mm wallet unlock` when the user did not pass `--password` or set the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.d.cts","sourceRoot":"","sources":["../../src/daemon/prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,CAMrD;AAED;;;;;;;GAOG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAMtD"}
|
|
1
|
+
{"version":3,"file":"prompts.d.cts","sourceRoot":"","sources":["../../src/daemon/prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,CAMrD;AAED;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAMnE;AAED;;;;;;;GAOG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAMtD"}
|
|
@@ -8,6 +8,17 @@
|
|
|
8
8
|
* @returns True if the user confirmed.
|
|
9
9
|
*/
|
|
10
10
|
export declare function confirmPurge(): Promise<boolean>;
|
|
11
|
+
/**
|
|
12
|
+
* Ask the user to confirm broadcasting a transaction. Used by `mm wallet send`
|
|
13
|
+
* when neither `--yes` nor `--dry-run` was passed. Same dynamic-import +
|
|
14
|
+
* ESM-interop pattern as {@link confirmPurge}. Defaults to `false` so an
|
|
15
|
+
* accidental bare Enter never broadcasts.
|
|
16
|
+
*
|
|
17
|
+
* @param summary - A human-readable description of the transaction to send
|
|
18
|
+
* (recipient, amount, network), shown above the prompt.
|
|
19
|
+
* @returns True if the user confirmed.
|
|
20
|
+
*/
|
|
21
|
+
export declare function confirmSend(summary: string): Promise<boolean>;
|
|
11
22
|
/**
|
|
12
23
|
* Prompt the user for the wallet password, with input masked. Used by
|
|
13
24
|
* `mm wallet unlock` when the user did not pass `--password` or set the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.d.mts","sourceRoot":"","sources":["../../src/daemon/prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,CAMrD;AAED;;;;;;;GAOG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAMtD"}
|
|
1
|
+
{"version":3,"file":"prompts.d.mts","sourceRoot":"","sources":["../../src/daemon/prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,CAMrD;AAED;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAMnE;AAED;;;;;;;GAOG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAMtD"}
|
package/dist/daemon/prompts.mjs
CHANGED
|
@@ -14,6 +14,23 @@ export async function confirmPurge() {
|
|
|
14
14
|
default: false,
|
|
15
15
|
});
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Ask the user to confirm broadcasting a transaction. Used by `mm wallet send`
|
|
19
|
+
* when neither `--yes` nor `--dry-run` was passed. Same dynamic-import +
|
|
20
|
+
* ESM-interop pattern as {@link confirmPurge}. Defaults to `false` so an
|
|
21
|
+
* accidental bare Enter never broadcasts.
|
|
22
|
+
*
|
|
23
|
+
* @param summary - A human-readable description of the transaction to send
|
|
24
|
+
* (recipient, amount, network), shown above the prompt.
|
|
25
|
+
* @returns True if the user confirmed.
|
|
26
|
+
*/
|
|
27
|
+
export async function confirmSend(summary) {
|
|
28
|
+
const { default: confirm } = await import("@inquirer/confirm");
|
|
29
|
+
return confirm({
|
|
30
|
+
message: `${summary}\nBroadcast this transaction?`,
|
|
31
|
+
default: false,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
17
34
|
/**
|
|
18
35
|
* Prompt the user for the wallet password, with input masked. Used by
|
|
19
36
|
* `mm wallet unlock` when the user did not pass `--password` or set the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.mjs","sourceRoot":"","sources":["../../src/daemon/prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,qBAAqB,CAAC;IAC/D,OAAO,OAAO,CAAC;QACb,OAAO,EAAE,2DAA2D;QACpE,OAAO,EAAE,KAAK;KACf,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,sBAAsB,CAAC;IACjE,OAAO,QAAQ,CAAC;QACd,OAAO,EAAE,kBAAkB;QAC3B,IAAI,EAAE,IAAI;KACX,CAAC,CAAC;AACL,CAAC","sourcesContent":["/**\n * Ask the user to confirm the destructive `daemon purge` operation.\n *\n * Wraps `@inquirer/confirm` in a dynamic import so this CommonJS-compiled\n * package can interop with that ESM-only dependency, and so tests can mock\n * the prompt without going through jest's ESM mock machinery.\n *\n * @returns True if the user confirmed.\n */\nexport async function confirmPurge(): Promise<boolean> {\n const { default: confirm } = await import('@inquirer/confirm');\n return confirm({\n message: 'This will stop the daemon and delete all state. Continue?',\n default: false,\n });\n}\n\n/**\n * Prompt the user for the wallet password, with input masked. Used by\n * `mm wallet unlock` when the user did not pass `--password` or set the\n * `MM_WALLET_PASSWORD` env var. Same dynamic-import + ESM-interop pattern\n * as {@link confirmPurge}.\n *\n * @returns The password the user typed.\n */\nexport async function promptPassword(): Promise<string> {\n const { default: password } = await import('@inquirer/password');\n return password({\n message: 'Wallet password:',\n mask: true,\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"prompts.mjs","sourceRoot":"","sources":["../../src/daemon/prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,qBAAqB,CAAC;IAC/D,OAAO,OAAO,CAAC;QACb,OAAO,EAAE,2DAA2D;QACpE,OAAO,EAAE,KAAK;KACf,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAe;IAC/C,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,qBAAqB,CAAC;IAC/D,OAAO,OAAO,CAAC;QACb,OAAO,EAAE,GAAG,OAAO,+BAA+B;QAClD,OAAO,EAAE,KAAK;KACf,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,sBAAsB,CAAC;IACjE,OAAO,QAAQ,CAAC;QACd,OAAO,EAAE,kBAAkB;QAC3B,IAAI,EAAE,IAAI;KACX,CAAC,CAAC;AACL,CAAC","sourcesContent":["/**\n * Ask the user to confirm the destructive `daemon purge` operation.\n *\n * Wraps `@inquirer/confirm` in a dynamic import so this CommonJS-compiled\n * package can interop with that ESM-only dependency, and so tests can mock\n * the prompt without going through jest's ESM mock machinery.\n *\n * @returns True if the user confirmed.\n */\nexport async function confirmPurge(): Promise<boolean> {\n const { default: confirm } = await import('@inquirer/confirm');\n return confirm({\n message: 'This will stop the daemon and delete all state. Continue?',\n default: false,\n });\n}\n\n/**\n * Ask the user to confirm broadcasting a transaction. Used by `mm wallet send`\n * when neither `--yes` nor `--dry-run` was passed. Same dynamic-import +\n * ESM-interop pattern as {@link confirmPurge}. Defaults to `false` so an\n * accidental bare Enter never broadcasts.\n *\n * @param summary - A human-readable description of the transaction to send\n * (recipient, amount, network), shown above the prompt.\n * @returns True if the user confirmed.\n */\nexport async function confirmSend(summary: string): Promise<boolean> {\n const { default: confirm } = await import('@inquirer/confirm');\n return confirm({\n message: `${summary}\\nBroadcast this transaction?`,\n default: false,\n });\n}\n\n/**\n * Prompt the user for the wallet password, with input masked. Used by\n * `mm wallet unlock` when the user did not pass `--password` or set the\n * `MM_WALLET_PASSWORD` env var. Same dynamic-import + ESM-interop pattern\n * as {@link confirmPurge}.\n *\n * @returns The password the user typed.\n */\nexport async function promptPassword(): Promise<string> {\n const { default: password } = await import('@inquirer/password');\n return password({\n message: 'Wallet password:',\n mask: true,\n });\n}\n"]}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runSendTransaction = exports.SendTransactionBroadcastResultStruct = exports.SendTransactionDryRunResultStruct = exports.SendTransactionParamsStruct = void 0;
|
|
4
|
+
const superstruct_1 = require("@metamask/superstruct");
|
|
5
|
+
const utils_1 = require("@metamask/utils");
|
|
6
|
+
/**
|
|
7
|
+
* Origin recorded on daemon-initiated transactions. Mirrors
|
|
8
|
+
* `ORIGIN_METAMASK` from `@metamask/controller-utils` (a single string
|
|
9
|
+
* constant, inlined here to avoid pulling that whole package in as a
|
|
10
|
+
* dependency for one value).
|
|
11
|
+
*/
|
|
12
|
+
const INTERNAL_ORIGIN = 'metamask';
|
|
13
|
+
/**
|
|
14
|
+
* Struct for a `0x`-prefixed 20-byte hex address. `isValidHexAddress` accepts
|
|
15
|
+
* an all-lowercase address or a valid EIP-55 checksummed one, so a plain
|
|
16
|
+
* lowercase paste works while a mistyped mixed-case address is rejected.
|
|
17
|
+
*/
|
|
18
|
+
const AddressStruct = (0, superstruct_1.define)('Address', (value) => typeof value === 'string' && (0, utils_1.isValidHexAddress)(value)
|
|
19
|
+
? true
|
|
20
|
+
: 'Expected a 0x-prefixed 20-byte hex address');
|
|
21
|
+
/**
|
|
22
|
+
* Params struct for the `sendTransaction` RPC method.
|
|
23
|
+
*
|
|
24
|
+
* The transaction fields (`to`, `value`, `data`, gas overrides) are canonical
|
|
25
|
+
* `0x`-prefixed hex — any unit conversion (e.g. ether → wei) is the CLI
|
|
26
|
+
* command's job, so the daemon boundary stays unambiguous. Exactly one of
|
|
27
|
+
* `networkClientId` / `chainId` selects the network client; the refinement
|
|
28
|
+
* below rejects supplying both or neither. `dryRun` short-circuits before
|
|
29
|
+
* broadcast (see {@link runSendTransaction}).
|
|
30
|
+
*/
|
|
31
|
+
exports.SendTransactionParamsStruct = (0, superstruct_1.refine)((0, superstruct_1.object)({
|
|
32
|
+
to: AddressStruct,
|
|
33
|
+
from: (0, superstruct_1.optional)(AddressStruct),
|
|
34
|
+
value: (0, superstruct_1.optional)(utils_1.StrictHexStruct),
|
|
35
|
+
data: (0, superstruct_1.optional)(utils_1.StrictHexStruct),
|
|
36
|
+
gas: (0, superstruct_1.optional)(utils_1.StrictHexStruct),
|
|
37
|
+
maxFeePerGas: (0, superstruct_1.optional)(utils_1.StrictHexStruct),
|
|
38
|
+
maxPriorityFeePerGas: (0, superstruct_1.optional)(utils_1.StrictHexStruct),
|
|
39
|
+
gasPrice: (0, superstruct_1.optional)(utils_1.StrictHexStruct),
|
|
40
|
+
networkClientId: (0, superstruct_1.optional)((0, superstruct_1.nonempty)((0, superstruct_1.string)())),
|
|
41
|
+
chainId: (0, superstruct_1.optional)(utils_1.StrictHexStruct),
|
|
42
|
+
dryRun: (0, superstruct_1.optional)((0, superstruct_1.boolean)()),
|
|
43
|
+
}), 'SendTransactionParams', (value) => {
|
|
44
|
+
if ((value.networkClientId === undefined) ===
|
|
45
|
+
(value.chainId === undefined)) {
|
|
46
|
+
return 'Exactly one of `networkClientId` or `chainId` must be provided';
|
|
47
|
+
}
|
|
48
|
+
// `gasPrice` (legacy) and the EIP-1559 fields are mutually exclusive:
|
|
49
|
+
// `TransactionController` rejects the combination at broadcast, so reject
|
|
50
|
+
// it here at the boundary instead — otherwise a dry-run and the
|
|
51
|
+
// confirmation preview would show a plan that always fails at send.
|
|
52
|
+
if (value.gasPrice !== undefined &&
|
|
53
|
+
(value.maxFeePerGas !== undefined ||
|
|
54
|
+
value.maxPriorityFeePerGas !== undefined)) {
|
|
55
|
+
return '`gasPrice` cannot be combined with `maxFeePerGas` or `maxPriorityFeePerGas`';
|
|
56
|
+
}
|
|
57
|
+
return true;
|
|
58
|
+
});
|
|
59
|
+
/**
|
|
60
|
+
* The resolved plan a `dryRun` returns: the network client and sender the
|
|
61
|
+
* daemon would use, without adding or broadcasting anything. Exported as a
|
|
62
|
+
* struct so the CLI can validate the payload it reads back over JSON-RPC
|
|
63
|
+
* (which erases types on the wire) rather than trusting its shape.
|
|
64
|
+
*/
|
|
65
|
+
exports.SendTransactionDryRunResultStruct = (0, superstruct_1.object)({
|
|
66
|
+
dryRun: (0, superstruct_1.literal)(true),
|
|
67
|
+
from: utils_1.StrictHexStruct,
|
|
68
|
+
to: utils_1.StrictHexStruct,
|
|
69
|
+
value: utils_1.StrictHexStruct,
|
|
70
|
+
networkClientId: (0, superstruct_1.string)(),
|
|
71
|
+
});
|
|
72
|
+
/**
|
|
73
|
+
* The outcome of a broadcast send: the on-chain hash plus the id/status the
|
|
74
|
+
* daemon tracks the transaction under. Exported as a struct for the same
|
|
75
|
+
* client-side validation reason as {@link SendTransactionDryRunResultStruct}.
|
|
76
|
+
*/
|
|
77
|
+
exports.SendTransactionBroadcastResultStruct = (0, superstruct_1.object)({
|
|
78
|
+
transactionHash: (0, superstruct_1.string)(),
|
|
79
|
+
transactionId: (0, superstruct_1.string)(),
|
|
80
|
+
status: (0, superstruct_1.string)(),
|
|
81
|
+
});
|
|
82
|
+
/**
|
|
83
|
+
* Add and broadcast a transaction through the daemon-hosted
|
|
84
|
+
* `TransactionController`, returning a serializable result.
|
|
85
|
+
*
|
|
86
|
+
* `TransactionController:addTransaction` returns `{ transactionMeta, result }`
|
|
87
|
+
* where `result` is a `Promise<hash>` that resolves once the transaction is
|
|
88
|
+
* signed and broadcast. That promise is not JSON-serializable, so it cannot
|
|
89
|
+
* travel back over the daemon's JSON-RPC socket via the generic `call`
|
|
90
|
+
* dispatch — hence this dedicated handler, which awaits the broadcast
|
|
91
|
+
* server-side and returns only the resolved hash (and id/status).
|
|
92
|
+
*
|
|
93
|
+
* The network client is resolved from `chainId` (via `NetworkController`) when
|
|
94
|
+
* `networkClientId` is not given directly, and `from` defaults to the selected
|
|
95
|
+
* account. The transaction is submitted as `isInternal` (the daemon is driven
|
|
96
|
+
* only by its owner over the `0600` same-user socket), which skips
|
|
97
|
+
* origin/permitted-account validation; its approval request is auto-accepted
|
|
98
|
+
* by the daemon's auto-approval subscription.
|
|
99
|
+
*
|
|
100
|
+
* When `dryRun` is set, the network client and sender are resolved and the
|
|
101
|
+
* params validated, but nothing is added or broadcast — the resolved plan is
|
|
102
|
+
* returned so the CLI can preview it before the user confirms.
|
|
103
|
+
*
|
|
104
|
+
* @param messenger - The wallet root messenger.
|
|
105
|
+
* @param params - Validated `sendTransaction` params.
|
|
106
|
+
* @returns The dry-run plan, or the broadcast hash with its id and status.
|
|
107
|
+
*/
|
|
108
|
+
async function runSendTransaction(messenger, params) {
|
|
109
|
+
const { to, value = '0x0', data, gas, maxFeePerGas, maxPriorityFeePerGas, gasPrice, networkClientId: networkClientIdParam, chainId, dryRun, } = params;
|
|
110
|
+
// The struct guarantees exactly one of `networkClientId` / `chainId`, so
|
|
111
|
+
// `chainId` is defined whenever `networkClientId` is not.
|
|
112
|
+
const networkClientId = networkClientIdParam ??
|
|
113
|
+
messenger.call('NetworkController:findNetworkClientIdByChainId', chainId);
|
|
114
|
+
const from = params.from ??
|
|
115
|
+
messenger.call('AccountsController:getSelectedAccount').address;
|
|
116
|
+
if (dryRun) {
|
|
117
|
+
return { dryRun: true, from, to, value, networkClientId };
|
|
118
|
+
}
|
|
119
|
+
const txParams = {
|
|
120
|
+
from,
|
|
121
|
+
to,
|
|
122
|
+
value,
|
|
123
|
+
...(data === undefined ? {} : { data }),
|
|
124
|
+
...(gas === undefined ? {} : { gas }),
|
|
125
|
+
...(maxFeePerGas === undefined ? {} : { maxFeePerGas }),
|
|
126
|
+
...(maxPriorityFeePerGas === undefined ? {} : { maxPriorityFeePerGas }),
|
|
127
|
+
...(gasPrice === undefined ? {} : { gasPrice }),
|
|
128
|
+
};
|
|
129
|
+
const { result, transactionMeta } = await messenger.call('TransactionController:addTransaction', txParams, { networkClientId, origin: INTERNAL_ORIGIN, isInternal: true });
|
|
130
|
+
// `result` resolves only once the transaction is signed and broadcast (see
|
|
131
|
+
// the function JSDoc); awaiting it here is what this handler exists for.
|
|
132
|
+
const transactionHash = await result;
|
|
133
|
+
// Re-read the live record for the current status: `transactionMeta` is the
|
|
134
|
+
// creation snapshot (still `unapproved`). If the record is already gone,
|
|
135
|
+
// fall back to `submitted` — reaching this point means `result` resolved, so
|
|
136
|
+
// the transaction was broadcast, never merely `unapproved`.
|
|
137
|
+
const [current] = messenger.call('TransactionController:getTransactions', {
|
|
138
|
+
searchCriteria: { id: transactionMeta.id },
|
|
139
|
+
});
|
|
140
|
+
return {
|
|
141
|
+
transactionHash,
|
|
142
|
+
transactionId: transactionMeta.id,
|
|
143
|
+
status: current?.status ?? 'submitted',
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
exports.runSendTransaction = runSendTransaction;
|
|
147
|
+
//# sourceMappingURL=send-transaction.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"send-transaction.cjs","sourceRoot":"","sources":["../../src/daemon/send-transaction.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n boolean,\n define,\n literal,\n nonempty,\n object,\n optional,\n refine,\n string,\n} from '@metamask/superstruct';\nimport type { Infer } from '@metamask/superstruct';\nimport { isValidHexAddress, StrictHexStruct } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\nimport type {\n DefaultActions,\n DefaultEvents,\n RootMessenger,\n} from '@metamask/wallet';\n\n/**\n * Origin recorded on daemon-initiated transactions. Mirrors\n * `ORIGIN_METAMASK` from `@metamask/controller-utils` (a single string\n * constant, inlined here to avoid pulling that whole package in as a\n * dependency for one value).\n */\nconst INTERNAL_ORIGIN = 'metamask';\n\n/**\n * Struct for a `0x`-prefixed 20-byte hex address. `isValidHexAddress` accepts\n * an all-lowercase address or a valid EIP-55 checksummed one, so a plain\n * lowercase paste works while a mistyped mixed-case address is rejected.\n */\nconst AddressStruct = define<Hex>('Address', (value) =>\n typeof value === 'string' && isValidHexAddress(value as Hex)\n ? true\n : 'Expected a 0x-prefixed 20-byte hex address',\n);\n\n/**\n * Params struct for the `sendTransaction` RPC method.\n *\n * The transaction fields (`to`, `value`, `data`, gas overrides) are canonical\n * `0x`-prefixed hex — any unit conversion (e.g. ether → wei) is the CLI\n * command's job, so the daemon boundary stays unambiguous. Exactly one of\n * `networkClientId` / `chainId` selects the network client; the refinement\n * below rejects supplying both or neither. `dryRun` short-circuits before\n * broadcast (see {@link runSendTransaction}).\n */\nexport const SendTransactionParamsStruct = refine(\n object({\n to: AddressStruct,\n from: optional(AddressStruct),\n value: optional(StrictHexStruct),\n data: optional(StrictHexStruct),\n gas: optional(StrictHexStruct),\n maxFeePerGas: optional(StrictHexStruct),\n maxPriorityFeePerGas: optional(StrictHexStruct),\n gasPrice: optional(StrictHexStruct),\n networkClientId: optional(nonempty(string())),\n chainId: optional(StrictHexStruct),\n dryRun: optional(boolean()),\n }),\n 'SendTransactionParams',\n (value) => {\n if (\n (value.networkClientId === undefined) ===\n (value.chainId === undefined)\n ) {\n return 'Exactly one of `networkClientId` or `chainId` must be provided';\n }\n // `gasPrice` (legacy) and the EIP-1559 fields are mutually exclusive:\n // `TransactionController` rejects the combination at broadcast, so reject\n // it here at the boundary instead — otherwise a dry-run and the\n // confirmation preview would show a plan that always fails at send.\n if (\n value.gasPrice !== undefined &&\n (value.maxFeePerGas !== undefined ||\n value.maxPriorityFeePerGas !== undefined)\n ) {\n return '`gasPrice` cannot be combined with `maxFeePerGas` or `maxPriorityFeePerGas`';\n }\n return true;\n },\n);\n\nexport type SendTransactionParams = Infer<typeof SendTransactionParamsStruct>;\n\n/**\n * The resolved plan a `dryRun` returns: the network client and sender the\n * daemon would use, without adding or broadcasting anything. Exported as a\n * struct so the CLI can validate the payload it reads back over JSON-RPC\n * (which erases types on the wire) rather than trusting its shape.\n */\nexport const SendTransactionDryRunResultStruct = object({\n dryRun: literal(true),\n from: StrictHexStruct,\n to: StrictHexStruct,\n value: StrictHexStruct,\n networkClientId: string(),\n});\n\n/**\n * The outcome of a broadcast send: the on-chain hash plus the id/status the\n * daemon tracks the transaction under. Exported as a struct for the same\n * client-side validation reason as {@link SendTransactionDryRunResultStruct}.\n */\nexport const SendTransactionBroadcastResultStruct = object({\n transactionHash: string(),\n transactionId: string(),\n status: string(),\n});\n\nexport type SendTransactionDryRunResult = Infer<\n typeof SendTransactionDryRunResultStruct\n>;\n\nexport type SendTransactionBroadcastResult = Infer<\n typeof SendTransactionBroadcastResultStruct\n>;\n\nexport type SendTransactionResult =\n | SendTransactionDryRunResult\n | SendTransactionBroadcastResult;\n\n/**\n * Add and broadcast a transaction through the daemon-hosted\n * `TransactionController`, returning a serializable result.\n *\n * `TransactionController:addTransaction` returns `{ transactionMeta, result }`\n * where `result` is a `Promise<hash>` that resolves once the transaction is\n * signed and broadcast. That promise is not JSON-serializable, so it cannot\n * travel back over the daemon's JSON-RPC socket via the generic `call`\n * dispatch — hence this dedicated handler, which awaits the broadcast\n * server-side and returns only the resolved hash (and id/status).\n *\n * The network client is resolved from `chainId` (via `NetworkController`) when\n * `networkClientId` is not given directly, and `from` defaults to the selected\n * account. The transaction is submitted as `isInternal` (the daemon is driven\n * only by its owner over the `0600` same-user socket), which skips\n * origin/permitted-account validation; its approval request is auto-accepted\n * by the daemon's auto-approval subscription.\n *\n * When `dryRun` is set, the network client and sender are resolved and the\n * params validated, but nothing is added or broadcast — the resolved plan is\n * returned so the CLI can preview it before the user confirms.\n *\n * @param messenger - The wallet root messenger.\n * @param params - Validated `sendTransaction` params.\n * @returns The dry-run plan, or the broadcast hash with its id and status.\n */\nexport async function runSendTransaction(\n messenger: Readonly<RootMessenger<DefaultActions, DefaultEvents>>,\n params: SendTransactionParams,\n): Promise<SendTransactionResult> {\n const {\n to,\n value = '0x0',\n data,\n gas,\n maxFeePerGas,\n maxPriorityFeePerGas,\n gasPrice,\n networkClientId: networkClientIdParam,\n chainId,\n dryRun,\n } = params;\n\n // The struct guarantees exactly one of `networkClientId` / `chainId`, so\n // `chainId` is defined whenever `networkClientId` is not.\n const networkClientId =\n networkClientIdParam ??\n messenger.call(\n 'NetworkController:findNetworkClientIdByChainId',\n chainId as Hex,\n );\n\n const from =\n params.from ??\n (messenger.call('AccountsController:getSelectedAccount').address as Hex);\n\n if (dryRun) {\n return { dryRun: true, from, to, value, networkClientId };\n }\n\n const txParams = {\n from,\n to,\n value,\n ...(data === undefined ? {} : { data }),\n ...(gas === undefined ? {} : { gas }),\n ...(maxFeePerGas === undefined ? {} : { maxFeePerGas }),\n ...(maxPriorityFeePerGas === undefined ? {} : { maxPriorityFeePerGas }),\n ...(gasPrice === undefined ? {} : { gasPrice }),\n };\n\n const { result, transactionMeta } = await messenger.call(\n 'TransactionController:addTransaction',\n txParams,\n { networkClientId, origin: INTERNAL_ORIGIN, isInternal: true },\n );\n\n // `result` resolves only once the transaction is signed and broadcast (see\n // the function JSDoc); awaiting it here is what this handler exists for.\n const transactionHash = await result;\n\n // Re-read the live record for the current status: `transactionMeta` is the\n // creation snapshot (still `unapproved`). If the record is already gone,\n // fall back to `submitted` — reaching this point means `result` resolved, so\n // the transaction was broadcast, never merely `unapproved`.\n const [current] = messenger.call('TransactionController:getTransactions', {\n searchCriteria: { id: transactionMeta.id },\n });\n\n return {\n transactionHash,\n transactionId: transactionMeta.id,\n status: current?.status ?? 'submitted',\n };\n}\n"]}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import type { Infer } from "@metamask/superstruct";
|
|
2
|
+
import type { DefaultActions, DefaultEvents, RootMessenger } from "@metamask/wallet";
|
|
3
|
+
/**
|
|
4
|
+
* Params struct for the `sendTransaction` RPC method.
|
|
5
|
+
*
|
|
6
|
+
* The transaction fields (`to`, `value`, `data`, gas overrides) are canonical
|
|
7
|
+
* `0x`-prefixed hex — any unit conversion (e.g. ether → wei) is the CLI
|
|
8
|
+
* command's job, so the daemon boundary stays unambiguous. Exactly one of
|
|
9
|
+
* `networkClientId` / `chainId` selects the network client; the refinement
|
|
10
|
+
* below rejects supplying both or neither. `dryRun` short-circuits before
|
|
11
|
+
* broadcast (see {@link runSendTransaction}).
|
|
12
|
+
*/
|
|
13
|
+
export declare const SendTransactionParamsStruct: import("@metamask/superstruct").Struct<{
|
|
14
|
+
to: `0x${string}`;
|
|
15
|
+
data?: `0x${string}` | undefined;
|
|
16
|
+
value?: `0x${string}` | undefined;
|
|
17
|
+
from?: `0x${string}` | undefined;
|
|
18
|
+
gas?: `0x${string}` | undefined;
|
|
19
|
+
maxFeePerGas?: `0x${string}` | undefined;
|
|
20
|
+
maxPriorityFeePerGas?: `0x${string}` | undefined;
|
|
21
|
+
gasPrice?: `0x${string}` | undefined;
|
|
22
|
+
networkClientId?: string | undefined;
|
|
23
|
+
chainId?: `0x${string}` | undefined;
|
|
24
|
+
dryRun?: boolean | undefined;
|
|
25
|
+
}, {
|
|
26
|
+
to: import("@metamask/superstruct").Struct<`0x${string}`, null>;
|
|
27
|
+
from: import("@metamask/superstruct").Struct<`0x${string}` | undefined, null>;
|
|
28
|
+
value: import("@metamask/superstruct").Struct<`0x${string}` | undefined, null>;
|
|
29
|
+
data: import("@metamask/superstruct").Struct<`0x${string}` | undefined, null>;
|
|
30
|
+
gas: import("@metamask/superstruct").Struct<`0x${string}` | undefined, null>;
|
|
31
|
+
maxFeePerGas: import("@metamask/superstruct").Struct<`0x${string}` | undefined, null>;
|
|
32
|
+
maxPriorityFeePerGas: import("@metamask/superstruct").Struct<`0x${string}` | undefined, null>;
|
|
33
|
+
gasPrice: import("@metamask/superstruct").Struct<`0x${string}` | undefined, null>;
|
|
34
|
+
networkClientId: import("@metamask/superstruct").Struct<string | undefined, null>;
|
|
35
|
+
chainId: import("@metamask/superstruct").Struct<`0x${string}` | undefined, null>;
|
|
36
|
+
dryRun: import("@metamask/superstruct").Struct<boolean | undefined, null>;
|
|
37
|
+
}>;
|
|
38
|
+
export type SendTransactionParams = Infer<typeof SendTransactionParamsStruct>;
|
|
39
|
+
/**
|
|
40
|
+
* The resolved plan a `dryRun` returns: the network client and sender the
|
|
41
|
+
* daemon would use, without adding or broadcasting anything. Exported as a
|
|
42
|
+
* struct so the CLI can validate the payload it reads back over JSON-RPC
|
|
43
|
+
* (which erases types on the wire) rather than trusting its shape.
|
|
44
|
+
*/
|
|
45
|
+
export declare const SendTransactionDryRunResultStruct: import("@metamask/superstruct").Struct<{
|
|
46
|
+
value: `0x${string}`;
|
|
47
|
+
to: `0x${string}`;
|
|
48
|
+
from: `0x${string}`;
|
|
49
|
+
networkClientId: string;
|
|
50
|
+
dryRun: true;
|
|
51
|
+
}, {
|
|
52
|
+
dryRun: import("@metamask/superstruct").Struct<true, true>;
|
|
53
|
+
from: import("@metamask/superstruct").Struct<`0x${string}`, null>;
|
|
54
|
+
to: import("@metamask/superstruct").Struct<`0x${string}`, null>;
|
|
55
|
+
value: import("@metamask/superstruct").Struct<`0x${string}`, null>;
|
|
56
|
+
networkClientId: import("@metamask/superstruct").Struct<string, null>;
|
|
57
|
+
}>;
|
|
58
|
+
/**
|
|
59
|
+
* The outcome of a broadcast send: the on-chain hash plus the id/status the
|
|
60
|
+
* daemon tracks the transaction under. Exported as a struct for the same
|
|
61
|
+
* client-side validation reason as {@link SendTransactionDryRunResultStruct}.
|
|
62
|
+
*/
|
|
63
|
+
export declare const SendTransactionBroadcastResultStruct: import("@metamask/superstruct").Struct<{
|
|
64
|
+
status: string;
|
|
65
|
+
transactionHash: string;
|
|
66
|
+
transactionId: string;
|
|
67
|
+
}, {
|
|
68
|
+
transactionHash: import("@metamask/superstruct").Struct<string, null>;
|
|
69
|
+
transactionId: import("@metamask/superstruct").Struct<string, null>;
|
|
70
|
+
status: import("@metamask/superstruct").Struct<string, null>;
|
|
71
|
+
}>;
|
|
72
|
+
export type SendTransactionDryRunResult = Infer<typeof SendTransactionDryRunResultStruct>;
|
|
73
|
+
export type SendTransactionBroadcastResult = Infer<typeof SendTransactionBroadcastResultStruct>;
|
|
74
|
+
export type SendTransactionResult = SendTransactionDryRunResult | SendTransactionBroadcastResult;
|
|
75
|
+
/**
|
|
76
|
+
* Add and broadcast a transaction through the daemon-hosted
|
|
77
|
+
* `TransactionController`, returning a serializable result.
|
|
78
|
+
*
|
|
79
|
+
* `TransactionController:addTransaction` returns `{ transactionMeta, result }`
|
|
80
|
+
* where `result` is a `Promise<hash>` that resolves once the transaction is
|
|
81
|
+
* signed and broadcast. That promise is not JSON-serializable, so it cannot
|
|
82
|
+
* travel back over the daemon's JSON-RPC socket via the generic `call`
|
|
83
|
+
* dispatch — hence this dedicated handler, which awaits the broadcast
|
|
84
|
+
* server-side and returns only the resolved hash (and id/status).
|
|
85
|
+
*
|
|
86
|
+
* The network client is resolved from `chainId` (via `NetworkController`) when
|
|
87
|
+
* `networkClientId` is not given directly, and `from` defaults to the selected
|
|
88
|
+
* account. The transaction is submitted as `isInternal` (the daemon is driven
|
|
89
|
+
* only by its owner over the `0600` same-user socket), which skips
|
|
90
|
+
* origin/permitted-account validation; its approval request is auto-accepted
|
|
91
|
+
* by the daemon's auto-approval subscription.
|
|
92
|
+
*
|
|
93
|
+
* When `dryRun` is set, the network client and sender are resolved and the
|
|
94
|
+
* params validated, but nothing is added or broadcast — the resolved plan is
|
|
95
|
+
* returned so the CLI can preview it before the user confirms.
|
|
96
|
+
*
|
|
97
|
+
* @param messenger - The wallet root messenger.
|
|
98
|
+
* @param params - Validated `sendTransaction` params.
|
|
99
|
+
* @returns The dry-run plan, or the broadcast hash with its id and status.
|
|
100
|
+
*/
|
|
101
|
+
export declare function runSendTransaction(messenger: Readonly<RootMessenger<DefaultActions, DefaultEvents>>, params: SendTransactionParams): Promise<SendTransactionResult>;
|
|
102
|
+
//# sourceMappingURL=send-transaction.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"send-transaction.d.cts","sourceRoot":"","sources":["../../src/daemon/send-transaction.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,KAAK,EAAE,8BAA8B;AAGnD,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EACb,aAAa,EACd,yBAAyB;AAqB1B;;;;;;;;;GASG;AACH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;EAmCvC,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAE9E;;;;;GAKG;AACH,eAAO,MAAM,iCAAiC;;;;;;;;;;;;EAM5C,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,oCAAoC;;;;;;;;EAI/C,CAAC;AAEH,MAAM,MAAM,2BAA2B,GAAG,KAAK,CAC7C,OAAO,iCAAiC,CACzC,CAAC;AAEF,MAAM,MAAM,8BAA8B,GAAG,KAAK,CAChD,OAAO,oCAAoC,CAC5C,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAC7B,2BAA2B,GAC3B,8BAA8B,CAAC;AAEnC;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,QAAQ,CAAC,aAAa,CAAC,cAAc,EAAE,aAAa,CAAC,CAAC,EACjE,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC,CAiEhC"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import type { Infer } from "@metamask/superstruct";
|
|
2
|
+
import type { DefaultActions, DefaultEvents, RootMessenger } from "@metamask/wallet";
|
|
3
|
+
/**
|
|
4
|
+
* Params struct for the `sendTransaction` RPC method.
|
|
5
|
+
*
|
|
6
|
+
* The transaction fields (`to`, `value`, `data`, gas overrides) are canonical
|
|
7
|
+
* `0x`-prefixed hex — any unit conversion (e.g. ether → wei) is the CLI
|
|
8
|
+
* command's job, so the daemon boundary stays unambiguous. Exactly one of
|
|
9
|
+
* `networkClientId` / `chainId` selects the network client; the refinement
|
|
10
|
+
* below rejects supplying both or neither. `dryRun` short-circuits before
|
|
11
|
+
* broadcast (see {@link runSendTransaction}).
|
|
12
|
+
*/
|
|
13
|
+
export declare const SendTransactionParamsStruct: import("@metamask/superstruct").Struct<{
|
|
14
|
+
to: `0x${string}`;
|
|
15
|
+
data?: `0x${string}` | undefined;
|
|
16
|
+
value?: `0x${string}` | undefined;
|
|
17
|
+
from?: `0x${string}` | undefined;
|
|
18
|
+
gas?: `0x${string}` | undefined;
|
|
19
|
+
maxFeePerGas?: `0x${string}` | undefined;
|
|
20
|
+
maxPriorityFeePerGas?: `0x${string}` | undefined;
|
|
21
|
+
gasPrice?: `0x${string}` | undefined;
|
|
22
|
+
networkClientId?: string | undefined;
|
|
23
|
+
chainId?: `0x${string}` | undefined;
|
|
24
|
+
dryRun?: boolean | undefined;
|
|
25
|
+
}, {
|
|
26
|
+
to: import("@metamask/superstruct").Struct<`0x${string}`, null>;
|
|
27
|
+
from: import("@metamask/superstruct").Struct<`0x${string}` | undefined, null>;
|
|
28
|
+
value: import("@metamask/superstruct").Struct<`0x${string}` | undefined, null>;
|
|
29
|
+
data: import("@metamask/superstruct").Struct<`0x${string}` | undefined, null>;
|
|
30
|
+
gas: import("@metamask/superstruct").Struct<`0x${string}` | undefined, null>;
|
|
31
|
+
maxFeePerGas: import("@metamask/superstruct").Struct<`0x${string}` | undefined, null>;
|
|
32
|
+
maxPriorityFeePerGas: import("@metamask/superstruct").Struct<`0x${string}` | undefined, null>;
|
|
33
|
+
gasPrice: import("@metamask/superstruct").Struct<`0x${string}` | undefined, null>;
|
|
34
|
+
networkClientId: import("@metamask/superstruct").Struct<string | undefined, null>;
|
|
35
|
+
chainId: import("@metamask/superstruct").Struct<`0x${string}` | undefined, null>;
|
|
36
|
+
dryRun: import("@metamask/superstruct").Struct<boolean | undefined, null>;
|
|
37
|
+
}>;
|
|
38
|
+
export type SendTransactionParams = Infer<typeof SendTransactionParamsStruct>;
|
|
39
|
+
/**
|
|
40
|
+
* The resolved plan a `dryRun` returns: the network client and sender the
|
|
41
|
+
* daemon would use, without adding or broadcasting anything. Exported as a
|
|
42
|
+
* struct so the CLI can validate the payload it reads back over JSON-RPC
|
|
43
|
+
* (which erases types on the wire) rather than trusting its shape.
|
|
44
|
+
*/
|
|
45
|
+
export declare const SendTransactionDryRunResultStruct: import("@metamask/superstruct").Struct<{
|
|
46
|
+
value: `0x${string}`;
|
|
47
|
+
to: `0x${string}`;
|
|
48
|
+
from: `0x${string}`;
|
|
49
|
+
networkClientId: string;
|
|
50
|
+
dryRun: true;
|
|
51
|
+
}, {
|
|
52
|
+
dryRun: import("@metamask/superstruct").Struct<true, true>;
|
|
53
|
+
from: import("@metamask/superstruct").Struct<`0x${string}`, null>;
|
|
54
|
+
to: import("@metamask/superstruct").Struct<`0x${string}`, null>;
|
|
55
|
+
value: import("@metamask/superstruct").Struct<`0x${string}`, null>;
|
|
56
|
+
networkClientId: import("@metamask/superstruct").Struct<string, null>;
|
|
57
|
+
}>;
|
|
58
|
+
/**
|
|
59
|
+
* The outcome of a broadcast send: the on-chain hash plus the id/status the
|
|
60
|
+
* daemon tracks the transaction under. Exported as a struct for the same
|
|
61
|
+
* client-side validation reason as {@link SendTransactionDryRunResultStruct}.
|
|
62
|
+
*/
|
|
63
|
+
export declare const SendTransactionBroadcastResultStruct: import("@metamask/superstruct").Struct<{
|
|
64
|
+
status: string;
|
|
65
|
+
transactionHash: string;
|
|
66
|
+
transactionId: string;
|
|
67
|
+
}, {
|
|
68
|
+
transactionHash: import("@metamask/superstruct").Struct<string, null>;
|
|
69
|
+
transactionId: import("@metamask/superstruct").Struct<string, null>;
|
|
70
|
+
status: import("@metamask/superstruct").Struct<string, null>;
|
|
71
|
+
}>;
|
|
72
|
+
export type SendTransactionDryRunResult = Infer<typeof SendTransactionDryRunResultStruct>;
|
|
73
|
+
export type SendTransactionBroadcastResult = Infer<typeof SendTransactionBroadcastResultStruct>;
|
|
74
|
+
export type SendTransactionResult = SendTransactionDryRunResult | SendTransactionBroadcastResult;
|
|
75
|
+
/**
|
|
76
|
+
* Add and broadcast a transaction through the daemon-hosted
|
|
77
|
+
* `TransactionController`, returning a serializable result.
|
|
78
|
+
*
|
|
79
|
+
* `TransactionController:addTransaction` returns `{ transactionMeta, result }`
|
|
80
|
+
* where `result` is a `Promise<hash>` that resolves once the transaction is
|
|
81
|
+
* signed and broadcast. That promise is not JSON-serializable, so it cannot
|
|
82
|
+
* travel back over the daemon's JSON-RPC socket via the generic `call`
|
|
83
|
+
* dispatch — hence this dedicated handler, which awaits the broadcast
|
|
84
|
+
* server-side and returns only the resolved hash (and id/status).
|
|
85
|
+
*
|
|
86
|
+
* The network client is resolved from `chainId` (via `NetworkController`) when
|
|
87
|
+
* `networkClientId` is not given directly, and `from` defaults to the selected
|
|
88
|
+
* account. The transaction is submitted as `isInternal` (the daemon is driven
|
|
89
|
+
* only by its owner over the `0600` same-user socket), which skips
|
|
90
|
+
* origin/permitted-account validation; its approval request is auto-accepted
|
|
91
|
+
* by the daemon's auto-approval subscription.
|
|
92
|
+
*
|
|
93
|
+
* When `dryRun` is set, the network client and sender are resolved and the
|
|
94
|
+
* params validated, but nothing is added or broadcast — the resolved plan is
|
|
95
|
+
* returned so the CLI can preview it before the user confirms.
|
|
96
|
+
*
|
|
97
|
+
* @param messenger - The wallet root messenger.
|
|
98
|
+
* @param params - Validated `sendTransaction` params.
|
|
99
|
+
* @returns The dry-run plan, or the broadcast hash with its id and status.
|
|
100
|
+
*/
|
|
101
|
+
export declare function runSendTransaction(messenger: Readonly<RootMessenger<DefaultActions, DefaultEvents>>, params: SendTransactionParams): Promise<SendTransactionResult>;
|
|
102
|
+
//# sourceMappingURL=send-transaction.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"send-transaction.d.mts","sourceRoot":"","sources":["../../src/daemon/send-transaction.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,KAAK,EAAE,8BAA8B;AAGnD,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EACb,aAAa,EACd,yBAAyB;AAqB1B;;;;;;;;;GASG;AACH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;EAmCvC,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAE9E;;;;;GAKG;AACH,eAAO,MAAM,iCAAiC;;;;;;;;;;;;EAM5C,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,oCAAoC;;;;;;;;EAI/C,CAAC;AAEH,MAAM,MAAM,2BAA2B,GAAG,KAAK,CAC7C,OAAO,iCAAiC,CACzC,CAAC;AAEF,MAAM,MAAM,8BAA8B,GAAG,KAAK,CAChD,OAAO,oCAAoC,CAC5C,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAC7B,2BAA2B,GAC3B,8BAA8B,CAAC;AAEnC;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,QAAQ,CAAC,aAAa,CAAC,cAAc,EAAE,aAAa,CAAC,CAAC,EACjE,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC,CAiEhC"}
|