@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
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { dataTestId, runAdapter, withExtensionPage } from '../platform/cdp.mjs';
|
|
2
|
-
|
|
3
|
-
function nonEmpty(value, name) {
|
|
4
|
-
if (value == null) return undefined;
|
|
5
|
-
const result = String(value).trim();
|
|
6
|
-
if (!result) throw new Error(`ui.activate_and_observe ${name} must not be empty.`);
|
|
7
|
-
return result;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
function boundedInteger(value, fallback, minimum, maximum, name) {
|
|
11
|
-
const result = value == null ? fallback : Number(value);
|
|
12
|
-
if (!Number.isInteger(result) || result < minimum || result > maximum) {
|
|
13
|
-
throw new Error(`ui.activate_and_observe ${name} must be an integer from ${minimum} to ${maximum}.`);
|
|
14
|
-
}
|
|
15
|
-
return result;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function stringList(value, name) {
|
|
19
|
-
if (value == null) return [];
|
|
20
|
-
if (!Array.isArray(value)) throw new Error(`ui.activate_and_observe ${name} must be an array.`);
|
|
21
|
-
return [...new Set(value.map((entry) => String(entry).trim()).filter(Boolean))];
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
runAdapter(async (input) => withExtensionPage(input, async (page) => {
|
|
25
|
-
const testId = nonEmpty(input.node?.test_id ?? input.node?.testID, 'test_id');
|
|
26
|
-
const selector = nonEmpty(input.node?.selector, 'selector');
|
|
27
|
-
if (Number(Boolean(testId)) + Number(Boolean(selector)) !== 1) {
|
|
28
|
-
throw new Error('ui.activate_and_observe requires exactly one of test_id or selector.');
|
|
29
|
-
}
|
|
30
|
-
const target = selector ?? dataTestId(testId);
|
|
31
|
-
const timeoutMs = boundedInteger(input.node?.timeout_ms, 10_000, 1, 60_000, 'timeout_ms');
|
|
32
|
-
const settleMs = boundedInteger(input.node?.settle_ms, 250, 0, 10_000, 'settle_ms');
|
|
33
|
-
const maxItems = boundedInteger(input.node?.max_items, 100, 1, 200, 'max_items');
|
|
34
|
-
const requireTestIds = stringList(input.node?.require_test_ids, 'require_test_ids');
|
|
35
|
-
const requireText = stringList(input.node?.require_text, 'require_text');
|
|
36
|
-
|
|
37
|
-
const deadline = Date.now() + timeoutMs;
|
|
38
|
-
let targetVisible = false;
|
|
39
|
-
while (Date.now() <= deadline) {
|
|
40
|
-
targetVisible = await page.evaluate(`(() => {
|
|
41
|
-
const element = document.querySelector(${JSON.stringify(target)});
|
|
42
|
-
if (!element) return false;
|
|
43
|
-
const style = getComputedStyle(element);
|
|
44
|
-
const rect = element.getBoundingClientRect();
|
|
45
|
-
return style.display !== 'none' && style.visibility !== 'hidden' && rect.width > 0 && rect.height > 0;
|
|
46
|
-
})()`);
|
|
47
|
-
if (targetVisible) break;
|
|
48
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
49
|
-
}
|
|
50
|
-
if (!targetVisible) throw new Error(`ui.activate_and_observe target did not become visible: ${target}`);
|
|
51
|
-
const interaction = await page.click(target);
|
|
52
|
-
if (settleMs > 0) await new Promise((resolve) => setTimeout(resolve, settleMs));
|
|
53
|
-
const observed = await page.evaluate(`(() => {
|
|
54
|
-
const maximum = ${JSON.stringify(maxItems)};
|
|
55
|
-
const controls = [];
|
|
56
|
-
for (const element of document.querySelectorAll('[data-testid]')) {
|
|
57
|
-
const testId = element.getAttribute('data-testid');
|
|
58
|
-
if (!testId) continue;
|
|
59
|
-
const style = getComputedStyle(element);
|
|
60
|
-
const rect = element.getBoundingClientRect();
|
|
61
|
-
if (style.display === 'none' || style.visibility === 'hidden' || rect.width <= 0 || rect.height <= 0) continue;
|
|
62
|
-
controls.push({
|
|
63
|
-
testId,
|
|
64
|
-
label: String(element.getAttribute('aria-label') || element.innerText || '')
|
|
65
|
-
.replace(/\\s+/gu, ' ')
|
|
66
|
-
.trim()
|
|
67
|
-
.slice(0, 500),
|
|
68
|
-
});
|
|
69
|
-
if (controls.length >= maximum) break;
|
|
70
|
-
}
|
|
71
|
-
return {
|
|
72
|
-
route: location.hash,
|
|
73
|
-
text: String(document.body?.innerText || '').replace(/\\s+/gu, ' ').trim().slice(0, 20_000),
|
|
74
|
-
controls,
|
|
75
|
-
};
|
|
76
|
-
})()`);
|
|
77
|
-
const observedTestIds = observed.controls.map((entry) => entry.testId);
|
|
78
|
-
const observedText = [observed.text, ...observed.controls.map((entry) => entry.label)].join(' ');
|
|
79
|
-
const missingTestIds = requireTestIds.filter((entry) => !observedTestIds.includes(entry));
|
|
80
|
-
const missingText = requireText.filter((entry) => !observedText.includes(entry));
|
|
81
|
-
if (missingTestIds.length > 0 || missingText.length > 0) {
|
|
82
|
-
throw new Error([
|
|
83
|
-
missingTestIds.length > 0 ? `missing test IDs: ${missingTestIds.join(', ')}` : '',
|
|
84
|
-
missingText.length > 0 ? `missing text: ${missingText.join(', ')}` : '',
|
|
85
|
-
].filter(Boolean).join('; '));
|
|
86
|
-
}
|
|
87
|
-
return {
|
|
88
|
-
action: input.action,
|
|
89
|
-
interaction,
|
|
90
|
-
route: observed.route,
|
|
91
|
-
controls: observed.controls,
|
|
92
|
-
observedTestIds,
|
|
93
|
-
matchedText: requireText,
|
|
94
|
-
proofPath: 'trusted-pointer-visible-ui',
|
|
95
|
-
};
|
|
96
|
-
}));
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://farmslot.io/schemas/recipe-v1.schema.json",
|
|
3
|
-
"title": "Assets release custom-gas token send",
|
|
4
|
-
"description": "Applies a custom gas limit to a tiny token send and proves the confirmed Activity details.",
|
|
5
|
-
"paramsSchema": {
|
|
6
|
-
"type": "object",
|
|
7
|
-
"additionalProperties": false,
|
|
8
|
-
"properties": {
|
|
9
|
-
"source_address": { "type": "string", "default": "0x8dc623e964475d4d669da601fd15ea9125469003" },
|
|
10
|
-
"network": { "type": "string", "default": "Arbitrum" },
|
|
11
|
-
"chain_id": { "type": "integer", "minimum": 1, "default": 42161 },
|
|
12
|
-
"symbol": { "type": "string", "default": "USDC" },
|
|
13
|
-
"recipient": { "type": "string", "default": "0x5993d2153f080470bfe765ae81f4fa5fa2080916" },
|
|
14
|
-
"amount": { "type": ["string", "number"], "default": "0.01" },
|
|
15
|
-
"gas_limit": { "type": ["string", "number"], "default": 70000 },
|
|
16
|
-
"confirm_live": { "type": "boolean", "default": false },
|
|
17
|
-
"timeout_ms": { "type": "integer", "minimum": 1000, "default": 120000 }
|
|
18
|
-
}
|
|
19
|
-
},
|
|
20
|
-
"workflow": {
|
|
21
|
-
"entry": "select-source",
|
|
22
|
-
"nodes": {
|
|
23
|
-
"select-source": {
|
|
24
|
-
"action": "metamask.wallet.select_account",
|
|
25
|
-
"address": "{{params.source_address}}",
|
|
26
|
-
"intent": "Select the funded source account",
|
|
27
|
-
"next": "select-network"
|
|
28
|
-
},
|
|
29
|
-
"select-network": {
|
|
30
|
-
"action": "ui.navigate",
|
|
31
|
-
"page": "network",
|
|
32
|
-
"network": "{{params.network}}",
|
|
33
|
-
"chain_id": "{{params.chain_id}}",
|
|
34
|
-
"add_if_missing": false,
|
|
35
|
-
"timeout_ms": "{{params.timeout_ms}}",
|
|
36
|
-
"intent": "Select the funded token network",
|
|
37
|
-
"next": "prepare-send"
|
|
38
|
-
},
|
|
39
|
-
"prepare-send": {
|
|
40
|
-
"action": "metamask.assets.prepare_send",
|
|
41
|
-
"symbol": "{{params.symbol}}",
|
|
42
|
-
"recipient": "{{params.recipient}}",
|
|
43
|
-
"amount": "{{params.amount}}",
|
|
44
|
-
"timeout_ms": "{{params.timeout_ms}}",
|
|
45
|
-
"intent": "Prepare the tiny token send",
|
|
46
|
-
"next": "review-send"
|
|
47
|
-
},
|
|
48
|
-
"review-send": {
|
|
49
|
-
"action": "metamask.assets.review_send",
|
|
50
|
-
"timeout_ms": "{{params.timeout_ms}}",
|
|
51
|
-
"intent": "Open the send confirmation",
|
|
52
|
-
"next": "set-custom-gas"
|
|
53
|
-
},
|
|
54
|
-
"set-custom-gas": {
|
|
55
|
-
"action": "metamask.assets.set_custom_gas",
|
|
56
|
-
"gas_limit": "{{params.gas_limit}}",
|
|
57
|
-
"timeout_ms": "{{params.timeout_ms}}",
|
|
58
|
-
"intent": "Apply and prove the requested custom gas limit",
|
|
59
|
-
"next": "capture-confirmation"
|
|
60
|
-
},
|
|
61
|
-
"capture-confirmation": {
|
|
62
|
-
"action": "ui.screenshot",
|
|
63
|
-
"path": "screenshots/assets-custom-gas-confirmation.png",
|
|
64
|
-
"label": "Custom-gas token send confirmation",
|
|
65
|
-
"intent": "Preserve the custom-gas review evidence",
|
|
66
|
-
"next": "finish-send"
|
|
67
|
-
},
|
|
68
|
-
"finish-send": {
|
|
69
|
-
"action": "metamask.assets.finish_send",
|
|
70
|
-
"decision": "confirm",
|
|
71
|
-
"symbol": "{{params.symbol}}",
|
|
72
|
-
"amount": "{{params.amount}}",
|
|
73
|
-
"confirm_live": "{{params.confirm_live}}",
|
|
74
|
-
"timeout_ms": "{{params.timeout_ms}}",
|
|
75
|
-
"intent": "Confirm the authorized tiny custom-gas send and prove Activity details",
|
|
76
|
-
"next": "capture-confirmed"
|
|
77
|
-
},
|
|
78
|
-
"capture-confirmed": {
|
|
79
|
-
"action": "ui.screenshot",
|
|
80
|
-
"path": "screenshots/assets-custom-gas-confirmed.png",
|
|
81
|
-
"label": "Custom-gas token send confirmed",
|
|
82
|
-
"intent": "Preserve the confirmed custom-gas transaction evidence",
|
|
83
|
-
"next": "done"
|
|
84
|
-
},
|
|
85
|
-
"done": { "action": "end", "status": "pass" }
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://farmslot.io/schemas/recipe-v1.schema.json",
|
|
3
|
-
"title": "Assets release native Max cancellation",
|
|
4
|
-
"description": "Prepares a native Max send, proves the fee-adjusted review, and cancels without broadcasting.",
|
|
5
|
-
"paramsSchema": {
|
|
6
|
-
"type": "object",
|
|
7
|
-
"additionalProperties": false,
|
|
8
|
-
"properties": {
|
|
9
|
-
"source_address": { "type": "string", "default": "0x8dc623e964475d4d669da601fd15ea9125469003" },
|
|
10
|
-
"network": { "type": "string", "default": "Ethereum" },
|
|
11
|
-
"chain_id": { "type": "integer", "minimum": 1, "default": 1 },
|
|
12
|
-
"symbol": { "type": "string", "default": "ETH" },
|
|
13
|
-
"recipient": { "type": "string", "default": "0x5993d2153f080470bfe765ae81f4fa5fa2080916" },
|
|
14
|
-
"timeout_ms": { "type": "integer", "minimum": 1000, "default": 60000 }
|
|
15
|
-
}
|
|
16
|
-
},
|
|
17
|
-
"workflow": {
|
|
18
|
-
"entry": "select-source",
|
|
19
|
-
"nodes": {
|
|
20
|
-
"select-source": {
|
|
21
|
-
"action": "metamask.wallet.select_account",
|
|
22
|
-
"address": "{{params.source_address}}",
|
|
23
|
-
"intent": "Select the funded source account",
|
|
24
|
-
"next": "select-network"
|
|
25
|
-
},
|
|
26
|
-
"select-network": {
|
|
27
|
-
"action": "ui.navigate",
|
|
28
|
-
"page": "network",
|
|
29
|
-
"network": "{{params.network}}",
|
|
30
|
-
"chain_id": "{{params.chain_id}}",
|
|
31
|
-
"add_if_missing": false,
|
|
32
|
-
"timeout_ms": "{{params.timeout_ms}}",
|
|
33
|
-
"intent": "Select the native asset network",
|
|
34
|
-
"next": "prepare-max"
|
|
35
|
-
},
|
|
36
|
-
"prepare-max": {
|
|
37
|
-
"action": "metamask.assets.prepare_send",
|
|
38
|
-
"symbol": "{{params.symbol}}",
|
|
39
|
-
"recipient": "{{params.recipient}}",
|
|
40
|
-
"max": true,
|
|
41
|
-
"timeout_ms": "{{params.timeout_ms}}",
|
|
42
|
-
"intent": "Prepare a fee-adjusted native Max send",
|
|
43
|
-
"next": "review-max"
|
|
44
|
-
},
|
|
45
|
-
"review-max": {
|
|
46
|
-
"action": "metamask.assets.review_send",
|
|
47
|
-
"timeout_ms": "{{params.timeout_ms}}",
|
|
48
|
-
"intent": "Prove the Max amount and network fee at review",
|
|
49
|
-
"next": "capture-max"
|
|
50
|
-
},
|
|
51
|
-
"capture-max": {
|
|
52
|
-
"action": "ui.screenshot",
|
|
53
|
-
"path": "screenshots/assets-native-max-review.png",
|
|
54
|
-
"label": "Native Max send review",
|
|
55
|
-
"intent": "Preserve the fee-adjusted Max evidence",
|
|
56
|
-
"next": "cancel-max"
|
|
57
|
-
},
|
|
58
|
-
"cancel-max": {
|
|
59
|
-
"action": "metamask.assets.finish_send",
|
|
60
|
-
"decision": "cancel",
|
|
61
|
-
"symbol": "{{params.symbol}}",
|
|
62
|
-
"amount": "max",
|
|
63
|
-
"timeout_ms": "{{params.timeout_ms}}",
|
|
64
|
-
"intent": "Cancel the Max send without broadcasting",
|
|
65
|
-
"next": "done"
|
|
66
|
-
},
|
|
67
|
-
"done": { "action": "end", "status": "pass" }
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://farmslot.io/schemas/recipe-v1.schema.json",
|
|
3
|
-
"title": "Assets release native Max self-send",
|
|
4
|
-
"description": "Submits a native Max self-send and proves its confirmed Activity details.",
|
|
5
|
-
"paramsSchema": {
|
|
6
|
-
"type": "object",
|
|
7
|
-
"additionalProperties": false,
|
|
8
|
-
"properties": {
|
|
9
|
-
"source_address": { "type": "string", "default": "0x8dc623e964475d4d669da601fd15ea9125469003" },
|
|
10
|
-
"network": { "type": "string", "default": "Ethereum" },
|
|
11
|
-
"chain_id": { "type": "integer", "minimum": 1, "default": 1 },
|
|
12
|
-
"symbol": { "type": "string", "default": "ETH" },
|
|
13
|
-
"confirm_live": { "type": "boolean", "default": false },
|
|
14
|
-
"timeout_ms": { "type": "integer", "minimum": 1000, "default": 120000 }
|
|
15
|
-
}
|
|
16
|
-
},
|
|
17
|
-
"workflow": {
|
|
18
|
-
"entry": "select-source",
|
|
19
|
-
"nodes": {
|
|
20
|
-
"select-source": {
|
|
21
|
-
"action": "metamask.wallet.select_account",
|
|
22
|
-
"address": "{{params.source_address}}",
|
|
23
|
-
"intent": "Select the funded source account",
|
|
24
|
-
"next": "select-network"
|
|
25
|
-
},
|
|
26
|
-
"select-network": {
|
|
27
|
-
"action": "ui.navigate",
|
|
28
|
-
"page": "network",
|
|
29
|
-
"network": "{{params.network}}",
|
|
30
|
-
"chain_id": "{{params.chain_id}}",
|
|
31
|
-
"add_if_missing": false,
|
|
32
|
-
"timeout_ms": "{{params.timeout_ms}}",
|
|
33
|
-
"intent": "Select the native asset network",
|
|
34
|
-
"next": "prepare-max"
|
|
35
|
-
},
|
|
36
|
-
"prepare-max": {
|
|
37
|
-
"action": "metamask.assets.prepare_send",
|
|
38
|
-
"symbol": "{{params.symbol}}",
|
|
39
|
-
"recipient": "{{params.source_address}}",
|
|
40
|
-
"max": true,
|
|
41
|
-
"timeout_ms": "{{params.timeout_ms}}",
|
|
42
|
-
"intent": "Prepare a native Max self-send",
|
|
43
|
-
"next": "review-max"
|
|
44
|
-
},
|
|
45
|
-
"review-max": {
|
|
46
|
-
"action": "metamask.assets.review_send",
|
|
47
|
-
"timeout_ms": "{{params.timeout_ms}}",
|
|
48
|
-
"intent": "Prove the confirmation amount and network fee",
|
|
49
|
-
"next": "capture-confirmation"
|
|
50
|
-
},
|
|
51
|
-
"capture-confirmation": {
|
|
52
|
-
"action": "ui.screenshot",
|
|
53
|
-
"path": "screenshots/assets-native-max-send-confirmation.png",
|
|
54
|
-
"label": "Native Max self-send confirmation",
|
|
55
|
-
"intent": "Preserve the reviewed Max evidence",
|
|
56
|
-
"next": "finish-send"
|
|
57
|
-
},
|
|
58
|
-
"finish-send": {
|
|
59
|
-
"action": "metamask.assets.finish_send",
|
|
60
|
-
"decision": "confirm",
|
|
61
|
-
"symbol": "{{params.symbol}}",
|
|
62
|
-
"amount": "max",
|
|
63
|
-
"confirm_live": "{{params.confirm_live}}",
|
|
64
|
-
"timeout_ms": "{{params.timeout_ms}}",
|
|
65
|
-
"intent": "Submit the authorized Max self-send and prove confirmed Activity details",
|
|
66
|
-
"next": "capture-confirmed"
|
|
67
|
-
},
|
|
68
|
-
"capture-confirmed": {
|
|
69
|
-
"action": "ui.screenshot",
|
|
70
|
-
"path": "screenshots/assets-native-max-send-confirmed.png",
|
|
71
|
-
"label": "Native Max self-send confirmed",
|
|
72
|
-
"intent": "Preserve the confirmed self-send evidence",
|
|
73
|
-
"next": "done"
|
|
74
|
-
},
|
|
75
|
-
"done": { "action": "end", "status": "pass" }
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://farmslot.io/schemas/recipe-v1.schema.json",
|
|
3
|
-
"title": "Assets release own-account token send",
|
|
4
|
-
"description": "Sends a tiny token amount between owned accounts and proves its confirmed Activity details.",
|
|
5
|
-
"paramsSchema": {
|
|
6
|
-
"type": "object",
|
|
7
|
-
"additionalProperties": false,
|
|
8
|
-
"properties": {
|
|
9
|
-
"source_address": { "type": "string", "default": "0x8dc623e964475d4d669da601fd15ea9125469003" },
|
|
10
|
-
"network": { "type": "string", "default": "Arbitrum" },
|
|
11
|
-
"chain_id": { "type": "integer", "minimum": 1, "default": 42161 },
|
|
12
|
-
"symbol": { "type": "string", "default": "USDC" },
|
|
13
|
-
"recipient": { "type": "string", "default": "0x5993d2153f080470bfe765ae81f4fa5fa2080916" },
|
|
14
|
-
"amount": { "type": ["string", "number"], "default": "0.01" },
|
|
15
|
-
"confirm_live": { "type": "boolean", "default": false },
|
|
16
|
-
"timeout_ms": { "type": "integer", "minimum": 1000, "default": 120000 }
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
"workflow": {
|
|
20
|
-
"entry": "select-source",
|
|
21
|
-
"nodes": {
|
|
22
|
-
"select-source": {
|
|
23
|
-
"action": "metamask.wallet.select_account",
|
|
24
|
-
"address": "{{params.source_address}}",
|
|
25
|
-
"intent": "Select the funded source account",
|
|
26
|
-
"next": "select-network"
|
|
27
|
-
},
|
|
28
|
-
"select-network": {
|
|
29
|
-
"action": "ui.navigate",
|
|
30
|
-
"page": "network",
|
|
31
|
-
"network": "{{params.network}}",
|
|
32
|
-
"chain_id": "{{params.chain_id}}",
|
|
33
|
-
"add_if_missing": false,
|
|
34
|
-
"timeout_ms": "{{params.timeout_ms}}",
|
|
35
|
-
"intent": "Select the funded token network",
|
|
36
|
-
"next": "prepare-send"
|
|
37
|
-
},
|
|
38
|
-
"prepare-send": {
|
|
39
|
-
"action": "metamask.assets.prepare_send",
|
|
40
|
-
"symbol": "{{params.symbol}}",
|
|
41
|
-
"recipient": "{{params.recipient}}",
|
|
42
|
-
"amount": "{{params.amount}}",
|
|
43
|
-
"timeout_ms": "{{params.timeout_ms}}",
|
|
44
|
-
"intent": "Prepare the tiny own-account token send",
|
|
45
|
-
"next": "review-send"
|
|
46
|
-
},
|
|
47
|
-
"review-send": {
|
|
48
|
-
"action": "metamask.assets.review_send",
|
|
49
|
-
"timeout_ms": "{{params.timeout_ms}}",
|
|
50
|
-
"intent": "Review the send and prove its network fee",
|
|
51
|
-
"next": "capture-confirmation"
|
|
52
|
-
},
|
|
53
|
-
"capture-confirmation": {
|
|
54
|
-
"action": "ui.screenshot",
|
|
55
|
-
"path": "screenshots/assets-own-account-send-confirmation.png",
|
|
56
|
-
"label": "Own-account token send confirmation",
|
|
57
|
-
"intent": "Preserve the reviewed send evidence",
|
|
58
|
-
"next": "finish-send"
|
|
59
|
-
},
|
|
60
|
-
"finish-send": {
|
|
61
|
-
"action": "metamask.assets.finish_send",
|
|
62
|
-
"decision": "confirm",
|
|
63
|
-
"symbol": "{{params.symbol}}",
|
|
64
|
-
"amount": "{{params.amount}}",
|
|
65
|
-
"confirm_live": "{{params.confirm_live}}",
|
|
66
|
-
"timeout_ms": "{{params.timeout_ms}}",
|
|
67
|
-
"intent": "Confirm the authorized tiny send and prove its Activity details",
|
|
68
|
-
"next": "capture-confirmed"
|
|
69
|
-
},
|
|
70
|
-
"capture-confirmed": {
|
|
71
|
-
"action": "ui.screenshot",
|
|
72
|
-
"path": "screenshots/assets-own-account-send-confirmed.png",
|
|
73
|
-
"label": "Own-account token send confirmed",
|
|
74
|
-
"intent": "Preserve the confirmed transaction evidence",
|
|
75
|
-
"next": "done"
|
|
76
|
-
},
|
|
77
|
-
"done": { "action": "end", "status": "pass" }
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|