@deeeed/metamask-harness 0.38.1 → 0.40.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 +58 -0
- package/adapters/extension/lib/playwright-cdp.cjs +17 -1
- package/adapters/extension/sidepanel-toggle.sh +135 -13
- package/dist/adapters/mobile/release-artifact.js +65 -0
- package/dist/adapters.js +27 -17
- package/dist/command-contract.js +10 -2
- package/dist/commands/call.js +7 -4
- package/dist/commands/launch/index.js +55 -3
- package/dist/commands/parse-args.js +6 -0
- package/dist/commands/run-engine.js +75 -39
- package/dist/funding-execution-context.js +1386 -0
- package/dist/live-adapter-contract.js +3 -1
- package/dist/metamask-action-validation.js +170 -3
- package/dist/mm-harness-cli.js +8 -2
- package/dist/recipe-security.js +5 -12
- package/dist/runner.js +102 -6
- package/docs/RECIPES.md +74 -1
- package/docs/RELEASE-QA-CAPABILITY-MAP.md +6 -5
- package/library/actions/extension/assets/open_details.mjs +30 -0
- package/library/actions/extension/assets/set_token_visibility.mjs +5 -0
- package/library/actions/extension/networks/add_chainlist.mjs +4 -0
- package/library/actions/extension/networks/add_custom.mjs +4 -0
- package/library/actions/extension/networks/custom_network.mjs +48 -1
- package/library/actions/extension/perps/assert_visible_consistency.mjs +366 -0
- package/library/actions/extension/perps/close_visible_position.mjs +299 -37
- package/library/actions/extension/perps/compare_provider_market.mjs +77 -0
- package/library/actions/extension/perps/edit_margin.mjs +285 -44
- package/library/actions/extension/perps/mutation-receipt.mjs +781 -0
- package/library/actions/extension/perps/perps.mjs +1029 -363
- package/library/actions/extension/perps/read_funds_confirmation.mjs +126 -13
- package/library/actions/extension/perps/read_snapshot.mjs +124 -3
- package/library/actions/extension/perps/read_visible_state.mjs +63 -5
- package/library/actions/extension/perps/search_markets.mjs +32 -0
- package/library/actions/extension/perps/select_activity_filter.mjs +81 -18
- package/library/actions/extension/perps/select_market_filter.mjs +48 -4
- package/library/actions/extension/perps/set_market_favorite.mjs +6 -1
- package/library/actions/extension/perps/update_position_tpsl.mjs +251 -69
- package/library/actions/extension/perps/visible-mutation-identity.mjs +164 -0
- package/library/actions/extension/platform/cdp.mjs +88 -9
- package/library/actions/extension/settings/set_basic_functionality.mjs +35 -7
- package/library/actions/extension/swap_bridge/read_visible_state.mjs +2 -6
- package/library/actions/extension/swap_bridge/set_amount.mjs +11 -2
- package/library/actions/extension/ui/navigate.mjs +45 -5
- package/library/actions/extension/wallet/import.mjs +70 -29
- package/library/actions/extension/wallet/lock.mjs +62 -5
- package/library/actions/extension/wallet/visible-session.mjs +218 -0
- package/library/actions/mobile/assets/import_custom_token.mjs +181 -0
- package/library/actions/mobile/assets/open_details.mjs +43 -0
- package/library/actions/mobile/assets/read_details.mjs +96 -0
- package/library/actions/mobile/assets/set_token_visibility.mjs +302 -0
- package/library/actions/mobile/assets/verify_sorting.mjs +104 -0
- package/library/actions/mobile/networks/add_custom.mjs +125 -0
- package/library/actions/mobile/networks/network-management.mjs +132 -0
- package/library/actions/mobile/networks/read_visible_state.mjs +43 -0
- package/library/actions/mobile/networks/remove_custom.mjs +100 -0
- package/library/actions/mobile/perps/search_markets.mjs +46 -0
- package/library/actions/mobile/perps/set_market_favorite.mjs +117 -0
- package/library/actions/mobile/platform/native-session-name.mjs +14 -0
- package/library/actions/mobile/platform/native-session.mjs +59 -0
- package/library/actions/mobile/platform/observe-ui.mjs +9 -1
- package/library/actions/mobile/swap_bridge/native-session.mjs +10 -45
- package/library/actions/mobile/swap_bridge/select_assets.mjs +15 -1
- package/library/actions/mobile/swap_bridge/set_amount.mjs +1 -1
- package/library/actions/mobile/swap_bridge/set_max_amount.mjs +55 -0
- package/library/actions/mobile/swap_bridge/set_slippage.mjs +96 -0
- package/library/actions/mobile/swap_bridge/submit_transaction.mjs +141 -0
- package/library/actions/mobile/ui/native-navigation.mjs +120 -23
- package/library/actions/mobile/ui/navigate.mjs +13 -2
- package/library/actions/mobile/wallet/import.mjs +17 -10
- package/library/actions/mobile/wallet/lock.mjs +14 -0
- package/library/actions/mobile/wallet/native-ui.mjs +88 -15
- package/library/actions/shared/perps/visible-state.mjs +33 -11
- package/library/actions/shared/swap-bridge/visible-state.mjs +15 -0
- package/library/manifests/extension.action-manifest.json +1707 -1241
- package/library/manifests/mobile.action-manifest.json +308 -1
- package/library/recipes/assets/release-token-details.recipe.json +5 -4
- package/library/recipes/assets/release-token-hide-readd.recipe.json +2 -0
- package/library/recipes/{assets → extension/assets}/release-custom-network-token-persistence.recipe.json +1 -0
- package/library/recipes/{perps → extension/perps}/release-activity-filters.recipe.json +5 -5
- package/library/recipes/{perps → extension/perps}/release-funds-flows.recipe.json +3 -3
- package/library/recipes/extension/perps/release-live-limit-order.recipe.json +24 -19
- package/library/recipes/extension/perps/release-market-filters.recipe.json +97 -0
- package/library/recipes/extension/perps/release-order-entry.recipe.json +4 -1
- package/library/recipes/extension/perps/release-order-validation.recipe.json +53 -14
- package/library/recipes/extension/perps/release-visible-consistency.recipe.json +47 -0
- package/library/recipes/extension/perps/source-dev-snapshot-consistency.recipe.json +76 -0
- package/library/recipes/mobile/networks/release-custom-network-persistence.recipe.json +90 -0
- package/library/recipes/mobile/networks/release-multichain-visibility.recipe.json +58 -0
- package/library/recipes/perps/release-live-market-order.recipe.json +30 -13
- package/library/recipes/perps/release-market-details.recipe.json +1 -1
- package/library/recipes/perps/release-market-search.recipe.json +8 -4
- package/library/recipes/perps/release-watchlist.recipe.json +31 -19
- package/library/recipes/swap-bridge/release-custom-slippage.recipe.json +5 -13
- package/library/recipes/swap-bridge/release-quote.recipe.json +1 -0
- package/library/recipes/wallet/import.recipe.json +4 -14
- package/package.json +1 -1
- package/library/actions/extension/assets/finish_send.mjs +0 -128
- package/library/actions/extension/swap_bridge/submit_transaction.mjs +0 -363
- package/library/actions/extension/ui/activate_and_observe.mjs +0 -96
- package/library/recipes/assets/release-custom-gas-send.recipe.json +0 -88
- package/library/recipes/assets/release-native-max-cancel.recipe.json +0 -70
- package/library/recipes/assets/release-native-max-send.recipe.json +0 -78
- package/library/recipes/assets/release-own-account-send.recipe.json +0 -80
- package/library/recipes/extension/runner/action-validation.recipe.json +0 -343
|
@@ -5,10 +5,13 @@
|
|
|
5
5
|
"paramsSchema": {
|
|
6
6
|
"type": "object",
|
|
7
7
|
"additionalProperties": false,
|
|
8
|
+
"required": [
|
|
9
|
+
"market"
|
|
10
|
+
],
|
|
8
11
|
"properties": {
|
|
9
12
|
"market": {
|
|
10
13
|
"type": "string",
|
|
11
|
-
"
|
|
14
|
+
"description": "Perps market with no existing position so the New Long and Short controls are available."
|
|
12
15
|
},
|
|
13
16
|
"amount": {
|
|
14
17
|
"type": "string",
|
|
@@ -5,10 +5,49 @@
|
|
|
5
5
|
"paramsSchema": {
|
|
6
6
|
"type": "object",
|
|
7
7
|
"additionalProperties": false,
|
|
8
|
+
"required": [
|
|
9
|
+
"market"
|
|
10
|
+
],
|
|
8
11
|
"properties": {
|
|
9
12
|
"market": {
|
|
10
13
|
"type": "string",
|
|
11
|
-
"
|
|
14
|
+
"description": "Perps market with no existing position so the New Long order form can be validated."
|
|
15
|
+
},
|
|
16
|
+
"below_minimum_amount": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"default": "1"
|
|
19
|
+
},
|
|
20
|
+
"valid_amount": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"default": "10"
|
|
23
|
+
},
|
|
24
|
+
"percent": {
|
|
25
|
+
"type": "string",
|
|
26
|
+
"default": "50"
|
|
27
|
+
},
|
|
28
|
+
"minimum_leverage": {
|
|
29
|
+
"type": "string",
|
|
30
|
+
"default": "1"
|
|
31
|
+
},
|
|
32
|
+
"keyboard_leverage": {
|
|
33
|
+
"type": "string",
|
|
34
|
+
"default": "2"
|
|
35
|
+
},
|
|
36
|
+
"maximum_leverage": {
|
|
37
|
+
"type": "string",
|
|
38
|
+
"default": "40"
|
|
39
|
+
},
|
|
40
|
+
"invalid_take_profit": {
|
|
41
|
+
"type": "string",
|
|
42
|
+
"default": "1000"
|
|
43
|
+
},
|
|
44
|
+
"valid_take_profit": {
|
|
45
|
+
"type": "string",
|
|
46
|
+
"default": "70000"
|
|
47
|
+
},
|
|
48
|
+
"invalid_stop_loss": {
|
|
49
|
+
"type": "string",
|
|
50
|
+
"default": "100000"
|
|
12
51
|
}
|
|
13
52
|
}
|
|
14
53
|
},
|
|
@@ -51,7 +90,7 @@
|
|
|
51
90
|
"enter-below-minimum": {
|
|
52
91
|
"action": "ui.set_input",
|
|
53
92
|
"selector": "[data-testid=\"amount-input-field\"] input",
|
|
54
|
-
"value": "
|
|
93
|
+
"value": "{{params.below_minimum_amount}}",
|
|
55
94
|
"intent": "Enter an amount below the market minimum",
|
|
56
95
|
"next": "assert-below-minimum"
|
|
57
96
|
},
|
|
@@ -61,7 +100,7 @@
|
|
|
61
100
|
"market": "{{params.market}}",
|
|
62
101
|
"direction": "long",
|
|
63
102
|
"order_type": "market",
|
|
64
|
-
"amount": "
|
|
103
|
+
"amount": "{{params.below_minimum_amount}}",
|
|
65
104
|
"submit_enabled": false,
|
|
66
105
|
"max_items": 150,
|
|
67
106
|
"intent": "Prove the below-minimum amount cannot be submitted",
|
|
@@ -70,14 +109,14 @@
|
|
|
70
109
|
"enter-valid-amount": {
|
|
71
110
|
"action": "ui.set_input",
|
|
72
111
|
"selector": "[data-testid=\"amount-input-field\"] input",
|
|
73
|
-
"value": "
|
|
112
|
+
"value": "{{params.valid_amount}}",
|
|
74
113
|
"intent": "Enter the minimum valid USD amount",
|
|
75
114
|
"next": "enter-percent"
|
|
76
115
|
},
|
|
77
116
|
"enter-percent": {
|
|
78
117
|
"action": "ui.set_input",
|
|
79
118
|
"selector": "[data-testid=\"balance-percent-input\"] input",
|
|
80
|
-
"value": "
|
|
119
|
+
"value": "{{params.percent}}",
|
|
81
120
|
"intent": "Enter a midpoint balance percentage",
|
|
82
121
|
"next": "assert-percent"
|
|
83
122
|
},
|
|
@@ -87,7 +126,7 @@
|
|
|
87
126
|
"market": "{{params.market}}",
|
|
88
127
|
"direction": "long",
|
|
89
128
|
"order_type": "market",
|
|
90
|
-
"percent": "
|
|
129
|
+
"percent": "{{params.percent}}",
|
|
91
130
|
"submit_enabled": true,
|
|
92
131
|
"max_items": 150,
|
|
93
132
|
"intent": "Prove percent input updates a valid order summary",
|
|
@@ -96,7 +135,7 @@
|
|
|
96
135
|
"enter-min-leverage": {
|
|
97
136
|
"action": "ui.set_input",
|
|
98
137
|
"selector": "[data-testid=\"leverage-input\"] input",
|
|
99
|
-
"value": "
|
|
138
|
+
"value": "{{params.minimum_leverage}}",
|
|
100
139
|
"intent": "Enter minimum leverage",
|
|
101
140
|
"next": "assert-min-leverage"
|
|
102
141
|
},
|
|
@@ -104,7 +143,7 @@
|
|
|
104
143
|
"action": "metamask.perps.read_visible_state",
|
|
105
144
|
"surface": "order-entry",
|
|
106
145
|
"market": "{{params.market}}",
|
|
107
|
-
"leverage": "
|
|
146
|
+
"leverage": "{{params.minimum_leverage}}",
|
|
108
147
|
"max_items": 150,
|
|
109
148
|
"intent": "Prove minimum leverage is accepted",
|
|
110
149
|
"next": "raise-with-keyboard"
|
|
@@ -119,7 +158,7 @@
|
|
|
119
158
|
"action": "metamask.perps.read_visible_state",
|
|
120
159
|
"surface": "order-entry",
|
|
121
160
|
"market": "{{params.market}}",
|
|
122
|
-
"leverage": "
|
|
161
|
+
"leverage": "{{params.keyboard_leverage}}",
|
|
123
162
|
"max_items": 150,
|
|
124
163
|
"intent": "Prove the keyboard changes leverage by one step",
|
|
125
164
|
"next": "enter-max-leverage"
|
|
@@ -127,7 +166,7 @@
|
|
|
127
166
|
"enter-max-leverage": {
|
|
128
167
|
"action": "ui.set_input",
|
|
129
168
|
"selector": "[data-testid=\"leverage-input\"] input",
|
|
130
|
-
"value": "
|
|
169
|
+
"value": "{{params.maximum_leverage}}",
|
|
131
170
|
"intent": "Enter the market maximum leverage",
|
|
132
171
|
"next": "assert-max-leverage"
|
|
133
172
|
},
|
|
@@ -135,7 +174,7 @@
|
|
|
135
174
|
"action": "metamask.perps.read_visible_state",
|
|
136
175
|
"surface": "order-entry",
|
|
137
176
|
"market": "{{params.market}}",
|
|
138
|
-
"leverage": "
|
|
177
|
+
"leverage": "{{params.maximum_leverage}}",
|
|
139
178
|
"max_items": 150,
|
|
140
179
|
"intent": "Prove maximum leverage is accepted",
|
|
141
180
|
"next": "enable-auto-close"
|
|
@@ -164,7 +203,7 @@
|
|
|
164
203
|
"enter-invalid-take-profit": {
|
|
165
204
|
"action": "ui.set_input",
|
|
166
205
|
"selector": "[data-testid=\"tp-price-input\"] input",
|
|
167
|
-
"value": "
|
|
206
|
+
"value": "{{params.invalid_take_profit}}",
|
|
168
207
|
"intent": "Enter a take-profit below the long entry price",
|
|
169
208
|
"next": "assert-invalid-take-profit"
|
|
170
209
|
},
|
|
@@ -182,14 +221,14 @@
|
|
|
182
221
|
"enter-valid-take-profit": {
|
|
183
222
|
"action": "ui.set_input",
|
|
184
223
|
"selector": "[data-testid=\"tp-price-input\"] input",
|
|
185
|
-
"value": "
|
|
224
|
+
"value": "{{params.valid_take_profit}}",
|
|
186
225
|
"intent": "Enter a take-profit above the long entry price",
|
|
187
226
|
"next": "enter-invalid-stop-loss"
|
|
188
227
|
},
|
|
189
228
|
"enter-invalid-stop-loss": {
|
|
190
229
|
"action": "ui.set_input",
|
|
191
230
|
"selector": "[data-testid=\"sl-price-input\"] input",
|
|
192
|
-
"value": "
|
|
231
|
+
"value": "{{params.invalid_stop_loss}}",
|
|
193
232
|
"intent": "Enter a stop-loss above the long entry price",
|
|
194
233
|
"next": "assert-invalid-stop-loss"
|
|
195
234
|
},
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://farmslot.io/schemas/recipe-v1.schema.json",
|
|
3
|
+
"title": "Perps release visible consistency",
|
|
4
|
+
"description": "Proves bounded visible market-list row changes and containment of recent Perps activity across every activity filter on packaged Extension builds; it does not assert other market-detail surfaces.",
|
|
5
|
+
"paramsSchema": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"properties": {
|
|
9
|
+
"sample_count": { "type": "integer", "minimum": 2, "default": 3 },
|
|
10
|
+
"sample_interval_ms": { "type": "integer", "minimum": 100, "default": 1000 },
|
|
11
|
+
"minimum_changed_count": { "type": "integer", "minimum": 1, "default": 1 },
|
|
12
|
+
"minimum_recent_activity_count": { "type": "integer", "minimum": 1, "default": 1 },
|
|
13
|
+
"timeout_ms": { "type": "integer", "minimum": 1000, "default": 30000 }
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"workflow": {
|
|
17
|
+
"entry": "market-stream",
|
|
18
|
+
"nodes": {
|
|
19
|
+
"market-stream": {
|
|
20
|
+
"action": "metamask.perps.assert_visible_consistency",
|
|
21
|
+
"mode": "market-stream",
|
|
22
|
+
"sample_count": "{{params.sample_count}}",
|
|
23
|
+
"sample_interval_ms": "{{params.sample_interval_ms}}",
|
|
24
|
+
"minimum_changed_count": "{{params.minimum_changed_count}}",
|
|
25
|
+
"timeout_ms": "{{params.timeout_ms}}",
|
|
26
|
+
"intent": "Prove bounded changes in rendered market-row facts",
|
|
27
|
+
"next": "activity-containment"
|
|
28
|
+
},
|
|
29
|
+
"activity-containment": {
|
|
30
|
+
"action": "metamask.perps.assert_visible_consistency",
|
|
31
|
+
"mode": "activity-containment",
|
|
32
|
+
"minimum_recent_activity_count": "{{params.minimum_recent_activity_count}}",
|
|
33
|
+
"timeout_ms": "{{params.timeout_ms}}",
|
|
34
|
+
"intent": "Prove recent visible activity identities are contained in full activity",
|
|
35
|
+
"next": "capture"
|
|
36
|
+
},
|
|
37
|
+
"capture": {
|
|
38
|
+
"action": "ui.screenshot",
|
|
39
|
+
"path": "screenshots/perps-visible-consistency.png",
|
|
40
|
+
"label": "Perps visible activity consistency",
|
|
41
|
+
"intent": "Preserve reviewer-visible proof of the full activity surface",
|
|
42
|
+
"next": "done"
|
|
43
|
+
},
|
|
44
|
+
"done": { "action": "end", "status": "pass" }
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://farmslot.io/schemas/recipe-v1.schema.json",
|
|
3
|
+
"title": "Perps source-dev snapshot consistency",
|
|
4
|
+
"description": "Uses the optional source-dev Extension background hook to sample bounded Perps market data and compare one generic visible activity-card identity with normalized history.",
|
|
5
|
+
"paramsSchema": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"properties": {
|
|
9
|
+
"sample_count": {
|
|
10
|
+
"type": "integer",
|
|
11
|
+
"minimum": 2,
|
|
12
|
+
"default": 3
|
|
13
|
+
},
|
|
14
|
+
"sample_interval_ms": {
|
|
15
|
+
"type": "integer",
|
|
16
|
+
"minimum": 100,
|
|
17
|
+
"default": 1000
|
|
18
|
+
},
|
|
19
|
+
"minimum_changed_market_count": {
|
|
20
|
+
"type": "integer",
|
|
21
|
+
"minimum": 0,
|
|
22
|
+
"default": 0,
|
|
23
|
+
"description": "Optional live-price movement assertion. Set above zero only when the proof requires observed market changes."
|
|
24
|
+
},
|
|
25
|
+
"minimum_history_count": {
|
|
26
|
+
"type": "integer",
|
|
27
|
+
"minimum": 1,
|
|
28
|
+
"default": 1
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"workflow": {
|
|
33
|
+
"entry": "open-activity",
|
|
34
|
+
"nodes": {
|
|
35
|
+
"open-activity": {
|
|
36
|
+
"action": "ui.navigate",
|
|
37
|
+
"page": "perps-activity",
|
|
38
|
+
"intent": "Open live Perps activity through visible controls",
|
|
39
|
+
"next": "show-funds-activity"
|
|
40
|
+
},
|
|
41
|
+
"show-funds-activity": {
|
|
42
|
+
"action": "metamask.perps.select_activity_filter",
|
|
43
|
+
"filter": "deposits",
|
|
44
|
+
"intent": "Show visible activity cards before generic identity comparison",
|
|
45
|
+
"next": "sample"
|
|
46
|
+
},
|
|
47
|
+
"sample": {
|
|
48
|
+
"action": "metamask.perps.read_snapshot",
|
|
49
|
+
"include": ["markets", "history"],
|
|
50
|
+
"sampling": {
|
|
51
|
+
"count": "{{params.sample_count}}",
|
|
52
|
+
"interval_ms": "{{params.sample_interval_ms}}"
|
|
53
|
+
},
|
|
54
|
+
"expect": {
|
|
55
|
+
"minimum_changed_market_count": "{{params.minimum_changed_market_count}}",
|
|
56
|
+
"minimum_history_count": "{{params.minimum_history_count}}",
|
|
57
|
+
"require_activity_history_agreement": true
|
|
58
|
+
},
|
|
59
|
+
"max_items_per_section": 100,
|
|
60
|
+
"intent": "Prove bounded market changes and one exact visible activity-to-history identity",
|
|
61
|
+
"next": "capture"
|
|
62
|
+
},
|
|
63
|
+
"capture": {
|
|
64
|
+
"action": "ui.screenshot",
|
|
65
|
+
"path": "screenshots/perps-snapshot-consistency.png",
|
|
66
|
+
"label": "Perps snapshot activity agreement",
|
|
67
|
+
"intent": "Preserve reviewer-visible proof of the compared activity surface",
|
|
68
|
+
"next": "done"
|
|
69
|
+
},
|
|
70
|
+
"done": {
|
|
71
|
+
"action": "end",
|
|
72
|
+
"status": "pass"
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://farmslot.io/schemas/recipe-v1.schema.json",
|
|
3
|
+
"title": "Mobile release custom-network persistence",
|
|
4
|
+
"description": "Adds a custom network through native settings, proves it survives lock/unlock, and removes it.",
|
|
5
|
+
"paramsSchema": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"properties": {
|
|
9
|
+
"network": { "type": "string", "default": "PulseChain" },
|
|
10
|
+
"rpc_url": { "type": "string", "default": "https://rpc.pulsechain.com" },
|
|
11
|
+
"chain_id": { "type": "integer", "minimum": 1, "default": 369 },
|
|
12
|
+
"symbol": { "type": "string", "default": "PLS" },
|
|
13
|
+
"explorer_url": { "type": "string", "default": "https://scan.pulsechain.com" },
|
|
14
|
+
"timeout_ms": { "type": "integer", "minimum": 1000, "default": 60000 }
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"workflow": {
|
|
18
|
+
"entry": "open-wallet",
|
|
19
|
+
"nodes": {
|
|
20
|
+
"open-wallet": {
|
|
21
|
+
"action": "ui.navigate",
|
|
22
|
+
"page": "home",
|
|
23
|
+
"intent": "Open the wallet before custom-network setup",
|
|
24
|
+
"next": "add-network"
|
|
25
|
+
},
|
|
26
|
+
"add-network": {
|
|
27
|
+
"action": "metamask.networks.add_custom",
|
|
28
|
+
"network": "{{params.network}}",
|
|
29
|
+
"rpc_url": "{{params.rpc_url}}",
|
|
30
|
+
"chain_id": "{{params.chain_id}}",
|
|
31
|
+
"symbol": "{{params.symbol}}",
|
|
32
|
+
"explorer_url": "{{params.explorer_url}}",
|
|
33
|
+
"timeout_ms": "{{params.timeout_ms}}",
|
|
34
|
+
"intent": "Add the custom network through visible settings",
|
|
35
|
+
"next": "assert-added"
|
|
36
|
+
},
|
|
37
|
+
"assert-added": {
|
|
38
|
+
"action": "metamask.networks.read_visible_state",
|
|
39
|
+
"network": "{{params.network}}",
|
|
40
|
+
"chain_id": "{{params.chain_id}}",
|
|
41
|
+
"settle_ms": 1000,
|
|
42
|
+
"timeout_ms": "{{params.timeout_ms}}",
|
|
43
|
+
"intent": "Prove the custom network is present",
|
|
44
|
+
"next": "capture-before"
|
|
45
|
+
},
|
|
46
|
+
"capture-before": {
|
|
47
|
+
"action": "ui.screenshot",
|
|
48
|
+
"path": "screenshots/custom-network-before-lock.png",
|
|
49
|
+
"label": "Custom network before lock",
|
|
50
|
+
"intent": "Preserve pre-lock network evidence",
|
|
51
|
+
"next": "lock-wallet"
|
|
52
|
+
},
|
|
53
|
+
"lock-wallet": {
|
|
54
|
+
"action": "metamask.wallet.lock",
|
|
55
|
+
"intent": "Lock the wallet through visible native controls",
|
|
56
|
+
"next": "unlock-wallet"
|
|
57
|
+
},
|
|
58
|
+
"unlock-wallet": {
|
|
59
|
+
"action": "metamask.wallet.ensure_unlocked",
|
|
60
|
+
"intent": "Unlock the same persisted profile",
|
|
61
|
+
"next": "assert-persisted"
|
|
62
|
+
},
|
|
63
|
+
"assert-persisted": {
|
|
64
|
+
"action": "metamask.networks.read_visible_state",
|
|
65
|
+
"network": "{{params.network}}",
|
|
66
|
+
"chain_id": "{{params.chain_id}}",
|
|
67
|
+
"settle_ms": 1000,
|
|
68
|
+
"timeout_ms": "{{params.timeout_ms}}",
|
|
69
|
+
"intent": "Prove the custom network survived lock and unlock",
|
|
70
|
+
"next": "capture-after"
|
|
71
|
+
},
|
|
72
|
+
"capture-after": {
|
|
73
|
+
"action": "ui.screenshot",
|
|
74
|
+
"path": "screenshots/custom-network-after-unlock.png",
|
|
75
|
+
"label": "Custom network after unlock",
|
|
76
|
+
"intent": "Preserve post-unlock network evidence",
|
|
77
|
+
"next": "remove-network"
|
|
78
|
+
},
|
|
79
|
+
"remove-network": {
|
|
80
|
+
"action": "metamask.networks.remove_custom",
|
|
81
|
+
"network": "{{params.network}}",
|
|
82
|
+
"chain_id": "{{params.chain_id}}",
|
|
83
|
+
"timeout_ms": "{{params.timeout_ms}}",
|
|
84
|
+
"intent": "Remove the custom network and prove it is absent",
|
|
85
|
+
"next": "done"
|
|
86
|
+
},
|
|
87
|
+
"done": { "action": "end", "status": "pass" }
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://farmslot.io/schemas/recipe-v1.schema.json",
|
|
3
|
+
"title": "Mobile multi-network asset visibility",
|
|
4
|
+
"description": "Proves funded assets from multiple protocol families are visible together in the opaque Mobile wallet.",
|
|
5
|
+
"paramsSchema": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"properties": {
|
|
9
|
+
"symbols": {
|
|
10
|
+
"type": "array",
|
|
11
|
+
"items": { "type": "string" },
|
|
12
|
+
"default": ["ETH", "SOL"]
|
|
13
|
+
},
|
|
14
|
+
"minimum_asset_count": {
|
|
15
|
+
"type": "integer",
|
|
16
|
+
"minimum": 2,
|
|
17
|
+
"default": 2
|
|
18
|
+
},
|
|
19
|
+
"timeout_ms": {
|
|
20
|
+
"type": "integer",
|
|
21
|
+
"minimum": 1000,
|
|
22
|
+
"default": 45000
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"workflow": {
|
|
27
|
+
"entry": "open-wallet",
|
|
28
|
+
"nodes": {
|
|
29
|
+
"open-wallet": {
|
|
30
|
+
"action": "ui.navigate",
|
|
31
|
+
"page": "home",
|
|
32
|
+
"timeout_ms": "{{params.timeout_ms}}",
|
|
33
|
+
"intent": "Open the aggregate Mobile wallet token list",
|
|
34
|
+
"next": "assert-multichain-assets"
|
|
35
|
+
},
|
|
36
|
+
"assert-multichain-assets": {
|
|
37
|
+
"action": "metamask.assets.read_visible_state",
|
|
38
|
+
"require_symbols": "{{params.symbols}}",
|
|
39
|
+
"minimum_asset_count": "{{params.minimum_asset_count}}",
|
|
40
|
+
"require_fiat": true,
|
|
41
|
+
"max_items": 100,
|
|
42
|
+
"intent": "Prove assets from the requested protocol families are simultaneously visible",
|
|
43
|
+
"next": "capture-wallet"
|
|
44
|
+
},
|
|
45
|
+
"capture-wallet": {
|
|
46
|
+
"action": "ui.screenshot",
|
|
47
|
+
"path": "screenshots/mobile-multichain-assets.png",
|
|
48
|
+
"label": "Mobile multi-network asset visibility",
|
|
49
|
+
"intent": "Preserve reviewer-visible proof of aggregate multi-network holdings",
|
|
50
|
+
"next": "done"
|
|
51
|
+
},
|
|
52
|
+
"done": {
|
|
53
|
+
"action": "end",
|
|
54
|
+
"status": "pass"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -19,11 +19,25 @@
|
|
|
19
19
|
"leverage": {
|
|
20
20
|
"type": "integer",
|
|
21
21
|
"minimum": 1,
|
|
22
|
-
|
|
22
|
+
"default": 1
|
|
23
|
+
},
|
|
24
|
+
"provider": {
|
|
25
|
+
"type": "string",
|
|
26
|
+
"default": "hyperliquid"
|
|
27
|
+
},
|
|
28
|
+
"network": {
|
|
29
|
+
"type": "string",
|
|
30
|
+
"enum": [
|
|
31
|
+
"mainnet",
|
|
32
|
+
"testnet"
|
|
33
|
+
],
|
|
34
|
+
"default": "mainnet"
|
|
23
35
|
},
|
|
24
36
|
"confirm_live": {
|
|
25
37
|
"type": "boolean"
|
|
26
|
-
}
|
|
38
|
+
},
|
|
39
|
+
"identity_rounding_tolerance_base_units": { "type": "string", "default": "10000" },
|
|
40
|
+
"balance_reconciliation_tolerance_base_units": { "type": "string", "default": "1000000" }
|
|
27
41
|
}
|
|
28
42
|
},
|
|
29
43
|
"workflow": {
|
|
@@ -33,15 +47,6 @@
|
|
|
33
47
|
"action": "ui.navigate",
|
|
34
48
|
"page": "perps",
|
|
35
49
|
"intent": "Show the live Perps home surface",
|
|
36
|
-
"next": "assert-clean"
|
|
37
|
-
},
|
|
38
|
-
"assert-clean": {
|
|
39
|
-
"action": "metamask.perps.read_visible_state",
|
|
40
|
-
"surface": "home",
|
|
41
|
-
"maximum_position_count": 0,
|
|
42
|
-
"require_features": ["balance", "market-list"],
|
|
43
|
-
"max_items": 150,
|
|
44
|
-
"intent": "Prove there is no open position before placing the order",
|
|
45
50
|
"next": "open-market-list"
|
|
46
51
|
},
|
|
47
52
|
"open-market-list": {
|
|
@@ -63,8 +68,12 @@
|
|
|
63
68
|
"side": "long",
|
|
64
69
|
"amount": "{{params.amount}}",
|
|
65
70
|
"leverage": "{{params.leverage}}",
|
|
71
|
+
"provider": "{{params.provider}}",
|
|
72
|
+
"network": "{{params.network}}",
|
|
66
73
|
"order_type": "market",
|
|
67
74
|
"confirm_live": "{{params.confirm_live}}",
|
|
75
|
+
"identity_rounding_tolerance_base_units": "{{params.identity_rounding_tolerance_base_units}}",
|
|
76
|
+
"submit_attempts": 1,
|
|
68
77
|
"timeout_ms": 45000,
|
|
69
78
|
"intent": "Submit the authorized order exactly once",
|
|
70
79
|
"next": "wait-position"
|
|
@@ -100,14 +109,22 @@
|
|
|
100
109
|
"action": "metamask.perps.close_visible_position",
|
|
101
110
|
"market": "{{params.market}}",
|
|
102
111
|
"confirm_live": "{{params.confirm_live}}",
|
|
112
|
+
"funding_side": "long",
|
|
113
|
+
"funding_amount": "{{params.amount}}",
|
|
114
|
+
"provider": "{{params.provider}}",
|
|
115
|
+
"network": "{{params.network}}",
|
|
116
|
+
"leverage": "{{params.leverage}}",
|
|
117
|
+
"identity_rounding_tolerance_base_units": "{{params.identity_rounding_tolerance_base_units}}",
|
|
118
|
+
"balance_reconciliation_tolerance_base_units": "{{params.balance_reconciliation_tolerance_base_units}}",
|
|
103
119
|
"intent": "Close the live position after proving it",
|
|
104
120
|
"next": "assert-closed"
|
|
105
121
|
},
|
|
106
122
|
"assert-closed": {
|
|
107
123
|
"action": "metamask.perps.read_visible_state",
|
|
108
|
-
"surface": "
|
|
109
|
-
"market": "{{params.market}}",
|
|
124
|
+
"surface": "home",
|
|
110
125
|
"maximum_position_count": 0,
|
|
126
|
+
"maximum_order_count": 0,
|
|
127
|
+
"require_features": ["balance", "market-list"],
|
|
111
128
|
"minimum_activity_count": 1,
|
|
112
129
|
"max_items": 150,
|
|
113
130
|
"intent": "Prove the position was removed and close activity was recorded",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://farmslot.io/schemas/recipe-v1.schema.json",
|
|
3
3
|
"title": "Perps release market details",
|
|
4
|
-
"description": "Opens one live Perps market through visible UI and proves its price, change, statistics, and Long/Short controls
|
|
4
|
+
"description": "Opens one live Perps market through visible UI and proves its header price, change, statistics, and Long/Short controls; it does not assert chart data.",
|
|
5
5
|
"paramsSchema": {
|
|
6
6
|
"type": "object",
|
|
7
7
|
"additionalProperties": false,
|
|
@@ -18,6 +18,11 @@
|
|
|
18
18
|
"type": "integer",
|
|
19
19
|
"minimum": 1,
|
|
20
20
|
"default": 3
|
|
21
|
+
},
|
|
22
|
+
"minimum_unfiltered_results": {
|
|
23
|
+
"type": "integer",
|
|
24
|
+
"minimum": 1,
|
|
25
|
+
"default": 5
|
|
21
26
|
}
|
|
22
27
|
}
|
|
23
28
|
},
|
|
@@ -39,16 +44,15 @@
|
|
|
39
44
|
"assert-unfiltered": {
|
|
40
45
|
"action": "metamask.perps.read_visible_state",
|
|
41
46
|
"surface": "market-list",
|
|
42
|
-
"minimum_market_count":
|
|
47
|
+
"minimum_market_count": "{{params.minimum_unfiltered_results}}",
|
|
43
48
|
"require_features": ["market-list"],
|
|
44
49
|
"max_items": 100,
|
|
45
50
|
"intent": "Prove the live market list is populated before filtering",
|
|
46
51
|
"next": "search"
|
|
47
52
|
},
|
|
48
53
|
"search": {
|
|
49
|
-
"action": "
|
|
50
|
-
"
|
|
51
|
-
"value": "{{params.query}}",
|
|
54
|
+
"action": "metamask.perps.search_markets",
|
|
55
|
+
"query": "{{params.query}}",
|
|
52
56
|
"intent": "Enter the market search through trusted keyboard input",
|
|
53
57
|
"next": "assert-filtered"
|
|
54
58
|
},
|
|
@@ -45,28 +45,27 @@
|
|
|
45
45
|
"action": "ui.navigate",
|
|
46
46
|
"page": "perps",
|
|
47
47
|
"intent": "Show Perps home after adding the favorite",
|
|
48
|
-
"next": "
|
|
48
|
+
"next": "reopen-market-list-added"
|
|
49
49
|
},
|
|
50
|
-
"
|
|
51
|
-
"action": "metamask.perps.read_visible_state",
|
|
52
|
-
"surface": "home",
|
|
53
|
-
"market": "{{params.market}}",
|
|
54
|
-
"require_test_ids": ["perps-watchlist-{{params.market}}"],
|
|
55
|
-
"max_items": 150,
|
|
56
|
-
"intent": "Prove the favorite persists on the home watchlist",
|
|
57
|
-
"next": "reopen-market-list"
|
|
58
|
-
},
|
|
59
|
-
"reopen-market-list": {
|
|
50
|
+
"reopen-market-list-added": {
|
|
60
51
|
"action": "ui.navigate",
|
|
61
52
|
"page": "perps-market-list",
|
|
62
|
-
"intent": "Reopen the
|
|
63
|
-
"next": "reopen-market"
|
|
53
|
+
"intent": "Reopen the market list after adding the favorite",
|
|
54
|
+
"next": "reopen-market-added"
|
|
64
55
|
},
|
|
65
|
-
"reopen-market": {
|
|
56
|
+
"reopen-market-added": {
|
|
66
57
|
"action": "ui.navigate",
|
|
67
58
|
"page": "perps-market",
|
|
68
59
|
"market": "{{params.market}}",
|
|
69
60
|
"intent": "Reopen the favorited market",
|
|
61
|
+
"next": "assert-added"
|
|
62
|
+
},
|
|
63
|
+
"assert-added": {
|
|
64
|
+
"action": "metamask.perps.set_market_favorite",
|
|
65
|
+
"market": "{{params.market}}",
|
|
66
|
+
"favorite": true,
|
|
67
|
+
"require_unchanged": true,
|
|
68
|
+
"intent": "Prove the favorite persisted after navigating away and back",
|
|
70
69
|
"next": "remove-favorite"
|
|
71
70
|
},
|
|
72
71
|
"remove-favorite": {
|
|
@@ -80,14 +79,27 @@
|
|
|
80
79
|
"action": "ui.navigate",
|
|
81
80
|
"page": "perps",
|
|
82
81
|
"intent": "Show Perps home after removing the favorite",
|
|
82
|
+
"next": "reopen-market-list-removed"
|
|
83
|
+
},
|
|
84
|
+
"reopen-market-list-removed": {
|
|
85
|
+
"action": "ui.navigate",
|
|
86
|
+
"page": "perps-market-list",
|
|
87
|
+
"intent": "Reopen the market list after removing the favorite",
|
|
88
|
+
"next": "reopen-market-removed"
|
|
89
|
+
},
|
|
90
|
+
"reopen-market-removed": {
|
|
91
|
+
"action": "ui.navigate",
|
|
92
|
+
"page": "perps-market",
|
|
93
|
+
"market": "{{params.market}}",
|
|
94
|
+
"intent": "Reopen the unfavorited market",
|
|
83
95
|
"next": "assert-removed"
|
|
84
96
|
},
|
|
85
97
|
"assert-removed": {
|
|
86
|
-
"action": "metamask.perps.
|
|
87
|
-
"
|
|
88
|
-
"
|
|
89
|
-
"
|
|
90
|
-
"intent": "Prove the
|
|
98
|
+
"action": "metamask.perps.set_market_favorite",
|
|
99
|
+
"market": "{{params.market}}",
|
|
100
|
+
"favorite": false,
|
|
101
|
+
"require_unchanged": true,
|
|
102
|
+
"intent": "Prove the removal persisted after navigating away and back",
|
|
91
103
|
"next": "done"
|
|
92
104
|
},
|
|
93
105
|
"done": {
|