@deeeed/metamask-harness 0.45.0 → 0.46.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 +20 -0
- package/adapters/mobile/bridge-runtime/cdp-bridge.cjs +12 -3
- package/dist/commands/call.js +2 -9
- package/dist/commands/run-engine.js +7 -71
- package/dist/commands/run.js +2 -7
- package/docs/CONTRIBUTING.md +8 -0
- package/docs/RECIPES.md +13 -1
- package/library/actions/extension/perps/update_position_tpsl.mjs +3 -8
- package/library/actions/mobile/perps/perps.mjs +750 -39
- package/library/manifests/mobile.action-manifest.json +101 -6
- package/library/recipes/mobile/perps/chase-assert-running.recipe.json +110 -0
- package/library/recipes/mobile/perps/chase-place.recipe.json +145 -0
- package/library/recipes/mobile/perps/chase-terminate.recipe.json +98 -0
- package/library/recipes/mobile/perps/pro-order-setup.recipe.json +111 -0
- package/library/recipes/mobile/perps/pro-order-start-state.recipe.json +53 -0
- package/library/recipes/mobile/perps/scale-assert-orders.recipe.json +126 -0
- package/library/recipes/mobile/perps/scale-place.recipe.json +186 -0
- package/library/recipes/mobile/perps/twap-assert-active.recipe.json +97 -0
- package/library/recipes/mobile/perps/twap-place.recipe.json +146 -0
- package/package.json +1 -1
- package/site/perps-advanced-orders-qa.html +96 -0
- package/site/perps.html +11 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://farmslot.io/schemas/recipe-v1.schema.json",
|
|
3
|
+
"title": "Assert Mobile Pro Scale child orders",
|
|
4
|
+
"description": "Opens the standard Orders tab and proves the selected Scale ladder produced the requested number of child orders.",
|
|
5
|
+
"paramsSchema": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["account"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"account": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"description": "Exact fixture account name, such as Trading or dev1."
|
|
13
|
+
},
|
|
14
|
+
"provider": { "type": "string", "default": "hyperliquid" },
|
|
15
|
+
"network": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"enum": ["testnet", "mainnet"],
|
|
18
|
+
"default": "testnet",
|
|
19
|
+
"description": "Assertions are read-only and may inspect either network."
|
|
20
|
+
},
|
|
21
|
+
"market": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"default": "BTC"
|
|
24
|
+
},
|
|
25
|
+
"orders": {
|
|
26
|
+
"type": "integer",
|
|
27
|
+
"enum": [3],
|
|
28
|
+
"default": 3
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"workflow": {
|
|
33
|
+
"entry": "prepare",
|
|
34
|
+
"nodes": {
|
|
35
|
+
"prepare": {
|
|
36
|
+
"action": "call",
|
|
37
|
+
"ref": "perps.pro-order-start-state",
|
|
38
|
+
"params": {
|
|
39
|
+
"account": "{{params.account}}",
|
|
40
|
+
"provider": "{{params.provider}}",
|
|
41
|
+
"network": "{{params.network}}",
|
|
42
|
+
"market": "{{params.market}}"
|
|
43
|
+
},
|
|
44
|
+
"intent": "Reach and prove the requested Pro market without changing Scale orders.",
|
|
45
|
+
"next": "position-tab"
|
|
46
|
+
},
|
|
47
|
+
"position-tab": {
|
|
48
|
+
"action": "ui.scroll",
|
|
49
|
+
"test_id": "perps-pro-market-positions-panel-tab-orders",
|
|
50
|
+
"scroll_into_view": true,
|
|
51
|
+
"intent": "Expose the standard Orders tab for visible review.",
|
|
52
|
+
"next": "wait-tab"
|
|
53
|
+
},
|
|
54
|
+
"wait-tab": {
|
|
55
|
+
"action": "ui.wait_for",
|
|
56
|
+
"test_id": "perps-pro-market-positions-panel-tab-orders",
|
|
57
|
+
"expected": "visible",
|
|
58
|
+
"timeout_ms": 15000,
|
|
59
|
+
"intent": "Require the standard Orders tab to be visible.",
|
|
60
|
+
"next": "open-tab"
|
|
61
|
+
},
|
|
62
|
+
"open-tab": {
|
|
63
|
+
"action": "ui.press",
|
|
64
|
+
"test_id": "perps-pro-market-positions-panel-tab-orders",
|
|
65
|
+
"intent": "Open the standard order list.",
|
|
66
|
+
"next": "wait-first-child"
|
|
67
|
+
},
|
|
68
|
+
"wait-first-child": {
|
|
69
|
+
"action": "ui.wait_for",
|
|
70
|
+
"test_id": "perps-pro-market-order-row-{{params.market}}-0",
|
|
71
|
+
"expected": "visible",
|
|
72
|
+
"timeout_ms": 15000,
|
|
73
|
+
"intent": "Require a visible standard child order for the selected market.",
|
|
74
|
+
"next": "capture-first-child"
|
|
75
|
+
},
|
|
76
|
+
"capture-first-child": {
|
|
77
|
+
"action": "ui.screenshot",
|
|
78
|
+
"path": "screenshots/evidence-scale-orders-first-{{params.market}}.png",
|
|
79
|
+
"label": "The standard Orders tab shows the Scale count and first child Limit order.",
|
|
80
|
+
"intent": "Preserve the visible Scale order count and first child for review.",
|
|
81
|
+
"next": "position-second-child"
|
|
82
|
+
},
|
|
83
|
+
"position-second-child": {
|
|
84
|
+
"action": "ui.scroll",
|
|
85
|
+
"test_id": "perps-pro-market-order-row-{{params.market}}-1",
|
|
86
|
+
"scroll_into_view": true,
|
|
87
|
+
"intent": "Expose the second Scale child order.",
|
|
88
|
+
"next": "wait-second-child"
|
|
89
|
+
},
|
|
90
|
+
"wait-second-child": {
|
|
91
|
+
"action": "ui.wait_for",
|
|
92
|
+
"test_id": "perps-pro-market-order-row-{{params.market}}-1",
|
|
93
|
+
"expected": "visible",
|
|
94
|
+
"timeout_ms": 15000,
|
|
95
|
+
"intent": "Require the second visible Scale child order for the selected market.",
|
|
96
|
+
"next": "position-third-child"
|
|
97
|
+
},
|
|
98
|
+
"position-third-child": {
|
|
99
|
+
"action": "ui.scroll",
|
|
100
|
+
"test_id": "perps-pro-market-order-row-{{params.market}}-2",
|
|
101
|
+
"scroll_into_view": true,
|
|
102
|
+
"intent": "Expose the third Scale child order.",
|
|
103
|
+
"next": "wait-third-child"
|
|
104
|
+
},
|
|
105
|
+
"wait-third-child": {
|
|
106
|
+
"action": "ui.wait_for",
|
|
107
|
+
"test_id": "perps-pro-market-order-row-{{params.market}}-2",
|
|
108
|
+
"expected": "visible",
|
|
109
|
+
"timeout_ms": 15000,
|
|
110
|
+
"intent": "Require the third visible Scale child order for the selected market.",
|
|
111
|
+
"next": "capture"
|
|
112
|
+
},
|
|
113
|
+
"capture": {
|
|
114
|
+
"action": "ui.screenshot",
|
|
115
|
+
"path": "screenshots/evidence-scale-orders-{{params.market}}.png",
|
|
116
|
+
"label": "The standard Orders tab shows the second and third Scale child Limit orders.",
|
|
117
|
+
"intent": "Preserve the visible lower Scale child orders for review.",
|
|
118
|
+
"next": "done"
|
|
119
|
+
},
|
|
120
|
+
"done": {
|
|
121
|
+
"action": "end",
|
|
122
|
+
"status": "pass"
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://farmslot.io/schemas/recipe-v1.schema.json",
|
|
3
|
+
"title": "Place a Mobile Pro Scale order",
|
|
4
|
+
"description": "Places a parameterized Scale ladder through visible Mobile Pro controls, cleaning only the testnet path.",
|
|
5
|
+
"paramsSchema": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["account"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"account": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"description": "Exact fixture account name, such as Trading or dev1."
|
|
13
|
+
},
|
|
14
|
+
"provider": { "type": "string", "default": "hyperliquid" },
|
|
15
|
+
"network": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"enum": ["testnet", "mainnet"],
|
|
18
|
+
"default": "testnet",
|
|
19
|
+
"description": "Mainnet placement requires an explicit user request."
|
|
20
|
+
},
|
|
21
|
+
"market": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"default": "BTC"
|
|
24
|
+
},
|
|
25
|
+
"side": {
|
|
26
|
+
"type": "string",
|
|
27
|
+
"enum": [
|
|
28
|
+
"long",
|
|
29
|
+
"short"
|
|
30
|
+
],
|
|
31
|
+
"default": "long"
|
|
32
|
+
},
|
|
33
|
+
"notional": {
|
|
34
|
+
"type": "string",
|
|
35
|
+
"default": "100"
|
|
36
|
+
},
|
|
37
|
+
"orders": {
|
|
38
|
+
"type": "string",
|
|
39
|
+
"default": "3"
|
|
40
|
+
},
|
|
41
|
+
"skew": {
|
|
42
|
+
"type": "string",
|
|
43
|
+
"default": "1"
|
|
44
|
+
},
|
|
45
|
+
"start_price": {
|
|
46
|
+
"type": "string",
|
|
47
|
+
"default": "70000",
|
|
48
|
+
"description": "Lower ladder price; override when changing market."
|
|
49
|
+
},
|
|
50
|
+
"end_price": {
|
|
51
|
+
"type": "string",
|
|
52
|
+
"default": "75000",
|
|
53
|
+
"description": "Upper ladder price; override when changing market."
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"workflow": {
|
|
58
|
+
"entry": "prepare",
|
|
59
|
+
"nodes": {
|
|
60
|
+
"prepare": {
|
|
61
|
+
"action": "call",
|
|
62
|
+
"ref": "perps.pro-order-setup",
|
|
63
|
+
"params": {
|
|
64
|
+
"account": "{{params.account}}",
|
|
65
|
+
"provider": "{{params.provider}}",
|
|
66
|
+
"network": "{{params.network}}",
|
|
67
|
+
"market": "{{params.market}}",
|
|
68
|
+
"side": "{{params.side}}"
|
|
69
|
+
},
|
|
70
|
+
"intent": "Prepare the requested Pro order form and Advanced picker.",
|
|
71
|
+
"next": "position-scale"
|
|
72
|
+
},
|
|
73
|
+
"position-scale": {
|
|
74
|
+
"action": "ui.scroll",
|
|
75
|
+
"test_id": "perps-order-type-scale",
|
|
76
|
+
"scroll_into_view": true,
|
|
77
|
+
"intent": "Expose the Scale option for visible selection.",
|
|
78
|
+
"next": "wait-scale"
|
|
79
|
+
},
|
|
80
|
+
"wait-scale": {
|
|
81
|
+
"action": "ui.wait_for",
|
|
82
|
+
"test_id": "perps-order-type-scale",
|
|
83
|
+
"expected": "visible",
|
|
84
|
+
"timeout_ms": 10000,
|
|
85
|
+
"intent": "Fail closed unless Scale is visibly offered.",
|
|
86
|
+
"next": "select-scale"
|
|
87
|
+
},
|
|
88
|
+
"select-scale": {
|
|
89
|
+
"action": "ui.press",
|
|
90
|
+
"test_id": "perps-order-type-scale",
|
|
91
|
+
"intent": "Select Scale.",
|
|
92
|
+
"next": "position-fields"
|
|
93
|
+
},
|
|
94
|
+
"position-fields": {
|
|
95
|
+
"action": "ui.scroll",
|
|
96
|
+
"test_id": "perps-pro-order-form-scale-fields",
|
|
97
|
+
"scroll_into_view": true,
|
|
98
|
+
"intent": "Expose the Scale inputs for visible entry.",
|
|
99
|
+
"next": "wait-fields"
|
|
100
|
+
},
|
|
101
|
+
"wait-fields": {
|
|
102
|
+
"action": "ui.wait_for",
|
|
103
|
+
"test_id": "perps-pro-order-form-scale-fields",
|
|
104
|
+
"expected": "visible",
|
|
105
|
+
"timeout_ms": 10000,
|
|
106
|
+
"intent": "Confirm the Scale ladder inputs are visible.",
|
|
107
|
+
"next": "set-start"
|
|
108
|
+
},
|
|
109
|
+
"set-start": {
|
|
110
|
+
"action": "ui.set_input",
|
|
111
|
+
"test_id": "perps-pro-order-form-scale-start-price",
|
|
112
|
+
"value": "{{params.start_price}}",
|
|
113
|
+
"intent": "Define the first price in the ladder.",
|
|
114
|
+
"next": "set-end"
|
|
115
|
+
},
|
|
116
|
+
"set-end": {
|
|
117
|
+
"action": "ui.set_input",
|
|
118
|
+
"test_id": "perps-pro-order-form-scale-end-price",
|
|
119
|
+
"value": "{{params.end_price}}",
|
|
120
|
+
"intent": "Define the last price in the ladder.",
|
|
121
|
+
"next": "set-orders"
|
|
122
|
+
},
|
|
123
|
+
"set-orders": {
|
|
124
|
+
"action": "ui.set_input",
|
|
125
|
+
"test_id": "perps-pro-order-form-scale-total-orders",
|
|
126
|
+
"value": "{{params.orders}}",
|
|
127
|
+
"intent": "Divide the ladder into the requested child count.",
|
|
128
|
+
"next": "set-skew"
|
|
129
|
+
},
|
|
130
|
+
"set-skew": {
|
|
131
|
+
"action": "ui.set_input",
|
|
132
|
+
"test_id": "perps-pro-order-form-scale-size-skew",
|
|
133
|
+
"value": "{{params.skew}}",
|
|
134
|
+
"intent": "Distribute notional with the requested size skew.",
|
|
135
|
+
"next": "set-size"
|
|
136
|
+
},
|
|
137
|
+
"set-size": {
|
|
138
|
+
"action": "ui.set_input",
|
|
139
|
+
"test_id": "perps-pro-order-form-size-input",
|
|
140
|
+
"value": "{{params.notional}}",
|
|
141
|
+
"intent": "Enter the requested total USD notional.",
|
|
142
|
+
"next": "position-preview"
|
|
143
|
+
},
|
|
144
|
+
"position-preview": {
|
|
145
|
+
"action": "ui.scroll",
|
|
146
|
+
"test_id": "perps-pro-order-form-scale-preview",
|
|
147
|
+
"scroll_into_view": true,
|
|
148
|
+
"intent": "Expose the generated Scale preview for review.",
|
|
149
|
+
"next": "wait-preview"
|
|
150
|
+
},
|
|
151
|
+
"wait-preview": {
|
|
152
|
+
"action": "ui.wait_for",
|
|
153
|
+
"test_id": "perps-pro-order-form-scale-preview",
|
|
154
|
+
"expected": "visible",
|
|
155
|
+
"timeout_ms": 15000,
|
|
156
|
+
"intent": "Require a visible Scale preview before submission.",
|
|
157
|
+
"next": "position-submit"
|
|
158
|
+
},
|
|
159
|
+
"position-submit": {
|
|
160
|
+
"action": "ui.scroll",
|
|
161
|
+
"test_id": "perps-pro-order-form-scale-preview",
|
|
162
|
+
"scroll_into_view": true,
|
|
163
|
+
"intent": "Expose the final Scale fee row directly above submission.",
|
|
164
|
+
"next": "wait-submit"
|
|
165
|
+
},
|
|
166
|
+
"wait-submit": {
|
|
167
|
+
"action": "ui.wait_for",
|
|
168
|
+
"test_id": "perps-pro-order-form-place-order",
|
|
169
|
+
"expected": "visible",
|
|
170
|
+
"timeout_ms": 10000,
|
|
171
|
+
"intent": "Confirm the Scale ladder can be submitted.",
|
|
172
|
+
"next": "submit"
|
|
173
|
+
},
|
|
174
|
+
"submit": {
|
|
175
|
+
"action": "ui.press",
|
|
176
|
+
"test_id": "perps-pro-order-form-place-order",
|
|
177
|
+
"intent": "Submit the Scale ladder to the selected provider and network.",
|
|
178
|
+
"next": "done"
|
|
179
|
+
},
|
|
180
|
+
"done": {
|
|
181
|
+
"action": "end",
|
|
182
|
+
"status": "pass"
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://farmslot.io/schemas/recipe-v1.schema.json",
|
|
3
|
+
"title": "Assert an active Mobile Pro TWAP",
|
|
4
|
+
"description": "Opens the TWAP Active tab and proves the selected market remains visible after placement.",
|
|
5
|
+
"paramsSchema": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"properties": {
|
|
9
|
+
"account": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"default": "",
|
|
12
|
+
"description": "Optional exact fixture account name, such as Trading or dev1. Omit it to keep the currently selected account."
|
|
13
|
+
},
|
|
14
|
+
"provider": { "type": "string", "default": "hyperliquid" },
|
|
15
|
+
"network": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"enum": ["testnet", "mainnet"],
|
|
18
|
+
"default": "testnet",
|
|
19
|
+
"description": "Assertions are read-only and may inspect either network."
|
|
20
|
+
},
|
|
21
|
+
"market": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"default": "BTC"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"workflow": {
|
|
28
|
+
"entry": "prepare",
|
|
29
|
+
"nodes": {
|
|
30
|
+
"prepare": {
|
|
31
|
+
"action": "call",
|
|
32
|
+
"ref": "perps.pro-order-start-state",
|
|
33
|
+
"params": {
|
|
34
|
+
"account": "{{params.account}}",
|
|
35
|
+
"provider": "{{params.provider}}",
|
|
36
|
+
"network": "{{params.network}}",
|
|
37
|
+
"market": "{{params.market}}"
|
|
38
|
+
},
|
|
39
|
+
"intent": "Reach and prove the requested Pro market without changing orders.",
|
|
40
|
+
"next": "position-tab"
|
|
41
|
+
},
|
|
42
|
+
"position-tab": {
|
|
43
|
+
"action": "ui.scroll",
|
|
44
|
+
"test_id": "perps-pro-market-positions-panel-tab-twap",
|
|
45
|
+
"scroll_into_view": true,
|
|
46
|
+
"intent": "Expose the TWAP management tab for visible review.",
|
|
47
|
+
"next": "wait-tab"
|
|
48
|
+
},
|
|
49
|
+
"wait-tab": {
|
|
50
|
+
"action": "ui.wait_for",
|
|
51
|
+
"test_id": "perps-pro-market-positions-panel-tab-twap",
|
|
52
|
+
"expected": "visible",
|
|
53
|
+
"timeout_ms": 15000,
|
|
54
|
+
"intent": "Require the TWAP management tab to be visible.",
|
|
55
|
+
"next": "open-tab"
|
|
56
|
+
},
|
|
57
|
+
"open-tab": {
|
|
58
|
+
"action": "ui.press",
|
|
59
|
+
"test_id": "perps-pro-market-positions-panel-tab-twap",
|
|
60
|
+
"intent": "Open TWAP management.",
|
|
61
|
+
"next": "open-active"
|
|
62
|
+
},
|
|
63
|
+
"open-active": {
|
|
64
|
+
"action": "ui.press",
|
|
65
|
+
"test_id": "perps-pro-market-twap-view-tab-active",
|
|
66
|
+
"intent": "Select Active explicitly so History cannot satisfy the assertion.",
|
|
67
|
+
"next": "position-market"
|
|
68
|
+
},
|
|
69
|
+
"position-market": {
|
|
70
|
+
"action": "ui.scroll",
|
|
71
|
+
"test_id": "perps-pro-market-twap-market-{{params.market}}",
|
|
72
|
+
"offset": 600,
|
|
73
|
+
"intent": "Expose an active card for the selected market.",
|
|
74
|
+
"next": "wait-market"
|
|
75
|
+
},
|
|
76
|
+
"wait-market": {
|
|
77
|
+
"action": "ui.wait_for",
|
|
78
|
+
"test_id": "perps-pro-market-twap-market-{{params.market}}",
|
|
79
|
+
"expected": "visible",
|
|
80
|
+
"timeout_ms": 20000,
|
|
81
|
+
"intent": "Require an active card for the selected market to remain visible.",
|
|
82
|
+
"next": "capture"
|
|
83
|
+
},
|
|
84
|
+
"capture": {
|
|
85
|
+
"action": "ui.screenshot",
|
|
86
|
+
"path": "screenshots/evidence-twap-active-{{params.market}}.png",
|
|
87
|
+
"label": "The selected market is visible in the TWAP Active tab.",
|
|
88
|
+
"intent": "Preserve the visible active TWAP card for review.",
|
|
89
|
+
"next": "done"
|
|
90
|
+
},
|
|
91
|
+
"done": {
|
|
92
|
+
"action": "end",
|
|
93
|
+
"status": "pass"
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://farmslot.io/schemas/recipe-v1.schema.json",
|
|
3
|
+
"title": "Place a Mobile Pro TWAP",
|
|
4
|
+
"description": "Places one parameterized TWAP through visible Mobile Pro controls, cleaning only the testnet path.",
|
|
5
|
+
"paramsSchema": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"properties": {
|
|
9
|
+
"account": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"default": "",
|
|
12
|
+
"description": "Optional exact fixture account name, such as Trading or dev1. Omit it to keep the currently selected account."
|
|
13
|
+
},
|
|
14
|
+
"provider": { "type": "string", "default": "hyperliquid" },
|
|
15
|
+
"network": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"enum": ["testnet", "mainnet"],
|
|
18
|
+
"default": "testnet",
|
|
19
|
+
"description": "Mainnet placement requires an explicit user request."
|
|
20
|
+
},
|
|
21
|
+
"market": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"default": "BTC"
|
|
24
|
+
},
|
|
25
|
+
"side": {
|
|
26
|
+
"type": "string",
|
|
27
|
+
"enum": [
|
|
28
|
+
"long",
|
|
29
|
+
"short"
|
|
30
|
+
],
|
|
31
|
+
"default": "long"
|
|
32
|
+
},
|
|
33
|
+
"notional": {
|
|
34
|
+
"type": "string",
|
|
35
|
+
"default": "110"
|
|
36
|
+
},
|
|
37
|
+
"randomize": {
|
|
38
|
+
"type": "string",
|
|
39
|
+
"enum": ["true", "false"],
|
|
40
|
+
"default": "false"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"workflow": {
|
|
45
|
+
"entry": "prepare",
|
|
46
|
+
"nodes": {
|
|
47
|
+
"prepare": {
|
|
48
|
+
"action": "call",
|
|
49
|
+
"ref": "perps.pro-order-setup",
|
|
50
|
+
"params": {
|
|
51
|
+
"account": "{{params.account}}",
|
|
52
|
+
"provider": "{{params.provider}}",
|
|
53
|
+
"network": "{{params.network}}",
|
|
54
|
+
"market": "{{params.market}}",
|
|
55
|
+
"side": "{{params.side}}"
|
|
56
|
+
},
|
|
57
|
+
"intent": "Prepare the requested Pro order form and Advanced picker.",
|
|
58
|
+
"next": "position-twap"
|
|
59
|
+
},
|
|
60
|
+
"position-twap": {
|
|
61
|
+
"action": "ui.scroll",
|
|
62
|
+
"test_id": "perps-order-type-twap",
|
|
63
|
+
"scroll_into_view": true,
|
|
64
|
+
"intent": "Expose the TWAP option for visible selection.",
|
|
65
|
+
"next": "wait-twap"
|
|
66
|
+
},
|
|
67
|
+
"wait-twap": {
|
|
68
|
+
"action": "ui.wait_for",
|
|
69
|
+
"test_id": "perps-order-type-twap",
|
|
70
|
+
"expected": "visible",
|
|
71
|
+
"timeout_ms": 10000,
|
|
72
|
+
"intent": "Fail closed unless TWAP is visibly offered.",
|
|
73
|
+
"next": "select-twap"
|
|
74
|
+
},
|
|
75
|
+
"select-twap": {
|
|
76
|
+
"action": "ui.press",
|
|
77
|
+
"test_id": "perps-order-type-twap",
|
|
78
|
+
"intent": "Select TWAP.",
|
|
79
|
+
"next": "position-size"
|
|
80
|
+
},
|
|
81
|
+
"position-size": {
|
|
82
|
+
"action": "ui.scroll",
|
|
83
|
+
"test_id": "perps-pro-order-form-size-card",
|
|
84
|
+
"scroll_into_view": true,
|
|
85
|
+
"intent": "Expose the TWAP size input for visible entry.",
|
|
86
|
+
"next": "wait-size"
|
|
87
|
+
},
|
|
88
|
+
"wait-size": {
|
|
89
|
+
"action": "ui.wait_for",
|
|
90
|
+
"test_id": "perps-pro-order-form-size-card",
|
|
91
|
+
"expected": "visible",
|
|
92
|
+
"timeout_ms": 10000,
|
|
93
|
+
"intent": "Confirm the TWAP size card is visible.",
|
|
94
|
+
"next": "set-size"
|
|
95
|
+
},
|
|
96
|
+
"set-size": {
|
|
97
|
+
"action": "ui.set_input",
|
|
98
|
+
"test_id": "perps-pro-order-form-size-input",
|
|
99
|
+
"value": "{{params.notional}}",
|
|
100
|
+
"intent": "Enter the requested USD notional.",
|
|
101
|
+
"next": "choose-randomize"
|
|
102
|
+
},
|
|
103
|
+
"choose-randomize": {
|
|
104
|
+
"action": "switch",
|
|
105
|
+
"value": "{{params.randomize}}",
|
|
106
|
+
"equals": "true",
|
|
107
|
+
"cases": {
|
|
108
|
+
"match": "enable-randomize"
|
|
109
|
+
},
|
|
110
|
+
"default": "position-submit",
|
|
111
|
+
"intent": "Apply the requested randomization setting."
|
|
112
|
+
},
|
|
113
|
+
"enable-randomize": {
|
|
114
|
+
"action": "ui.press",
|
|
115
|
+
"test_id": "perps-pro-order-form-twap-randomize",
|
|
116
|
+
"intent": "Enable randomized slice timing.",
|
|
117
|
+
"next": "position-submit"
|
|
118
|
+
},
|
|
119
|
+
"position-submit": {
|
|
120
|
+
"action": "ui.scroll",
|
|
121
|
+
"test_id": "perps-pro-order-form-summary-fees",
|
|
122
|
+
"scroll_into_view": true,
|
|
123
|
+
"intent": "Expose the final TWAP fee row directly above submission.",
|
|
124
|
+
"next": "wait-submit"
|
|
125
|
+
},
|
|
126
|
+
"wait-submit": {
|
|
127
|
+
"action": "ui.wait_for",
|
|
128
|
+
"test_id": "perps-pro-order-form-place-order",
|
|
129
|
+
"expected": "visible",
|
|
130
|
+
"timeout_ms": 10000,
|
|
131
|
+
"intent": "Confirm the valid TWAP can be submitted.",
|
|
132
|
+
"next": "submit"
|
|
133
|
+
},
|
|
134
|
+
"submit": {
|
|
135
|
+
"action": "ui.press",
|
|
136
|
+
"test_id": "perps-pro-order-form-place-order",
|
|
137
|
+
"intent": "Submit the TWAP to the selected provider and network.",
|
|
138
|
+
"next": "done"
|
|
139
|
+
},
|
|
140
|
+
"done": {
|
|
141
|
+
"action": "end",
|
|
142
|
+
"status": "pass"
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>Mobile Pro advanced orders — QA walkthrough</title>
|
|
7
|
+
<meta name="description" content="Offline QA walkthrough and reusable mm-harness commands for Mobile Pro TWAP, Chase, and Scale orders.">
|
|
8
|
+
<link rel="icon" href="assets/metamask-fox.svg" type="image/svg+xml">
|
|
9
|
+
<link rel="stylesheet" href="assets/style.css?v=4">
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<a class="skip" href="#checks">Skip to checks</a>
|
|
13
|
+
<header class="topbar">
|
|
14
|
+
<div class="wrap topbar-inner">
|
|
15
|
+
<a class="brand" href="index.html"><img class="brand-mark" src="assets/metamask-fox.svg" alt="" width="22" height="22"><span class="brand-name">recipes</span></a>
|
|
16
|
+
<nav class="nav" aria-label="Main">
|
|
17
|
+
<a class="nav-cta" href="index.html#prompt">Quick start</a>
|
|
18
|
+
<a href="how-it-works.html">How it works</a>
|
|
19
|
+
<a href="perps.html" aria-current="page">Team / Perps</a>
|
|
20
|
+
<a href="cheatsheet.html">Cheatsheet</a>
|
|
21
|
+
<a href="architecture.html">Architecture</a>
|
|
22
|
+
<a href="tutorials/index.html">Tutorials</a>
|
|
23
|
+
</nav>
|
|
24
|
+
</div>
|
|
25
|
+
</header>
|
|
26
|
+
<main>
|
|
27
|
+
<section class="wrap hero" style="padding-bottom:1rem">
|
|
28
|
+
<span class="eyebrow">Mobile Pro QA</span>
|
|
29
|
+
<h1>Advanced orders must remain observable</h1>
|
|
30
|
+
<p class="lede">Place TWAP, Chase, and Scale through visible Pro controls, then prove the resulting work remains available where a trader expects to monitor it.</p>
|
|
31
|
+
<div class="hero-meta"><span>Hyperliquid testnet</span><span>visible UI only</span><span>parameterized recipes</span></div>
|
|
32
|
+
</section>
|
|
33
|
+
|
|
34
|
+
<section class="wrap" id="checks">
|
|
35
|
+
<div class="note blue">
|
|
36
|
+
<span class="note-title">Safety boundary</span>
|
|
37
|
+
<p>Use a prepared fixture wallet with the three Mobile flags enabled. Omit <code>account</code> to keep the account already selected in MetaMask. Provider, network, and market use the recipe defaults; every recipe defaults to testnet. Mainnet requires an explicit user request; never infer it from context. Assertions preserve orders on either network, and placement preserves existing mainnet trading state. Do not use React state overrides, coordinate gestures, reloads, or background transitions to repair a failed proof.</p>
|
|
38
|
+
</div>
|
|
39
|
+
|
|
40
|
+
<h2>Preflight</h2>
|
|
41
|
+
<ol>
|
|
42
|
+
<li>Launch and verify the prepared Mobile slot with <code>mm-harness launch ios --verify --adapter mobile --target <mobile-checkout></code>.</li>
|
|
43
|
+
<li>Confirm the recipes appear in <code>mm-harness run --list --adapter mobile</code>.</li>
|
|
44
|
+
<li>Choose a funded testnet account and market, and pass explicit parameters when its safe ladder prices differ from the BTC defaults.</li>
|
|
45
|
+
<li>Let cleanup finish after every lane. Preserve the first failure and its trace.</li>
|
|
46
|
+
</ol>
|
|
47
|
+
|
|
48
|
+
<h2>TWAP: place, then monitor</h2>
|
|
49
|
+
<div class="cmd"><pre><code>mm-harness run perps.twap-place account=dev1 provider=hyperliquid network=testnet market=BTC side=long notional=110 randomize=false --adapter mobile
|
|
50
|
+
mm-harness run perps.twap-assert-active account=dev1 provider=hyperliquid network=testnet market=BTC --adapter mobile</code></pre></div>
|
|
51
|
+
<ol>
|
|
52
|
+
<li>The Advanced picker visibly offers TWAP.</li>
|
|
53
|
+
<li>The five-minute schedule is accepted and the form resets.</li>
|
|
54
|
+
<li>The TWAP tab opens on Active and shows a card for the selected market.</li>
|
|
55
|
+
</ol>
|
|
56
|
+
<p>A placement toast without an active card is a product failure: the schedule has vanished from the trader's monitoring surface. Mobile supports a 24-hour venue maximum; do not claim a seven-day duration, trigger price, or max price.</p>
|
|
57
|
+
|
|
58
|
+
<h2>Chase: survive a foreground dwell</h2>
|
|
59
|
+
<div class="cmd"><pre><code>mm-harness run perps.chase-place account=dev1 provider=hyperliquid network=testnet market=BTC side=long notional=100 max_distance=5000 --adapter mobile
|
|
60
|
+
mm-harness run perps.chase-assert-running account=dev1 provider=hyperliquid network=testnet market=BTC dwell_ms=12000 --adapter mobile
|
|
61
|
+
mm-harness run perps.chase-terminate account=dev1 provider=hyperliquid network=testnet market=BTC --adapter mobile</code></pre></div>
|
|
62
|
+
<ol>
|
|
63
|
+
<li>The Advanced picker visibly offers Chase and the form shows its foreground disclosure.</li>
|
|
64
|
+
<li>After placement, the Chase tab shows the market as Running.</li>
|
|
65
|
+
<li>The app remains foregrounded for the full dwell. The same row must still be visible afterward.</li>
|
|
66
|
+
<li>Terminate the session and confirm it leaves the active list.</li>
|
|
67
|
+
</ol>
|
|
68
|
+
<p>If the row disappears during the dwell, classify whether the trace shows product state loss, selector drift, harness transport failure, or a venue rejection. Do not claim force-kill conversion; Mobile's supported boundary is graceful foreground/background lifecycle handling.</p>
|
|
69
|
+
|
|
70
|
+
<h2>Scale: expose every child order</h2>
|
|
71
|
+
<div class="cmd"><pre><code>mm-harness run perps.scale-place account=dev1 provider=hyperliquid network=testnet market=BTC side=long notional=100 orders=3 skew=1 start_price=70000 end_price=75000 --adapter mobile
|
|
72
|
+
mm-harness run perps.scale-assert-orders account=dev1 provider=hyperliquid network=testnet market=BTC orders=3 --adapter mobile</code></pre></div>
|
|
73
|
+
<ol>
|
|
74
|
+
<li>The Advanced picker visibly offers Scale.</li>
|
|
75
|
+
<li>Start, end, order count, skew, and notional produce a visible preview before submission.</li>
|
|
76
|
+
<li>The standard Orders tab reports the requested count and shows the child entries as Limit orders.</li>
|
|
77
|
+
</ol>
|
|
78
|
+
<p>Partial venue acceptance is a failed full-ladder proof. This walkthrough does not claim group cancellation.</p>
|
|
79
|
+
|
|
80
|
+
<h2>Classify and report</h2>
|
|
81
|
+
<div class="table-scroll">
|
|
82
|
+
<table>
|
|
83
|
+
<thead><tr><th>Class</th><th>Evidence</th><th>Action</th></tr></thead>
|
|
84
|
+
<tbody>
|
|
85
|
+
<tr><td>Product defect</td><td>Bridge remains live; product selector/state disappears or venue-backed UI contradicts acceptance.</td><td>Record the first failing node, trace, screenshot, market, side, and elapsed time.</td></tr>
|
|
86
|
+
<tr><td>Recipe drift</td><td>Current product source or live tree establishes an intentional selector/flow change.</td><td>Repair the smallest node and rerun every caller.</td></tr>
|
|
87
|
+
<tr><td>Harness defect</td><td>A declared action violates its schema or reports a false verdict independent of product behavior.</td><td>Fix the harness and retain before/after proof.</td></tr>
|
|
88
|
+
<tr><td>Environment or venue</td><td>Fixture, funding, connectivity, capability, or exchange rejection prevents the product claim.</td><td>Fail closed and report the precise prerequisite; do not manufacture state.</td></tr>
|
|
89
|
+
</tbody>
|
|
90
|
+
</table>
|
|
91
|
+
</div>
|
|
92
|
+
</section>
|
|
93
|
+
</main>
|
|
94
|
+
<script type="module" src="assets/progress.mjs?v=4"></script>
|
|
95
|
+
</body>
|
|
96
|
+
</html>
|