@deeeed/metamask-harness 0.44.0 → 0.44.1
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
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.44.1 - 2026-08-27
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Accept retained market context as lifecycle-valid Homepage evidence during account-only switches.
|
|
10
|
+
- Require controller-backed Mobile unlock proof before continuing a recipe after startup or restart.
|
|
11
|
+
|
|
5
12
|
## 0.44.0 - 2026-08-25
|
|
6
13
|
|
|
7
14
|
### Fixed
|
|
@@ -418,8 +418,15 @@ const COMMANDS = {
|
|
|
418
418
|
var agenticPresent = typeof globalThis.__AGENTIC__ !== 'undefined';
|
|
419
419
|
var route = globalThis.__AGENTIC__?.getRoute() || null;
|
|
420
420
|
var account = null;
|
|
421
|
+
var keyringUnlocked = false;
|
|
421
422
|
try { account = globalThis.__AGENTIC__?.getSelectedAccount() || null; } catch(e) {}
|
|
422
|
-
|
|
423
|
+
try { keyringUnlocked = globalThis.Engine?.context?.KeyringController?.isUnlocked?.() === true; } catch(e) {}
|
|
424
|
+
return {
|
|
425
|
+
route: route,
|
|
426
|
+
account: account,
|
|
427
|
+
agenticPresent: agenticPresent,
|
|
428
|
+
keyringUnlocked: keyringUnlocked,
|
|
429
|
+
};
|
|
423
430
|
})()`;
|
|
424
431
|
const snapshot = await cdpEval(client, expr);
|
|
425
432
|
return { ...snapshot, deviceName: deviceName || '', platform: platform || '' };
|
|
@@ -680,6 +680,13 @@ function frameTime(record) {
|
|
|
680
680
|
|
|
681
681
|
function frameIsFresh(record) {
|
|
682
682
|
if (record.fresh_for_lifecycle === false) return false;
|
|
683
|
+
if (record.source === "retained_market_context") {
|
|
684
|
+
return (
|
|
685
|
+
record.lifecycle === "account_switch" &&
|
|
686
|
+
!isAccountContentVariant(record.content_variant) &&
|
|
687
|
+
record.fresh_for_lifecycle === true
|
|
688
|
+
);
|
|
689
|
+
}
|
|
683
690
|
return (
|
|
684
691
|
FRESH_SOURCES.has(record.source) ||
|
|
685
692
|
((record.source === "resident_state" || record.source === "memory_cache") &&
|
|
@@ -94,7 +94,7 @@ async function waitForWalletState(input, initialStatus, timeoutMs) {
|
|
|
94
94
|
const deadline = Date.now() + timeoutMs;
|
|
95
95
|
let last = initialStatus;
|
|
96
96
|
while (true) {
|
|
97
|
-
if (
|
|
97
|
+
if (isUnlockedStatus(last, input) || routeName(last, input) === 'Login') return last;
|
|
98
98
|
if (Date.now() >= deadline) break;
|
|
99
99
|
await new Promise((resolve) => setTimeout(resolve, 250));
|
|
100
100
|
try {
|
|
@@ -104,6 +104,11 @@ async function waitForWalletState(input, initialStatus, timeoutMs) {
|
|
|
104
104
|
// still bounds this loop and the final error reports the last wallet state.
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
|
+
if (selectedAccount(last, input)) {
|
|
108
|
+
throw new Error(
|
|
109
|
+
`Mobile wallet route and controller unlock state did not settle within the remaining ${timeoutMs}ms target budget (route ${routeName(last, input) || 'unknown'}).`,
|
|
110
|
+
);
|
|
111
|
+
}
|
|
107
112
|
throw new Error(
|
|
108
113
|
`No wallet onboarded on this device (route ${routeName(last, input) || 'unknown'}, empty wallet status) — unlock has nothing to unlock.\n Next: mm-harness fixtures set # applies the fixture wallet, then re-run: mm-harness call ensure_unlocked`,
|
|
109
114
|
);
|
|
@@ -116,7 +121,7 @@ async function waitForUnlocked(input, timeoutMs = 30000) {
|
|
|
116
121
|
while (Date.now() < deadline) {
|
|
117
122
|
try {
|
|
118
123
|
last = await statusBeforeDeadline(input, deadline);
|
|
119
|
-
if (
|
|
124
|
+
if (isUnlockedStatus(last, input)) return last;
|
|
120
125
|
} catch (error) {
|
|
121
126
|
lastError = error;
|
|
122
127
|
}
|
|
@@ -126,7 +131,14 @@ async function waitForUnlocked(input, timeoutMs = 30000) {
|
|
|
126
131
|
}
|
|
127
132
|
|
|
128
133
|
function isUnlockedStatus(status, input) {
|
|
129
|
-
|
|
134
|
+
const selected = selectedStatus(status, input);
|
|
135
|
+
const route = routeName(status, input);
|
|
136
|
+
return (
|
|
137
|
+
Boolean(selectedAccount(status, input)) &&
|
|
138
|
+
selected?.keyringUnlocked === true &&
|
|
139
|
+
route.length > 0 &&
|
|
140
|
+
route !== 'Login'
|
|
141
|
+
);
|
|
130
142
|
}
|
|
131
143
|
|
|
132
144
|
async function waitForStableUnlocked(input, initialStatus, stableMs = 750) {
|
|
@@ -188,6 +200,8 @@ export async function ensureUnlocked(input) {
|
|
|
188
200
|
action: input.action,
|
|
189
201
|
unlocked: true,
|
|
190
202
|
alreadyUnlocked: true,
|
|
203
|
+
keyringUnlocked:
|
|
204
|
+
selectedStatus(stableBefore, input)?.keyringUnlocked === true,
|
|
191
205
|
account: selectedAccount(stableBefore, input),
|
|
192
206
|
deviceName: selectedStatus(stableBefore, input)?.deviceName ?? null,
|
|
193
207
|
platform: selectedStatus(stableBefore, input)?.platform ?? null,
|
|
@@ -209,11 +223,13 @@ export async function ensureUnlocked(input) {
|
|
|
209
223
|
}
|
|
210
224
|
try {
|
|
211
225
|
const current = await statusBeforeDeadline(input, unlockDeadline);
|
|
212
|
-
if (
|
|
226
|
+
if (isUnlockedStatus(current, input)) {
|
|
213
227
|
return {
|
|
214
228
|
action: input.action,
|
|
215
229
|
unlocked: true,
|
|
216
230
|
alreadyUnlocked: true,
|
|
231
|
+
keyringUnlocked:
|
|
232
|
+
selectedStatus(current, input)?.keyringUnlocked === true,
|
|
217
233
|
account: selectedAccount(current, input),
|
|
218
234
|
deviceName: selectedStatus(current, input)?.deviceName ?? null,
|
|
219
235
|
platform: selectedStatus(current, input)?.platform ?? null,
|
|
@@ -246,6 +262,8 @@ export async function ensureUnlocked(input) {
|
|
|
246
262
|
return {
|
|
247
263
|
action: input.action,
|
|
248
264
|
unlocked: Boolean(result?.ok ?? result?.unlocked ?? true),
|
|
265
|
+
keyringUnlocked:
|
|
266
|
+
selectedStatus(stableAfter, input)?.keyringUnlocked === true,
|
|
249
267
|
account: selectedAccount(stableAfter, input),
|
|
250
268
|
route: selectedStatus(stableAfter, input)?.route ?? null,
|
|
251
269
|
deviceName: selectedStatus(stableAfter, input)?.deviceName ?? null,
|