@broccolo1d/wallet-browser 0.1.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.
Files changed (53) hide show
  1. package/dist/cli.d.ts +14 -0
  2. package/dist/cli.d.ts.map +1 -0
  3. package/dist/cli.js +197 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/config.d.ts +45 -0
  6. package/dist/config.d.ts.map +1 -0
  7. package/dist/config.js +149 -0
  8. package/dist/config.js.map +1 -0
  9. package/dist/extension-pages.d.ts +26 -0
  10. package/dist/extension-pages.d.ts.map +1 -0
  11. package/dist/extension-pages.js +140 -0
  12. package/dist/extension-pages.js.map +1 -0
  13. package/dist/fixture-harness.d.ts +22 -0
  14. package/dist/fixture-harness.d.ts.map +1 -0
  15. package/dist/fixture-harness.js +69 -0
  16. package/dist/fixture-harness.js.map +1 -0
  17. package/dist/fixture-proof.d.ts +23 -0
  18. package/dist/fixture-proof.d.ts.map +1 -0
  19. package/dist/fixture-proof.js +90 -0
  20. package/dist/fixture-proof.js.map +1 -0
  21. package/dist/index.d.ts +13 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +13 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/launcher.d.ts +15 -0
  26. package/dist/launcher.d.ts.map +1 -0
  27. package/dist/launcher.js +26 -0
  28. package/dist/launcher.js.map +1 -0
  29. package/dist/metamask-prompts.d.ts +27 -0
  30. package/dist/metamask-prompts.d.ts.map +1 -0
  31. package/dist/metamask-prompts.js +116 -0
  32. package/dist/metamask-prompts.js.map +1 -0
  33. package/dist/metamask-smoke.d.ts +54 -0
  34. package/dist/metamask-smoke.d.ts.map +1 -0
  35. package/dist/metamask-smoke.js +261 -0
  36. package/dist/metamask-smoke.js.map +1 -0
  37. package/dist/network.d.ts +79 -0
  38. package/dist/network.d.ts.map +1 -0
  39. package/dist/network.js +243 -0
  40. package/dist/network.js.map +1 -0
  41. package/dist/onboarding.d.ts +95 -0
  42. package/dist/onboarding.d.ts.map +1 -0
  43. package/dist/onboarding.js +197 -0
  44. package/dist/onboarding.js.map +1 -0
  45. package/dist/profile-bootstrap.d.ts +33 -0
  46. package/dist/profile-bootstrap.d.ts.map +1 -0
  47. package/dist/profile-bootstrap.js +46 -0
  48. package/dist/profile-bootstrap.js.map +1 -0
  49. package/dist/wallet-control.d.ts +137 -0
  50. package/dist/wallet-control.d.ts.map +1 -0
  51. package/dist/wallet-control.js +453 -0
  52. package/dist/wallet-control.js.map +1 -0
  53. package/package.json +35 -0
@@ -0,0 +1,69 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { mkdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { FIXTURE_CONNECTION_PROOF_MANIFEST, verifyFixtureConnectionProofManifest } from './fixture-proof.js';
5
+ import { DEFAULT_SEPOLIA_CHAIN_ID } from './network.js';
6
+ import { maskEthereumAddress } from './profile-bootstrap.js';
7
+ import { connectWallet } from './wallet-control.js';
8
+ export async function runFixtureConnectionProof(options) {
9
+ const artifactDir = options.artifactDir;
10
+ mkdirSync(artifactDir, { recursive: true, mode: 0o700 });
11
+ const connection = await connectWallet({
12
+ dapp: options.dapp,
13
+ prompt: options.prompt,
14
+ network: options.network,
15
+ expectedAccount: options.expectedAccount,
16
+ expectedChainId: options.expectedChainId ?? DEFAULT_SEPOLIA_CHAIN_ID,
17
+ origin: options.origin,
18
+ guardrails: createFixtureGuardrails(options),
19
+ logger: options.logger
20
+ });
21
+ const evidence = {
22
+ connectionState: 'connected',
23
+ maskedAccount: maskEthereumAddress(connection.activeAccount),
24
+ chainId: connection.chainId,
25
+ origin: sanitizeProofOrigin(options.origin)
26
+ };
27
+ const screenshotFile = 'fixture-connected.png';
28
+ const screenshotPath = join(artifactDir, screenshotFile);
29
+ await options.captureScreenshot({ path: screenshotPath, evidence });
30
+ const screenshot = createScreenshotManifestEntry(artifactDir, screenshotFile);
31
+ const manifest = {
32
+ artifactType: 'fixture-dapp-wallet-connection-proof',
33
+ target: 'fixture-dapp',
34
+ status: 'connected',
35
+ evidence,
36
+ screenshots: [screenshot],
37
+ notes: [
38
+ 'Generated by local fixture connection proof harness after wallet-control verified account and chain.',
39
+ 'Artifact is local-only under .wallet-artifacts and must be inspected before sharing.',
40
+ ...(options.notes ?? [])
41
+ ]
42
+ };
43
+ writeFileSync(join(artifactDir, FIXTURE_CONNECTION_PROOF_MANIFEST), `${JSON.stringify(manifest, null, 2)}\n`, { mode: 0o600 });
44
+ return verifyFixtureConnectionProofManifest(artifactDir);
45
+ }
46
+ function createFixtureGuardrails(options) {
47
+ return {
48
+ allowedOrigins: options.allowedOrigins ?? [sanitizeProofOrigin(options.origin)],
49
+ maxTransactionValueWei: 0n
50
+ };
51
+ }
52
+ function createScreenshotManifestEntry(artifactDir, file) {
53
+ const screenshotPath = join(artifactDir, file);
54
+ const bytes = readFileSync(screenshotPath);
55
+ return {
56
+ label: 'fixture-connected',
57
+ file,
58
+ sizeBytes: statSync(screenshotPath).size,
59
+ sha256: createHash('sha256').update(bytes).digest('hex')
60
+ };
61
+ }
62
+ function sanitizeProofOrigin(origin) {
63
+ const parsed = new URL(origin);
64
+ if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
65
+ throw new Error('Fixture proof origin must be an http(s) URL.');
66
+ }
67
+ return `${parsed.origin}${parsed.pathname === '/' ? '' : parsed.pathname}`;
68
+ }
69
+ //# sourceMappingURL=fixture-harness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fixture-harness.js","sourceRoot":"","sources":["../src/fixture-harness.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ export declare const FIXTURE_CONNECTION_PROOF_MANIFEST = "FIXTURE-PROOF-MANIFEST.json";
2
+ export interface FixtureConnectionProofEvidence {
3
+ connectionState: 'connected';
4
+ maskedAccount: string;
5
+ chainId: number;
6
+ origin: string;
7
+ }
8
+ export interface FixtureConnectionProofScreenshot {
9
+ label: 'fixture-connected';
10
+ file: string;
11
+ sizeBytes: number;
12
+ sha256: string;
13
+ }
14
+ export interface FixtureConnectionProofVerificationResult {
15
+ status: 'verified';
16
+ artifactDir: string;
17
+ manifestPath: string;
18
+ evidence: FixtureConnectionProofEvidence;
19
+ screenshots: FixtureConnectionProofScreenshot[];
20
+ notes: string[];
21
+ }
22
+ export declare function verifyFixtureConnectionProofManifest(artifactDir: string): FixtureConnectionProofVerificationResult;
23
+ //# sourceMappingURL=fixture-proof.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fixture-proof.d.ts","sourceRoot":"","sources":["../src/fixture-proof.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,iCAAiC,gCAAgC,CAAC;AAE/E,MAAM,WAAW,8BAA8B;IAC7C,eAAe,EAAE,WAAW,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gCAAgC;IAC/C,KAAK,EAAE,mBAAmB,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAWD,MAAM,WAAW,wCAAwC;IACvD,MAAM,EAAE,UAAU,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,8BAA8B,CAAC;IACzC,WAAW,EAAE,gCAAgC,EAAE,CAAC;IAChD,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,wBAAgB,oCAAoC,CAAC,WAAW,EAAE,MAAM,GAAG,wCAAwC,CA8ClH"}
@@ -0,0 +1,90 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { existsSync, readFileSync, statSync } from 'node:fs';
3
+ import { basename, join } from 'node:path';
4
+ import { DEFAULT_SEPOLIA_CHAIN_ID } from './network.js';
5
+ export const FIXTURE_CONNECTION_PROOF_MANIFEST = 'FIXTURE-PROOF-MANIFEST.json';
6
+ export function verifyFixtureConnectionProofManifest(artifactDir) {
7
+ const manifestPath = join(artifactDir, FIXTURE_CONNECTION_PROOF_MANIFEST);
8
+ const manifestText = readFileSync(manifestPath, 'utf8');
9
+ if (manifestText.includes(artifactDir)) {
10
+ throw new Error('Fixture connection proof manifest must not contain the full artifact directory path.');
11
+ }
12
+ const manifest = JSON.parse(manifestText);
13
+ if (manifest.artifactType !== 'fixture-dapp-wallet-connection-proof') {
14
+ throw new Error('Fixture connection proof manifest has an unexpected artifact type.');
15
+ }
16
+ if (manifest.target !== 'fixture-dapp') {
17
+ throw new Error('Fixture connection proof manifest has an unexpected target.');
18
+ }
19
+ if (manifest.status !== 'connected' || manifest.evidence?.connectionState !== 'connected') {
20
+ throw new Error('Fixture connection proof must show connected fixture state before it can be accepted.');
21
+ }
22
+ if (manifest.evidence.chainId !== DEFAULT_SEPOLIA_CHAIN_ID) {
23
+ throw new Error(`Fixture connection proof must be captured on Sepolia chain ${DEFAULT_SEPOLIA_CHAIN_ID}.`);
24
+ }
25
+ if (!isMaskedAccount(manifest.evidence.maskedAccount)) {
26
+ throw new Error('Fixture connection proof masked account must be shortened and must not contain a full wallet address.');
27
+ }
28
+ if (containsFullAddress(manifestText)) {
29
+ throw new Error('Fixture connection proof manifest must not contain full wallet addresses.');
30
+ }
31
+ if (!isSafeOrigin(manifest.evidence.origin)) {
32
+ throw new Error('Fixture connection proof origin must be a safe http(s) origin or local fixture URL without query strings.');
33
+ }
34
+ if (!Array.isArray(manifest.screenshots) || manifest.screenshots.length === 0) {
35
+ throw new Error('Fixture connection proof manifest must list at least one screenshot.');
36
+ }
37
+ const screenshots = manifest.screenshots.map((screenshot) => verifyFixtureProofScreenshot(artifactDir, screenshot));
38
+ if (!screenshots.some((screenshot) => screenshot.label === 'fixture-connected')) {
39
+ throw new Error('Fixture connection proof manifest must include a fixture-connected screenshot.');
40
+ }
41
+ return {
42
+ status: 'verified',
43
+ artifactDir,
44
+ manifestPath,
45
+ evidence: manifest.evidence,
46
+ screenshots,
47
+ notes: Array.isArray(manifest.notes) ? manifest.notes : []
48
+ };
49
+ }
50
+ function verifyFixtureProofScreenshot(artifactDir, screenshot) {
51
+ if (screenshot.label !== 'fixture-connected') {
52
+ throw new Error(`Fixture connection proof manifest contains an unexpected screenshot label: ${String(screenshot.label)}`);
53
+ }
54
+ if (!isSafeArtifactFileName(screenshot.file)) {
55
+ throw new Error(`Fixture connection proof screenshot file must be a safe basename: ${String(screenshot.file)}`);
56
+ }
57
+ const screenshotPath = join(artifactDir, screenshot.file);
58
+ if (!existsSync(screenshotPath)) {
59
+ throw new Error(`Fixture connection proof screenshot is missing: ${screenshot.file}`);
60
+ }
61
+ const bytes = readFileSync(screenshotPath);
62
+ const sizeBytes = statSync(screenshotPath).size;
63
+ const sha256 = createHash('sha256').update(bytes).digest('hex');
64
+ if (screenshot.sizeBytes !== sizeBytes) {
65
+ throw new Error(`Fixture connection proof screenshot size mismatch for ${screenshot.file}.`);
66
+ }
67
+ if (screenshot.sha256 !== sha256) {
68
+ throw new Error(`Fixture connection proof screenshot hash mismatch for ${screenshot.file}.`);
69
+ }
70
+ return { ...screenshot, sizeBytes, sha256 };
71
+ }
72
+ function isMaskedAccount(value) {
73
+ return typeof value === 'string' && /^0x[0-9a-fA-F]{4}(?:…|\.\.\.)[0-9a-fA-F]{4,5}$/.test(value) && !containsFullAddress(value);
74
+ }
75
+ function containsFullAddress(value) {
76
+ return /0x[0-9a-fA-F]{40}/.test(value);
77
+ }
78
+ function isSafeOrigin(value) {
79
+ try {
80
+ const parsed = new URL(value);
81
+ return (parsed.protocol === 'http:' || parsed.protocol === 'https:') && parsed.search === '' && parsed.hash === '';
82
+ }
83
+ catch {
84
+ return false;
85
+ }
86
+ }
87
+ function isSafeArtifactFileName(fileName) {
88
+ return typeof fileName === 'string' && fileName.length > 0 && fileName === basename(fileName) && !fileName.includes('..');
89
+ }
90
+ //# sourceMappingURL=fixture-proof.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fixture-proof.js","sourceRoot":"","sources":["../src/fixture-proof.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export { PINNED_METAMASK_VERSION, resolveWalletBrowserConfig, type MetaMaskExtensionIdentity, type ResolveWalletBrowserConfigOptions, type WalletBrowserConfig, type WalletBrowserEnv } from './config.js';
2
+ export { buildChromiumExtensionArgs, launchWalletBrowser, prepareChromiumLaunchOptions, type PreparedChromiumLaunchOptions, type WalletBrowserLaunchResult } from './launcher.js';
3
+ export { discoverMetaMaskExtensionPage, getMetaMaskExtensionPagePath, waitForMetaMaskExtensionPage, type DiscoverMetaMaskExtensionPageOptions, type ExtensionBrowserContextLike, type ExtensionPageLike, type MetaMaskExtensionPagePath, type WaitForMetaMaskExtensionPageOptions } from './extension-pages.js';
4
+ export { captureFixtureExtensionSmokeScreenshots, captureMetaMaskSmokeScreenshots, resolveDefaultFixtureDappSmokeUrl, writeSmokeArtifactManifest, verifySmokeArtifactManifest, writeSmokeInspectionGuide, type MetaMaskSmokeOptions, type MetaMaskSmokeResult, type MetaMaskSmokeScreenshot, type RunMetaMaskSmoke } from './metamask-smoke.js';
5
+ export { DEFAULT_METAMASK_PROMPT_SELECTORS, approveMetaMaskConnectionPrompt, assertMetaMaskConnectionPromptText, createMetaMaskPromptDriver, type MetaMaskPromptDriverOptions, type MetaMaskPromptLocatorLike, type MetaMaskPromptPageLike, type MetaMaskPromptSelectors } from './metamask-prompts.js';
6
+ export { FIXTURE_CONNECTION_PROOF_MANIFEST, verifyFixtureConnectionProofManifest, type FixtureConnectionProofEvidence, type FixtureConnectionProofScreenshot, type FixtureConnectionProofVerificationResult } from './fixture-proof.js';
7
+ export { runFixtureConnectionProof, type FixtureConnectionScreenshotCaptureInput, type RunFixtureConnectionProofOptions } from './fixture-harness.js';
8
+ export { runWalletBrowserCli, type WalletBrowserCliOptions } from './cli.js';
9
+ export { DEFAULT_METAMASK_ONBOARDING_TIMEOUT_MS, METAMASK_ONBOARDING_SELECTORS, createMetaMaskOnboardingPlan, createMetaMaskPageDriver, findMetaMaskExtensionPage, importPrivateKeyIntoMetaMaskPage, isMetaMaskExtensionPageUrl, maskSecret, resolveMetaMaskOnboardingConfig, runMetaMaskOnboarding, unlockMetaMaskPage, validateEthereumAddress, validateMetaMaskPassword, validatePrivateKey, verifyMetaMaskActiveAddress, type MetaMaskImportPrivateKeyInput, type MetaMaskExtensionPageDiscoveryOptions, type MetaMaskOnboardingConfig, type MetaMaskOnboardingDriver, type MetaMaskOnboardingEnv, type MetaMaskOnboardingResult, type MetaMaskOnboardingState, type MetaMaskOnboardingStatus, type MetaMaskPageDriverOptions, type MetaMaskUnlockInput, type RedactedMetaMaskOnboardingPlan, type ResolveMetaMaskOnboardingConfigOptions } from './onboarding.js';
10
+ export { DEFAULT_ALLOWED_WALLET_CHAIN_IDS, DEFAULT_NETWORK_ASSERTION_TIMEOUT_MS, DEFAULT_SEPOLIA_CHAIN_ID, assertExpectedChainAndAccount, chainIdToHex, createMetaMaskNetworkPageDriver, createSepoliaAddChainInput, createSepoliaNetworkPlan, isAllowedWalletChainId, normalizeChainId, normalizeExpectedAccount, provisionSepoliaNetwork, redactRpcUrl, resolveSepoliaNetworkConfig, validateOptionalRpcUrl, type AddEthereumChainInput, type MetaMaskNetworkDriver, type MetaMaskNetworkPageDriverOptions, type RedactedSepoliaNetworkPlan, type ResolveSepoliaNetworkConfigOptions, type SepoliaNetworkAssertionResult, type SepoliaNetworkConfig, type SepoliaNetworkEnv } from './network.js';
11
+ export { createProfileBootstrapImportDryRun, createProfileBootstrapImportManifest, maskEthereumAddress, type ProfileBootstrapImportDryRunResult, type ProfileBootstrapImportEnv, type ProfileBootstrapImportManifest, type ResolveProfileBootstrapImportOptions } from './profile-bootstrap.js';
12
+ export { approveSignature, approveTransaction, assertWalletState, connectWallet, createWalletDappPageDriver, resetProfile, switchNetwork, type ApproveSignatureOptions, type ApproveTransactionOptions, type ConnectWalletOptions, type ConnectWalletResult, type ResetProfileOptions, type ResetProfileResult, type WalletConnectionPromptInput, type WalletControlAction, type WalletControlLogEvent, type WalletControlLogStatus, type WalletControlLogger, type WalletDappDriver, type WalletDappPageDriverOptions, type WalletGuardrailConfig, type WalletDappPageDriverSelectors, type WalletDappPageLike, type WalletDappPageLocator, type WalletPromptDriver, type WalletSignaturePromptInput, type WalletSignatureRequestInput, type WalletStateOptions, type WalletTransactionPromptInput, type WalletTransactionRequestInput } from './wallet-control.js';
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,13 @@
1
+ export { PINNED_METAMASK_VERSION, resolveWalletBrowserConfig } from './config.js';
2
+ export { buildChromiumExtensionArgs, launchWalletBrowser, prepareChromiumLaunchOptions } from './launcher.js';
3
+ export { discoverMetaMaskExtensionPage, getMetaMaskExtensionPagePath, waitForMetaMaskExtensionPage } from './extension-pages.js';
4
+ export { captureFixtureExtensionSmokeScreenshots, captureMetaMaskSmokeScreenshots, resolveDefaultFixtureDappSmokeUrl, writeSmokeArtifactManifest, verifySmokeArtifactManifest, writeSmokeInspectionGuide } from './metamask-smoke.js';
5
+ export { DEFAULT_METAMASK_PROMPT_SELECTORS, approveMetaMaskConnectionPrompt, assertMetaMaskConnectionPromptText, createMetaMaskPromptDriver } from './metamask-prompts.js';
6
+ export { FIXTURE_CONNECTION_PROOF_MANIFEST, verifyFixtureConnectionProofManifest } from './fixture-proof.js';
7
+ export { runFixtureConnectionProof } from './fixture-harness.js';
8
+ export { runWalletBrowserCli } from './cli.js';
9
+ export { DEFAULT_METAMASK_ONBOARDING_TIMEOUT_MS, METAMASK_ONBOARDING_SELECTORS, createMetaMaskOnboardingPlan, createMetaMaskPageDriver, findMetaMaskExtensionPage, importPrivateKeyIntoMetaMaskPage, isMetaMaskExtensionPageUrl, maskSecret, resolveMetaMaskOnboardingConfig, runMetaMaskOnboarding, unlockMetaMaskPage, validateEthereumAddress, validateMetaMaskPassword, validatePrivateKey, verifyMetaMaskActiveAddress } from './onboarding.js';
10
+ export { DEFAULT_ALLOWED_WALLET_CHAIN_IDS, DEFAULT_NETWORK_ASSERTION_TIMEOUT_MS, DEFAULT_SEPOLIA_CHAIN_ID, assertExpectedChainAndAccount, chainIdToHex, createMetaMaskNetworkPageDriver, createSepoliaAddChainInput, createSepoliaNetworkPlan, isAllowedWalletChainId, normalizeChainId, normalizeExpectedAccount, provisionSepoliaNetwork, redactRpcUrl, resolveSepoliaNetworkConfig, validateOptionalRpcUrl } from './network.js';
11
+ export { createProfileBootstrapImportDryRun, createProfileBootstrapImportManifest, maskEthereumAddress } from './profile-bootstrap.js';
12
+ export { approveSignature, approveTransaction, assertWalletState, connectWallet, createWalletDappPageDriver, resetProfile, switchNetwork } from './wallet-control.js';
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,0BAA0B,EAK3B,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,0BAA0B,EAC1B,mBAAmB,EACnB,4BAA4B,EAG7B,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,6BAA6B,EAC7B,4BAA4B,EAC5B,4BAA4B,EAM7B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,uCAAuC,EACvC,+BAA+B,EAC/B,iCAAiC,EACjC,0BAA0B,EAC1B,2BAA2B,EAC3B,yBAAyB,EAK1B,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,iCAAiC,EACjC,+BAA+B,EAC/B,kCAAkC,EAClC,0BAA0B,EAK3B,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,iCAAiC,EACjC,oCAAoC,EAIrC,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,yBAAyB,EAG1B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,mBAAmB,EAAgC,MAAM,UAAU,CAAC;AAE7E,OAAO,EACL,sCAAsC,EACtC,6BAA6B,EAC7B,4BAA4B,EAC5B,wBAAwB,EACxB,yBAAyB,EACzB,gCAAgC,EAChC,0BAA0B,EAC1B,UAAU,EACV,+BAA+B,EAC/B,qBAAqB,EACrB,kBAAkB,EAClB,uBAAuB,EACvB,wBAAwB,EACxB,kBAAkB,EAClB,2BAA2B,EAa5B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,gCAAgC,EAChC,oCAAoC,EACpC,wBAAwB,EACxB,6BAA6B,EAC7B,YAAY,EACZ,+BAA+B,EAC/B,0BAA0B,EAC1B,wBAAwB,EACxB,sBAAsB,EACtB,gBAAgB,EAChB,wBAAwB,EACxB,uBAAuB,EACvB,YAAY,EACZ,2BAA2B,EAC3B,sBAAsB,EASvB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,kCAAkC,EAClC,oCAAoC,EACpC,mBAAmB,EAKpB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,aAAa,EACb,0BAA0B,EAC1B,YAAY,EACZ,aAAa,EAwBd,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { chromium, type BrowserContext } from 'playwright';
2
+ import { type ResolveWalletBrowserConfigOptions, type WalletBrowserConfig } from './config.js';
3
+ export interface PreparedChromiumLaunchOptions {
4
+ browserName: 'chromium';
5
+ userDataDir: string;
6
+ options: NonNullable<Parameters<typeof chromium.launchPersistentContext>[1]>;
7
+ }
8
+ export interface WalletBrowserLaunchResult {
9
+ context: BrowserContext;
10
+ config: WalletBrowserConfig;
11
+ }
12
+ export declare function buildChromiumExtensionArgs(metamaskExtensionPath: string): string[];
13
+ export declare function prepareChromiumLaunchOptions(config: WalletBrowserConfig): PreparedChromiumLaunchOptions;
14
+ export declare function launchWalletBrowser(options?: ResolveWalletBrowserConfigOptions): Promise<WalletBrowserLaunchResult>;
15
+ //# sourceMappingURL=launcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launcher.d.ts","sourceRoot":"","sources":["../src/launcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAE3D,OAAO,EAA8B,KAAK,iCAAiC,EAAE,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAE3H,MAAM,WAAW,6BAA6B;IAC5C,WAAW,EAAE,UAAU,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,WAAW,CAAC,UAAU,CAAC,OAAO,QAAQ,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAC9E;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,EAAE,mBAAmB,CAAC;CAC7B;AAED,wBAAgB,0BAA0B,CAAC,qBAAqB,EAAE,MAAM,GAAG,MAAM,EAAE,CAKlF;AAED,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,mBAAmB,GAAG,6BAA6B,CAUvG;AAED,wBAAsB,mBAAmB,CACvC,OAAO,GAAE,iCAAsC,GAC9C,OAAO,CAAC,yBAAyB,CAAC,CAMpC"}
@@ -0,0 +1,26 @@
1
+ import { chromium } from 'playwright';
2
+ import { resolveWalletBrowserConfig } from './config.js';
3
+ export function buildChromiumExtensionArgs(metamaskExtensionPath) {
4
+ return [
5
+ `--disable-extensions-except=${metamaskExtensionPath}`,
6
+ `--load-extension=${metamaskExtensionPath}`
7
+ ];
8
+ }
9
+ export function prepareChromiumLaunchOptions(config) {
10
+ return {
11
+ browserName: 'chromium',
12
+ userDataDir: config.profileDir,
13
+ options: {
14
+ headless: false,
15
+ args: buildChromiumExtensionArgs(config.metamaskExtensionPath),
16
+ viewport: { width: 1280, height: 900 }
17
+ }
18
+ };
19
+ }
20
+ export async function launchWalletBrowser(options = {}) {
21
+ const config = resolveWalletBrowserConfig(options);
22
+ const launchOptions = prepareChromiumLaunchOptions(config);
23
+ const context = await chromium.launchPersistentContext(launchOptions.userDataDir, launchOptions.options);
24
+ return { context, config };
25
+ }
26
+ //# sourceMappingURL=launcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launcher.js","sourceRoot":"","sources":["../src/launcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAuB,MAAM,YAAY,CAAC;AAE3D,OAAO,EAAE,0BAA0B,EAAoE,MAAM,aAAa,CAAC;AAa3H,MAAM,UAAU,0BAA0B,CAAC,qBAA6B;IACtE,OAAO;QACL,+BAA+B,qBAAqB,EAAE;QACtD,oBAAoB,qBAAqB,EAAE;KAC5C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,4BAA4B,CAAC,MAA2B;IACtE,OAAO;QACL,WAAW,EAAE,UAAU;QACvB,WAAW,EAAE,MAAM,CAAC,UAAU;QAC9B,OAAO,EAAE;YACP,QAAQ,EAAE,KAAK;YACf,IAAI,EAAE,0BAA0B,CAAC,MAAM,CAAC,qBAAqB,CAAC;YAC9D,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE;SACvC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,UAA6C,EAAE;IAE/C,MAAM,MAAM,GAAG,0BAA0B,CAAC,OAAO,CAAC,CAAC;IACnD,MAAM,aAAa,GAAG,4BAA4B,CAAC,MAAM,CAAC,CAAC;IAC3D,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,uBAAuB,CAAC,aAAa,CAAC,WAAW,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IAEzG,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { type ExtensionBrowserContextLike, type ExtensionPageLike } from './extension-pages.js';
2
+ import { type WalletConnectionPromptInput, type WalletPromptDriver } from './wallet-control.js';
3
+ export interface MetaMaskPromptLocatorLike {
4
+ textContent?(): Promise<string | null>;
5
+ isVisible?(): Promise<boolean>;
6
+ click?(): Promise<void>;
7
+ }
8
+ export interface MetaMaskPromptPageLike extends ExtensionPageLike {
9
+ locator(selector: string): MetaMaskPromptLocatorLike;
10
+ }
11
+ export interface MetaMaskPromptSelectors {
12
+ pageText: string;
13
+ nextButtonCandidates: readonly string[];
14
+ connectButtonCandidates: readonly string[];
15
+ }
16
+ export interface MetaMaskPromptDriverOptions {
17
+ context: ExtensionBrowserContextLike;
18
+ extensionId?: string;
19
+ timeoutMs?: number;
20
+ ensureKeeperPage?: boolean;
21
+ selectors?: Partial<MetaMaskPromptSelectors>;
22
+ }
23
+ export declare const DEFAULT_METAMASK_PROMPT_SELECTORS: MetaMaskPromptSelectors;
24
+ export declare function createMetaMaskPromptDriver(options: MetaMaskPromptDriverOptions): WalletPromptDriver;
25
+ export declare function approveMetaMaskConnectionPrompt(page: MetaMaskPromptPageLike, input: WalletConnectionPromptInput, selectors?: MetaMaskPromptSelectors): Promise<void>;
26
+ export declare function assertMetaMaskConnectionPromptText(promptText: string, expectedOrigin?: string): void;
27
+ //# sourceMappingURL=metamask-prompts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metamask-prompts.d.ts","sourceRoot":"","sources":["../src/metamask-prompts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgC,KAAK,2BAA2B,EAAE,KAAK,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9H,OAAO,EAAE,KAAK,2BAA2B,EAAE,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEhG,MAAM,WAAW,yBAAyB;IACxC,WAAW,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACvC,SAAS,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/B,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB;AAED,MAAM,WAAW,sBAAuB,SAAQ,iBAAiB;IAC/D,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,yBAAyB,CAAC;CACtD;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,uBAAuB,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5C;AAED,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,2BAA2B,CAAC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,SAAS,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,CAAC;CAC9C;AAED,eAAO,MAAM,iCAAiC,EAAE,uBAW/C,CAAC;AAqBF,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,2BAA2B,GAAG,kBAAkB,CAYnG;AAED,wBAAsB,+BAA+B,CACnD,IAAI,EAAE,sBAAsB,EAC5B,KAAK,EAAE,2BAA2B,EAClC,SAAS,GAAE,uBAA2D,GACrE,OAAO,CAAC,IAAI,CAAC,CAcf;AAED,wBAAgB,kCAAkC,CAAC,UAAU,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAepG"}
@@ -0,0 +1,116 @@
1
+ import { waitForMetaMaskExtensionPage } from './extension-pages.js';
2
+ export const DEFAULT_METAMASK_PROMPT_SELECTORS = {
3
+ pageText: 'body',
4
+ nextButtonCandidates: [
5
+ '[data-testid="page-container-footer-next"]',
6
+ 'button:has-text("Next")'
7
+ ],
8
+ connectButtonCandidates: [
9
+ '[data-testid="page-container-footer-connect"]',
10
+ '[data-testid="page-container-footer-confirm"]',
11
+ 'button:has-text("Connect")'
12
+ ]
13
+ };
14
+ const CONNECTION_PROMPT_MARKERS = [
15
+ 'connect with metamask',
16
+ 'connect to',
17
+ 'wants to connect',
18
+ 'permissions request'
19
+ ];
20
+ const NON_CONNECTION_PROMPT_MARKERS = [
21
+ 'confirm transaction',
22
+ 'send transaction',
23
+ 'transaction request',
24
+ 'signature request',
25
+ 'sign message',
26
+ 'personal_sign',
27
+ 'spending cap',
28
+ 'approve token',
29
+ 'edit permission'
30
+ ];
31
+ export function createMetaMaskPromptDriver(options) {
32
+ return {
33
+ async approveConnection(input) {
34
+ const page = await waitForMetaMaskExtensionPage(options.context, {
35
+ extensionId: options.extensionId,
36
+ preferredPath: '/notification.html',
37
+ timeoutMs: options.timeoutMs,
38
+ ensureKeeperPage: options.ensureKeeperPage ?? true
39
+ });
40
+ await approveMetaMaskConnectionPrompt(page, input, mergePromptSelectors(options.selectors));
41
+ }
42
+ };
43
+ }
44
+ export async function approveMetaMaskConnectionPrompt(page, input, selectors = DEFAULT_METAMASK_PROMPT_SELECTORS) {
45
+ const promptText = await readPromptText(page, selectors.pageText);
46
+ assertMetaMaskConnectionPromptText(promptText, input.origin);
47
+ const nextButton = await findVisibleClickable(page, selectors.nextButtonCandidates);
48
+ if (nextButton) {
49
+ await nextButton.click?.();
50
+ }
51
+ const connectButton = await findVisibleClickable(page, selectors.connectButtonCandidates);
52
+ if (!connectButton) {
53
+ throw new Error('MetaMask connect approval button was not visible; refusing to approve unknown prompt state.');
54
+ }
55
+ await connectButton.click?.();
56
+ }
57
+ export function assertMetaMaskConnectionPromptText(promptText, expectedOrigin) {
58
+ const normalizedText = promptText.toLowerCase();
59
+ const unexpectedMarker = NON_CONNECTION_PROMPT_MARKERS.find((marker) => normalizedText.includes(marker));
60
+ if (unexpectedMarker) {
61
+ throw new Error(`Unexpected MetaMask prompt marker "${unexpectedMarker}" while expecting a connection prompt; refusing to click.`);
62
+ }
63
+ if (!CONNECTION_PROMPT_MARKERS.some((marker) => normalizedText.includes(marker))) {
64
+ throw new Error('MetaMask notification page did not look like a connection prompt; refusing to click.');
65
+ }
66
+ const expectedOriginMarker = normalizeExpectedOriginMarker(expectedOrigin);
67
+ if (expectedOriginMarker && !normalizedText.includes(expectedOriginMarker.toLowerCase())) {
68
+ throw new Error(`Expected dapp origin ${expectedOriginMarker} was not found in MetaMask connection prompt; refusing to click.`);
69
+ }
70
+ }
71
+ async function readPromptText(page, selector) {
72
+ const text = await page.locator(selector).textContent?.();
73
+ if (!text?.trim()) {
74
+ throw new Error('MetaMask prompt text was empty; refusing to click unknown prompt state.');
75
+ }
76
+ return text;
77
+ }
78
+ async function findVisibleClickable(page, selectors) {
79
+ for (const selector of selectors) {
80
+ try {
81
+ const locator = page.locator(selector);
82
+ if (!locator.click) {
83
+ continue;
84
+ }
85
+ const visible = locator.isVisible ? await locator.isVisible() : true;
86
+ if (visible) {
87
+ return locator;
88
+ }
89
+ }
90
+ catch {
91
+ // Try the next selector candidate; fail closed only if none match.
92
+ }
93
+ }
94
+ return undefined;
95
+ }
96
+ function mergePromptSelectors(selectors) {
97
+ return {
98
+ pageText: selectors?.pageText ?? DEFAULT_METAMASK_PROMPT_SELECTORS.pageText,
99
+ nextButtonCandidates: selectors?.nextButtonCandidates ?? DEFAULT_METAMASK_PROMPT_SELECTORS.nextButtonCandidates,
100
+ connectButtonCandidates: selectors?.connectButtonCandidates ?? DEFAULT_METAMASK_PROMPT_SELECTORS.connectButtonCandidates
101
+ };
102
+ }
103
+ function normalizeExpectedOriginMarker(origin) {
104
+ const trimmed = origin?.trim();
105
+ if (!trimmed) {
106
+ return undefined;
107
+ }
108
+ try {
109
+ const parsed = new URL(trimmed);
110
+ return parsed.origin;
111
+ }
112
+ catch {
113
+ return trimmed.split(/[?#]/, 1)[0];
114
+ }
115
+ }
116
+ //# sourceMappingURL=metamask-prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metamask-prompts.js","sourceRoot":"","sources":["../src/metamask-prompts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ import type { WalletBrowserEnv } from './config.js';
2
+ export interface MetaMaskSmokeOptions {
3
+ cwd?: string;
4
+ env?: WalletBrowserEnv;
5
+ artifactDir?: string;
6
+ extensionScreenshotLabel?: 'metamask-extension' | 'fixture-extension';
7
+ notes?: string[];
8
+ }
9
+ export interface MetaMaskSmokeScreenshot {
10
+ label: 'browser-page' | 'metamask-extension' | 'fixture-extension';
11
+ path: string;
12
+ }
13
+ export interface MetaMaskSmokeResult {
14
+ status: 'captured';
15
+ artifactDir: string;
16
+ screenshots: MetaMaskSmokeScreenshot[];
17
+ inspectionGuidePath: string;
18
+ manifestPath: string;
19
+ notes: string[];
20
+ }
21
+ interface SmokeInspectionGuideOptions {
22
+ artifactDir: string;
23
+ screenshots: readonly MetaMaskSmokeScreenshot[];
24
+ notes: readonly string[];
25
+ }
26
+ interface SmokeArtifactManifestOptions {
27
+ artifactDir: string;
28
+ screenshots: readonly MetaMaskSmokeScreenshot[];
29
+ inspectionGuidePath: string;
30
+ notes: readonly string[];
31
+ }
32
+ export interface SmokeArtifactManifestScreenshot {
33
+ label: MetaMaskSmokeScreenshot['label'];
34
+ file: string;
35
+ sizeBytes: number;
36
+ sha256: string;
37
+ }
38
+ export interface SmokeArtifactVerificationResult {
39
+ status: 'verified';
40
+ artifactDir: string;
41
+ manifestPath: string;
42
+ inspectionGuidePath: string;
43
+ screenshots: SmokeArtifactManifestScreenshot[];
44
+ notes: string[];
45
+ }
46
+ export type RunMetaMaskSmoke = (options: MetaMaskSmokeOptions) => Promise<MetaMaskSmokeResult>;
47
+ export declare function captureMetaMaskSmokeScreenshots(options?: MetaMaskSmokeOptions): Promise<MetaMaskSmokeResult>;
48
+ export declare function captureFixtureExtensionSmokeScreenshots(options?: MetaMaskSmokeOptions): Promise<MetaMaskSmokeResult>;
49
+ export declare function resolveDefaultFixtureDappSmokeUrl(cwd: string): string | undefined;
50
+ export declare function writeSmokeInspectionGuide(options: SmokeInspectionGuideOptions): string;
51
+ export declare function writeSmokeArtifactManifest(options: SmokeArtifactManifestOptions): string;
52
+ export declare function verifySmokeArtifactManifest(artifactDir: string): SmokeArtifactVerificationResult;
53
+ export {};
54
+ //# sourceMappingURL=metamask-smoke.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metamask-smoke.d.ts","sourceRoot":"","sources":["../src/metamask-smoke.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAIpD,MAAM,WAAW,oBAAoB;IACnC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,gBAAgB,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wBAAwB,CAAC,EAAE,oBAAoB,GAAG,mBAAmB,CAAC;IACtE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,cAAc,GAAG,oBAAoB,GAAG,mBAAmB,CAAC;IACnE,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,UAAU,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,uBAAuB,EAAE,CAAC;IACvC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,UAAU,2BAA2B;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,SAAS,uBAAuB,EAAE,CAAC;IAChD,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B;AAED,UAAU,4BAA4B;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,SAAS,uBAAuB,EAAE,CAAC;IAChD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,+BAA+B;IAC9C,KAAK,EAAE,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AASD,MAAM,WAAW,+BAA+B;IAC9C,MAAM,EAAE,UAAU,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,WAAW,EAAE,+BAA+B,EAAE,CAAC;IAC/C,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,EAAE,oBAAoB,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAE/F,wBAAsB,+BAA+B,CAAC,OAAO,GAAE,oBAAyB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAyCtH;AAED,wBAAsB,uCAAuC,CAAC,OAAO,GAAE,oBAAyB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAsB9H;AAwCD,wBAAgB,iCAAiC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGjF;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,2BAA2B,GAAG,MAAM,CA0BtF;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,4BAA4B,GAAG,MAAM,CA0BxF;AAED,wBAAgB,2BAA2B,CAAC,WAAW,EAAE,MAAM,GAAG,+BAA+B,CA+BhG"}