@deeeed/metamask-harness 0.35.0 → 0.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +39 -0
- package/README.md +9 -1
- package/adapters/extension/artifact-runtime-state.cjs +128 -0
- package/adapters/extension/check-infura-readiness.cjs +102 -0
- package/adapters/extension/inject.mjs +2 -0
- package/adapters/extension/launch-browser.cjs +22 -0
- package/adapters/extension/live.sh +103 -18
- package/adapters/extension/readiness.mjs +77 -36
- package/adapters/extension/snapshot-dist.sh +88 -3
- package/adapters/extension/start-watch.sh +15 -0
- package/adapters/extension/verify.sh +6 -2
- package/adapters/extension/wallet-fixture-state.cjs +3 -1
- package/adapters/manifest.json +25 -1
- package/adapters/mobile/bridge-runtime/cdp-bridge.cjs +73 -42
- package/adapters/mobile/reset-app-data.sh +154 -0
- package/adapters/shared/log-tui.mjs +1 -1
- package/dist/adapters/extension/artifact-integrity.js +38 -0
- package/dist/adapters/extension/extension-id.js +23 -4
- package/dist/adapters/extension/product-config.js +29 -1
- package/dist/adapters/extension/release-artifact.js +386 -0
- package/dist/adapters/extension/runtime-decision.js +161 -20
- package/dist/adapters/extension/runtime.js +127 -0
- package/dist/adapters/mobile/release-artifact-state.js +124 -0
- package/dist/adapters/mobile/release-artifact.js +295 -0
- package/dist/adapters.js +29 -4
- package/dist/cli-commands.js +1 -1
- package/dist/cli.js +2 -2
- package/dist/command-contract.js +17 -1
- package/dist/commands/call.js +2 -1
- package/dist/commands/device-target.js +5 -0
- package/dist/commands/fixtures.js +106 -31
- package/dist/commands/launch/extension.js +92 -7
- package/dist/commands/launch/index.js +13 -0
- package/dist/commands/launch/mobile.js +2 -0
- package/dist/commands/provision.js +2 -0
- package/dist/commands/run-engine.js +89 -5
- package/dist/commands/run.js +3 -1
- package/dist/commands/runtime-launch.js +178 -10
- package/dist/heal-bounds.js +1 -1
- package/dist/live-adapter-contract.js +3 -1
- package/dist/metamask-action-validation.js +47 -1
- package/dist/mm-harness-cli.js +37 -4
- package/dist/recipe-security.js +3 -0
- package/dist/run-diagnostics.js +1 -1
- package/docs/RECIPES.md +29 -0
- package/docs/RELEASE-QA-CAPABILITY-MAP.md +150 -0
- package/library/actions/extension/perps/perps.mjs +2 -0
- package/library/actions/extension/perps/read_snapshot.mjs +470 -0
- package/library/actions/extension/platform/cdp.mjs +6 -3
- package/library/actions/extension/wallet/import.mjs +201 -0
- package/library/actions/extension/wallet/reset.mjs +98 -0
- package/library/actions/extension/wallet/secret-input.mjs +98 -0
- package/library/actions/extension/wallet/state.mjs +1 -0
- package/library/actions/mobile/analytics/consent-settings.mjs +112 -0
- package/library/actions/mobile/analytics/set_consent.mjs +4 -112
- package/library/actions/mobile/platform/bridge.mjs +8 -0
- package/library/actions/mobile/platform/observe-ui.mjs +84 -2
- package/library/actions/mobile/ui/native-navigation.mjs +225 -0
- package/library/actions/mobile/ui/navigate.mjs +7 -0
- package/library/actions/mobile/wallet/import.mjs +328 -0
- package/library/actions/mobile/wallet/native-ui.mjs +493 -0
- package/library/actions/mobile/wallet/read_state.mjs +16 -0
- package/library/actions/mobile/wallet/reset-helper.mjs +99 -0
- package/library/actions/mobile/wallet/reset.mjs +20 -0
- package/library/actions/shared/ui/locators.mjs +7 -0
- package/library/actions/shared/wallet/import-source.mjs +101 -0
- package/library/manifests/extension.action-manifest.json +228 -0
- package/library/manifests/mobile.action-manifest.json +124 -0
- package/library/recipes/extension/runner/action-validation.recipe.json +12 -1
- package/library/recipes/wallet/import.recipe.json +102 -0
- package/library/recipes/wallet/reset-import.recipe.json +107 -0
- package/package.json +1 -1
- package/scripts/completions.sh +2 -2
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
|
|
4
|
+
import { mnemonicToAccount } from 'viem/accounts';
|
|
5
|
+
|
|
6
|
+
import { walletFixturePath } from '../../harness-exports.mjs';
|
|
7
|
+
|
|
8
|
+
const ENV_NAME = /^[A-Z_][A-Z0-9_]*$/u;
|
|
9
|
+
|
|
10
|
+
function environmentValue(input, name) {
|
|
11
|
+
if (!ENV_NAME.test(name)) {
|
|
12
|
+
throw new Error(`Wallet import environment name is invalid: ${name}`);
|
|
13
|
+
}
|
|
14
|
+
return input.context?.env?.[name] ?? process.env[name];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async function optionalFixture(projectRoot) {
|
|
18
|
+
const absolutePath = walletFixturePath(projectRoot);
|
|
19
|
+
try {
|
|
20
|
+
return {
|
|
21
|
+
absolutePath,
|
|
22
|
+
relativePath: path.relative(projectRoot, absolutePath),
|
|
23
|
+
value: JSON.parse(await readFile(absolutePath, 'utf8')),
|
|
24
|
+
};
|
|
25
|
+
} catch (error) {
|
|
26
|
+
if (error?.code === 'ENOENT') return null;
|
|
27
|
+
throw error;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export async function resolveWalletImportCredentials(input) {
|
|
32
|
+
const source = String(input.node?.credential_source ?? 'auto');
|
|
33
|
+
if (!['auto', 'environment', 'fixture'].includes(source)) {
|
|
34
|
+
throw new Error('metamask.wallet.import credential_source must be auto, environment, or fixture.');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const srpEnv = String(input.node?.srp_env ?? 'MM_HARNESS_WALLET_SRP');
|
|
38
|
+
const passwordEnv = String(input.node?.password_env ?? 'MM_HARNESS_WALLET_PASSWORD');
|
|
39
|
+
const environmentMnemonic = source === 'fixture'
|
|
40
|
+
? undefined
|
|
41
|
+
: environmentValue(input, srpEnv)?.trim();
|
|
42
|
+
const environmentPassword = source === 'fixture'
|
|
43
|
+
? undefined
|
|
44
|
+
: environmentValue(input, passwordEnv);
|
|
45
|
+
const fixture = source === 'environment' || (environmentMnemonic && environmentPassword)
|
|
46
|
+
? null
|
|
47
|
+
: await optionalFixture(input.context.projectRoot);
|
|
48
|
+
const fixtureMnemonic = source === 'environment'
|
|
49
|
+
? undefined
|
|
50
|
+
: fixture?.value?.accounts?.find((account) => account?.type === 'mnemonic')?.value?.trim();
|
|
51
|
+
const mnemonic = environmentMnemonic || fixtureMnemonic;
|
|
52
|
+
const password = environmentPassword ||
|
|
53
|
+
(source === 'environment' ? undefined : fixture?.value?.password);
|
|
54
|
+
|
|
55
|
+
if (!mnemonic) {
|
|
56
|
+
throw new Error(
|
|
57
|
+
`Wallet import requires ${srpEnv} or a mnemonic account in temp/recipe/runtime/wallet-fixture.json.\n` +
|
|
58
|
+
` Next: export ${srpEnv}=<secret-recovery-phrase>`,
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
if (typeof password !== 'string' || password.length === 0) {
|
|
62
|
+
throw new Error(
|
|
63
|
+
`Wallet import requires ${passwordEnv} or password in temp/recipe/runtime/wallet-fixture.json.\n` +
|
|
64
|
+
` Next: export ${passwordEnv}=<wallet-password>`,
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
let expectedAddress;
|
|
69
|
+
try {
|
|
70
|
+
expectedAddress = mnemonicToAccount(mnemonic).address.toLowerCase();
|
|
71
|
+
} catch {
|
|
72
|
+
throw new Error('Wallet import Secret Recovery Phrase is invalid.');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
mnemonic,
|
|
77
|
+
password,
|
|
78
|
+
expectedAddress,
|
|
79
|
+
source: environmentMnemonic ? 'environment' : 'fixture',
|
|
80
|
+
sourceName: environmentMnemonic ? srpEnv : fixture?.relativePath,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function walletImportMethod(input) {
|
|
85
|
+
const method = String(input.node?.method ?? 'auto');
|
|
86
|
+
if (!['auto', 'profile', 'ui'].includes(method)) {
|
|
87
|
+
throw new Error('metamask.wallet.import method must be auto, profile, or ui.');
|
|
88
|
+
}
|
|
89
|
+
return method;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function validateWalletImportOptions(platform, node) {
|
|
93
|
+
const interests = Array.isArray(node?.interests) ? node.interests : [];
|
|
94
|
+
const metametrics = node?.metametrics === true || node?.metametrics === 'true';
|
|
95
|
+
if (platform === 'extension' && interests.length > 0) {
|
|
96
|
+
throw new Error('Wallet import interests are supported only on Mobile.');
|
|
97
|
+
}
|
|
98
|
+
if (platform === 'mobile' && interests.length > 0 && !metametrics) {
|
|
99
|
+
throw new Error('Mobile onboarding interests require metametrics=true.');
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -1099,6 +1099,45 @@
|
|
|
1099
1099
|
],
|
|
1100
1100
|
"execution_capabilities": []
|
|
1101
1101
|
},
|
|
1102
|
+
"metamask.wallet.validate_import": {
|
|
1103
|
+
"description": "Validate wallet recovery credentials and derive the expected primary address without launching or mutating the app.",
|
|
1104
|
+
"schema": {
|
|
1105
|
+
"type": "object",
|
|
1106
|
+
"properties": {
|
|
1107
|
+
"credential_source": {
|
|
1108
|
+
"type": "string",
|
|
1109
|
+
"enum": ["auto", "environment", "fixture"]
|
|
1110
|
+
},
|
|
1111
|
+
"srp_env": {
|
|
1112
|
+
"type": "string"
|
|
1113
|
+
},
|
|
1114
|
+
"password_env": {
|
|
1115
|
+
"type": "string"
|
|
1116
|
+
},
|
|
1117
|
+
"metametrics": {
|
|
1118
|
+
"type": "boolean"
|
|
1119
|
+
},
|
|
1120
|
+
"interests": {
|
|
1121
|
+
"type": "array",
|
|
1122
|
+
"items": {
|
|
1123
|
+
"type": "string"
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
},
|
|
1127
|
+
"additionalProperties": false
|
|
1128
|
+
},
|
|
1129
|
+
"examples": [
|
|
1130
|
+
{
|
|
1131
|
+
"action": "metamask.wallet.validate_import",
|
|
1132
|
+
"credential_source": "auto",
|
|
1133
|
+
"intent": "Validate recovery credentials before resetting a wallet",
|
|
1134
|
+
"next": "done"
|
|
1135
|
+
}
|
|
1136
|
+
],
|
|
1137
|
+
"execution_capabilities": [
|
|
1138
|
+
"host-read-export"
|
|
1139
|
+
]
|
|
1140
|
+
},
|
|
1102
1141
|
"metamask.wallet.setup": {
|
|
1103
1142
|
"description": "Import the wallet fixture accounts and password so the app starts from a known signed-in state.",
|
|
1104
1143
|
"schema": {
|
|
@@ -1117,6 +1156,94 @@
|
|
|
1117
1156
|
"app-mutation"
|
|
1118
1157
|
]
|
|
1119
1158
|
},
|
|
1159
|
+
"metamask.wallet.import": {
|
|
1160
|
+
"description": "Make the wallet ready by reusing a fixture-backed profile or importing the primary mnemonic through visible onboarding UI.",
|
|
1161
|
+
"schema": {
|
|
1162
|
+
"type": "object",
|
|
1163
|
+
"properties": {
|
|
1164
|
+
"method": {
|
|
1165
|
+
"type": "string",
|
|
1166
|
+
"enum": ["auto", "profile", "ui"]
|
|
1167
|
+
},
|
|
1168
|
+
"credential_source": {
|
|
1169
|
+
"type": "string",
|
|
1170
|
+
"enum": ["auto", "environment", "fixture"]
|
|
1171
|
+
},
|
|
1172
|
+
"srp_env": {
|
|
1173
|
+
"type": "string"
|
|
1174
|
+
},
|
|
1175
|
+
"password_env": {
|
|
1176
|
+
"type": "string"
|
|
1177
|
+
},
|
|
1178
|
+
"metametrics": {
|
|
1179
|
+
"type": "boolean",
|
|
1180
|
+
"default": false,
|
|
1181
|
+
"description": "Enable MetaMetrics during visible onboarding."
|
|
1182
|
+
},
|
|
1183
|
+
"biometrics": {
|
|
1184
|
+
"type": "boolean",
|
|
1185
|
+
"default": false,
|
|
1186
|
+
"description": "Mobile-only biometric onboarding preference; ignored on Extension."
|
|
1187
|
+
},
|
|
1188
|
+
"notifications": {
|
|
1189
|
+
"type": "boolean",
|
|
1190
|
+
"default": false,
|
|
1191
|
+
"description": "Mobile-only push notification onboarding preference; ignored on Extension."
|
|
1192
|
+
},
|
|
1193
|
+
"skip_wallet_tour": {
|
|
1194
|
+
"type": "boolean",
|
|
1195
|
+
"default": true,
|
|
1196
|
+
"description": "Mobile-only wallet-home tour preference; ignored on Extension."
|
|
1197
|
+
},
|
|
1198
|
+
"interests": {
|
|
1199
|
+
"type": "array",
|
|
1200
|
+
"items": {
|
|
1201
|
+
"type": "string",
|
|
1202
|
+
"enum": ["swap_tokens", "trade_perpetuals", "prediction_markets", "send_receive_crypto", "earn_and_spend", "use_other_crypto_apps"]
|
|
1203
|
+
},
|
|
1204
|
+
"default": [],
|
|
1205
|
+
"description": "Mobile-only onboarding interests; ignored when empty on Extension."
|
|
1206
|
+
},
|
|
1207
|
+
"timeout_ms": {
|
|
1208
|
+
"type": "number"
|
|
1209
|
+
}
|
|
1210
|
+
},
|
|
1211
|
+
"additionalProperties": false
|
|
1212
|
+
},
|
|
1213
|
+
"examples": [
|
|
1214
|
+
{
|
|
1215
|
+
"action": "metamask.wallet.import",
|
|
1216
|
+
"method": "auto",
|
|
1217
|
+
"intent": "Use an existing fixture profile or import through onboarding",
|
|
1218
|
+
"next": "done"
|
|
1219
|
+
}
|
|
1220
|
+
],
|
|
1221
|
+
"execution_capabilities": [
|
|
1222
|
+
"app-mutation"
|
|
1223
|
+
]
|
|
1224
|
+
},
|
|
1225
|
+
"metamask.wallet.reset": {
|
|
1226
|
+
"description": "Delete the current wallet through the visible client reset flow and reach fresh onboarding.",
|
|
1227
|
+
"schema": {
|
|
1228
|
+
"type": "object",
|
|
1229
|
+
"properties": {
|
|
1230
|
+
"timeout_ms": {
|
|
1231
|
+
"type": "number"
|
|
1232
|
+
}
|
|
1233
|
+
},
|
|
1234
|
+
"additionalProperties": false
|
|
1235
|
+
},
|
|
1236
|
+
"examples": [
|
|
1237
|
+
{
|
|
1238
|
+
"action": "metamask.wallet.reset",
|
|
1239
|
+
"intent": "Reset the wallet through visible UI before importing it again",
|
|
1240
|
+
"next": "done"
|
|
1241
|
+
}
|
|
1242
|
+
],
|
|
1243
|
+
"execution_capabilities": [
|
|
1244
|
+
"app-mutation"
|
|
1245
|
+
]
|
|
1246
|
+
},
|
|
1120
1247
|
"metamask.wallet.ensure_unlocked": {
|
|
1121
1248
|
"description": "Unlock the wallet with the fixture password when it is currently locked.",
|
|
1122
1249
|
"schema": {
|
|
@@ -1321,6 +1448,107 @@
|
|
|
1321
1448
|
],
|
|
1322
1449
|
"execution_capabilities": []
|
|
1323
1450
|
},
|
|
1451
|
+
"metamask.perps.read_snapshot": {
|
|
1452
|
+
"description": "Read a bounded, redacted snapshot of live Extension Perps state through product background APIs.",
|
|
1453
|
+
"schema": {
|
|
1454
|
+
"type": "object",
|
|
1455
|
+
"properties": {
|
|
1456
|
+
"include": {
|
|
1457
|
+
"type": "array",
|
|
1458
|
+
"items": {
|
|
1459
|
+
"type": "string",
|
|
1460
|
+
"enum": [
|
|
1461
|
+
"account",
|
|
1462
|
+
"markets",
|
|
1463
|
+
"positions",
|
|
1464
|
+
"orders",
|
|
1465
|
+
"history",
|
|
1466
|
+
"watchlist"
|
|
1467
|
+
]
|
|
1468
|
+
},
|
|
1469
|
+
"minItems": 1,
|
|
1470
|
+
"default": [
|
|
1471
|
+
"account",
|
|
1472
|
+
"markets",
|
|
1473
|
+
"positions",
|
|
1474
|
+
"orders",
|
|
1475
|
+
"history",
|
|
1476
|
+
"watchlist"
|
|
1477
|
+
],
|
|
1478
|
+
"description": "Sections to request. Every requested section must be available or the action fails."
|
|
1479
|
+
},
|
|
1480
|
+
"market": {
|
|
1481
|
+
"type": "string",
|
|
1482
|
+
"description": "Optional single market filter."
|
|
1483
|
+
},
|
|
1484
|
+
"markets": {
|
|
1485
|
+
"type": "array",
|
|
1486
|
+
"items": {
|
|
1487
|
+
"type": "string"
|
|
1488
|
+
},
|
|
1489
|
+
"maxItems": 100,
|
|
1490
|
+
"description": "Optional market filters applied to market-scoped sections."
|
|
1491
|
+
},
|
|
1492
|
+
"history": {
|
|
1493
|
+
"type": "object",
|
|
1494
|
+
"properties": {
|
|
1495
|
+
"start_time_ms": {
|
|
1496
|
+
"type": "integer",
|
|
1497
|
+
"minimum": 0,
|
|
1498
|
+
"description": "Inclusive history start time in Unix milliseconds. Defaults to 30 days before end_time_ms."
|
|
1499
|
+
},
|
|
1500
|
+
"end_time_ms": {
|
|
1501
|
+
"type": "integer",
|
|
1502
|
+
"minimum": 0,
|
|
1503
|
+
"description": "Inclusive history end time in Unix milliseconds. Defaults to the current time."
|
|
1504
|
+
},
|
|
1505
|
+
"account_id": {
|
|
1506
|
+
"type": "string",
|
|
1507
|
+
"description": "Optional CAIP account ID passed to the product history API; the value is not returned."
|
|
1508
|
+
},
|
|
1509
|
+
"limit": {
|
|
1510
|
+
"type": "integer",
|
|
1511
|
+
"minimum": 1,
|
|
1512
|
+
"default": 100,
|
|
1513
|
+
"description": "Maximum history items returned after product filtering."
|
|
1514
|
+
}
|
|
1515
|
+
},
|
|
1516
|
+
"additionalProperties": false
|
|
1517
|
+
},
|
|
1518
|
+
"max_items_per_section": {
|
|
1519
|
+
"type": "integer",
|
|
1520
|
+
"minimum": 1,
|
|
1521
|
+
"default": 100,
|
|
1522
|
+
"description": "Maximum normalized items returned for each requested list section."
|
|
1523
|
+
},
|
|
1524
|
+
"timeout_ms": {
|
|
1525
|
+
"type": "integer",
|
|
1526
|
+
"minimum": 1000,
|
|
1527
|
+
"default": 20000,
|
|
1528
|
+
"description": "Per-request background API timeout."
|
|
1529
|
+
}
|
|
1530
|
+
},
|
|
1531
|
+
"additionalProperties": false
|
|
1532
|
+
},
|
|
1533
|
+
"examples": [
|
|
1534
|
+
{
|
|
1535
|
+
"action": "metamask.perps.read_snapshot",
|
|
1536
|
+
"include": [
|
|
1537
|
+
"account",
|
|
1538
|
+
"markets",
|
|
1539
|
+
"positions",
|
|
1540
|
+
"orders"
|
|
1541
|
+
],
|
|
1542
|
+
"markets": [
|
|
1543
|
+
"BTC",
|
|
1544
|
+
"ETH"
|
|
1545
|
+
],
|
|
1546
|
+
"intent": "Read the bounded Perps state needed for release validation",
|
|
1547
|
+
"next": "done"
|
|
1548
|
+
}
|
|
1549
|
+
],
|
|
1550
|
+
"execution_capabilities": []
|
|
1551
|
+
},
|
|
1324
1552
|
"metamask.perps.read_positions": {
|
|
1325
1553
|
"description": "extension Read live Perps positions; without a selector, return all live positions.",
|
|
1326
1554
|
"schema": {
|
|
@@ -1237,6 +1237,45 @@
|
|
|
1237
1237
|
],
|
|
1238
1238
|
"execution_capabilities": []
|
|
1239
1239
|
},
|
|
1240
|
+
"metamask.wallet.validate_import": {
|
|
1241
|
+
"description": "Validate wallet recovery credentials and derive the expected primary address without launching or mutating the app.",
|
|
1242
|
+
"schema": {
|
|
1243
|
+
"type": "object",
|
|
1244
|
+
"properties": {
|
|
1245
|
+
"credential_source": {
|
|
1246
|
+
"type": "string",
|
|
1247
|
+
"enum": ["auto", "environment", "fixture"]
|
|
1248
|
+
},
|
|
1249
|
+
"srp_env": {
|
|
1250
|
+
"type": "string"
|
|
1251
|
+
},
|
|
1252
|
+
"password_env": {
|
|
1253
|
+
"type": "string"
|
|
1254
|
+
},
|
|
1255
|
+
"metametrics": {
|
|
1256
|
+
"type": "boolean"
|
|
1257
|
+
},
|
|
1258
|
+
"interests": {
|
|
1259
|
+
"type": "array",
|
|
1260
|
+
"items": {
|
|
1261
|
+
"type": "string"
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
},
|
|
1265
|
+
"additionalProperties": false
|
|
1266
|
+
},
|
|
1267
|
+
"examples": [
|
|
1268
|
+
{
|
|
1269
|
+
"action": "metamask.wallet.validate_import",
|
|
1270
|
+
"credential_source": "auto",
|
|
1271
|
+
"intent": "Validate recovery credentials before resetting a wallet",
|
|
1272
|
+
"next": "done"
|
|
1273
|
+
}
|
|
1274
|
+
],
|
|
1275
|
+
"execution_capabilities": [
|
|
1276
|
+
"host-read-export"
|
|
1277
|
+
]
|
|
1278
|
+
},
|
|
1240
1279
|
"metamask.wallet.setup": {
|
|
1241
1280
|
"description": "Import the wallet fixture accounts and password so the app starts from a known signed-in state.",
|
|
1242
1281
|
"schema": {
|
|
@@ -1253,6 +1292,91 @@
|
|
|
1253
1292
|
],
|
|
1254
1293
|
"execution_capabilities": ["app-mutation"]
|
|
1255
1294
|
},
|
|
1295
|
+
"metamask.wallet.import": {
|
|
1296
|
+
"description": "Make the wallet ready by reusing a fixture-backed profile or importing the primary mnemonic through visible onboarding UI.",
|
|
1297
|
+
"schema": {
|
|
1298
|
+
"type": "object",
|
|
1299
|
+
"properties": {
|
|
1300
|
+
"method": {
|
|
1301
|
+
"type": "string",
|
|
1302
|
+
"enum": ["auto", "profile", "ui"]
|
|
1303
|
+
},
|
|
1304
|
+
"credential_source": {
|
|
1305
|
+
"type": "string",
|
|
1306
|
+
"enum": ["auto", "environment", "fixture"]
|
|
1307
|
+
},
|
|
1308
|
+
"srp_env": {
|
|
1309
|
+
"type": "string"
|
|
1310
|
+
},
|
|
1311
|
+
"password_env": {
|
|
1312
|
+
"type": "string"
|
|
1313
|
+
},
|
|
1314
|
+
"metametrics": {
|
|
1315
|
+
"type": "boolean",
|
|
1316
|
+
"default": false,
|
|
1317
|
+
"description": "Enable MetaMetrics during visible onboarding."
|
|
1318
|
+
},
|
|
1319
|
+
"biometrics": {
|
|
1320
|
+
"type": "boolean",
|
|
1321
|
+
"enum": [false],
|
|
1322
|
+
"default": false,
|
|
1323
|
+
"description": "Biometric authentication is disabled because unattended recipes cannot satisfy the device prompt."
|
|
1324
|
+
},
|
|
1325
|
+
"notifications": {
|
|
1326
|
+
"type": "boolean",
|
|
1327
|
+
"default": false,
|
|
1328
|
+
"description": "Enable push notifications during Mobile onboarding; defaults off."
|
|
1329
|
+
},
|
|
1330
|
+
"skip_wallet_tour": {
|
|
1331
|
+
"type": "boolean",
|
|
1332
|
+
"default": true,
|
|
1333
|
+
"description": "Skip the Mobile wallet-home tour after onboarding; defaults on so recipes reach a usable wallet."
|
|
1334
|
+
},
|
|
1335
|
+
"interests": {
|
|
1336
|
+
"type": "array",
|
|
1337
|
+
"items": {
|
|
1338
|
+
"type": "string",
|
|
1339
|
+
"enum": ["swap_tokens", "trade_perpetuals", "prediction_markets", "send_receive_crypto", "earn_and_spend", "use_other_crypto_apps"]
|
|
1340
|
+
},
|
|
1341
|
+
"default": [],
|
|
1342
|
+
"description": "Select optional onboarding interests; an empty list skips the questionnaire."
|
|
1343
|
+
},
|
|
1344
|
+
"timeout_ms": {
|
|
1345
|
+
"type": "number"
|
|
1346
|
+
}
|
|
1347
|
+
},
|
|
1348
|
+
"additionalProperties": false
|
|
1349
|
+
},
|
|
1350
|
+
"examples": [
|
|
1351
|
+
{
|
|
1352
|
+
"action": "metamask.wallet.import",
|
|
1353
|
+
"method": "auto",
|
|
1354
|
+
"intent": "Use an existing fixture profile or import through onboarding",
|
|
1355
|
+
"next": "done"
|
|
1356
|
+
}
|
|
1357
|
+
],
|
|
1358
|
+
"execution_capabilities": ["app-mutation"]
|
|
1359
|
+
},
|
|
1360
|
+
"metamask.wallet.reset": {
|
|
1361
|
+
"description": "Delete the current wallet through the visible client reset flow and reach fresh onboarding.",
|
|
1362
|
+
"schema": {
|
|
1363
|
+
"type": "object",
|
|
1364
|
+
"properties": {
|
|
1365
|
+
"timeout_ms": {
|
|
1366
|
+
"type": "number"
|
|
1367
|
+
}
|
|
1368
|
+
},
|
|
1369
|
+
"additionalProperties": false
|
|
1370
|
+
},
|
|
1371
|
+
"examples": [
|
|
1372
|
+
{
|
|
1373
|
+
"action": "metamask.wallet.reset",
|
|
1374
|
+
"intent": "Reset the wallet through visible UI before importing it again",
|
|
1375
|
+
"next": "done"
|
|
1376
|
+
}
|
|
1377
|
+
],
|
|
1378
|
+
"execution_capabilities": ["app-mutation"]
|
|
1379
|
+
},
|
|
1256
1380
|
"metamask.wallet.ensure_unlocked": {
|
|
1257
1381
|
"description": "Unlock the wallet with the fixture password when it is currently locked.",
|
|
1258
1382
|
"schema": {
|
|
@@ -158,11 +158,22 @@
|
|
|
158
158
|
},
|
|
159
159
|
"perps-navigate-market": {
|
|
160
160
|
"action": "ui.navigate",
|
|
161
|
-
"next": "
|
|
161
|
+
"next": "read-snapshot",
|
|
162
162
|
"intent": "Show the ETH Perps market details",
|
|
163
163
|
"page": "perps-market",
|
|
164
164
|
"market": "ETH"
|
|
165
165
|
},
|
|
166
|
+
"read-snapshot": {
|
|
167
|
+
"action": "metamask.perps.read_snapshot",
|
|
168
|
+
"include": [
|
|
169
|
+
"markets"
|
|
170
|
+
],
|
|
171
|
+
"markets": [
|
|
172
|
+
"ETH"
|
|
173
|
+
],
|
|
174
|
+
"next": "start-state",
|
|
175
|
+
"intent": "Read a bounded live Perps market snapshot"
|
|
176
|
+
},
|
|
166
177
|
"ensure-clean": {
|
|
167
178
|
"action": "metamask.perps.ensure_positions",
|
|
168
179
|
"market": "ETH",
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://farmslot.io/schemas/recipe-v1.schema.json",
|
|
3
|
+
"title": "Import or reuse a MetaMask wallet",
|
|
4
|
+
"description": "Make a Mobile or Extension wallet ready by reusing its fixture-backed profile or importing the primary mnemonic through visible onboarding UI.",
|
|
5
|
+
"paramsSchema": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"properties": {
|
|
9
|
+
"method": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"enum": ["auto", "profile", "ui"],
|
|
12
|
+
"default": "auto",
|
|
13
|
+
"description": "Choose automatically from visible wallet state, require an existing profile, or require real-user onboarding UI."
|
|
14
|
+
},
|
|
15
|
+
"credential_source": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"enum": ["auto", "environment", "fixture"],
|
|
18
|
+
"default": "auto",
|
|
19
|
+
"description": "Read secrets from the named environment variables first, or require one source explicitly."
|
|
20
|
+
},
|
|
21
|
+
"srp_env": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"default": "MM_HARNESS_WALLET_SRP",
|
|
24
|
+
"description": "Environment variable containing the Secret Recovery Phrase; the value is never stored in the recipe or evidence."
|
|
25
|
+
},
|
|
26
|
+
"password_env": {
|
|
27
|
+
"type": "string",
|
|
28
|
+
"default": "MM_HARNESS_WALLET_PASSWORD",
|
|
29
|
+
"description": "Environment variable containing the wallet password; the value is never stored in the recipe or evidence."
|
|
30
|
+
},
|
|
31
|
+
"metametrics": {
|
|
32
|
+
"type": "boolean",
|
|
33
|
+
"default": false,
|
|
34
|
+
"description": "Enable MetaMetrics during visible onboarding; defaults off."
|
|
35
|
+
},
|
|
36
|
+
"biometrics": {
|
|
37
|
+
"type": "boolean",
|
|
38
|
+
"enum": [false],
|
|
39
|
+
"default": false,
|
|
40
|
+
"description": "Keep Mobile biometric authentication disabled for unattended validation."
|
|
41
|
+
},
|
|
42
|
+
"notifications": {
|
|
43
|
+
"type": "boolean",
|
|
44
|
+
"default": false,
|
|
45
|
+
"description": "Enable Mobile push notifications during onboarding; defaults off."
|
|
46
|
+
},
|
|
47
|
+
"skip_wallet_tour": {
|
|
48
|
+
"type": "boolean",
|
|
49
|
+
"default": true,
|
|
50
|
+
"description": "Skip the Mobile wallet-home tour so the recipe ends at a usable wallet."
|
|
51
|
+
},
|
|
52
|
+
"interests": {
|
|
53
|
+
"type": "array",
|
|
54
|
+
"items": {
|
|
55
|
+
"type": "string",
|
|
56
|
+
"enum": ["swap_tokens", "trade_perpetuals", "prediction_markets", "send_receive_crypto", "earn_and_spend", "use_other_crypto_apps"]
|
|
57
|
+
},
|
|
58
|
+
"default": [],
|
|
59
|
+
"description": "Mobile-only onboarding interests; an empty list skips the optional questionnaire."
|
|
60
|
+
},
|
|
61
|
+
"timeout_ms": {
|
|
62
|
+
"type": "number",
|
|
63
|
+
"default": 300000,
|
|
64
|
+
"description": "Maximum time for each onboarding transition and final wallet readiness."
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
"workflow": {
|
|
69
|
+
"entry": "fixture-status",
|
|
70
|
+
"nodes": {
|
|
71
|
+
"fixture-status": {
|
|
72
|
+
"action": "metamask.wallet.fixture_status",
|
|
73
|
+
"intent": "Record whether a canonical fixture is available without exposing its secrets",
|
|
74
|
+
"next": "import"
|
|
75
|
+
},
|
|
76
|
+
"import": {
|
|
77
|
+
"action": "metamask.wallet.import",
|
|
78
|
+
"method": "{{params.method}}",
|
|
79
|
+
"credential_source": "{{params.credential_source}}",
|
|
80
|
+
"srp_env": "{{params.srp_env}}",
|
|
81
|
+
"password_env": "{{params.password_env}}",
|
|
82
|
+
"metametrics": "{{params.metametrics}}",
|
|
83
|
+
"biometrics": "{{params.biometrics}}",
|
|
84
|
+
"notifications": "{{params.notifications}}",
|
|
85
|
+
"skip_wallet_tour": "{{params.skip_wallet_tour}}",
|
|
86
|
+
"interests": "{{params.interests}}",
|
|
87
|
+
"timeout_ms": "{{params.timeout_ms}}",
|
|
88
|
+
"intent": "Reuse the fixture-backed wallet or import it through the visible onboarding flow",
|
|
89
|
+
"next": "state"
|
|
90
|
+
},
|
|
91
|
+
"state": {
|
|
92
|
+
"action": "metamask.wallet.read_state",
|
|
93
|
+
"intent": "Prove the wallet has a selected account after setup",
|
|
94
|
+
"next": "done"
|
|
95
|
+
},
|
|
96
|
+
"done": {
|
|
97
|
+
"action": "end",
|
|
98
|
+
"status": "pass"
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|