@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.
- package/dist/cli.d.ts +14 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +197 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +45 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +149 -0
- package/dist/config.js.map +1 -0
- package/dist/extension-pages.d.ts +26 -0
- package/dist/extension-pages.d.ts.map +1 -0
- package/dist/extension-pages.js +140 -0
- package/dist/extension-pages.js.map +1 -0
- package/dist/fixture-harness.d.ts +22 -0
- package/dist/fixture-harness.d.ts.map +1 -0
- package/dist/fixture-harness.js +69 -0
- package/dist/fixture-harness.js.map +1 -0
- package/dist/fixture-proof.d.ts +23 -0
- package/dist/fixture-proof.d.ts.map +1 -0
- package/dist/fixture-proof.js +90 -0
- package/dist/fixture-proof.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/launcher.d.ts +15 -0
- package/dist/launcher.d.ts.map +1 -0
- package/dist/launcher.js +26 -0
- package/dist/launcher.js.map +1 -0
- package/dist/metamask-prompts.d.ts +27 -0
- package/dist/metamask-prompts.d.ts.map +1 -0
- package/dist/metamask-prompts.js +116 -0
- package/dist/metamask-prompts.js.map +1 -0
- package/dist/metamask-smoke.d.ts +54 -0
- package/dist/metamask-smoke.d.ts.map +1 -0
- package/dist/metamask-smoke.js +261 -0
- package/dist/metamask-smoke.js.map +1 -0
- package/dist/network.d.ts +79 -0
- package/dist/network.d.ts.map +1 -0
- package/dist/network.js +243 -0
- package/dist/network.js.map +1 -0
- package/dist/onboarding.d.ts +95 -0
- package/dist/onboarding.d.ts.map +1 -0
- package/dist/onboarding.js +197 -0
- package/dist/onboarding.js.map +1 -0
- package/dist/profile-bootstrap.d.ts +33 -0
- package/dist/profile-bootstrap.d.ts.map +1 -0
- package/dist/profile-bootstrap.js +46 -0
- package/dist/profile-bootstrap.js.map +1 -0
- package/dist/wallet-control.d.ts +137 -0
- package/dist/wallet-control.d.ts.map +1 -0
- package/dist/wallet-control.js +453 -0
- package/dist/wallet-control.js.map +1 -0
- package/package.json +35 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import type { BrowserContext, Page } from 'playwright';
|
|
2
|
+
import type { WalletBrowserEnv } from './config.js';
|
|
3
|
+
export type MetaMaskOnboardingState = 'needs-import' | 'locked' | 'unlocked' | 'unknown';
|
|
4
|
+
export type MetaMaskOnboardingStatus = 'pending' | 'verified';
|
|
5
|
+
export interface MetaMaskOnboardingEnv extends WalletBrowserEnv {
|
|
6
|
+
SEPOLIA_WALLET_ADDRESS?: string;
|
|
7
|
+
SEPOLIA_WALLET_PRIVATE_KEY?: string;
|
|
8
|
+
METAMASK_PASSWORD?: string;
|
|
9
|
+
METAMASK_ONBOARDING_TIMEOUT_MS?: string;
|
|
10
|
+
METAMASK_ONBOARDING_DEBUG?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface ResolveMetaMaskOnboardingConfigOptions {
|
|
13
|
+
env?: MetaMaskOnboardingEnv;
|
|
14
|
+
expectedAddress?: string;
|
|
15
|
+
privateKey?: string;
|
|
16
|
+
password?: string;
|
|
17
|
+
timeoutMs?: number;
|
|
18
|
+
debug?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface MetaMaskOnboardingConfig {
|
|
21
|
+
expectedAddress: string;
|
|
22
|
+
privateKey: string;
|
|
23
|
+
password: string;
|
|
24
|
+
timeoutMs: number;
|
|
25
|
+
debug: boolean;
|
|
26
|
+
}
|
|
27
|
+
export interface RedactedMetaMaskOnboardingPlan {
|
|
28
|
+
status: 'pending';
|
|
29
|
+
expectedAddress: string;
|
|
30
|
+
privateKey: string;
|
|
31
|
+
password: string;
|
|
32
|
+
timeoutMs: number;
|
|
33
|
+
debug: boolean;
|
|
34
|
+
selectors: typeof METAMASK_ONBOARDING_SELECTORS;
|
|
35
|
+
run(driver: MetaMaskOnboardingDriver): Promise<MetaMaskOnboardingResult>;
|
|
36
|
+
}
|
|
37
|
+
export interface MetaMaskOnboardingResult {
|
|
38
|
+
status: MetaMaskOnboardingStatus;
|
|
39
|
+
expectedAddress: string;
|
|
40
|
+
activeAddress: string;
|
|
41
|
+
}
|
|
42
|
+
export interface MetaMaskImportPrivateKeyInput {
|
|
43
|
+
expectedAddress: string;
|
|
44
|
+
privateKey: string;
|
|
45
|
+
password: string;
|
|
46
|
+
timeoutMs: number;
|
|
47
|
+
}
|
|
48
|
+
export interface MetaMaskUnlockInput {
|
|
49
|
+
expectedAddress: string;
|
|
50
|
+
password: string;
|
|
51
|
+
timeoutMs: number;
|
|
52
|
+
}
|
|
53
|
+
export interface MetaMaskOnboardingDriver {
|
|
54
|
+
getState(): Promise<MetaMaskOnboardingState>;
|
|
55
|
+
importPrivateKey(input: MetaMaskImportPrivateKeyInput): Promise<void>;
|
|
56
|
+
unlock(input: MetaMaskUnlockInput): Promise<void>;
|
|
57
|
+
getActiveAddress(): Promise<string>;
|
|
58
|
+
}
|
|
59
|
+
export interface MetaMaskPageDriverOptions {
|
|
60
|
+
context: BrowserContext;
|
|
61
|
+
page?: Page;
|
|
62
|
+
extensionId?: string;
|
|
63
|
+
timeoutMs?: number;
|
|
64
|
+
}
|
|
65
|
+
export interface MetaMaskExtensionPageDiscoveryOptions {
|
|
66
|
+
context: BrowserContext;
|
|
67
|
+
extensionId?: string;
|
|
68
|
+
}
|
|
69
|
+
export declare const DEFAULT_METAMASK_ONBOARDING_TIMEOUT_MS = 60000;
|
|
70
|
+
export declare const METAMASK_ONBOARDING_SELECTORS: {
|
|
71
|
+
readonly termsCheckbox: "[data-testid=\"onboarding-terms-checkbox\"]";
|
|
72
|
+
readonly importWalletButton: "[data-testid=\"onboarding-import-wallet\"]";
|
|
73
|
+
readonly noThanksMetricsButton: "[data-testid=\"metametrics-no-thanks\"]";
|
|
74
|
+
readonly privateKeyInput: "[data-testid=\"private-key-box\"]";
|
|
75
|
+
readonly passwordInput: "[data-testid=\"create-password-new\"]";
|
|
76
|
+
readonly confirmPasswordInput: "[data-testid=\"create-password-confirm\"]";
|
|
77
|
+
readonly importSubmitButton: "[data-testid=\"import-wallet-button\"]";
|
|
78
|
+
readonly unlockPasswordInput: "[data-testid=\"unlock-password\"]";
|
|
79
|
+
readonly unlockSubmitButton: "[data-testid=\"unlock-submit\"]";
|
|
80
|
+
readonly accountAddressButton: "[data-testid=\"account-menu-icon\"]";
|
|
81
|
+
};
|
|
82
|
+
export declare function resolveMetaMaskOnboardingConfig(options?: ResolveMetaMaskOnboardingConfigOptions): MetaMaskOnboardingConfig;
|
|
83
|
+
export declare function validateEthereumAddress(value: string | undefined): string;
|
|
84
|
+
export declare function validatePrivateKey(value: string | undefined): string;
|
|
85
|
+
export declare function validateMetaMaskPassword(value: string | undefined): string;
|
|
86
|
+
export declare function maskSecret(value: string): string;
|
|
87
|
+
export declare function createMetaMaskOnboardingPlan(config: MetaMaskOnboardingConfig): RedactedMetaMaskOnboardingPlan;
|
|
88
|
+
export declare function runMetaMaskOnboarding(config: MetaMaskOnboardingConfig, driver: MetaMaskOnboardingDriver): Promise<MetaMaskOnboardingResult>;
|
|
89
|
+
export declare function importPrivateKeyIntoMetaMaskPage(_page: Page, _input: MetaMaskImportPrivateKeyInput): Promise<void>;
|
|
90
|
+
export declare function unlockMetaMaskPage(page: Page, input: MetaMaskUnlockInput): Promise<void>;
|
|
91
|
+
export declare function verifyMetaMaskActiveAddress(_page: Page, _expectedAddress: string): Promise<string>;
|
|
92
|
+
export declare function isMetaMaskExtensionPageUrl(url: string, extensionId?: string): boolean;
|
|
93
|
+
export declare function findMetaMaskExtensionPage(options: MetaMaskExtensionPageDiscoveryOptions): Page;
|
|
94
|
+
export declare function createMetaMaskPageDriver(options: MetaMaskPageDriverOptions): Promise<MetaMaskOnboardingDriver>;
|
|
95
|
+
//# sourceMappingURL=onboarding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"onboarding.d.ts","sourceRoot":"","sources":["../src/onboarding.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { discoverMetaMaskExtensionPage, isMetaMaskExtensionPageUrl as isKnownMetaMaskExtensionPageUrl } from './extension-pages.js';
|
|
2
|
+
export const DEFAULT_METAMASK_ONBOARDING_TIMEOUT_MS = 60_000;
|
|
3
|
+
export const METAMASK_ONBOARDING_SELECTORS = {
|
|
4
|
+
termsCheckbox: '[data-testid="onboarding-terms-checkbox"]',
|
|
5
|
+
importWalletButton: '[data-testid="onboarding-import-wallet"]',
|
|
6
|
+
noThanksMetricsButton: '[data-testid="metametrics-no-thanks"]',
|
|
7
|
+
privateKeyInput: '[data-testid="private-key-box"]',
|
|
8
|
+
passwordInput: '[data-testid="create-password-new"]',
|
|
9
|
+
confirmPasswordInput: '[data-testid="create-password-confirm"]',
|
|
10
|
+
importSubmitButton: '[data-testid="import-wallet-button"]',
|
|
11
|
+
unlockPasswordInput: '[data-testid="unlock-password"]',
|
|
12
|
+
unlockSubmitButton: '[data-testid="unlock-submit"]',
|
|
13
|
+
accountAddressButton: '[data-testid="account-menu-icon"]'
|
|
14
|
+
};
|
|
15
|
+
export function resolveMetaMaskOnboardingConfig(options = {}) {
|
|
16
|
+
const env = options.env ?? process.env;
|
|
17
|
+
const expectedAddress = validateEthereumAddress(options.expectedAddress ?? env.SEPOLIA_WALLET_ADDRESS);
|
|
18
|
+
const privateKey = validatePrivateKey(options.privateKey ?? env.SEPOLIA_WALLET_PRIVATE_KEY);
|
|
19
|
+
const password = validateMetaMaskPassword(options.password ?? env.METAMASK_PASSWORD);
|
|
20
|
+
return {
|
|
21
|
+
expectedAddress,
|
|
22
|
+
privateKey,
|
|
23
|
+
password,
|
|
24
|
+
timeoutMs: resolveTimeoutMs(options.timeoutMs, env.METAMASK_ONBOARDING_TIMEOUT_MS),
|
|
25
|
+
debug: options.debug ?? parseBoolean(env.METAMASK_ONBOARDING_DEBUG)
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export function validateEthereumAddress(value) {
|
|
29
|
+
const trimmed = value?.trim();
|
|
30
|
+
if (!trimmed || !/^0x[a-fA-F0-9]{40}$/i.test(trimmed)) {
|
|
31
|
+
throw new Error('SEPOLIA_WALLET_ADDRESS must be a 0x-prefixed 20-byte Ethereum address.');
|
|
32
|
+
}
|
|
33
|
+
return trimmed.toLowerCase();
|
|
34
|
+
}
|
|
35
|
+
export function validatePrivateKey(value) {
|
|
36
|
+
const trimmed = value?.trim();
|
|
37
|
+
if (!trimmed) {
|
|
38
|
+
throw new Error('SEPOLIA_WALLET_PRIVATE_KEY is required for MetaMask onboarding.');
|
|
39
|
+
}
|
|
40
|
+
const normalized = trimmed.startsWith('0x') ? trimmed : `0x${trimmed}`;
|
|
41
|
+
if (!/^0x[a-fA-F0-9]{64}$/.test(normalized)) {
|
|
42
|
+
throw new Error('SEPOLIA_WALLET_PRIVATE_KEY must be a 32-byte hex private key.');
|
|
43
|
+
}
|
|
44
|
+
return normalized;
|
|
45
|
+
}
|
|
46
|
+
export function validateMetaMaskPassword(value) {
|
|
47
|
+
const trimmed = value?.trim();
|
|
48
|
+
if (!trimmed || trimmed.length < 8) {
|
|
49
|
+
throw new Error('METAMASK_PASSWORD must be at least 8 characters long.');
|
|
50
|
+
}
|
|
51
|
+
return trimmed;
|
|
52
|
+
}
|
|
53
|
+
export function maskSecret(value) {
|
|
54
|
+
if (/^0x[a-fA-F0-9]{64}$/.test(value)) {
|
|
55
|
+
return `${value.slice(0, 4)}…${value.slice(-4)}`;
|
|
56
|
+
}
|
|
57
|
+
return `[redacted:${value.length} chars]`;
|
|
58
|
+
}
|
|
59
|
+
export function createMetaMaskOnboardingPlan(config) {
|
|
60
|
+
return {
|
|
61
|
+
status: 'pending',
|
|
62
|
+
expectedAddress: config.expectedAddress,
|
|
63
|
+
privateKey: maskSecret(config.privateKey),
|
|
64
|
+
password: maskSecret(config.password),
|
|
65
|
+
timeoutMs: config.timeoutMs,
|
|
66
|
+
debug: config.debug,
|
|
67
|
+
selectors: METAMASK_ONBOARDING_SELECTORS,
|
|
68
|
+
run: (driver) => runMetaMaskOnboarding(config, driver)
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
export async function runMetaMaskOnboarding(config, driver) {
|
|
72
|
+
const state = await runRedactedOnboardingStep(config, 'read MetaMask onboarding state', () => driver.getState());
|
|
73
|
+
switch (state) {
|
|
74
|
+
case 'needs-import':
|
|
75
|
+
await runRedactedOnboardingStep(config, 'import private key into MetaMask', () => driver.importPrivateKey({
|
|
76
|
+
expectedAddress: config.expectedAddress,
|
|
77
|
+
privateKey: config.privateKey,
|
|
78
|
+
password: config.password,
|
|
79
|
+
timeoutMs: config.timeoutMs
|
|
80
|
+
}));
|
|
81
|
+
await runRedactedOnboardingStep(config, 'unlock MetaMask', () => driver.unlock({ expectedAddress: config.expectedAddress, password: config.password, timeoutMs: config.timeoutMs }));
|
|
82
|
+
break;
|
|
83
|
+
case 'locked':
|
|
84
|
+
await runRedactedOnboardingStep(config, 'unlock MetaMask', () => driver.unlock({ expectedAddress: config.expectedAddress, password: config.password, timeoutMs: config.timeoutMs }));
|
|
85
|
+
break;
|
|
86
|
+
case 'unlocked':
|
|
87
|
+
break;
|
|
88
|
+
case 'unknown':
|
|
89
|
+
throw new Error('Unknown MetaMask onboarding state; refusing to continue without leaking onboarding secrets.');
|
|
90
|
+
}
|
|
91
|
+
const activeAddress = validateEthereumAddress(await runRedactedOnboardingStep(config, 'read active MetaMask address', () => driver.getActiveAddress()));
|
|
92
|
+
if (activeAddress !== config.expectedAddress) {
|
|
93
|
+
throw new Error(`MetaMask active address ${activeAddress} does not match expected ${config.expectedAddress}.`);
|
|
94
|
+
}
|
|
95
|
+
return { status: 'verified', expectedAddress: config.expectedAddress, activeAddress };
|
|
96
|
+
}
|
|
97
|
+
export async function importPrivateKeyIntoMetaMaskPage(_page, _input) {
|
|
98
|
+
throw new Error('MetaMask page import automation is not implemented yet; selector contract is exported for the pinned onboarding flow.');
|
|
99
|
+
}
|
|
100
|
+
export async function unlockMetaMaskPage(page, input) {
|
|
101
|
+
await page.locator(METAMASK_ONBOARDING_SELECTORS.unlockPasswordInput).fill(input.password);
|
|
102
|
+
await page.locator(METAMASK_ONBOARDING_SELECTORS.unlockSubmitButton).click();
|
|
103
|
+
}
|
|
104
|
+
export async function verifyMetaMaskActiveAddress(_page, _expectedAddress) {
|
|
105
|
+
throw new Error('MetaMask active-address verification is not implemented yet; use a MetaMaskOnboardingDriver mock until real extension page selectors are wired.');
|
|
106
|
+
}
|
|
107
|
+
export function isMetaMaskExtensionPageUrl(url, extensionId) {
|
|
108
|
+
return isKnownMetaMaskExtensionPageUrl(url, { extensionId });
|
|
109
|
+
}
|
|
110
|
+
export function findMetaMaskExtensionPage(options) {
|
|
111
|
+
try {
|
|
112
|
+
return discoverMetaMaskExtensionPage(options.context.pages(), { extensionId: options.extensionId });
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
116
|
+
if (message.startsWith('No MetaMask extension page found')) {
|
|
117
|
+
throw new Error('Unknown MetaMask extension UI state: no MetaMask extension page is open in the provided BrowserContext.');
|
|
118
|
+
}
|
|
119
|
+
if (message.startsWith('Multiple MetaMask extension page candidates found')) {
|
|
120
|
+
throw new Error('Unknown MetaMask extension UI state: multiple MetaMask extension pages are open; pass an explicit Page to avoid ambiguity.');
|
|
121
|
+
}
|
|
122
|
+
throw error;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
export async function createMetaMaskPageDriver(options) {
|
|
126
|
+
const page = options.page ?? findMetaMaskExtensionPage(options);
|
|
127
|
+
return {
|
|
128
|
+
async getState() {
|
|
129
|
+
if (await hasAnyVisibleSelector(page, [METAMASK_ONBOARDING_SELECTORS.unlockPasswordInput])) {
|
|
130
|
+
return 'locked';
|
|
131
|
+
}
|
|
132
|
+
if (await hasAnyVisibleSelector(page, [
|
|
133
|
+
METAMASK_ONBOARDING_SELECTORS.termsCheckbox,
|
|
134
|
+
METAMASK_ONBOARDING_SELECTORS.importWalletButton,
|
|
135
|
+
METAMASK_ONBOARDING_SELECTORS.privateKeyInput
|
|
136
|
+
])) {
|
|
137
|
+
return 'needs-import';
|
|
138
|
+
}
|
|
139
|
+
if (await hasAnyVisibleSelector(page, [METAMASK_ONBOARDING_SELECTORS.accountAddressButton])) {
|
|
140
|
+
return 'unlocked';
|
|
141
|
+
}
|
|
142
|
+
return 'unknown';
|
|
143
|
+
},
|
|
144
|
+
async importPrivateKey(input) {
|
|
145
|
+
await importPrivateKeyIntoMetaMaskPage(page, input);
|
|
146
|
+
},
|
|
147
|
+
async unlock(input) {
|
|
148
|
+
await unlockMetaMaskPage(page, input);
|
|
149
|
+
},
|
|
150
|
+
async getActiveAddress() {
|
|
151
|
+
return verifyMetaMaskActiveAddress(page, '');
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
async function hasAnyVisibleSelector(page, selectors) {
|
|
156
|
+
for (const selector of selectors) {
|
|
157
|
+
try {
|
|
158
|
+
if ((await page.locator(selector).count()) > 0) {
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
function resolveTimeoutMs(explicit, envValue) {
|
|
169
|
+
const value = explicit ?? (envValue?.trim() ? Number(envValue) : DEFAULT_METAMASK_ONBOARDING_TIMEOUT_MS);
|
|
170
|
+
if (!Number.isInteger(value) || value <= 0) {
|
|
171
|
+
throw new Error('METAMASK_ONBOARDING_TIMEOUT_MS must be a positive integer number of milliseconds.');
|
|
172
|
+
}
|
|
173
|
+
return value;
|
|
174
|
+
}
|
|
175
|
+
async function runRedactedOnboardingStep(config, step, action) {
|
|
176
|
+
try {
|
|
177
|
+
return await action();
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
const rawMessage = error instanceof Error ? error.message : String(error);
|
|
181
|
+
throw new Error(`Failed to ${step}: ${redactOnboardingSecrets(rawMessage, config)}`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
function redactOnboardingSecrets(message, config) {
|
|
185
|
+
return [config.privateKey, config.privateKey.slice(2), config.password]
|
|
186
|
+
.filter((value) => value.length > 0)
|
|
187
|
+
.reduce((redacted, secret) => redacted.split(secret).join(maskSecret(secret)), message)
|
|
188
|
+
.replace(/0x[a-fA-F0-9]{64}/g, '[redacted:private-key]')
|
|
189
|
+
.replace(/\b[a-fA-F0-9]{64}\b/g, '[redacted:private-key]');
|
|
190
|
+
}
|
|
191
|
+
function parseBoolean(value) {
|
|
192
|
+
if (value === undefined || value.trim() === '') {
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
return ['1', 'true', 'yes', 'on'].includes(value.trim().toLowerCase());
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=onboarding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"onboarding.js","sourceRoot":"","sources":["../src/onboarding.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type WalletBrowserConfig, type WalletBrowserEnv } from './config.js';
|
|
2
|
+
import { type MetaMaskOnboardingConfig, type MetaMaskOnboardingEnv } from './onboarding.js';
|
|
3
|
+
export interface ProfileBootstrapImportEnv extends WalletBrowserEnv, MetaMaskOnboardingEnv {
|
|
4
|
+
}
|
|
5
|
+
export interface ResolveProfileBootstrapImportOptions {
|
|
6
|
+
cwd?: string;
|
|
7
|
+
env?: ProfileBootstrapImportEnv;
|
|
8
|
+
now?: Date;
|
|
9
|
+
}
|
|
10
|
+
export interface ProfileBootstrapImportManifest {
|
|
11
|
+
artifactType: 'wallet-profile-bootstrap-import';
|
|
12
|
+
status: 'dry-run';
|
|
13
|
+
walletAddress: string;
|
|
14
|
+
profileName: string;
|
|
15
|
+
metamaskExtension: {
|
|
16
|
+
version: string;
|
|
17
|
+
identity: WalletBrowserConfig['metamaskExtensionIdentity'];
|
|
18
|
+
};
|
|
19
|
+
secrets: {
|
|
20
|
+
privateKeyConfigured: boolean;
|
|
21
|
+
passwordConfigured: boolean;
|
|
22
|
+
};
|
|
23
|
+
safetyNotes: string[];
|
|
24
|
+
}
|
|
25
|
+
export interface ProfileBootstrapImportDryRunResult {
|
|
26
|
+
status: 'dry-run';
|
|
27
|
+
manifestPath: string;
|
|
28
|
+
manifest: ProfileBootstrapImportManifest;
|
|
29
|
+
}
|
|
30
|
+
export declare function maskEthereumAddress(address: string): string;
|
|
31
|
+
export declare function createProfileBootstrapImportManifest(walletConfig: WalletBrowserConfig, onboardingConfig: MetaMaskOnboardingConfig): ProfileBootstrapImportManifest;
|
|
32
|
+
export declare function createProfileBootstrapImportDryRun(options?: ResolveProfileBootstrapImportOptions): ProfileBootstrapImportDryRunResult;
|
|
33
|
+
//# sourceMappingURL=profile-bootstrap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-bootstrap.d.ts","sourceRoot":"","sources":["../src/profile-bootstrap.ts"],"names":[],"mappings":"AAGA,OAAO,EAA8B,KAAK,mBAAmB,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC1G,OAAO,EAAmC,KAAK,wBAAwB,EAAE,KAAK,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAE7H,MAAM,WAAW,yBAA0B,SAAQ,gBAAgB,EAAE,qBAAqB;CAAG;AAE7F,MAAM,WAAW,oCAAoC;IACnD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,yBAAyB,CAAC;IAChC,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAED,MAAM,WAAW,8BAA8B;IAC7C,YAAY,EAAE,iCAAiC,CAAC;IAChD,MAAM,EAAE,SAAS,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,mBAAmB,CAAC,2BAA2B,CAAC,CAAC;KAC5D,CAAC;IACF,OAAO,EAAE;QACP,oBAAoB,EAAE,OAAO,CAAC;QAC9B,kBAAkB,EAAE,OAAO,CAAC;KAC7B,CAAC;IACF,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,kCAAkC;IACjD,MAAM,EAAE,SAAS,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,8BAA8B,CAAC;CAC1C;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAG3D;AAED,wBAAgB,oCAAoC,CAClD,YAAY,EAAE,mBAAmB,EACjC,gBAAgB,EAAE,wBAAwB,GACzC,8BAA8B,CAoBhC;AAED,wBAAgB,kCAAkC,CAChD,OAAO,GAAE,oCAAyC,GACjD,kCAAkC,CAcpC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { resolveWalletBrowserConfig } from './config.js';
|
|
4
|
+
import { resolveMetaMaskOnboardingConfig } from './onboarding.js';
|
|
5
|
+
export function maskEthereumAddress(address) {
|
|
6
|
+
const normalized = address.toLowerCase();
|
|
7
|
+
return `${normalized.slice(0, 6)}…${normalized.slice(-4)}`;
|
|
8
|
+
}
|
|
9
|
+
export function createProfileBootstrapImportManifest(walletConfig, onboardingConfig) {
|
|
10
|
+
return {
|
|
11
|
+
artifactType: 'wallet-profile-bootstrap-import',
|
|
12
|
+
status: 'dry-run',
|
|
13
|
+
walletAddress: maskEthereumAddress(onboardingConfig.expectedAddress),
|
|
14
|
+
profileName: walletConfig.profileName,
|
|
15
|
+
metamaskExtension: {
|
|
16
|
+
version: walletConfig.metamaskExtensionVersion,
|
|
17
|
+
identity: walletConfig.metamaskExtensionIdentity
|
|
18
|
+
},
|
|
19
|
+
secrets: {
|
|
20
|
+
privateKeyConfigured: onboardingConfig.privateKey.length > 0,
|
|
21
|
+
passwordConfigured: onboardingConfig.password.length > 0
|
|
22
|
+
},
|
|
23
|
+
safetyNotes: [
|
|
24
|
+
'No browser was launched and no private key or password was entered during this dry run.',
|
|
25
|
+
'Generated artifacts are local-only under .wallet-artifacts and must remain ignored.',
|
|
26
|
+
'Use only burner/testnet wallets and inspect artifacts before sharing any evidence.'
|
|
27
|
+
]
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export function createProfileBootstrapImportDryRun(options = {}) {
|
|
31
|
+
const cwd = options.cwd ?? process.cwd();
|
|
32
|
+
const env = options.env ?? process.env;
|
|
33
|
+
const onboardingConfig = resolveMetaMaskOnboardingConfig({ env });
|
|
34
|
+
const walletConfig = resolveWalletBrowserConfig({ cwd, env });
|
|
35
|
+
const manifest = createProfileBootstrapImportManifest(walletConfig, onboardingConfig);
|
|
36
|
+
const runId = formatRunId(options.now ?? new Date());
|
|
37
|
+
const artifactDir = join(cwd, '.wallet-artifacts', 'profile-bootstrap-import', runId);
|
|
38
|
+
const manifestPath = join(artifactDir, 'BOOTSTRAP-MANIFEST.json');
|
|
39
|
+
mkdirSync(artifactDir, { recursive: true });
|
|
40
|
+
writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`, { mode: 0o600 });
|
|
41
|
+
return { status: 'dry-run', manifestPath, manifest };
|
|
42
|
+
}
|
|
43
|
+
function formatRunId(now) {
|
|
44
|
+
return now.toISOString().replace(/[:.]/g, '-');
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=profile-bootstrap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-bootstrap.js","sourceRoot":"","sources":["../src/profile-bootstrap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,0BAA0B,EAAmD,MAAM,aAAa,CAAC;AAC1G,OAAO,EAAE,+BAA+B,EAA6D,MAAM,iBAAiB,CAAC;AAgC7H,MAAM,UAAU,mBAAmB,CAAC,OAAe;IACjD,MAAM,UAAU,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IACzC,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,oCAAoC,CAClD,YAAiC,EACjC,gBAA0C;IAE1C,OAAO;QACL,YAAY,EAAE,iCAAiC;QAC/C,MAAM,EAAE,SAAS;QACjB,aAAa,EAAE,mBAAmB,CAAC,gBAAgB,CAAC,eAAe,CAAC;QACpE,WAAW,EAAE,YAAY,CAAC,WAAW;QACrC,iBAAiB,EAAE;YACjB,OAAO,EAAE,YAAY,CAAC,wBAAwB;YAC9C,QAAQ,EAAE,YAAY,CAAC,yBAAyB;SACjD;QACD,OAAO,EAAE;YACP,oBAAoB,EAAE,gBAAgB,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC;YAC5D,kBAAkB,EAAE,gBAAgB,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC;SACzD;QACD,WAAW,EAAE;YACX,yFAAyF;YACzF,qFAAqF;YACrF,oFAAoF;SACrF;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kCAAkC,CAChD,UAAgD,EAAE;IAElD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACzC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACvC,MAAM,gBAAgB,GAAG,+BAA+B,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;IAClE,MAAM,YAAY,GAAG,0BAA0B,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;IAC9D,MAAM,QAAQ,GAAG,oCAAoC,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC;IACtF,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;IACrD,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,KAAK,CAAC,CAAC;IACtF,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,EAAE,yBAAyB,CAAC,CAAC;IAElE,SAAS,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,aAAa,CAAC,YAAY,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAEvF,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC;AACvD,CAAC;AAED,SAAS,WAAW,CAAC,GAAS;IAC5B,OAAO,GAAG,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;AACjD,CAAC"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { type MetaMaskNetworkDriver, type SepoliaNetworkAssertionResult } from './network.js';
|
|
2
|
+
export type WalletControlAction = 'connectWallet' | 'approveSignature' | 'approveTransaction' | 'switchNetwork' | 'assertWalletState' | 'resetProfile';
|
|
3
|
+
export type WalletControlLogStatus = 'started' | 'prompt-approved' | 'verified' | 'deleted' | 'skipped' | 'failed';
|
|
4
|
+
export interface WalletControlLogEvent {
|
|
5
|
+
action: WalletControlAction;
|
|
6
|
+
status: WalletControlLogStatus;
|
|
7
|
+
origin?: string;
|
|
8
|
+
chainId?: number;
|
|
9
|
+
chainIdHex?: string;
|
|
10
|
+
account?: string;
|
|
11
|
+
target?: string;
|
|
12
|
+
valueWei?: string;
|
|
13
|
+
decision?: 'pending' | 'approved' | 'rejected';
|
|
14
|
+
promptType?: 'connect' | 'signature' | 'transaction';
|
|
15
|
+
metadata?: unknown;
|
|
16
|
+
}
|
|
17
|
+
export type WalletControlLogger = (event: WalletControlLogEvent) => void;
|
|
18
|
+
export interface WalletDappDriver {
|
|
19
|
+
requestConnect(): Promise<void>;
|
|
20
|
+
getConnectedAccount(): Promise<string | undefined>;
|
|
21
|
+
requestSignature?(input: WalletSignatureRequestInput): Promise<void>;
|
|
22
|
+
requestTransaction?(input: WalletTransactionRequestInput): Promise<void>;
|
|
23
|
+
}
|
|
24
|
+
export interface WalletDappPageLocator {
|
|
25
|
+
click(): Promise<void>;
|
|
26
|
+
textContent(): Promise<string | null>;
|
|
27
|
+
}
|
|
28
|
+
export interface WalletDappPageLike {
|
|
29
|
+
locator(selector: string): WalletDappPageLocator;
|
|
30
|
+
}
|
|
31
|
+
export interface WalletDappPageDriverSelectors {
|
|
32
|
+
connectButton: string;
|
|
33
|
+
connectedAccount: string;
|
|
34
|
+
signMessageButton: string;
|
|
35
|
+
sendTransactionButton: string;
|
|
36
|
+
}
|
|
37
|
+
export interface WalletDappPageDriverOptions {
|
|
38
|
+
page: WalletDappPageLike;
|
|
39
|
+
selectors: WalletDappPageDriverSelectors;
|
|
40
|
+
}
|
|
41
|
+
export interface WalletSignatureRequestInput {
|
|
42
|
+
origin?: string;
|
|
43
|
+
expectedAccount: string;
|
|
44
|
+
message?: string;
|
|
45
|
+
}
|
|
46
|
+
export interface WalletTransactionRequestInput {
|
|
47
|
+
origin?: string;
|
|
48
|
+
expectedAccount: string;
|
|
49
|
+
to?: string;
|
|
50
|
+
value?: string;
|
|
51
|
+
}
|
|
52
|
+
export interface WalletConnectionPromptInput {
|
|
53
|
+
origin?: string;
|
|
54
|
+
expectedAccount: string;
|
|
55
|
+
expectedChainIdHex: string;
|
|
56
|
+
}
|
|
57
|
+
export interface WalletSignaturePromptInput {
|
|
58
|
+
origin?: string;
|
|
59
|
+
expectedAccount: string;
|
|
60
|
+
message?: string;
|
|
61
|
+
}
|
|
62
|
+
export interface WalletTransactionPromptInput {
|
|
63
|
+
origin?: string;
|
|
64
|
+
expectedAccount: string;
|
|
65
|
+
to?: string;
|
|
66
|
+
value?: string;
|
|
67
|
+
}
|
|
68
|
+
export interface WalletGuardrailConfig {
|
|
69
|
+
maxTransactionValueWei?: string | number | bigint;
|
|
70
|
+
allowedOrigins?: readonly string[];
|
|
71
|
+
allowedTargets?: readonly string[];
|
|
72
|
+
}
|
|
73
|
+
export interface WalletPromptDriver {
|
|
74
|
+
approveConnection?(input: WalletConnectionPromptInput): Promise<void>;
|
|
75
|
+
approveSignature?(input: WalletSignaturePromptInput): Promise<void>;
|
|
76
|
+
approveTransaction?(input: WalletTransactionPromptInput): Promise<void>;
|
|
77
|
+
}
|
|
78
|
+
export interface WalletStateOptions {
|
|
79
|
+
network: MetaMaskNetworkDriver;
|
|
80
|
+
expectedAccount: string;
|
|
81
|
+
expectedChainId: string | number;
|
|
82
|
+
logger?: WalletControlLogger;
|
|
83
|
+
metadata?: unknown;
|
|
84
|
+
}
|
|
85
|
+
export interface ConnectWalletOptions extends WalletStateOptions {
|
|
86
|
+
dapp: WalletDappDriver;
|
|
87
|
+
prompt: WalletPromptDriver;
|
|
88
|
+
origin?: string;
|
|
89
|
+
guardrails?: WalletGuardrailConfig;
|
|
90
|
+
}
|
|
91
|
+
export type ConnectWalletResult = Omit<SepoliaNetworkAssertionResult, 'status'> & {
|
|
92
|
+
status: 'connected';
|
|
93
|
+
};
|
|
94
|
+
export interface ApproveSignatureOptions {
|
|
95
|
+
prompt: WalletPromptDriver;
|
|
96
|
+
dapp?: Pick<WalletDappDriver, 'requestSignature'>;
|
|
97
|
+
origin?: string;
|
|
98
|
+
expectedAccount: string;
|
|
99
|
+
expectedChainId?: string | number;
|
|
100
|
+
network?: MetaMaskNetworkDriver;
|
|
101
|
+
message?: string;
|
|
102
|
+
guardrails?: WalletGuardrailConfig;
|
|
103
|
+
logger?: WalletControlLogger;
|
|
104
|
+
metadata?: unknown;
|
|
105
|
+
}
|
|
106
|
+
export interface ApproveTransactionOptions {
|
|
107
|
+
prompt: WalletPromptDriver;
|
|
108
|
+
dapp?: Pick<WalletDappDriver, 'requestTransaction'>;
|
|
109
|
+
origin?: string;
|
|
110
|
+
expectedAccount: string;
|
|
111
|
+
expectedChainId?: string | number;
|
|
112
|
+
network?: MetaMaskNetworkDriver;
|
|
113
|
+
to?: string;
|
|
114
|
+
value?: string;
|
|
115
|
+
guardrails?: WalletGuardrailConfig;
|
|
116
|
+
logger?: WalletControlLogger;
|
|
117
|
+
metadata?: unknown;
|
|
118
|
+
}
|
|
119
|
+
export interface ResetProfileOptions {
|
|
120
|
+
profileDir: string;
|
|
121
|
+
allowedProfileRoot?: string;
|
|
122
|
+
logger?: WalletControlLogger;
|
|
123
|
+
metadata?: unknown;
|
|
124
|
+
}
|
|
125
|
+
export interface ResetProfileResult {
|
|
126
|
+
status: 'deleted' | 'skipped';
|
|
127
|
+
profileDir: string;
|
|
128
|
+
allowedProfileRoot: string;
|
|
129
|
+
}
|
|
130
|
+
export declare function createWalletDappPageDriver(options: WalletDappPageDriverOptions): WalletDappDriver;
|
|
131
|
+
export declare function connectWallet(options: ConnectWalletOptions): Promise<ConnectWalletResult>;
|
|
132
|
+
export declare function approveSignature(options: ApproveSignatureOptions): Promise<void>;
|
|
133
|
+
export declare function approveTransaction(options: ApproveTransactionOptions): Promise<void>;
|
|
134
|
+
export declare function switchNetwork(options: WalletStateOptions): Promise<SepoliaNetworkAssertionResult>;
|
|
135
|
+
export declare function assertWalletState(options: WalletStateOptions): Promise<SepoliaNetworkAssertionResult>;
|
|
136
|
+
export declare function resetProfile(options: ResetProfileOptions): Promise<ResetProfileResult>;
|
|
137
|
+
//# sourceMappingURL=wallet-control.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallet-control.d.ts","sourceRoot":"","sources":["../src/wallet-control.ts"],"names":[],"mappings":"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"}
|