@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
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { type WalletBrowserEnv } from './config.js';
|
|
3
|
+
import { type RunMetaMaskSmoke } from './metamask-smoke.js';
|
|
4
|
+
export interface WalletBrowserCliOptions {
|
|
5
|
+
argv?: string[];
|
|
6
|
+
cwd?: string;
|
|
7
|
+
env?: WalletBrowserEnv;
|
|
8
|
+
stdout?: (message: string) => void;
|
|
9
|
+
stderr?: (message: string) => void;
|
|
10
|
+
runMetaMaskSmoke?: RunMetaMaskSmoke;
|
|
11
|
+
runFixtureExtensionSmoke?: RunMetaMaskSmoke;
|
|
12
|
+
}
|
|
13
|
+
export declare function runWalletBrowserCli(options?: WalletBrowserCliOptions): Promise<number>;
|
|
14
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAA8B,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAKhF,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,qBAAqB,CAAC;AAE7B,MAAM,WAAW,uBAAuB;IACtC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,gBAAgB,CAAC;IACvB,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,wBAAwB,CAAC,EAAE,gBAAgB,CAAC;CAC7C;AAkFD,wBAAsB,mBAAmB,CAAC,OAAO,GAAE,uBAA4B,GAAG,OAAO,CAAC,MAAM,CAAC,CAwIhG"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { prepareChromiumLaunchOptions } from './launcher.js';
|
|
3
|
+
import { resolveWalletBrowserConfig } from './config.js';
|
|
4
|
+
import { createMetaMaskOnboardingPlan, resolveMetaMaskOnboardingConfig } from './onboarding.js';
|
|
5
|
+
import { createSepoliaNetworkPlan, resolveSepoliaNetworkConfig } from './network.js';
|
|
6
|
+
import { createProfileBootstrapImportDryRun } from './profile-bootstrap.js';
|
|
7
|
+
import { verifyFixtureConnectionProofManifest } from './fixture-proof.js';
|
|
8
|
+
import { captureFixtureExtensionSmokeScreenshots, captureMetaMaskSmokeScreenshots, verifySmokeArtifactManifest } from './metamask-smoke.js';
|
|
9
|
+
const PREPARE_CONFIG_KEYS = [
|
|
10
|
+
'METAMASK_EXTENSION_PATH',
|
|
11
|
+
'METAMASK_EXTENSION_DIR',
|
|
12
|
+
'METAMASK_EXTENSION_VERSION',
|
|
13
|
+
'WALLET_PROFILE_DIR',
|
|
14
|
+
'WALLET_PROFILE_NAME',
|
|
15
|
+
'PRESERVE_WALLET_PROFILE'
|
|
16
|
+
];
|
|
17
|
+
const PREPARE_ERROR_REDACT_KEYS = ['METAMASK_EXTENSION_PATH', 'METAMASK_EXTENSION_DIR', 'WALLET_PROFILE_DIR'];
|
|
18
|
+
const USAGE = `Usage:
|
|
19
|
+
wallet-browser prepare
|
|
20
|
+
wallet-browser smoke-metamask
|
|
21
|
+
wallet-browser smoke-fixture-extension
|
|
22
|
+
wallet-browser verify-smoke-artifacts <artifact-dir>
|
|
23
|
+
wallet-browser verify-fixture-proof <artifact-dir>
|
|
24
|
+
wallet-browser onboarding-plan
|
|
25
|
+
wallet-browser profile-bootstrap-import --dry-run
|
|
26
|
+
wallet-browser network-plan
|
|
27
|
+
|
|
28
|
+
Print a sanitized Chromium persistent-context launch plan for the pinned MetaMask extension profile,
|
|
29
|
+
launch real Chromium with MetaMask loaded and capture local-only smoke screenshots,
|
|
30
|
+
launch real Chromium with a generated fake extension to prove extension-loading mechanics only,
|
|
31
|
+
print a redacted MetaMask onboarding plan for the configured burner wallet, or print a
|
|
32
|
+
redacted Sepolia network provisioning plan.
|
|
33
|
+
The prepare command does not launch Chromium. The smoke-metamask command launches Chromium but
|
|
34
|
+
never imports, unlocks, connects, signs, or transacts. Plan commands validate injected environment/config
|
|
35
|
+
and never print raw private keys, wallet passwords, or RPC tokens.
|
|
36
|
+
`;
|
|
37
|
+
function summarizePrepareConfig(env) {
|
|
38
|
+
const present = [];
|
|
39
|
+
const missing = [];
|
|
40
|
+
for (const key of PREPARE_CONFIG_KEYS) {
|
|
41
|
+
const value = env[key];
|
|
42
|
+
if (typeof value === 'string' && value.trim() !== '') {
|
|
43
|
+
present.push(key);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
missing.push(key);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return { present, missing };
|
|
50
|
+
}
|
|
51
|
+
function redactPrepareError(message, env) {
|
|
52
|
+
let redacted = message;
|
|
53
|
+
for (const key of PREPARE_ERROR_REDACT_KEYS) {
|
|
54
|
+
const value = env[key]?.trim();
|
|
55
|
+
if (value) {
|
|
56
|
+
redacted = redacted.replaceAll(value, `[redacted:${key}]`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return redacted;
|
|
60
|
+
}
|
|
61
|
+
export async function runWalletBrowserCli(options = {}) {
|
|
62
|
+
const argv = options.argv ?? process.argv.slice(2);
|
|
63
|
+
const stdout = options.stdout ?? ((message) => process.stdout.write(message));
|
|
64
|
+
const stderr = options.stderr ?? ((message) => process.stderr.write(message));
|
|
65
|
+
const command = argv[0] ?? 'prepare';
|
|
66
|
+
if (command === '--help' || command === '-h' || command === 'help') {
|
|
67
|
+
stdout(USAGE);
|
|
68
|
+
return 0;
|
|
69
|
+
}
|
|
70
|
+
if (command === 'smoke-metamask') {
|
|
71
|
+
try {
|
|
72
|
+
const runSmoke = options.runMetaMaskSmoke ?? captureMetaMaskSmokeScreenshots;
|
|
73
|
+
const result = await runSmoke({ cwd: options.cwd, env: options.env });
|
|
74
|
+
stdout(`${JSON.stringify(result, null, 2)}\n`);
|
|
75
|
+
return 0;
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
stderr(`${redactPrepareError(error instanceof Error ? error.message : String(error), options.env ?? process.env)}\n`);
|
|
79
|
+
return 1;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (command === 'smoke-fixture-extension') {
|
|
83
|
+
try {
|
|
84
|
+
const runSmoke = options.runFixtureExtensionSmoke ?? captureFixtureExtensionSmokeScreenshots;
|
|
85
|
+
const result = await runSmoke({ cwd: options.cwd, env: options.env });
|
|
86
|
+
stdout(`${JSON.stringify(result, null, 2)}\n`);
|
|
87
|
+
return 0;
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
stderr(`${redactPrepareError(error instanceof Error ? error.message : String(error), options.env ?? process.env)}\n`);
|
|
91
|
+
return 1;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (command === 'verify-smoke-artifacts') {
|
|
95
|
+
const artifactDir = argv[1];
|
|
96
|
+
if (!artifactDir) {
|
|
97
|
+
stderr(`Missing artifact directory for verify-smoke-artifacts.\n\n${USAGE}`);
|
|
98
|
+
return 1;
|
|
99
|
+
}
|
|
100
|
+
try {
|
|
101
|
+
const result = verifySmokeArtifactManifest(artifactDir);
|
|
102
|
+
stdout(`${JSON.stringify(result, null, 2)}\n`);
|
|
103
|
+
return 0;
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
stderr(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
107
|
+
return 1;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (command === 'verify-fixture-proof') {
|
|
111
|
+
const artifactDir = argv[1];
|
|
112
|
+
if (!artifactDir) {
|
|
113
|
+
stderr(`Missing artifact directory for verify-fixture-proof.\n\n${USAGE}`);
|
|
114
|
+
return 1;
|
|
115
|
+
}
|
|
116
|
+
try {
|
|
117
|
+
const result = verifyFixtureConnectionProofManifest(artifactDir);
|
|
118
|
+
const publicResult = { ...result, artifactDir: '[redacted:artifact-dir]', manifestPath: '[redacted:manifest-path]' };
|
|
119
|
+
stdout(`${JSON.stringify(publicResult, null, 2)}\n`);
|
|
120
|
+
return 0;
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
stderr(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
124
|
+
return 1;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (command === 'onboarding-plan') {
|
|
128
|
+
try {
|
|
129
|
+
const onboardingConfig = resolveMetaMaskOnboardingConfig({ env: options.env });
|
|
130
|
+
const plan = createMetaMaskOnboardingPlan(onboardingConfig);
|
|
131
|
+
stdout(`${JSON.stringify(plan, null, 2)}\n`);
|
|
132
|
+
return 0;
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
stderr(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
136
|
+
return 1;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (command === 'profile-bootstrap-import') {
|
|
140
|
+
if (!argv.includes('--dry-run')) {
|
|
141
|
+
stderr('profile-bootstrap-import currently requires --dry-run; real browser import automation is intentionally not run by this command yet.\n');
|
|
142
|
+
return 1;
|
|
143
|
+
}
|
|
144
|
+
try {
|
|
145
|
+
const result = createProfileBootstrapImportDryRun({ cwd: options.cwd, env: options.env });
|
|
146
|
+
stdout(`${JSON.stringify(result, null, 2)}\n`);
|
|
147
|
+
return 0;
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
stderr(`${redactPrepareError(error instanceof Error ? error.message : String(error), options.env ?? process.env)}\n`);
|
|
151
|
+
return 1;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (command === 'network-plan') {
|
|
155
|
+
try {
|
|
156
|
+
const networkConfig = resolveSepoliaNetworkConfig({ env: options.env });
|
|
157
|
+
const plan = createSepoliaNetworkPlan(networkConfig);
|
|
158
|
+
stdout(`${JSON.stringify(plan, null, 2)}\n`);
|
|
159
|
+
return 0;
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
stderr(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
163
|
+
return 1;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (command !== 'prepare') {
|
|
167
|
+
stderr(`Unknown command: ${command}\n\n${USAGE}`);
|
|
168
|
+
return 1;
|
|
169
|
+
}
|
|
170
|
+
try {
|
|
171
|
+
const config = resolveWalletBrowserConfig({ cwd: options.cwd, env: options.env });
|
|
172
|
+
const launchOptions = prepareChromiumLaunchOptions(config);
|
|
173
|
+
const plan = {
|
|
174
|
+
browserName: launchOptions.browserName,
|
|
175
|
+
userDataDir: launchOptions.userDataDir,
|
|
176
|
+
args: [...(launchOptions.options.args ?? [])],
|
|
177
|
+
metamaskExtensionPath: config.metamaskExtensionPath,
|
|
178
|
+
metamaskExtensionVersion: config.metamaskExtensionVersion,
|
|
179
|
+
metamaskExtensionIdentity: config.metamaskExtensionIdentity,
|
|
180
|
+
profileDir: config.profileDir,
|
|
181
|
+
profileName: config.profileName,
|
|
182
|
+
preserveProfile: config.preserveProfile,
|
|
183
|
+
config: summarizePrepareConfig(options.env ?? process.env)
|
|
184
|
+
};
|
|
185
|
+
stdout(`${JSON.stringify(plan, null, 2)}\n`);
|
|
186
|
+
return 0;
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
190
|
+
stderr(`${redactPrepareError(message, options.env ?? process.env)}\n`);
|
|
191
|
+
return 1;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
195
|
+
process.exitCode = await runWalletBrowserCli();
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export declare const PINNED_METAMASK_VERSION = "13.29.0";
|
|
2
|
+
export interface WalletBrowserEnv {
|
|
3
|
+
[key: string]: string | undefined;
|
|
4
|
+
METAMASK_EXTENSION_PATH?: string;
|
|
5
|
+
METAMASK_EXTENSION_DIR?: string;
|
|
6
|
+
METAMASK_EXTENSION_VERSION?: string;
|
|
7
|
+
WALLET_PROFILE_DIR?: string;
|
|
8
|
+
WALLET_PROFILE_NAME?: string;
|
|
9
|
+
PRESERVE_WALLET_PROFILE?: string;
|
|
10
|
+
SEPOLIA_WALLET_ADDRESS?: string;
|
|
11
|
+
SEPOLIA_WALLET_PRIVATE_KEY?: string;
|
|
12
|
+
METAMASK_PASSWORD?: string;
|
|
13
|
+
METAMASK_ONBOARDING_TIMEOUT_MS?: string;
|
|
14
|
+
METAMASK_ONBOARDING_DEBUG?: string;
|
|
15
|
+
SEPOLIA_CHAIN_ID?: string;
|
|
16
|
+
SEPOLIA_RPC_URL?: string;
|
|
17
|
+
METAMASK_NETWORK_ASSERTION_TIMEOUT_MS?: string;
|
|
18
|
+
METAMASK_NETWORK_DEBUG?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface ResolveWalletBrowserConfigOptions {
|
|
21
|
+
cwd?: string;
|
|
22
|
+
env?: WalletBrowserEnv;
|
|
23
|
+
metamaskExtensionPath?: string;
|
|
24
|
+
metamaskExtensionDir?: string;
|
|
25
|
+
metamaskExtensionVersion?: string;
|
|
26
|
+
profileDir?: string;
|
|
27
|
+
profileName?: string;
|
|
28
|
+
preserveProfile?: boolean;
|
|
29
|
+
}
|
|
30
|
+
export interface MetaMaskExtensionIdentity {
|
|
31
|
+
name: string;
|
|
32
|
+
shortName?: string;
|
|
33
|
+
version?: string;
|
|
34
|
+
}
|
|
35
|
+
export interface WalletBrowserConfig {
|
|
36
|
+
browserName: 'chromium';
|
|
37
|
+
metamaskExtensionPath: string;
|
|
38
|
+
metamaskExtensionVersion: string;
|
|
39
|
+
metamaskExtensionIdentity: MetaMaskExtensionIdentity;
|
|
40
|
+
profileDir: string;
|
|
41
|
+
profileName: string;
|
|
42
|
+
preserveProfile: boolean;
|
|
43
|
+
}
|
|
44
|
+
export declare function resolveWalletBrowserConfig(options?: ResolveWalletBrowserConfigOptions): WalletBrowserConfig;
|
|
45
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,uBAAuB,YAAY,CAAC;AAEjD,MAAM,WAAW,gBAAgB;IAC/B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAClC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,8BAA8B,CAAC,EAAE,MAAM,CAAC;IACxC,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,qCAAqC,CAAC,EAAE,MAAM,CAAC;IAC/C,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,iCAAiC;IAChD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,gBAAgB,CAAC;IACvB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,UAAU,CAAC;IACxB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,wBAAwB,EAAE,MAAM,CAAC;IACjC,yBAAyB,EAAE,yBAAyB,CAAC;IACrD,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAID,wBAAgB,0BAA0B,CAAC,OAAO,GAAE,iCAAsC,GAAG,mBAAmB,CAsC/G"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, statSync } from 'node:fs';
|
|
2
|
+
import { isAbsolute, join, parse, relative, resolve, sep } from 'node:path';
|
|
3
|
+
export const PINNED_METAMASK_VERSION = '13.29.0';
|
|
4
|
+
const DEFAULT_PROFILE_NAME = 'sepolia-burner';
|
|
5
|
+
export function resolveWalletBrowserConfig(options = {}) {
|
|
6
|
+
const cwd = options.cwd ?? process.cwd();
|
|
7
|
+
const env = options.env ?? process.env;
|
|
8
|
+
const metamaskExtensionVersion = options.metamaskExtensionVersion?.trim() || env.METAMASK_EXTENSION_VERSION?.trim() || PINNED_METAMASK_VERSION;
|
|
9
|
+
const extensionPathValue = options.metamaskExtensionPath ??
|
|
10
|
+
options.metamaskExtensionDir ??
|
|
11
|
+
env.METAMASK_EXTENSION_PATH ??
|
|
12
|
+
env.METAMASK_EXTENSION_DIR ??
|
|
13
|
+
defaultMetamaskExtensionPath(metamaskExtensionVersion);
|
|
14
|
+
const usesDefaultExtensionArtifact = options.metamaskExtensionPath === undefined &&
|
|
15
|
+
options.metamaskExtensionDir === undefined &&
|
|
16
|
+
env.METAMASK_EXTENSION_PATH === undefined &&
|
|
17
|
+
env.METAMASK_EXTENSION_DIR === undefined;
|
|
18
|
+
const metamaskExtensionPath = resolve(cwd, extensionPathValue);
|
|
19
|
+
assertDirectory(metamaskExtensionPath, 'MetaMask extension path');
|
|
20
|
+
const metamaskExtensionIdentity = readMetaMaskManifestIdentity(metamaskExtensionPath);
|
|
21
|
+
if (usesDefaultExtensionArtifact) {
|
|
22
|
+
assertManifestVersionMatchesConfiguredVersion(metamaskExtensionIdentity, metamaskExtensionVersion, metamaskExtensionPath);
|
|
23
|
+
}
|
|
24
|
+
const profileName = sanitizeProfileName(options.profileName ?? env.WALLET_PROFILE_NAME ?? DEFAULT_PROFILE_NAME);
|
|
25
|
+
const profileDir = resolve(cwd, options.profileDir ?? env.WALLET_PROFILE_DIR ?? `.wallet-profiles/${profileName}`);
|
|
26
|
+
assertSafeProfileDir(profileDir, cwd, metamaskExtensionPath);
|
|
27
|
+
mkdirSync(profileDir, { recursive: true });
|
|
28
|
+
assertDirectory(profileDir, 'Wallet browser profile directory');
|
|
29
|
+
return {
|
|
30
|
+
browserName: 'chromium',
|
|
31
|
+
metamaskExtensionPath,
|
|
32
|
+
metamaskExtensionVersion,
|
|
33
|
+
metamaskExtensionIdentity,
|
|
34
|
+
profileDir,
|
|
35
|
+
profileName,
|
|
36
|
+
preserveProfile: options.preserveProfile ?? parseBoolean(env.PRESERVE_WALLET_PROFILE)
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function defaultMetamaskExtensionPath(version) {
|
|
40
|
+
return join('.wallet-extensions', 'metamask', version, 'chrome');
|
|
41
|
+
}
|
|
42
|
+
function assertDirectory(path, label) {
|
|
43
|
+
if (!existsSync(path)) {
|
|
44
|
+
throw new Error(`${label} does not exist: ${path}. Set METAMASK_EXTENSION_PATH or METAMASK_EXTENSION_DIR to an unpacked MetaMask extension directory, or prepare the pinned default artifact under ${defaultMetamaskExtensionPath(PINNED_METAMASK_VERSION)}.`);
|
|
45
|
+
}
|
|
46
|
+
if (!statSync(path).isDirectory()) {
|
|
47
|
+
throw new Error(`${label} must be a directory: ${path}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function assertSafeProfileDir(profileDir, cwd, metamaskExtensionPath) {
|
|
51
|
+
const root = parse(profileDir).root;
|
|
52
|
+
if (profileDir === root || profileDir === resolve(cwd)) {
|
|
53
|
+
throw new Error('Wallet browser profile directory is unsafe; use an isolated directory under .wallet-profiles or an explicit wallet profile root.');
|
|
54
|
+
}
|
|
55
|
+
if (isSamePathOrChild(profileDir, metamaskExtensionPath) || isSamePathOrChild(metamaskExtensionPath, profileDir)) {
|
|
56
|
+
throw new Error('Wallet browser profile directory must not overlap the MetaMask extension path.');
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function isSamePathOrChild(candidatePath, parentPath) {
|
|
60
|
+
const relation = relative(parentPath, candidatePath);
|
|
61
|
+
return relation === '' || (!relation.startsWith('..') && !isAbsolute(relation) && !relation.startsWith(sep));
|
|
62
|
+
}
|
|
63
|
+
function assertManifestVersionMatchesConfiguredVersion(identity, configuredVersion, extensionPath) {
|
|
64
|
+
if (identity.version !== configuredVersion) {
|
|
65
|
+
throw new Error(`MetaMask extension manifest version must match configured version for default artifact ${extensionPath}: expected ${configuredVersion}, found ${identity.version ?? 'missing'}.`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function readMetaMaskManifestIdentity(extensionPath) {
|
|
69
|
+
const manifestPath = join(extensionPath, 'manifest.json');
|
|
70
|
+
if (!existsSync(manifestPath)) {
|
|
71
|
+
throw new Error(`MetaMask extension manifest is missing: ${manifestPath}`);
|
|
72
|
+
}
|
|
73
|
+
const manifest = readManifest(manifestPath);
|
|
74
|
+
if (manifest.manifest_version !== 3) {
|
|
75
|
+
throw new Error(`MetaMask extension manifest_version must be 3: ${manifestPath}`);
|
|
76
|
+
}
|
|
77
|
+
const rawName = typeof manifest.name === 'string' ? manifest.name : '';
|
|
78
|
+
const rawShortName = typeof manifest.short_name === 'string' ? manifest.short_name : '';
|
|
79
|
+
const localeMessages = readLocaleMessages(extensionPath, manifest);
|
|
80
|
+
const name = resolveManifestText(rawName, localeMessages).trim();
|
|
81
|
+
const shortName = resolveManifestText(rawShortName, localeMessages).trim();
|
|
82
|
+
if (!isMetaMaskManifestName(name) && !isMetaMaskManifestName(shortName)) {
|
|
83
|
+
throw new Error(`MetaMask extension manifest must identify MetaMask: ${manifestPath}`);
|
|
84
|
+
}
|
|
85
|
+
const identity = { name };
|
|
86
|
+
if (shortName !== '') {
|
|
87
|
+
identity.shortName = shortName;
|
|
88
|
+
}
|
|
89
|
+
if (typeof manifest.version === 'string' && manifest.version.trim() !== '') {
|
|
90
|
+
identity.version = manifest.version;
|
|
91
|
+
}
|
|
92
|
+
return identity;
|
|
93
|
+
}
|
|
94
|
+
function isMetaMaskManifestName(value) {
|
|
95
|
+
return value.trim().toLowerCase() === 'metamask';
|
|
96
|
+
}
|
|
97
|
+
function readLocaleMessages(extensionPath, manifest) {
|
|
98
|
+
const defaultLocale = typeof manifest.default_locale === 'string' ? manifest.default_locale.trim() : '';
|
|
99
|
+
if (defaultLocale === '') {
|
|
100
|
+
return {};
|
|
101
|
+
}
|
|
102
|
+
const messagesPath = join(extensionPath, '_locales', defaultLocale, 'messages.json');
|
|
103
|
+
if (!existsSync(messagesPath)) {
|
|
104
|
+
return {};
|
|
105
|
+
}
|
|
106
|
+
const messages = readManifest(messagesPath);
|
|
107
|
+
const resolved = {};
|
|
108
|
+
for (const [key, value] of Object.entries(messages)) {
|
|
109
|
+
if (value !== null && typeof value === 'object' && !Array.isArray(value)) {
|
|
110
|
+
const message = value.message;
|
|
111
|
+
if (typeof message === 'string') {
|
|
112
|
+
resolved[key] = message;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return resolved;
|
|
117
|
+
}
|
|
118
|
+
function resolveManifestText(value, localeMessages) {
|
|
119
|
+
return value.replace(/__MSG_([A-Za-z0-9_@]+)__/g, (match, key) => localeMessages[key] ?? match);
|
|
120
|
+
}
|
|
121
|
+
function readManifest(manifestPath) {
|
|
122
|
+
try {
|
|
123
|
+
const manifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
|
|
124
|
+
if (manifest === null || typeof manifest !== 'object' || Array.isArray(manifest)) {
|
|
125
|
+
throw new Error('manifest root is not an object');
|
|
126
|
+
}
|
|
127
|
+
return manifest;
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
throw new Error(`MetaMask extension manifest must be valid JSON: ${manifestPath}${error instanceof Error ? ` (${error.message})` : ''}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function parseBoolean(value) {
|
|
134
|
+
if (value === undefined || value.trim() === '') {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
return ['1', 'true', 'yes', 'on'].includes(value.trim().toLowerCase());
|
|
138
|
+
}
|
|
139
|
+
function sanitizeProfileName(value) {
|
|
140
|
+
const trimmed = value.trim();
|
|
141
|
+
if (trimmed === '') {
|
|
142
|
+
return DEFAULT_PROFILE_NAME;
|
|
143
|
+
}
|
|
144
|
+
if (!/^[a-zA-Z0-9._-]+$/.test(trimmed)) {
|
|
145
|
+
throw new Error('WALLET_PROFILE_NAME may only contain letters, numbers, dots, underscores, and hyphens.');
|
|
146
|
+
}
|
|
147
|
+
return trimmed;
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface ExtensionPageLike {
|
|
2
|
+
url(): string;
|
|
3
|
+
isClosed?(): boolean;
|
|
4
|
+
bringToFront?(): Promise<void>;
|
|
5
|
+
}
|
|
6
|
+
export interface ExtensionBrowserContextLike<Page extends ExtensionPageLike = ExtensionPageLike> {
|
|
7
|
+
pages(): readonly Page[];
|
|
8
|
+
waitForEvent?(eventName: 'page', options?: {
|
|
9
|
+
timeout?: number;
|
|
10
|
+
}): Promise<Page>;
|
|
11
|
+
newPage?(): Promise<Page>;
|
|
12
|
+
}
|
|
13
|
+
export interface DiscoverMetaMaskExtensionPageOptions {
|
|
14
|
+
extensionId?: string;
|
|
15
|
+
preferredPath?: MetaMaskExtensionPagePath;
|
|
16
|
+
}
|
|
17
|
+
export interface WaitForMetaMaskExtensionPageOptions extends DiscoverMetaMaskExtensionPageOptions {
|
|
18
|
+
timeoutMs?: number;
|
|
19
|
+
ensureKeeperPage?: boolean;
|
|
20
|
+
}
|
|
21
|
+
export type MetaMaskExtensionPagePath = '/home.html' | '/notification.html';
|
|
22
|
+
export declare function isMetaMaskExtensionPageUrl(url: string, options?: DiscoverMetaMaskExtensionPageOptions): boolean;
|
|
23
|
+
export declare function getMetaMaskExtensionPagePath(url: string, options?: Pick<DiscoverMetaMaskExtensionPageOptions, 'extensionId'>): MetaMaskExtensionPagePath | undefined;
|
|
24
|
+
export declare function discoverMetaMaskExtensionPage<Page extends ExtensionPageLike>(pages: readonly Page[], options?: DiscoverMetaMaskExtensionPageOptions): Page;
|
|
25
|
+
export declare function waitForMetaMaskExtensionPage<Page extends ExtensionPageLike>(context: ExtensionBrowserContextLike<Page>, options?: WaitForMetaMaskExtensionPageOptions): Promise<Page>;
|
|
26
|
+
//# sourceMappingURL=extension-pages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension-pages.d.ts","sourceRoot":"","sources":["../src/extension-pages.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,GAAG,IAAI,MAAM,CAAC;IACd,QAAQ,CAAC,IAAI,OAAO,CAAC;IACrB,YAAY,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,2BAA2B,CAAC,IAAI,SAAS,iBAAiB,GAAG,iBAAiB;IAC7F,KAAK,IAAI,SAAS,IAAI,EAAE,CAAC;IACzB,YAAY,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChF,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED,MAAM,WAAW,oCAAoC;IACnD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,yBAAyB,CAAC;CAC3C;AAED,MAAM,WAAW,mCAAoC,SAAQ,oCAAoC;IAC/F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,MAAM,yBAAyB,GAAG,YAAY,GAAG,oBAAoB,CAAC;AAK5E,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,oCAAyC,GAAG,OAAO,CAEnH;AAED,wBAAgB,4BAA4B,CAC1C,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,oCAAoC,EAAE,aAAa,CAAM,GACtE,yBAAyB,GAAG,SAAS,CAoBvC;AAED,wBAAgB,6BAA6B,CAAC,IAAI,SAAS,iBAAiB,EAC1E,KAAK,EAAE,SAAS,IAAI,EAAE,EACtB,OAAO,GAAE,oCAAyC,GACjD,IAAI,CAsBN;AAED,wBAAsB,4BAA4B,CAAC,IAAI,SAAS,iBAAiB,EAC/E,OAAO,EAAE,2BAA2B,CAAC,IAAI,CAAC,EAC1C,OAAO,GAAE,mCAAwC,GAChD,OAAO,CAAC,IAAI,CAAC,CAmCf"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
const METAMASK_PAGE_PATHS = new Set(['/home.html', '/notification.html']);
|
|
2
|
+
const DEFAULT_WAIT_TIMEOUT_MS = 5_000;
|
|
3
|
+
export function isMetaMaskExtensionPageUrl(url, options = {}) {
|
|
4
|
+
return getMetaMaskExtensionPagePath(url, options) !== undefined;
|
|
5
|
+
}
|
|
6
|
+
export function getMetaMaskExtensionPagePath(url, options = {}) {
|
|
7
|
+
let parsed;
|
|
8
|
+
try {
|
|
9
|
+
parsed = new URL(url);
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
if (parsed.protocol !== 'chrome-extension:') {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
const extensionId = options.extensionId?.trim();
|
|
18
|
+
if (extensionId && parsed.hostname !== extensionId) {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
return METAMASK_PAGE_PATHS.has(parsed.pathname)
|
|
22
|
+
? parsed.pathname
|
|
23
|
+
: undefined;
|
|
24
|
+
}
|
|
25
|
+
export function discoverMetaMaskExtensionPage(pages, options = {}) {
|
|
26
|
+
const candidates = collectMetaMaskExtensionPageCandidates(pages, options);
|
|
27
|
+
if (candidates.length === 0) {
|
|
28
|
+
throw new Error('No MetaMask extension page found. Expected one chrome-extension://<id>/home.html or notification.html page.');
|
|
29
|
+
}
|
|
30
|
+
if (options.preferredPath) {
|
|
31
|
+
const preferred = candidates.filter((candidate) => candidate.path === options.preferredPath);
|
|
32
|
+
if (preferred.length === 1) {
|
|
33
|
+
return preferred[0].page;
|
|
34
|
+
}
|
|
35
|
+
if (preferred.length > 1) {
|
|
36
|
+
throw new Error(`Multiple MetaMask extension page candidates found for preferred path ${options.preferredPath}; refusing to choose an ambiguous wallet UI page.`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (candidates.length > 1) {
|
|
40
|
+
throw new Error('Multiple MetaMask extension page candidates found; refusing to choose an ambiguous wallet UI page.');
|
|
41
|
+
}
|
|
42
|
+
return candidates[0].page;
|
|
43
|
+
}
|
|
44
|
+
export async function waitForMetaMaskExtensionPage(context, options = {}) {
|
|
45
|
+
const timeoutMs = validateTimeoutMs(options.timeoutMs ?? DEFAULT_WAIT_TIMEOUT_MS);
|
|
46
|
+
await ensureKeeperPageIfNeeded(context, options);
|
|
47
|
+
const immediate = tryDiscoverMetaMaskExtensionPage(context.pages(), options);
|
|
48
|
+
if (immediate) {
|
|
49
|
+
await immediate.bringToFront?.();
|
|
50
|
+
return immediate;
|
|
51
|
+
}
|
|
52
|
+
const deadline = Date.now() + timeoutMs;
|
|
53
|
+
let lastError = 'No MetaMask extension page found.';
|
|
54
|
+
while (Date.now() <= deadline) {
|
|
55
|
+
if (context.waitForEvent) {
|
|
56
|
+
const remaining = Math.max(1, deadline - Date.now());
|
|
57
|
+
try {
|
|
58
|
+
await context.waitForEvent('page', { timeout: remaining });
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
lastError = error instanceof Error ? error.message : String(error);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const discovered = tryDiscoverMetaMaskExtensionPage(context.pages(), options);
|
|
65
|
+
if (discovered) {
|
|
66
|
+
await discovered.bringToFront?.();
|
|
67
|
+
return discovered;
|
|
68
|
+
}
|
|
69
|
+
if (!context.waitForEvent) {
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
throw new Error(`Timed out waiting for MetaMask extension page after ${timeoutMs}ms: ${lastError}`);
|
|
74
|
+
}
|
|
75
|
+
function collectMetaMaskExtensionPageCandidates(pages, options) {
|
|
76
|
+
const candidates = [];
|
|
77
|
+
for (const page of pages) {
|
|
78
|
+
if (isClosed(page)) {
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
let url;
|
|
82
|
+
try {
|
|
83
|
+
url = page.url();
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
const path = getMetaMaskExtensionPagePath(url, options);
|
|
89
|
+
if (path) {
|
|
90
|
+
candidates.push({ page, path });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return candidates;
|
|
94
|
+
}
|
|
95
|
+
async function ensureKeeperPageIfNeeded(context, options) {
|
|
96
|
+
if (!options.ensureKeeperPage || !context.newPage) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const hasOpenNonExtensionPage = context.pages().some((page) => {
|
|
100
|
+
if (isClosed(page)) {
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
try {
|
|
104
|
+
return !page.url().startsWith('chrome-extension://');
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
if (!hasOpenNonExtensionPage) {
|
|
111
|
+
await context.newPage();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function tryDiscoverMetaMaskExtensionPage(pages, options) {
|
|
115
|
+
try {
|
|
116
|
+
return discoverMetaMaskExtensionPage(pages, options);
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
120
|
+
if (message.startsWith('No MetaMask extension page found')) {
|
|
121
|
+
return undefined;
|
|
122
|
+
}
|
|
123
|
+
throw error;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function isClosed(page) {
|
|
127
|
+
try {
|
|
128
|
+
return page.isClosed?.() ?? false;
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
function validateTimeoutMs(timeoutMs) {
|
|
135
|
+
if (!Number.isInteger(timeoutMs) || timeoutMs <= 0) {
|
|
136
|
+
throw new Error('MetaMask extension page wait timeout must be a positive integer number of milliseconds.');
|
|
137
|
+
}
|
|
138
|
+
return timeoutMs;
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=extension-pages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension-pages.js","sourceRoot":"","sources":["../src/extension-pages.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type FixtureConnectionProofEvidence, type FixtureConnectionProofVerificationResult } from './fixture-proof.js';
|
|
2
|
+
import { type WalletControlLogger, type WalletDappDriver, type WalletPromptDriver } from './wallet-control.js';
|
|
3
|
+
import type { MetaMaskNetworkDriver } from './network.js';
|
|
4
|
+
export interface FixtureConnectionScreenshotCaptureInput {
|
|
5
|
+
path: string;
|
|
6
|
+
evidence: FixtureConnectionProofEvidence;
|
|
7
|
+
}
|
|
8
|
+
export interface RunFixtureConnectionProofOptions {
|
|
9
|
+
artifactDir: string;
|
|
10
|
+
dapp: WalletDappDriver;
|
|
11
|
+
prompt: WalletPromptDriver;
|
|
12
|
+
network: MetaMaskNetworkDriver;
|
|
13
|
+
origin: string;
|
|
14
|
+
expectedAccount: string;
|
|
15
|
+
expectedChainId?: string | number;
|
|
16
|
+
allowedOrigins?: readonly string[];
|
|
17
|
+
captureScreenshot(input: FixtureConnectionScreenshotCaptureInput): Promise<void>;
|
|
18
|
+
logger?: WalletControlLogger;
|
|
19
|
+
notes?: readonly string[];
|
|
20
|
+
}
|
|
21
|
+
export declare function runFixtureConnectionProof(options: RunFixtureConnectionProofOptions): Promise<FixtureConnectionProofVerificationResult>;
|
|
22
|
+
//# sourceMappingURL=fixture-harness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fixture-harness.d.ts","sourceRoot":"","sources":["../src/fixture-harness.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,KAAK,8BAA8B,EAEnC,KAAK,wCAAwC,EAC9C,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EAErB,KAAK,kBAAkB,EACxB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAE1D,MAAM,WAAW,uCAAuC;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,8BAA8B,CAAC;CAC1C;AAED,MAAM,WAAW,gCAAgC;IAC/C,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,gBAAgB,CAAC;IACvB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,OAAO,EAAE,qBAAqB,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAClC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,iBAAiB,CAAC,KAAK,EAAE,uCAAuC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjF,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAC7B,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3B;AAWD,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,gCAAgC,GACxC,OAAO,CAAC,wCAAwC,CAAC,CA0CnD"}
|