@deeeed/metamask-harness 0.18.0 → 0.19.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 +187 -0
- package/README.md +4 -7
- package/adapters/core/inject.sh +1 -6
- package/adapters/extension/inject.mjs +1 -4
- package/adapters/extension/verify.sh +1 -1
- package/adapters/mobile/inject.sh +5 -4
- package/adapters/mobile/verify.sh +15 -19
- package/adapters/shared/harness-source-fingerprint.mjs +14 -12
- package/dist/adapters/harness-freshness.js +49 -0
- package/dist/cli.js +0 -4
- package/dist/command-contract.js +51 -40
- package/dist/command-journal.js +50 -12
- package/dist/commands/call.js +95 -20
- package/dist/commands/check.js +1 -1
- package/dist/commands/completion-candidates.js +7 -19
- package/dist/commands/fixtures.js +50 -1
- package/dist/commands/last.js +9 -1
- package/dist/commands/launch/extension.js +2 -2
- package/dist/commands/launch/mobile.js +2 -0
- package/dist/commands/list-executables.js +56 -20
- package/dist/commands/manifest.js +28 -12
- package/dist/commands/parse-args.js +55 -3
- package/dist/commands/provision.js +0 -1
- package/dist/commands/run-engine.js +514 -336
- package/dist/commands/run.js +25 -37
- package/dist/commands/shared.js +1 -1
- package/dist/heal-bounds.js +5 -0
- package/dist/mm-harness-cli.js +22 -30
- package/dist/run-diagnostics.js +1 -1
- package/dist/run-recording.js +1 -1
- package/dist/runner.js +24 -2
- package/docs/CONTRIBUTING.md +2 -3
- package/docs/QA.md +0 -1
- package/docs/RECIPES.md +52 -91
- package/library/README.md +5 -5
- package/library/actions/core/perps/_controller.mjs +33 -1
- package/library/actions/core/perps/assert_orders.mjs +6 -7
- package/library/actions/core/perps/assert_positions.mjs +6 -7
- package/library/actions/core/perps/close_orders.mjs +2 -0
- package/library/actions/core/perps/close_positions.mjs +2 -0
- package/library/actions/core/perps/ensure_orders.mjs +4 -2
- package/library/actions/core/perps/ensure_positions.mjs +4 -2
- package/library/actions/core/perps/place_order.mjs +7 -3
- package/library/actions/extension/perps/assert_orders.mjs +2 -1
- package/library/actions/extension/perps/assert_positions.mjs +2 -1
- package/library/actions/extension/perps/perps.mjs +43 -14
- package/library/actions/mobile/perps/assert_orders.mjs +2 -1
- package/library/actions/mobile/perps/assert_positions.mjs +2 -1
- package/library/actions/mobile/perps/perps.mjs +40 -12
- package/library/library.json +1 -1
- package/library/manifests/core.action-manifest.json +1170 -413
- package/library/manifests/extension.action-manifest.json +1495 -641
- package/library/manifests/mobile.action-manifest.json +1704 -769
- package/library/recipes/app/lifecycle.android-smoke.mobile.recipe.json +63 -81
- package/library/recipes/perps/clean-market-testnet.core.recipe.json +44 -0
- package/library/recipes/perps/clean-market-testnet.recipe.json +49 -0
- package/library/recipes/perps/lifecycle.recipe.json +136 -180
- package/library/recipes/perps/order-lifecycle.core.recipe.json +71 -67
- package/library/recipes/perps/performance.background-resume.mobile.recipe.json +51 -67
- package/library/recipes/perps/performance.cold-start.mobile.recipe.json +51 -67
- package/library/recipes/perps/performance.mobile.recipe.json +37 -51
- package/library/recipes/perps/performance.warm-start.mobile.recipe.json +44 -59
- package/library/recipes/perps/read-markets.core.recipe.json +29 -31
- package/library/recipes/perps/smoke.core.recipe.json +29 -32
- package/library/recipes/perps/smoke.extension.recipe.json +41 -44
- package/library/recipes/perps/smoke.mobile.recipe.json +42 -44
- package/library/recipes/perps/trading-lifecycle.core.recipe.json +69 -65
- package/library/recipes/runner/action-validation.extension.recipe.json +312 -405
- package/library/recipes/runner/action-validation.mobile.recipe.json +316 -409
- package/library/recipes/runner/smoke.core.recipe.json +18 -20
- package/library/recipes/runner/smoke.extension.recipe.json +23 -24
- package/library/recipes/runner/smoke.mobile.recipe.json +23 -24
- package/library/recipes/wallet/smoke.extension.recipe.json +33 -35
- package/library/recipes/wallet/smoke.mobile.recipe.json +33 -35
- package/package.json +3 -3
- package/scripts/completions.sh +1 -4
- package/dist/adapters/extension/harness-freshness.js +0 -39
- package/dist/commands/flows.js +0 -91
- package/library/flows/perps.flows.json +0 -64
|
@@ -1,37 +1,35 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
2
|
+
"$schema": "https://farmslot.io/schemas/recipe-v1.schema.json",
|
|
3
3
|
"title": "MetaMask core headless Perps read",
|
|
4
4
|
"description": "Proves the headless `core` adapter instantiates @metamask/perps-controller against a resolved MetaMask/core checkout and reads live HyperLiquid testnet Perps state (positions, open orders, account state) over HTTP — no CDP, bridge, or UI.",
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
"
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
"
|
|
32
|
-
|
|
33
|
-
"status": "pass"
|
|
34
|
-
}
|
|
5
|
+
"workflow": {
|
|
6
|
+
"entry": "status",
|
|
7
|
+
"nodes": {
|
|
8
|
+
"status": {
|
|
9
|
+
"action": "app.status",
|
|
10
|
+
"next": "read_positions",
|
|
11
|
+
"intent": "Resolve the core checkout and report headless compatibility mode"
|
|
12
|
+
},
|
|
13
|
+
"read_positions": {
|
|
14
|
+
"action": "metamask.perps.read_positions",
|
|
15
|
+
"mode": "all",
|
|
16
|
+
"next": "read_orders",
|
|
17
|
+
"intent": "Read live Perps positions from the headless controller"
|
|
18
|
+
},
|
|
19
|
+
"read_orders": {
|
|
20
|
+
"action": "metamask.perps.read_orders",
|
|
21
|
+
"mode": "all",
|
|
22
|
+
"next": "read_account",
|
|
23
|
+
"intent": "Read live Perps open orders from the headless controller"
|
|
24
|
+
},
|
|
25
|
+
"read_account": {
|
|
26
|
+
"action": "metamask.perps.read_account",
|
|
27
|
+
"next": "done",
|
|
28
|
+
"intent": "Read live Perps account state from the headless controller"
|
|
29
|
+
},
|
|
30
|
+
"done": {
|
|
31
|
+
"action": "end",
|
|
32
|
+
"status": "pass"
|
|
35
33
|
}
|
|
36
34
|
}
|
|
37
35
|
}
|
|
@@ -1,38 +1,35 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
2
|
+
"$schema": "https://farmslot.io/schemas/recipe-v1.schema.json",
|
|
3
3
|
"title": "MetaMask core Perps smoke",
|
|
4
4
|
"description": "Non-mutating Perps domain smoke for the headless core adapter: instantiates the Perps controller and reads live positions, orders, and account state.",
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
"
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
"
|
|
32
|
-
|
|
33
|
-
"status": "pass",
|
|
34
|
-
"intent": "Finish the core Perps smoke"
|
|
35
|
-
}
|
|
5
|
+
"workflow": {
|
|
6
|
+
"entry": "status",
|
|
7
|
+
"nodes": {
|
|
8
|
+
"status": {
|
|
9
|
+
"action": "app.status",
|
|
10
|
+
"next": "read-positions",
|
|
11
|
+
"intent": "Resolve the core checkout and report headless compatibility mode"
|
|
12
|
+
},
|
|
13
|
+
"read-positions": {
|
|
14
|
+
"action": "metamask.perps.read_positions",
|
|
15
|
+
"mode": "all",
|
|
16
|
+
"next": "read-orders",
|
|
17
|
+
"intent": "Read live Perps positions from the headless controller"
|
|
18
|
+
},
|
|
19
|
+
"read-orders": {
|
|
20
|
+
"action": "metamask.perps.read_orders",
|
|
21
|
+
"mode": "all",
|
|
22
|
+
"next": "read-account",
|
|
23
|
+
"intent": "Read live Perps open orders from the headless controller"
|
|
24
|
+
},
|
|
25
|
+
"read-account": {
|
|
26
|
+
"action": "metamask.perps.read_account",
|
|
27
|
+
"next": "done",
|
|
28
|
+
"intent": "Read live Perps account state from the headless controller"
|
|
29
|
+
},
|
|
30
|
+
"done": {
|
|
31
|
+
"action": "end",
|
|
32
|
+
"status": "pass"
|
|
36
33
|
}
|
|
37
34
|
}
|
|
38
35
|
}
|
|
@@ -1,50 +1,47 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
2
|
+
"$schema": "https://farmslot.io/schemas/recipe-v1.schema.json",
|
|
3
3
|
"title": "MetaMask Extension Perps smoke",
|
|
4
4
|
"description": "Non-mutating Perps domain smoke for MetaMask Extension: verifies CDP, unlocks if needed, opens the Perps page, and reads live Perps positions and orders.",
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
"
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
"
|
|
44
|
-
|
|
45
|
-
"status": "pass",
|
|
46
|
-
"intent": "Finish the Extension Perps smoke"
|
|
47
|
-
}
|
|
5
|
+
"workflow": {
|
|
6
|
+
"entry": "status",
|
|
7
|
+
"nodes": {
|
|
8
|
+
"status": {
|
|
9
|
+
"action": "app.status",
|
|
10
|
+
"next": "cdp",
|
|
11
|
+
"intent": "Resolve the Extension checkout and adapter status before Perps proof"
|
|
12
|
+
},
|
|
13
|
+
"cdp": {
|
|
14
|
+
"action": "cdp.target",
|
|
15
|
+
"required": true,
|
|
16
|
+
"timeout_ms": 15000,
|
|
17
|
+
"next": "ensure-unlocked",
|
|
18
|
+
"intent": "Confirm the Extension CDP runtime is reachable"
|
|
19
|
+
},
|
|
20
|
+
"ensure-unlocked": {
|
|
21
|
+
"action": "metamask.wallet.ensure_unlocked",
|
|
22
|
+
"timeout_ms": 45000,
|
|
23
|
+
"next": "open-perps",
|
|
24
|
+
"intent": "Ensure the wallet is unlocked before opening Perps"
|
|
25
|
+
},
|
|
26
|
+
"open-perps": {
|
|
27
|
+
"action": "ui.navigate",
|
|
28
|
+
"page": "perps",
|
|
29
|
+
"next": "read-positions",
|
|
30
|
+
"intent": "Show the Perps home surface"
|
|
31
|
+
},
|
|
32
|
+
"read-positions": {
|
|
33
|
+
"action": "metamask.perps.read_positions",
|
|
34
|
+
"next": "read-orders",
|
|
35
|
+
"intent": "Read live Perps positions without mutating account state"
|
|
36
|
+
},
|
|
37
|
+
"read-orders": {
|
|
38
|
+
"action": "metamask.perps.read_orders",
|
|
39
|
+
"next": "done",
|
|
40
|
+
"intent": "Read live Perps open orders without mutating account state"
|
|
41
|
+
},
|
|
42
|
+
"done": {
|
|
43
|
+
"action": "end",
|
|
44
|
+
"status": "pass"
|
|
48
45
|
}
|
|
49
46
|
}
|
|
50
47
|
}
|
|
@@ -1,50 +1,48 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
2
|
+
"$schema": "https://farmslot.io/schemas/recipe-v1.schema.json",
|
|
3
3
|
"title": "MetaMask Mobile Perps smoke",
|
|
4
4
|
"description": "Non-mutating Perps domain smoke for MetaMask Mobile: verifies the live bridge, unlocks if needed, opens the Perps market list, and reads live Perps positions and orders.",
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
"
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
"intent": "Finish the Mobile Perps smoke"
|
|
47
|
-
}
|
|
5
|
+
"workflow": {
|
|
6
|
+
"entry": "status",
|
|
7
|
+
"nodes": {
|
|
8
|
+
"status": {
|
|
9
|
+
"action": "app.status",
|
|
10
|
+
"next": "cdp",
|
|
11
|
+
"intent": "Resolve the Mobile checkout and adapter status before Perps proof"
|
|
12
|
+
},
|
|
13
|
+
"cdp": {
|
|
14
|
+
"action": "cdp.target",
|
|
15
|
+
"required": true,
|
|
16
|
+
"timeout_ms": 15000,
|
|
17
|
+
"next": "ensure-unlocked",
|
|
18
|
+
"intent": "Confirm the React Native debug bridge is reachable"
|
|
19
|
+
},
|
|
20
|
+
"ensure-unlocked": {
|
|
21
|
+
"action": "metamask.wallet.ensure_unlocked",
|
|
22
|
+
"next": "open-perps",
|
|
23
|
+
"intent": "Ensure the wallet is unlocked before opening Perps",
|
|
24
|
+
"target_timeout_ms": 45000,
|
|
25
|
+
"unlock_timeout_ms": 45000
|
|
26
|
+
},
|
|
27
|
+
"open-perps": {
|
|
28
|
+
"action": "ui.navigate",
|
|
29
|
+
"page": "perps",
|
|
30
|
+
"next": "read-positions",
|
|
31
|
+
"intent": "Show the Perps market list"
|
|
32
|
+
},
|
|
33
|
+
"read-positions": {
|
|
34
|
+
"action": "metamask.perps.read_positions",
|
|
35
|
+
"next": "read-orders",
|
|
36
|
+
"intent": "Read live Perps positions without mutating account state"
|
|
37
|
+
},
|
|
38
|
+
"read-orders": {
|
|
39
|
+
"action": "metamask.perps.read_orders",
|
|
40
|
+
"next": "done",
|
|
41
|
+
"intent": "Read live Perps open orders without mutating account state"
|
|
42
|
+
},
|
|
43
|
+
"done": {
|
|
44
|
+
"action": "end",
|
|
45
|
+
"status": "pass"
|
|
48
46
|
}
|
|
49
47
|
}
|
|
50
48
|
}
|
|
@@ -1,75 +1,79 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
2
|
+
"$schema": "https://farmslot.io/schemas/recipe-v1.schema.json",
|
|
3
3
|
"title": "MetaMask core headless Perps trading lifecycle",
|
|
4
4
|
"description": "Proves the headless `core` adapter places and closes a REAL Perps order on HyperLiquid testnet through the full signing path: a default viem signer backs the perps controller's wallet adapter, the active HyperLiquid testnet provider is initialized, and a small BTC long is opened then closed. Leaves the account FLAT. No CDP, bridge, or UI.",
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
"workflow": {
|
|
6
|
+
"entry": "status",
|
|
7
|
+
"nodes": {
|
|
8
|
+
"status": {
|
|
9
|
+
"action": "app.status",
|
|
10
|
+
"next": "start_flat",
|
|
11
|
+
"intent": "Resolve the core checkout and report headless compatibility mode"
|
|
12
|
+
},
|
|
13
|
+
"start_flat": {
|
|
14
|
+
"action": "metamask.perps.start_state",
|
|
15
|
+
"market": "BTC",
|
|
16
|
+
"positions": {
|
|
17
|
+
"state": "none"
|
|
13
18
|
},
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"market": "BTC",
|
|
17
|
-
"positions": { "state": "none" },
|
|
18
|
-
"orders": { "state": "none" },
|
|
19
|
-
"network": "testnet",
|
|
20
|
-
"timeout_ms": 45000,
|
|
21
|
-
"next": "place_order",
|
|
22
|
-
"intent": "Converge BTC testnet baseline to flat (no positions, no orders) before the proof window"
|
|
19
|
+
"orders": {
|
|
20
|
+
"state": "none"
|
|
23
21
|
},
|
|
24
|
-
"
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
22
|
+
"network": "testnet",
|
|
23
|
+
"timeout_ms": 45000,
|
|
24
|
+
"next": "place_order",
|
|
25
|
+
"intent": "Converge BTC testnet baseline to flat (no positions, no orders) before the proof window"
|
|
26
|
+
},
|
|
27
|
+
"place_order": {
|
|
28
|
+
"action": "metamask.perps.place_order",
|
|
29
|
+
"market": "BTC",
|
|
30
|
+
"side": "long",
|
|
31
|
+
"notional": "11",
|
|
32
|
+
"leverage": 2,
|
|
33
|
+
"timeout_ms": 45000,
|
|
34
|
+
"next": "assert_open",
|
|
35
|
+
"intent": "Place a small BTC long market order via the headless controller (real signed order to HL testnet)"
|
|
36
|
+
},
|
|
37
|
+
"assert_open": {
|
|
38
|
+
"action": "metamask.perps.assert_positions",
|
|
39
|
+
"market": "BTC",
|
|
40
|
+
"state": "open",
|
|
41
|
+
"timeout_ms": 30000,
|
|
42
|
+
"next": "close_position",
|
|
43
|
+
"intent": "Assert the BTC position opened"
|
|
44
|
+
},
|
|
45
|
+
"close_position": {
|
|
46
|
+
"action": "metamask.perps.close_positions",
|
|
47
|
+
"market": "BTC",
|
|
48
|
+
"timeout_ms": 45000,
|
|
49
|
+
"next": "assert_flat",
|
|
50
|
+
"intent": "Close the BTC position via the headless controller (real signed close to HL testnet)"
|
|
51
|
+
},
|
|
52
|
+
"assert_flat": {
|
|
53
|
+
"action": "metamask.perps.assert_positions",
|
|
54
|
+
"market": "BTC",
|
|
55
|
+
"state": "none",
|
|
56
|
+
"timeout_ms": 30000,
|
|
57
|
+
"next": "teardown_flat",
|
|
58
|
+
"intent": "Assert the BTC position closed — account is flat"
|
|
59
|
+
},
|
|
60
|
+
"teardown_flat": {
|
|
61
|
+
"action": "metamask.perps.teardown_state",
|
|
62
|
+
"market": "BTC",
|
|
63
|
+
"positions": {
|
|
64
|
+
"state": "none"
|
|
34
65
|
},
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"market": "BTC",
|
|
38
|
-
"state": "open",
|
|
39
|
-
"timeout_ms": 30000,
|
|
40
|
-
"next": "close_position",
|
|
41
|
-
"intent": "Assert the BTC position opened"
|
|
66
|
+
"orders": {
|
|
67
|
+
"state": "none"
|
|
42
68
|
},
|
|
43
|
-
"
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
"assert_flat": {
|
|
52
|
-
"action": "metamask.perps.assert_positions",
|
|
53
|
-
"market": "BTC",
|
|
54
|
-
"state": "none",
|
|
55
|
-
"timeout_ms": 30000,
|
|
56
|
-
"next": "teardown_flat",
|
|
57
|
-
"intent": "Assert the BTC position closed — account is flat"
|
|
58
|
-
},
|
|
59
|
-
"teardown_flat": {
|
|
60
|
-
"action": "metamask.perps.teardown_state",
|
|
61
|
-
"market": "BTC",
|
|
62
|
-
"positions": { "state": "none" },
|
|
63
|
-
"orders": { "state": "none" },
|
|
64
|
-
"network": "testnet",
|
|
65
|
-
"timeout_ms": 45000,
|
|
66
|
-
"next": "done",
|
|
67
|
-
"intent": "Restore BTC testnet baseline to flat after the proof (leave the shared account clean)"
|
|
68
|
-
},
|
|
69
|
-
"done": {
|
|
70
|
-
"action": "end",
|
|
71
|
-
"status": "pass"
|
|
72
|
-
}
|
|
69
|
+
"network": "testnet",
|
|
70
|
+
"timeout_ms": 45000,
|
|
71
|
+
"next": "done",
|
|
72
|
+
"intent": "Restore BTC testnet baseline to flat after the proof (leave the shared account clean)"
|
|
73
|
+
},
|
|
74
|
+
"done": {
|
|
75
|
+
"action": "end",
|
|
76
|
+
"status": "pass"
|
|
73
77
|
}
|
|
74
78
|
}
|
|
75
79
|
}
|