@deeeed/metamask-harness 0.80.0 → 0.81.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/adapters/manifest.json +14 -30
  3. package/adapters/terminal/launch.mjs +17 -13
  4. package/adapters/terminal/lib/mainnet-guard.mjs +9 -0
  5. package/adapters/terminal/lib/readiness.mjs +20 -12
  6. package/adapters/terminal/policy.mjs +35 -0
  7. package/adapters/terminal/verify.mjs +10 -3
  8. package/adapters/terminal/wallet-host.mjs +43 -225
  9. package/dist/adapters/core/actions.js +4 -1
  10. package/dist/adapters/extension/actions.js +6 -2
  11. package/dist/adapters/extension/network-observer.js +13 -0
  12. package/dist/adapters/extension/run.js +112 -5
  13. package/dist/adapters/mobile/actions.js +4 -1
  14. package/dist/adapters/mobile/network-observer.js +68 -0
  15. package/dist/adapters/mobile/performance-observer.js +1 -3
  16. package/dist/adapters/mobile/run.js +32 -9
  17. package/dist/adapters/perps-order-inputs.js +36 -0
  18. package/dist/adapters/proof-failure.js +11 -0
  19. package/dist/adapters/terminal/actions.js +4 -1
  20. package/dist/adapters/terminal/doctor-checks.js +2 -0
  21. package/dist/adapters/terminal/launch.js +3 -0
  22. package/dist/adapters/terminal/overlay.js +8 -1
  23. package/dist/adapters/terminal/run.js +8 -3
  24. package/dist/adapters/terminal/surface.js +2 -0
  25. package/dist/adapters.js +20 -4
  26. package/dist/cli.js +31 -6
  27. package/dist/commands/check.js +30 -6
  28. package/dist/commands/completion-candidates.js +5 -5
  29. package/dist/commands/self-test.js +4 -3
  30. package/dist/engine.js +57 -0
  31. package/dist/funding-execution-context.js +81 -0
  32. package/dist/mm-harness-cli.js +3 -3
  33. package/dist/performance-observation.js +1 -3
  34. package/dist/recipe-assistance-context.js +6 -7
  35. package/dist/runner.js +2 -1
  36. package/docs/CONTRIBUTING.md +4 -2
  37. package/docs/RECIPES.md +31 -3
  38. package/library/actions/core/perps/_controller.mjs +24 -28
  39. package/library/actions/core/perps/_rewards.mjs +186 -0
  40. package/library/actions/core/perps/close_positions.mjs +1 -1
  41. package/library/actions/core/perps/place_order.mjs +167 -45
  42. package/library/actions/core/perps/quote_fees.mjs +7 -4
  43. package/library/actions/core/wallet/list_accounts.mjs +1 -1
  44. package/library/actions/extension/perps/close_visible_position.mjs +5 -0
  45. package/library/actions/extension/perps/edit_margin.mjs +4 -0
  46. package/library/actions/extension/perps/mutation-receipt.mjs +95 -3
  47. package/library/actions/extension/perps/perps.mjs +320 -3
  48. package/library/actions/extension/perps/place_order.mjs +3 -1
  49. package/library/actions/extension/perps/update_position_tpsl.mjs +4 -0
  50. package/library/actions/extension/platform/cdp.mjs +71 -3
  51. package/library/actions/mobile/perps/perps.mjs +216 -11
  52. package/library/actions/mobile/perps/place_order.mjs +3 -1
  53. package/library/actions/shared/perps/order-policy.mjs +177 -0
  54. package/library/actions/{core/wallet/_fixture-accounts.mjs → shared/wallet/fixture-accounts.mjs} +18 -3
  55. package/library/actions/terminal/app/launch.mjs +3 -2
  56. package/library/actions/terminal/platform/hud.mjs +2 -1
  57. package/library/actions/terminal/platform/page.mjs +2 -1
  58. package/library/actions/terminal/wallet/_signature-log.mjs +40 -161
  59. package/library/actions/terminal/wallet/assert_signatures.mjs +6 -12
  60. package/library/actions/terminal/wallet/read_signatures.mjs +10 -9
  61. package/library/manifests/core.action-manifest.json +6 -2
  62. package/library/manifests/extension.action-manifest.json +4 -0
  63. package/library/manifests/mobile.action-manifest.json +12 -0
  64. package/package.json +4 -4
  65. package/site/assets/help-recipes.json +1 -0
  66. package/adapters/terminal/lib/origin.mjs +0 -30
  67. package/adapters/terminal/lib/page-script.mjs +0 -246
  68. package/adapters/terminal/lib/strict-wallet.mjs +0 -138
  69. package/dist/commands/call.js +0 -671
  70. package/dist/commands/list-executables.js +0 -245
  71. package/dist/commands/manifest.js +0 -477
  72. package/dist/commands/run-engine.js +0 -1301
  73. package/dist/commands/run.js +0 -730
  74. package/dist/discovery.js +0 -15
  75. package/dist/metamask-action-validation.js +0 -68
  76. package/dist/network-observation.js +0 -290
@@ -1,138 +0,0 @@
1
- // EIP-1193 test wallet that enforces MetaMask's typed-data rule: reject
2
- // eth_signTypedData_v4 whose domain chainId differs from the active chain.
3
- // Signs with a viem account held by the wallet host; never exposes key
4
- // material. Ported from the TAT-4032 migration e2e strict wallet.
5
-
6
- export const DEFAULT_KNOWN_CHAINS = Object.freeze([1, 10, 137, 8453, 42161, 421614, 59144, 59141, 11155111]);
7
-
8
- const READ_RPC = {
9
- 1: 'https://ethereum-rpc.publicnode.com',
10
- 42161: 'https://arbitrum-one-rpc.publicnode.com',
11
- 421614: 'https://arbitrum-sepolia-rpc.publicnode.com',
12
- 59144: 'https://linea-rpc.publicnode.com',
13
- };
14
-
15
- // Only these reads go to the public RPC. Anything else the wallet does not
16
- // answer itself (eth_sendRawTransaction, account or filter methods, unknown
17
- // wallet_* calls) is refused before any network request.
18
- export const READ_ONLY_RPC_METHODS = Object.freeze([
19
- 'eth_blockNumber',
20
- 'eth_call',
21
- 'eth_estimateGas',
22
- 'eth_feeHistory',
23
- 'eth_gasPrice',
24
- 'eth_getBalance',
25
- 'eth_getBlockByHash',
26
- 'eth_getBlockByNumber',
27
- 'eth_getCode',
28
- 'eth_getLogs',
29
- 'eth_getStorageAt',
30
- 'eth_getTransactionByHash',
31
- 'eth_getTransactionCount',
32
- 'eth_getTransactionReceipt',
33
- 'eth_maxPriorityFeePerGas',
34
- 'web3_clientVersion',
35
- ]);
36
- const READ_ONLY = new Set(READ_ONLY_RPC_METHODS);
37
-
38
- function rpcError(message, code) {
39
- return Object.assign(new Error(message), { code });
40
- }
41
-
42
- function toBigIntDeep(types, primaryType, message) {
43
- const out = {};
44
- for (const field of types[primaryType] ?? []) {
45
- const value = message[field.name];
46
- if (value === undefined) continue;
47
- if (/^u?int\d*$/u.test(field.type)) out[field.name] = BigInt(value);
48
- else if (types[field.type]) out[field.name] = toBigIntDeep(types, field.type, value);
49
- else out[field.name] = value;
50
- }
51
- return out;
52
- }
53
-
54
- export function createStrictWallet({
55
- account,
56
- chainId = 42161,
57
- knownChains = DEFAULT_KNOWN_CHAINS,
58
- refuseSwitch = false,
59
- fetchImpl = globalThis.fetch,
60
- }) {
61
- let activeChain = chainId;
62
- const known = new Set(knownChains);
63
- let rpcId = 1;
64
-
65
- async function request({ method, params = [] }) {
66
- switch (method) {
67
- case 'eth_chainId':
68
- return `0x${activeChain.toString(16)}`;
69
- case 'net_version':
70
- return String(activeChain);
71
- case 'eth_accounts':
72
- case 'eth_requestAccounts':
73
- return [account.address];
74
- case 'wallet_requestPermissions':
75
- case 'wallet_getPermissions':
76
- return [{ parentCapability: 'eth_accounts', caveats: [{ type: 'restrictReturnedAccounts', value: [account.address.toLowerCase()] }] }];
77
- case 'wallet_revokePermissions':
78
- return null;
79
- case 'metamask_getProviderState':
80
- return { accounts: [account.address.toLowerCase()], chainId: `0x${activeChain.toString(16)}`, isUnlocked: true, networkVersion: String(activeChain) };
81
- case 'wallet_switchEthereumChain': {
82
- const id = Number.parseInt(params[0].chainId, 16);
83
- if (refuseSwitch) throw rpcError('User rejected the request.', 4001);
84
- if (!known.has(id)) throw rpcError(`Unrecognized chain ID ${params[0].chainId}`, 4902);
85
- activeChain = id;
86
- return null;
87
- }
88
- case 'wallet_addEthereumChain':
89
- known.add(Number.parseInt(params[0].chainId, 16));
90
- return null;
91
- case 'eth_signTypedData_v4': {
92
- const [from, raw] = params;
93
- const data = typeof raw === 'string' ? JSON.parse(raw) : raw;
94
- const domainChain = Number(BigInt(data.domain.chainId));
95
- if (String(from).toLowerCase() !== account.address.toLowerCase()) throw rpcError('Unknown account', 4100);
96
- if (domainChain !== activeChain) {
97
- throw rpcError(`Provided chainId "${domainChain}" must match the active chainId "${activeChain}"`, -32602);
98
- }
99
- const types = { ...data.types };
100
- delete types.EIP712Domain;
101
- return account.signTypedData({
102
- domain: { ...data.domain, chainId: domainChain },
103
- types,
104
- primaryType: data.primaryType,
105
- message: toBigIntDeep(types, data.primaryType, data.message),
106
- });
107
- }
108
- case 'personal_sign': {
109
- const [message, from] = params;
110
- if (String(from).toLowerCase() !== account.address.toLowerCase()) throw rpcError('Unknown account', 4100);
111
- return account.signMessage({ message: { raw: message } });
112
- }
113
- case 'eth_sendTransaction':
114
- case 'eth_sign':
115
- throw rpcError(`${method} is not supported by the strict test wallet`, 4200);
116
- default: {
117
- if (!READ_ONLY.has(method)) throw rpcError(`${method} is not supported by the strict test wallet`, 4200);
118
- const url = READ_RPC[activeChain];
119
- if (!url) throw rpcError(`No read RPC for chain ${activeChain}`, 4200);
120
- const response = await fetchImpl(url, {
121
- method: 'POST',
122
- headers: { 'content-type': 'application/json' },
123
- body: JSON.stringify({ jsonrpc: '2.0', id: rpcId++, method, params }),
124
- });
125
- const body = await response.json();
126
- if (body.error) throw rpcError(body.error.message, body.error.code);
127
- return body.result;
128
- }
129
- }
130
- }
131
-
132
- return {
133
- request,
134
- get chainId() {
135
- return activeChain;
136
- },
137
- };
138
- }