w3wallets 1.0.0-beta.7 → 1.0.0-beta.9
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/dist/index.d.mts +28 -8
- package/dist/index.d.ts +28 -8
- package/dist/index.js +128 -63
- package/dist/index.mjs +128 -63
- package/dist/scripts/cache.js +24 -9
- package/package.json +2 -2
- package/src/scripts/download.js +668 -0
package/dist/index.mjs
CHANGED
|
@@ -62,12 +62,12 @@ var ARIA_CLOSE_TIMEOUT = 500;
|
|
|
62
62
|
var POPUP_HIDDEN_TIMEOUT = 3e3;
|
|
63
63
|
var POST_UNLOCK_TIMEOUT = 3e4;
|
|
64
64
|
var NOTIFICATION_CHECK_TIMEOUT = 5e3;
|
|
65
|
-
var CONFIRMATION_ROUTE_TIMEOUT = 15e3;
|
|
66
65
|
var POST_CLICK_TIMEOUT = 1e4;
|
|
67
66
|
var BUTTON_OR_POPUP_TIMEOUT = 3e4;
|
|
68
67
|
var LAST_RESORT_CLICK_TIMEOUT = 1e4;
|
|
69
68
|
var LOCK_SCREEN_TIMEOUT = 3e4;
|
|
70
69
|
var MENU_BUTTON_TIMEOUT = 3e4;
|
|
70
|
+
var ONBOARD_VISIBLE_TIMEOUT = 3e4;
|
|
71
71
|
var MNEMONIC_KEY_DELAY = 5;
|
|
72
72
|
var MNEMONIC_WORD_DELAY = 100;
|
|
73
73
|
|
|
@@ -257,7 +257,6 @@ async function findCachedExtension(context, ExtensionClass, expectedExtensionId,
|
|
|
257
257
|
const page = await context.newPage();
|
|
258
258
|
if (homeUrl) {
|
|
259
259
|
await page.goto(`chrome-extension://${expectedExtensionId}/${homeUrl}`);
|
|
260
|
-
await page.goto(`chrome-extension://${expectedExtensionId}/${homeUrl}`);
|
|
261
260
|
}
|
|
262
261
|
const extension = new ExtensionClass(page, expectedExtensionId);
|
|
263
262
|
return extension;
|
|
@@ -324,7 +323,7 @@ var Metamask = class extends Wallet {
|
|
|
324
323
|
await this.page.goto(`chrome-extension://${this.extensionId}/home.html`);
|
|
325
324
|
await expect(
|
|
326
325
|
this.page.getByRole("button", { name: "I have an existing wallet" })
|
|
327
|
-
).toBeVisible({ timeout:
|
|
326
|
+
).toBeVisible({ timeout: ONBOARD_VISIBLE_TIMEOUT });
|
|
328
327
|
}
|
|
329
328
|
/**
|
|
330
329
|
* Onboard MetaMask with a mnemonic phrase
|
|
@@ -349,7 +348,6 @@ var Metamask = class extends Wallet {
|
|
|
349
348
|
}
|
|
350
349
|
const continueBtn = this.page.getByTestId("import-srp-confirm");
|
|
351
350
|
await expect(continueBtn).toBeEnabled({ timeout: config.expectTimeout });
|
|
352
|
-
await expect(continueBtn).toBeEnabled({ timeout: config.expectTimeout });
|
|
353
351
|
await continueBtn.click();
|
|
354
352
|
const passwordInputs = this.page.locator('input[type="password"]');
|
|
355
353
|
await passwordInputs.nth(0).fill(pwd);
|
|
@@ -363,10 +361,28 @@ var Metamask = class extends Wallet {
|
|
|
363
361
|
});
|
|
364
362
|
await openWalletBtn.click();
|
|
365
363
|
await this.page.goto(`chrome-extension://${this.extensionId}/home.html`);
|
|
366
|
-
|
|
364
|
+
const readyIndicator = this.page.getByTestId("account-options-menu-button");
|
|
365
|
+
const lockInput = this.page.getByTestId("unlock-password");
|
|
366
|
+
const state = await Promise.race([
|
|
367
|
+
readyIndicator.waitFor({ state: "visible", timeout: POST_UNLOCK_TIMEOUT }).then(() => "ready"),
|
|
368
|
+
lockInput.waitFor({ state: "visible", timeout: POST_UNLOCK_TIMEOUT }).then(() => "locked")
|
|
369
|
+
]).catch(() => "timeout");
|
|
370
|
+
debug(`metamask.onboard: post-navigate state=${state}`);
|
|
371
|
+
if (state === "locked") {
|
|
372
|
+
debug("metamask.onboard: vault locked after onboarding, auto-unlocking");
|
|
373
|
+
await lockInput.fill(password ?? this.defaultPassword);
|
|
374
|
+
await this.page.getByTestId("unlock-submit").click();
|
|
375
|
+
await this.page.waitForSelector('[data-testid="unlock-password"]', {
|
|
376
|
+
state: "hidden",
|
|
377
|
+
timeout: LOCK_SCREEN_TIMEOUT
|
|
378
|
+
});
|
|
379
|
+
await this.stabilizePostUnlock();
|
|
380
|
+
}
|
|
381
|
+
await this.closeExtraExtensionPages();
|
|
367
382
|
await this.page.goto(
|
|
368
383
|
`chrome-extension://${this.extensionId}/sidepanel.html`
|
|
369
384
|
);
|
|
385
|
+
await this.page.waitForLoadState("networkidle");
|
|
370
386
|
debug("metamask.onboard: complete");
|
|
371
387
|
}
|
|
372
388
|
/**
|
|
@@ -482,10 +498,37 @@ var Metamask = class extends Wallet {
|
|
|
482
498
|
}
|
|
483
499
|
await expect(readyIndicator).toBeVisible({ timeout: POST_UNLOCK_TIMEOUT });
|
|
484
500
|
}
|
|
501
|
+
/**
|
|
502
|
+
* Close extra MetaMask extension pages that the service worker opened
|
|
503
|
+
* during onboarding (e.g. home.html#/onboarding/completion).
|
|
504
|
+
* Keeps only this.page alive.
|
|
505
|
+
*/
|
|
506
|
+
async closeExtraExtensionPages() {
|
|
507
|
+
const extOrigin = `chrome-extension://${this.extensionId}`;
|
|
508
|
+
const context = this.page.context();
|
|
509
|
+
const extras = context.pages().filter((p) => p !== this.page && p.url().startsWith(extOrigin));
|
|
510
|
+
if (extras.length > 0) {
|
|
511
|
+
debug(
|
|
512
|
+
`metamask.closeExtraExtensionPages: closing ${extras.length} extra page(s)`
|
|
513
|
+
);
|
|
514
|
+
await Promise.all(extras.map((p) => p.close()));
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* Poll the URL until it leaves a confirmation route. Uses polling instead
|
|
519
|
+
* of waitForURL because MetaMask uses HashRouter and hash-only changes
|
|
520
|
+
* are not reliably caught by Playwright's navigation events.
|
|
521
|
+
*/
|
|
522
|
+
async waitForConfirmRouteExit(routePattern) {
|
|
523
|
+
const deadline = Date.now() + POST_CLICK_TIMEOUT;
|
|
524
|
+
while (routePattern.test(this.page.url()) && Date.now() < deadline) {
|
|
525
|
+
await this.page.waitForTimeout(500);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
485
528
|
/**
|
|
486
529
|
* Wait for a target button while handling the Transaction Shield popup.
|
|
487
|
-
*
|
|
488
|
-
*
|
|
530
|
+
* Navigates to sidepanel.html so MetaMask's ConfirmationHandler routes
|
|
531
|
+
* to the pending approval, then waits for the button to become visible.
|
|
489
532
|
*/
|
|
490
533
|
async waitAndClickButton(btnLocator) {
|
|
491
534
|
debug(`metamask.waitAndClickButton: navigating to sidepanel`);
|
|
@@ -496,63 +539,36 @@ var Metamask = class extends Wallet {
|
|
|
496
539
|
btnLocator.first().waitFor({ state: "visible", timeout }).then(() => "button"),
|
|
497
540
|
popup.first().waitFor({ state: "visible", timeout }).then(() => "popup")
|
|
498
541
|
]).catch(() => "timeout");
|
|
499
|
-
const handlePopupAndClick = async () => {
|
|
500
|
-
await this.dismissPopups();
|
|
501
|
-
await btnLocator.first().waitFor({ state: "visible", timeout: BUTTON_OR_POPUP_TIMEOUT });
|
|
502
|
-
await btnLocator.first().click();
|
|
503
|
-
};
|
|
504
542
|
await this.page.goto(sidepanelUrl);
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
} catch {
|
|
510
|
-
console.warn(
|
|
511
|
-
`[w3wallets] confirmation route not found, retrying. URL: ${this.page.url()}`
|
|
543
|
+
let result = await waitForButtonOrPopup(BUTTON_OR_POPUP_TIMEOUT);
|
|
544
|
+
if (result === "timeout") {
|
|
545
|
+
debug(
|
|
546
|
+
`metamask.waitAndClickButton: first wait timed out, reloading. URL: ${this.page.url()}`
|
|
512
547
|
);
|
|
513
548
|
await this.page.goto(sidepanelUrl);
|
|
514
|
-
|
|
515
|
-
await this.page.waitForURL(confirmRoutePattern, {
|
|
516
|
-
timeout: CONFIRMATION_ROUTE_TIMEOUT
|
|
517
|
-
});
|
|
518
|
-
} catch {
|
|
519
|
-
console.warn(
|
|
520
|
-
`[w3wallets] confirmation route not found after retry. URL: ${this.page.url()}`
|
|
521
|
-
);
|
|
522
|
-
}
|
|
549
|
+
result = await waitForButtonOrPopup(BUTTON_OR_POPUP_TIMEOUT);
|
|
523
550
|
}
|
|
524
|
-
const result = await waitForButtonOrPopup(BUTTON_OR_POPUP_TIMEOUT);
|
|
525
551
|
debug(
|
|
526
552
|
`metamask.waitAndClickButton: result=${result}, URL=${this.page.url()}`
|
|
527
553
|
);
|
|
528
554
|
if (result === "button") {
|
|
529
555
|
await btnLocator.first().click();
|
|
530
|
-
await this.
|
|
531
|
-
timeout: POST_CLICK_TIMEOUT
|
|
532
|
-
}).catch(() => {
|
|
533
|
-
console.warn(
|
|
534
|
-
`[w3wallets] still on confirmation route after click. URL: ${this.page.url()}`
|
|
535
|
-
);
|
|
536
|
-
});
|
|
556
|
+
await this.waitForConfirmRouteExit(confirmRoutePattern);
|
|
537
557
|
return;
|
|
538
558
|
}
|
|
539
559
|
if (result === "popup") {
|
|
540
|
-
await
|
|
541
|
-
await
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
console.warn(
|
|
545
|
-
`[w3wallets] still on confirmation route after popup dismiss. URL: ${this.page.url()}`
|
|
546
|
-
);
|
|
547
|
-
});
|
|
560
|
+
await this.dismissPopups();
|
|
561
|
+
await btnLocator.first().waitFor({ state: "visible", timeout: BUTTON_OR_POPUP_TIMEOUT });
|
|
562
|
+
await btnLocator.first().click();
|
|
563
|
+
await this.waitForConfirmRouteExit(confirmRoutePattern);
|
|
548
564
|
return;
|
|
549
565
|
}
|
|
550
566
|
const isOnConfirmRoute = confirmRoutePattern.test(this.page.url());
|
|
551
567
|
debug(
|
|
552
|
-
`metamask.waitAndClickButton: timeout
|
|
568
|
+
`metamask.waitAndClickButton: timeout. URL: ${this.page.url()}, onConfirmRoute: ${isOnConfirmRoute}`
|
|
553
569
|
);
|
|
554
570
|
console.warn(
|
|
555
|
-
`[w3wallets] no button or popup found after
|
|
571
|
+
`[w3wallets] no button or popup found after waiting. URL: ${this.page.url()}`
|
|
556
572
|
);
|
|
557
573
|
await btnLocator.first().click({ timeout: LAST_RESORT_CLICK_TIMEOUT });
|
|
558
574
|
}
|
|
@@ -574,14 +590,50 @@ var Metamask = class extends Wallet {
|
|
|
574
590
|
await this.page.goto(`chrome-extension://${this.extensionId}/home.html`);
|
|
575
591
|
const menuBtn = this.page.getByTestId("account-options-menu-button");
|
|
576
592
|
await menuBtn.waitFor({ state: "visible", timeout: MENU_BUTTON_TIMEOUT });
|
|
577
|
-
await menuBtn.click();
|
|
593
|
+
await menuBtn.click({ force: true });
|
|
578
594
|
await this.page.locator("text=Log out").click();
|
|
579
595
|
}
|
|
580
596
|
/**
|
|
581
|
-
*
|
|
582
|
-
*
|
|
583
|
-
*
|
|
584
|
-
|
|
597
|
+
* Force-persist the vault by locking the wallet. Called by the cache builder
|
|
598
|
+
* before closing the browser context. MetaMask MV3 stores the vault lazily —
|
|
599
|
+
* locking forces the encrypted vault to be written to chrome.storage.local.
|
|
600
|
+
*/
|
|
601
|
+
async beforeCacheClose() {
|
|
602
|
+
debug("metamask.beforeCacheClose: locking wallet to force vault persistence");
|
|
603
|
+
await this.page.goto(`chrome-extension://${this.extensionId}/home.html`);
|
|
604
|
+
const menuBtn = this.page.getByTestId("account-options-menu-button");
|
|
605
|
+
const lockInput = this.page.getByTestId("unlock-password");
|
|
606
|
+
const state = await Promise.race([
|
|
607
|
+
menuBtn.waitFor({ state: "visible", timeout: MENU_BUTTON_TIMEOUT }).then(() => "ready"),
|
|
608
|
+
lockInput.waitFor({ state: "visible", timeout: MENU_BUTTON_TIMEOUT }).then(() => "locked")
|
|
609
|
+
]).catch(() => "timeout");
|
|
610
|
+
debug(`metamask.beforeCacheClose: state=${state}`);
|
|
611
|
+
if (state === "ready") {
|
|
612
|
+
await this.lock();
|
|
613
|
+
await lockInput.waitFor({ state: "visible", timeout: LOCK_SCREEN_TIMEOUT }).catch(() => {
|
|
614
|
+
});
|
|
615
|
+
} else if (state === "timeout") {
|
|
616
|
+
debug("metamask.beforeCacheClose: forcing state sync via new UI connection");
|
|
617
|
+
const syncPage = await this.page.context().newPage();
|
|
618
|
+
await syncPage.goto(`chrome-extension://${this.extensionId}/home.html`);
|
|
619
|
+
await syncPage.waitForLoadState("networkidle");
|
|
620
|
+
const syncMenuBtn = syncPage.getByTestId("account-options-menu-button");
|
|
621
|
+
const syncLockInput = syncPage.getByTestId("unlock-password");
|
|
622
|
+
const syncState = await Promise.race([
|
|
623
|
+
syncMenuBtn.waitFor({ state: "visible", timeout: MENU_BUTTON_TIMEOUT }).then(() => "ready"),
|
|
624
|
+
syncLockInput.waitFor({ state: "visible", timeout: MENU_BUTTON_TIMEOUT }).then(() => "locked")
|
|
625
|
+
]).catch(() => "timeout");
|
|
626
|
+
debug(`metamask.beforeCacheClose: syncPage state=${syncState}`);
|
|
627
|
+
if (syncState === "ready") {
|
|
628
|
+
await syncMenuBtn.click({ force: true });
|
|
629
|
+
await syncPage.locator("text=Log out").click();
|
|
630
|
+
await syncLockInput.waitFor({ state: "visible", timeout: LOCK_SCREEN_TIMEOUT }).catch(() => {
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
await syncPage.close();
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
/**
|
|
585
637
|
* Unlock MetaMask with password.
|
|
586
638
|
* After unlocking, stabilizes the wallet UI by handling post-unlock
|
|
587
639
|
* screens (metametrics, onboarding completion) and dismissing queued
|
|
@@ -591,14 +643,21 @@ var Metamask = class extends Wallet {
|
|
|
591
643
|
debug("metamask.unlock: starting");
|
|
592
644
|
const pwd = password ?? this.defaultPassword;
|
|
593
645
|
await this.page.goto(`chrome-extension://${this.extensionId}/home.html`);
|
|
594
|
-
|
|
595
|
-
const
|
|
596
|
-
await
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
646
|
+
const lockInput = this.page.getByTestId("unlock-password");
|
|
647
|
+
const readyIndicator = this.page.getByTestId("account-options-menu-button");
|
|
648
|
+
const state = await Promise.race([
|
|
649
|
+
lockInput.waitFor({ state: "visible", timeout: POST_UNLOCK_TIMEOUT }).then(() => "locked"),
|
|
650
|
+
readyIndicator.waitFor({ state: "visible", timeout: POST_UNLOCK_TIMEOUT }).then(() => "ready")
|
|
651
|
+
]).catch(() => "timeout");
|
|
652
|
+
debug(`metamask.unlock: state=${state}`);
|
|
653
|
+
if (state === "locked") {
|
|
654
|
+
await lockInput.fill(pwd);
|
|
655
|
+
await this.page.getByTestId("unlock-submit").click();
|
|
656
|
+
await this.page.waitForSelector('[data-testid="unlock-password"]', {
|
|
657
|
+
state: "hidden",
|
|
658
|
+
timeout: LOCK_SCREEN_TIMEOUT
|
|
659
|
+
});
|
|
660
|
+
}
|
|
602
661
|
await this.stabilizePostUnlock();
|
|
603
662
|
debug("metamask.unlock: complete");
|
|
604
663
|
}
|
|
@@ -610,7 +669,7 @@ var Metamask = class extends Wallet {
|
|
|
610
669
|
debug(`metamask.switchNetwork: ${networkName} (${networkType})`);
|
|
611
670
|
await this.page.getByTestId("sort-by-networks").click();
|
|
612
671
|
if (networkType === "Custom") {
|
|
613
|
-
await this.page.getByRole("tab", { name: "Custom" }).click();
|
|
672
|
+
await this.page.getByRole("tab", { name: "Custom" }).click({ force: true });
|
|
614
673
|
}
|
|
615
674
|
await this.page.getByText(networkName).click();
|
|
616
675
|
await expect(this.page.getByTestId("sort-by-networks")).toHaveText(
|
|
@@ -636,7 +695,7 @@ var Metamask = class extends Wallet {
|
|
|
636
695
|
await this.page.getByRole("button", { name: /save/i }).click();
|
|
637
696
|
}
|
|
638
697
|
async addCustomNetwork(settings) {
|
|
639
|
-
await this.page.getByTestId("account-options-menu-button").click();
|
|
698
|
+
await this.page.getByTestId("account-options-menu-button").click({ force: true });
|
|
640
699
|
await this.page.getByTestId("global-menu-networks").click();
|
|
641
700
|
await this.page.getByRole("button", { name: "Add a custom network" }).click();
|
|
642
701
|
await this.page.getByTestId("network-form-network-name").fill(settings.name);
|
|
@@ -647,11 +706,17 @@ var Metamask = class extends Wallet {
|
|
|
647
706
|
await this.page.getByTestId("rpc-url-input-test").fill(settings.rpc);
|
|
648
707
|
await this.page.getByRole("button", { name: "Add URL" }).click();
|
|
649
708
|
await this.page.getByRole("button", { name: "Save" }).click();
|
|
709
|
+
await this.page.goto(`chrome-extension://${this.extensionId}/home.html`);
|
|
710
|
+
await this.page.waitForLoadState("domcontentloaded");
|
|
650
711
|
}
|
|
651
712
|
async enableTestNetworks() {
|
|
652
|
-
await this.page.getByTestId("account-options-menu-button").click();
|
|
713
|
+
await this.page.getByTestId("account-options-menu-button").click({ force: true });
|
|
653
714
|
await this.page.getByTestId("global-menu-networks").click();
|
|
654
|
-
|
|
715
|
+
const toggle = this.page.locator(
|
|
716
|
+
"text=Show test networks >> xpath=following-sibling::label"
|
|
717
|
+
);
|
|
718
|
+
await expect(toggle).toBeVisible({ timeout: config.expectTimeout });
|
|
719
|
+
await toggle.click();
|
|
655
720
|
await this.page.keyboard.press("Escape");
|
|
656
721
|
}
|
|
657
722
|
async importAccount(privateKey) {
|
package/dist/scripts/cache.js
CHANGED
|
@@ -89,7 +89,8 @@ async function waitForStorageStable(helperPage, helperUrl) {
|
|
|
89
89
|
const POLL_INTERVAL = STORAGE_POLL_INTERVAL;
|
|
90
90
|
const STABLE_CHECKS_REQUIRED = STORAGE_STABLE_CHECKS;
|
|
91
91
|
const start = Date.now();
|
|
92
|
-
let
|
|
92
|
+
let lastHash = "";
|
|
93
|
+
let lastKeyCount = 0;
|
|
93
94
|
let stableCount = 0;
|
|
94
95
|
while (Date.now() - start < TIMEOUT) {
|
|
95
96
|
await sleep(POLL_INTERVAL);
|
|
@@ -100,16 +101,19 @@ async function waitForStorageStable(helperPage, helperUrl) {
|
|
|
100
101
|
{ timeout: HELPER_PAGE_TIMEOUT }
|
|
101
102
|
);
|
|
102
103
|
const title = await helperPage.title();
|
|
103
|
-
const
|
|
104
|
+
const parts = title.split(":");
|
|
105
|
+
const keyCount = parseInt(parts[1], 10);
|
|
106
|
+
const hash = parts[2] ?? "";
|
|
104
107
|
if (keyCount === 0) continue;
|
|
105
|
-
if (
|
|
108
|
+
if (hash === lastHash) {
|
|
106
109
|
stableCount++;
|
|
107
110
|
} else {
|
|
108
111
|
stableCount = 1;
|
|
112
|
+
lastHash = hash;
|
|
109
113
|
lastKeyCount = keyCount;
|
|
110
114
|
}
|
|
111
115
|
debug(
|
|
112
|
-
`Storage poll: ${keyCount} keys (stable ${stableCount}/${STABLE_CHECKS_REQUIRED})`
|
|
116
|
+
`Storage poll: ${keyCount} keys, hash=${hash.slice(0, 8)} (stable ${stableCount}/${STABLE_CHECKS_REQUIRED})`
|
|
113
117
|
);
|
|
114
118
|
if (stableCount >= STABLE_CHECKS_REQUIRED) {
|
|
115
119
|
console.log(` Storage stabilized at ${keyCount} keys`);
|
|
@@ -176,16 +180,26 @@ async function buildCacheForSetup(compiledFilePath, originalFilePath, options2 =
|
|
|
176
180
|
await config.setupFn(wallet, page);
|
|
177
181
|
await page.goto(`chrome-extension://${extensionId}/home.html`);
|
|
178
182
|
await page.waitForLoadState("networkidle");
|
|
179
|
-
|
|
180
|
-
|
|
183
|
+
if (wallet.beforeCacheClose) {
|
|
184
|
+
debug("buildCache: calling wallet.beforeCacheClose()");
|
|
185
|
+
await wallet.beforeCacheClose();
|
|
186
|
+
await sleep(2e3);
|
|
187
|
+
}
|
|
181
188
|
try {
|
|
182
189
|
const extDir = import_path2.default.join(process.cwd(), W3WALLETS_DIR, config.extensionDir);
|
|
183
190
|
const helperJs = import_path2.default.join(extDir, "_w3wallets_helper.js");
|
|
184
191
|
const helperHtml = import_path2.default.join(extDir, "_w3wallets_helper.html");
|
|
185
192
|
import_fs2.default.writeFileSync(
|
|
186
193
|
helperJs,
|
|
187
|
-
`chrome.storage.local.get(null, (data) => {
|
|
188
|
-
|
|
194
|
+
`chrome.storage.local.get(null, async (data) => {
|
|
195
|
+
const keys = Object.keys(data);
|
|
196
|
+
const json = JSON.stringify(data);
|
|
197
|
+
// Compute a simple hash of all values via SubtleCrypto
|
|
198
|
+
const buf = new TextEncoder().encode(json);
|
|
199
|
+
const hashBuf = await crypto.subtle.digest("SHA-256", buf);
|
|
200
|
+
const hashArr = Array.from(new Uint8Array(hashBuf));
|
|
201
|
+
const hash = hashArr.map(b => b.toString(16).padStart(2, "0")).join("");
|
|
202
|
+
document.title = "done:" + keys.length + ":" + hash;
|
|
189
203
|
});`
|
|
190
204
|
);
|
|
191
205
|
import_fs2.default.writeFileSync(
|
|
@@ -231,7 +245,8 @@ async function buildAllCaches(directory, options2 = {}) {
|
|
|
231
245
|
outDir: distDir,
|
|
232
246
|
format: ["cjs"],
|
|
233
247
|
clean: true,
|
|
234
|
-
silent: true
|
|
248
|
+
silent: true,
|
|
249
|
+
external: ["@playwright/test"]
|
|
235
250
|
});
|
|
236
251
|
let built = 0;
|
|
237
252
|
let skipped = 0;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "w3wallets",
|
|
3
3
|
"description": "browser wallets for playwright",
|
|
4
|
-
"version": "1.0.0-beta.
|
|
4
|
+
"version": "1.0.0-beta.9",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"homepage": "https://github.com/Maksandre/w3wallets",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"files": [
|
|
29
29
|
"dist"
|
|
30
30
|
],
|
|
31
|
-
"bin": "./
|
|
31
|
+
"bin": "./src/scripts/download.js",
|
|
32
32
|
"scripts": {
|
|
33
33
|
"download-wallets": "npx w3wallets pjs mm",
|
|
34
34
|
"cache-wallets": "npx w3wallets cache --force ./tests/wallets-cache/",
|