w3wallets 0.10.2 → 1.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +51 -19
- package/dist/index.d.mts +125 -42
- package/dist/index.d.ts +125 -42
- package/dist/index.js +277 -241
- package/dist/index.mjs +266 -237
- package/package.json +2 -2
- package/src/scripts/download.js +366 -67
package/dist/index.js
CHANGED
|
@@ -30,6 +30,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
Backpack: () => Backpack,
|
|
34
|
+
Metamask: () => Metamask,
|
|
35
|
+
PolkadotJS: () => PolkadotJS,
|
|
36
|
+
backpack: () => backpack,
|
|
37
|
+
createWallet: () => createWallet,
|
|
38
|
+
metamask: () => metamask,
|
|
39
|
+
polkadotJS: () => polkadotJS,
|
|
33
40
|
withWallets: () => withWallets
|
|
34
41
|
});
|
|
35
42
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -37,17 +44,117 @@ module.exports = __toCommonJS(index_exports);
|
|
|
37
44
|
// src/withWallets.ts
|
|
38
45
|
var import_path = __toESM(require("path"));
|
|
39
46
|
var import_fs = __toESM(require("fs"));
|
|
47
|
+
var import_crypto = __toESM(require("crypto"));
|
|
48
|
+
var import_test = require("@playwright/test");
|
|
49
|
+
var W3WALLETS_DIR = ".w3wallets";
|
|
50
|
+
function sleep(ms) {
|
|
51
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
52
|
+
}
|
|
53
|
+
function withWallets(test, ...wallets) {
|
|
54
|
+
const extensionInfo = wallets.map((w) => {
|
|
55
|
+
const extPath = import_path.default.join(process.cwd(), W3WALLETS_DIR, w.extensionDir);
|
|
56
|
+
ensureWalletExtensionExists(extPath, w.name);
|
|
57
|
+
const extensionId = w.extensionId ?? getExtensionId(extPath);
|
|
58
|
+
return { path: extPath, id: extensionId, name: w.name };
|
|
59
|
+
});
|
|
60
|
+
const extensionPaths = extensionInfo.map((e) => e.path);
|
|
61
|
+
const fixtures = {
|
|
62
|
+
context: async ({}, use, testInfo) => {
|
|
63
|
+
const userDataDir = import_path.default.join(
|
|
64
|
+
process.cwd(),
|
|
65
|
+
W3WALLETS_DIR,
|
|
66
|
+
".context",
|
|
67
|
+
testInfo.testId
|
|
68
|
+
);
|
|
69
|
+
cleanUserDataDir(userDataDir);
|
|
70
|
+
const context = await import_test.chromium.launchPersistentContext(userDataDir, {
|
|
71
|
+
headless: testInfo.project.use.headless ?? true,
|
|
72
|
+
channel: "chromium",
|
|
73
|
+
args: [
|
|
74
|
+
`--disable-extensions-except=${extensionPaths.join(",")}`,
|
|
75
|
+
`--load-extension=${extensionPaths.join(",")}`
|
|
76
|
+
]
|
|
77
|
+
});
|
|
78
|
+
while (context.serviceWorkers().length < extensionPaths.length) {
|
|
79
|
+
await sleep(1e3);
|
|
80
|
+
}
|
|
81
|
+
await Promise.all(context.pages().map((page) => page.close()));
|
|
82
|
+
await use(context);
|
|
83
|
+
await context.close();
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
for (let i = 0; i < wallets.length; i++) {
|
|
87
|
+
const wallet = wallets[i];
|
|
88
|
+
const info = extensionInfo[i];
|
|
89
|
+
fixtures[wallet.name] = async ({ context }, use) => {
|
|
90
|
+
const instance = await initializeExtension(
|
|
91
|
+
context,
|
|
92
|
+
wallet.WalletClass,
|
|
93
|
+
info.id,
|
|
94
|
+
wallet.name
|
|
95
|
+
);
|
|
96
|
+
await use(instance);
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
return test.extend(fixtures);
|
|
100
|
+
}
|
|
101
|
+
function cleanUserDataDir(userDataDir) {
|
|
102
|
+
if (import_fs.default.existsSync(userDataDir)) {
|
|
103
|
+
import_fs.default.rmSync(userDataDir, { recursive: true });
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function ensureWalletExtensionExists(walletPath, walletName) {
|
|
107
|
+
if (!import_fs.default.existsSync(import_path.default.join(walletPath, "manifest.json"))) {
|
|
108
|
+
const cliAlias = walletName.toLowerCase();
|
|
109
|
+
throw new Error(
|
|
110
|
+
`Cannot find ${walletName}. Please download it via 'npx w3wallets ${cliAlias}'.`
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function getExtensionId(extensionPath) {
|
|
115
|
+
const absolutePath = import_path.default.resolve(extensionPath);
|
|
116
|
+
const manifestPath = import_path.default.join(absolutePath, "manifest.json");
|
|
117
|
+
const manifest = JSON.parse(import_fs.default.readFileSync(manifestPath, "utf-8"));
|
|
118
|
+
let dataToHash;
|
|
119
|
+
if (manifest.key) {
|
|
120
|
+
dataToHash = Buffer.from(manifest.key, "base64");
|
|
121
|
+
} else {
|
|
122
|
+
dataToHash = Buffer.from(absolutePath);
|
|
123
|
+
}
|
|
124
|
+
const hash = import_crypto.default.createHash("sha256").update(dataToHash).digest();
|
|
125
|
+
const ALPHABET = "abcdefghijklmnop";
|
|
126
|
+
let extensionId = "";
|
|
127
|
+
for (let i = 0; i < 16; i++) {
|
|
128
|
+
const byte = hash[i];
|
|
129
|
+
extensionId += ALPHABET[byte >> 4 & 15];
|
|
130
|
+
extensionId += ALPHABET[byte & 15];
|
|
131
|
+
}
|
|
132
|
+
return extensionId;
|
|
133
|
+
}
|
|
134
|
+
async function initializeExtension(context, ExtensionClass, expectedExtensionId, walletName) {
|
|
135
|
+
const expectedUrl = `chrome-extension://${expectedExtensionId}/`;
|
|
136
|
+
const worker = context.serviceWorkers().find((w) => w.url().startsWith(expectedUrl));
|
|
137
|
+
if (!worker) {
|
|
138
|
+
const availableIds = context.serviceWorkers().map((w) => w.url().split("/")[2]).filter(Boolean);
|
|
139
|
+
throw new Error(
|
|
140
|
+
`Service worker for ${walletName} (ID: ${expectedExtensionId}) not found. Available extension IDs: [${availableIds.join(", ")}]`
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
const page = await context.newPage();
|
|
144
|
+
const extension = new ExtensionClass(page, expectedExtensionId);
|
|
145
|
+
await extension.gotoOnboardPage();
|
|
146
|
+
return extension;
|
|
147
|
+
}
|
|
40
148
|
|
|
41
|
-
//
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
var import_test4 = require("@playwright/test");
|
|
149
|
+
// src/core/types.ts
|
|
150
|
+
function createWallet(config) {
|
|
151
|
+
return config;
|
|
152
|
+
}
|
|
46
153
|
|
|
47
|
-
// src/backpack/backpack.ts
|
|
48
|
-
var
|
|
154
|
+
// src/wallets/backpack/backpack.ts
|
|
155
|
+
var import_test2 = require("@playwright/test");
|
|
49
156
|
|
|
50
|
-
// src/wallet.ts
|
|
157
|
+
// src/core/wallet.ts
|
|
51
158
|
var Wallet = class {
|
|
52
159
|
constructor(page, extensionId) {
|
|
53
160
|
this.page = page;
|
|
@@ -55,7 +162,7 @@ var Wallet = class {
|
|
|
55
162
|
}
|
|
56
163
|
};
|
|
57
164
|
|
|
58
|
-
// src/backpack/backpack.ts
|
|
165
|
+
// src/wallets/backpack/backpack.ts
|
|
59
166
|
var Backpack = class extends Wallet {
|
|
60
167
|
defaultPassword = "11111111";
|
|
61
168
|
currentAccountId = 0;
|
|
@@ -64,7 +171,7 @@ var Backpack = class extends Wallet {
|
|
|
64
171
|
await this.page.goto(
|
|
65
172
|
`chrome-extension://${this.extensionId}/onboarding.html`
|
|
66
173
|
);
|
|
67
|
-
await (0,
|
|
174
|
+
await (0, import_test2.expect)(this.page.getByText("Welcome to Backpack")).toBeVisible();
|
|
68
175
|
}
|
|
69
176
|
async onboard(network, privateKey) {
|
|
70
177
|
this.currentAccountId++;
|
|
@@ -132,20 +239,153 @@ var Backpack = class extends Wallet {
|
|
|
132
239
|
await this.page.getByRole("textbox").nth(0).fill(this.defaultPassword);
|
|
133
240
|
await this.page.getByRole("textbox").nth(1).fill(this.defaultPassword);
|
|
134
241
|
await this.page.getByText("Next", { exact: true }).click();
|
|
135
|
-
await (0,
|
|
242
|
+
await (0, import_test2.expect)(this.page.getByText("You're all good!")).toBeVisible();
|
|
136
243
|
}
|
|
137
244
|
await this.page.goto(`chrome-extension://${this.extensionId}/popup.html`);
|
|
138
245
|
await this.page.getByTestId("__CAROUSEL_ITEM_0__").waitFor({ state: "visible" });
|
|
139
246
|
}
|
|
140
247
|
};
|
|
141
248
|
|
|
142
|
-
// src/
|
|
143
|
-
var
|
|
249
|
+
// src/wallets/metamask/metamask.ts
|
|
250
|
+
var import_test3 = require("@playwright/test");
|
|
251
|
+
var Metamask = class extends Wallet {
|
|
252
|
+
defaultPassword = "TestPassword123!";
|
|
253
|
+
async gotoOnboardPage() {
|
|
254
|
+
await this.page.goto(
|
|
255
|
+
`chrome-extension://${this.extensionId}/home.html#onboarding/welcome`
|
|
256
|
+
);
|
|
257
|
+
await (0, import_test3.expect)(
|
|
258
|
+
this.page.getByRole("button", { name: "I have an existing wallet" })
|
|
259
|
+
).toBeVisible();
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Onboard MetaMask with a mnemonic phrase
|
|
263
|
+
* @param mnemonic - 12 or 24 word recovery phrase
|
|
264
|
+
* @param password - Optional password (defaults to TestPassword123!)
|
|
265
|
+
*/
|
|
266
|
+
async onboard(mnemonic, password) {
|
|
267
|
+
const pwd = password ?? this.defaultPassword;
|
|
268
|
+
await this.page.getByRole("button", { name: "I have an existing wallet" }).click();
|
|
269
|
+
await this.page.getByRole("button", { name: "Import using Secret Recovery Phrase" }).click();
|
|
270
|
+
const textbox = this.page.getByRole("textbox");
|
|
271
|
+
await textbox.click();
|
|
272
|
+
await this.page.keyboard.type(mnemonic, { delay: 5 });
|
|
273
|
+
const continueBtn = this.page.getByTestId("import-srp-confirm");
|
|
274
|
+
await continueBtn.click();
|
|
275
|
+
const passwordInputs = this.page.locator('input[type="password"]');
|
|
276
|
+
await passwordInputs.nth(0).fill(pwd);
|
|
277
|
+
await passwordInputs.nth(1).fill(pwd);
|
|
278
|
+
await this.page.getByRole("checkbox").click();
|
|
279
|
+
await this.page.getByRole("button", { name: "Create password" }).click();
|
|
280
|
+
const metametricsBtn = this.page.getByTestId("metametrics-i-agree");
|
|
281
|
+
await metametricsBtn.waitFor({ state: "visible", timeout: 3e4 });
|
|
282
|
+
await metametricsBtn.click();
|
|
283
|
+
const openWalletBtn = this.page.getByRole("button", {
|
|
284
|
+
name: /open wallet/i
|
|
285
|
+
});
|
|
286
|
+
await openWalletBtn.waitFor({ state: "visible", timeout: 3e4 });
|
|
287
|
+
await openWalletBtn.click();
|
|
288
|
+
await this.page.goto(
|
|
289
|
+
`chrome-extension://${this.extensionId}/sidepanel.html`
|
|
290
|
+
);
|
|
291
|
+
await this.page.getByTestId("account-options-menu-button").waitFor({ state: "visible", timeout: 3e4 });
|
|
292
|
+
}
|
|
293
|
+
async approve() {
|
|
294
|
+
await this.page.getByTestId("confirm-btn").or(this.page.getByTestId("confirm-footer-button")).or(this.page.getByTestId("page-container-footer-next")).or(this.page.getByRole("button", { name: /confirm/i })).click();
|
|
295
|
+
await this.page.getByTestId("account-options-menu-button").waitFor({ state: "visible", timeout: 3e4 });
|
|
296
|
+
}
|
|
297
|
+
async deny() {
|
|
298
|
+
const cancelBtn = this.page.getByTestId("cancel-btn").or(this.page.getByTestId("confirm-footer-cancel-button")).or(this.page.getByTestId("page-container-footer-cancel")).or(this.page.getByRole("button", { name: /cancel|reject/i }));
|
|
299
|
+
await cancelBtn.first().click();
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Lock the MetaMask wallet
|
|
303
|
+
*/
|
|
304
|
+
async lock() {
|
|
305
|
+
await this.page.getByTestId("account-options-menu-button").click();
|
|
306
|
+
await this.page.locator("text=Lock MetaMask").click();
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Unlock MetaMask with password
|
|
310
|
+
*/
|
|
311
|
+
async unlock(password) {
|
|
312
|
+
const pwd = password ?? this.defaultPassword;
|
|
313
|
+
const passwordInput = this.page.getByTestId("unlock-password");
|
|
314
|
+
await passwordInput.fill(pwd);
|
|
315
|
+
await this.page.getByTestId("unlock-submit").click();
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Switch to an existing network in MetaMask
|
|
319
|
+
* @param networkName - Name of the network to switch to (e.g., "Ethereum Mainnet", "Sepolia")
|
|
320
|
+
*/
|
|
321
|
+
async switchNetwork(networkName, networkType = "Popular") {
|
|
322
|
+
await this.page.getByTestId("sort-by-networks").click();
|
|
323
|
+
if (networkType === "Custom") {
|
|
324
|
+
await this.page.getByRole("tab", { name: "Custom" }).click();
|
|
325
|
+
}
|
|
326
|
+
await this.page.getByText(networkName).click();
|
|
327
|
+
await (0, import_test3.expect)(this.page.getByTestId("sort-by-networks")).toHaveText(
|
|
328
|
+
networkName
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
async switchAccount(accountName) {
|
|
332
|
+
await this.page.getByTestId("account-menu-icon").click();
|
|
333
|
+
await this.page.getByText(accountName, { exact: true }).click();
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Add a custom network to MetaMask
|
|
337
|
+
*/
|
|
338
|
+
async addNetwork(network) {
|
|
339
|
+
await this.page.goto(
|
|
340
|
+
`chrome-extension://${this.extensionId}/home.html#settings/networks/add-network`
|
|
341
|
+
);
|
|
342
|
+
await this.page.getByTestId("network-form-network-name").fill(network.name);
|
|
343
|
+
await this.page.getByTestId("network-form-rpc-url").fill(network.rpc);
|
|
344
|
+
await this.page.getByTestId("network-form-chain-id").fill(network.chainId.toString());
|
|
345
|
+
await this.page.getByTestId("network-form-ticker-input").fill(network.currencySymbol);
|
|
346
|
+
await this.page.getByRole("button", { name: /save/i }).click();
|
|
347
|
+
}
|
|
348
|
+
async addCustomNetwork(settings) {
|
|
349
|
+
await this.page.getByTestId("account-options-menu-button").click();
|
|
350
|
+
await this.page.getByTestId("global-menu-networks").click();
|
|
351
|
+
await this.page.getByRole("button", { name: "Add a custom network" }).click();
|
|
352
|
+
await this.page.getByTestId("network-form-network-name").fill(settings.name);
|
|
353
|
+
await this.page.getByTestId("network-form-chain-id").fill(settings.chainId.toString());
|
|
354
|
+
await this.page.getByTestId("network-form-ticker-input").fill(settings.currencySymbol);
|
|
355
|
+
await this.page.getByTestId("test-add-rpc-drop-down").click();
|
|
356
|
+
await this.page.getByRole("button", { name: "Add RPC URL" }).click();
|
|
357
|
+
await this.page.getByTestId("rpc-url-input-test").fill(settings.rpc);
|
|
358
|
+
await this.page.getByRole("button", { name: "Add URL" }).click();
|
|
359
|
+
await this.page.getByRole("button", { name: "Save" }).click();
|
|
360
|
+
}
|
|
361
|
+
async enableTestNetworks() {
|
|
362
|
+
await this.page.getByTestId("account-options-menu-button").click();
|
|
363
|
+
await this.page.getByTestId("global-menu-networks").click();
|
|
364
|
+
await this.page.locator("text=Show test networks >> xpath=following-sibling::label").click();
|
|
365
|
+
await this.page.keyboard.press("Escape");
|
|
366
|
+
}
|
|
367
|
+
async importAccount(privateKey) {
|
|
368
|
+
await this.page.getByTestId("account-menu-icon").click();
|
|
369
|
+
await this.page.getByTestId("account-list-add-wallet-button").click();
|
|
370
|
+
await this.page.getByTestId("add-wallet-modal-import-account").click();
|
|
371
|
+
await this.page.locator("#private-key-box").fill(privateKey);
|
|
372
|
+
await this.page.getByTestId("import-account-confirm-button").click();
|
|
373
|
+
await this.page.getByRole("button", { name: "Back" }).click();
|
|
374
|
+
}
|
|
375
|
+
async accountNameIs(accountName) {
|
|
376
|
+
await (0, import_test3.expect)(this.page.getByTestId("account-menu-icon")).toContainText(
|
|
377
|
+
accountName
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
|
|
382
|
+
// src/wallets/polkadot-js/polkadot-js.ts
|
|
383
|
+
var import_test4 = require("@playwright/test");
|
|
144
384
|
var PolkadotJS = class extends Wallet {
|
|
145
385
|
defaultPassword = "11111111";
|
|
146
386
|
async gotoOnboardPage() {
|
|
147
387
|
await this.page.goto(`chrome-extension://${this.extensionId}/index.html`);
|
|
148
|
-
await (0,
|
|
388
|
+
await (0, import_test4.expect)(
|
|
149
389
|
this.page.getByText("Before we start, just a couple of notes")
|
|
150
390
|
).toBeVisible();
|
|
151
391
|
}
|
|
@@ -197,234 +437,30 @@ var PolkadotJS = class extends Wallet {
|
|
|
197
437
|
}
|
|
198
438
|
};
|
|
199
439
|
|
|
200
|
-
// src/
|
|
201
|
-
var
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
await this.page.getByTestId("create-password-new-input").fill(password);
|
|
217
|
-
await this.page.getByTestId("create-password-confirm-input").fill(password);
|
|
218
|
-
await this.page.getByTestId("create-password-terms").click();
|
|
219
|
-
await this.page.getByTestId("create-password-submit").click();
|
|
220
|
-
await this.page.getByTestId("metametrics-i-agree").click();
|
|
221
|
-
await this.page.getByTestId("onboarding-complete-done").click();
|
|
222
|
-
await this.clickTopRightCornerToCloseAllTheMarketingBullshit();
|
|
223
|
-
}
|
|
224
|
-
// async switchAccount(accountAddress: { address: string }): Promise<void>;
|
|
225
|
-
async switchAccount(accountNameOrAddress) {
|
|
226
|
-
await this.page.getByTestId("account-menu-icon").click();
|
|
227
|
-
await this.page.getByText(accountNameOrAddress.name, { exact: true }).click();
|
|
228
|
-
}
|
|
229
|
-
async importAccount(privateKey) {
|
|
230
|
-
await this.page.getByTestId("account-menu-icon").click();
|
|
231
|
-
await this.page.getByTestId("account-list-add-wallet-button").click();
|
|
232
|
-
await this.page.getByTestId("add-wallet-modal-import-account").click();
|
|
233
|
-
await this.page.locator("#private-key-box").fill(privateKey);
|
|
234
|
-
await this.page.getByTestId("import-account-confirm-button").click();
|
|
235
|
-
await this.page.getByRole("button", { name: "Back" }).click();
|
|
236
|
-
}
|
|
237
|
-
async addAccount(accountName) {
|
|
238
|
-
await this.page.getByTestId("account-menu-icon").click();
|
|
239
|
-
await this.page.getByTestId("multichain-account-menu-popover-action-button").click();
|
|
240
|
-
await this.page.getByTestId("multichain-account-menu-popover-add-account").click();
|
|
241
|
-
if (accountName) {
|
|
242
|
-
await this.page.locator("#account-name").fill(accountName);
|
|
243
|
-
}
|
|
244
|
-
await this.page.getByTestId("submit-add-account-with-name").click();
|
|
245
|
-
}
|
|
246
|
-
async getAccountName() {
|
|
247
|
-
const accountSelect = this.page.getByTestId("account-menu-icon");
|
|
248
|
-
await (0, import_test3.expect)(accountSelect).toBeVisible();
|
|
249
|
-
const text = await accountSelect.textContent();
|
|
250
|
-
if (!text) throw Error("Cannot get account name");
|
|
251
|
-
return text;
|
|
252
|
-
}
|
|
253
|
-
async connectToNetwork(networkName, networkType = "Popular") {
|
|
254
|
-
await this.page.getByTestId("sort-by-networks").click();
|
|
255
|
-
await this.page.getByRole("tab", { name: networkType, exact: true }).click();
|
|
256
|
-
const additionalNetwork = this.page.getByTestId("additional-network-item").getByText(networkName);
|
|
257
|
-
await this.page.getByText(networkName).click();
|
|
258
|
-
}
|
|
259
|
-
async addCustomNetwork(settings) {
|
|
260
|
-
await this.page.getByTestId("account-options-menu-button").click();
|
|
261
|
-
await this.page.getByTestId("global-menu-networks").click();
|
|
262
|
-
await this.page.getByRole("button", { name: "Add a custom network" }).click();
|
|
263
|
-
await this.page.getByTestId("network-form-network-name").fill(settings.name);
|
|
264
|
-
await this.page.getByTestId("network-form-chain-id").fill(settings.chainId.toString());
|
|
265
|
-
await this.page.getByTestId("network-form-ticker-input").fill(settings.currencySymbol);
|
|
266
|
-
await this.page.getByTestId("test-add-rpc-drop-down").click();
|
|
267
|
-
await this.page.getByRole("button", { name: "Add RPC URL" }).click();
|
|
268
|
-
await this.page.getByTestId("rpc-url-input-test").fill(settings.rpc);
|
|
269
|
-
await this.page.getByRole("button", { name: "Add URL" }).click();
|
|
270
|
-
await this.page.getByRole("button", { name: "Save" }).click();
|
|
271
|
-
}
|
|
272
|
-
async enableTestNetworks() {
|
|
273
|
-
await this.page.getByTestId("account-options-menu-button").click();
|
|
274
|
-
await this.page.getByTestId("global-menu-networks").click();
|
|
275
|
-
await this.page.locator("text=Show test networks >> xpath=following-sibling::label").click();
|
|
276
|
-
await this.page.keyboard.press("Escape");
|
|
277
|
-
}
|
|
278
|
-
async approve() {
|
|
279
|
-
const p = await this.page.context().newPage();
|
|
280
|
-
await p.goto(`chrome-extension://${this.extensionId}/notification.html`);
|
|
281
|
-
await p.locator(
|
|
282
|
-
'[data-testid="confirm-footer-button"], [data-testid="confirm-btn"], [data-testid="page-container-footer-next"], [data-testid="confirmation-submit-button"]'
|
|
283
|
-
).click();
|
|
284
|
-
await p.waitForSelector(".multichain-app-header", {
|
|
285
|
-
timeout: 1e4
|
|
286
|
-
});
|
|
287
|
-
await p.close();
|
|
288
|
-
}
|
|
289
|
-
async deny() {
|
|
290
|
-
return this.usingNotificationPage(
|
|
291
|
-
(p) => p.getByTestId("cancel-btn").click()
|
|
292
|
-
);
|
|
293
|
-
}
|
|
294
|
-
async usingNotificationPage(action) {
|
|
295
|
-
const p = await this.page.context().newPage();
|
|
296
|
-
await p.goto(`chrome-extension://${this.extensionId}/notification.html`);
|
|
297
|
-
await action(p);
|
|
298
|
-
await p.close();
|
|
299
|
-
}
|
|
300
|
-
async clickTopRightCornerToCloseAllTheMarketingBullshit() {
|
|
301
|
-
await this.page.waitForTimeout(500);
|
|
302
|
-
await this.page.keyboard.press("Escape");
|
|
303
|
-
await this.page.mouse.click(1e3, 10);
|
|
304
|
-
}
|
|
305
|
-
};
|
|
306
|
-
|
|
307
|
-
// src/withWallets.ts
|
|
308
|
-
var w3walletsDir = ".w3wallets";
|
|
309
|
-
function withWallets(test, ...config) {
|
|
310
|
-
const withBackpack = config.includes("backpack");
|
|
311
|
-
const withPolkadotJS = config.includes("polkadotJS");
|
|
312
|
-
const withMetamask = config.includes("metamask");
|
|
313
|
-
const backpackPath = import_path.default.join(process.cwd(), w3walletsDir, "backpack");
|
|
314
|
-
const polkadotJSPath = import_path.default.join(process.cwd(), w3walletsDir, "polkadotJS");
|
|
315
|
-
const metamaskPath = import_path.default.join(process.cwd(), w3walletsDir, "metamask");
|
|
316
|
-
return test.extend({
|
|
317
|
-
/**
|
|
318
|
-
* Sets up a persistent browser context with the requested extensions loaded.
|
|
319
|
-
*/
|
|
320
|
-
context: async ({}, use, testInfo) => {
|
|
321
|
-
const userDataDir = import_path.default.join(
|
|
322
|
-
process.cwd(),
|
|
323
|
-
".w3wallets",
|
|
324
|
-
".context",
|
|
325
|
-
testInfo.testId
|
|
326
|
-
);
|
|
327
|
-
cleanUserDataDir(userDataDir);
|
|
328
|
-
const extensionPaths = [];
|
|
329
|
-
if (withBackpack) {
|
|
330
|
-
ensureWalletExtensionExists(backpackPath, "backpack");
|
|
331
|
-
extensionPaths.push(backpackPath);
|
|
332
|
-
}
|
|
333
|
-
if (withPolkadotJS) {
|
|
334
|
-
ensureWalletExtensionExists(polkadotJSPath, "polkadotJS");
|
|
335
|
-
extensionPaths.push(polkadotJSPath);
|
|
336
|
-
}
|
|
337
|
-
if (withMetamask) {
|
|
338
|
-
ensureWalletExtensionExists(metamaskPath, "metamask");
|
|
339
|
-
extensionPaths.push(metamaskPath);
|
|
340
|
-
}
|
|
341
|
-
const context = await import_test4.chromium.launchPersistentContext(userDataDir, {
|
|
342
|
-
headless: testInfo.project.use.headless ?? true,
|
|
343
|
-
channel: "chromium",
|
|
344
|
-
args: [
|
|
345
|
-
`--disable-extensions-except=${extensionPaths.join(",")}`,
|
|
346
|
-
`--load-extension=${extensionPaths.join(",")}`
|
|
347
|
-
]
|
|
348
|
-
});
|
|
349
|
-
while (context.serviceWorkers().length < extensionPaths.length) {
|
|
350
|
-
await sleep(1e3);
|
|
351
|
-
}
|
|
352
|
-
await use(context);
|
|
353
|
-
await context.close();
|
|
354
|
-
},
|
|
355
|
-
backpack: async ({ context }, use) => {
|
|
356
|
-
if (!withBackpack) {
|
|
357
|
-
throw Error(
|
|
358
|
-
"The Backpack wallet hasn't been loaded. Add it to the withWallets function."
|
|
359
|
-
);
|
|
360
|
-
}
|
|
361
|
-
const backpack = await initializeExtension(
|
|
362
|
-
context,
|
|
363
|
-
Backpack,
|
|
364
|
-
"Backpack is not initialized"
|
|
365
|
-
);
|
|
366
|
-
await use(backpack);
|
|
367
|
-
},
|
|
368
|
-
polkadotJS: async ({ context }, use) => {
|
|
369
|
-
if (!withPolkadotJS) {
|
|
370
|
-
throw Error(
|
|
371
|
-
"The Polkadot{.js} wallet hasn't been loaded. Add it to the withWallets function."
|
|
372
|
-
);
|
|
373
|
-
}
|
|
374
|
-
const polkadotJS = await initializeExtension(
|
|
375
|
-
context,
|
|
376
|
-
PolkadotJS,
|
|
377
|
-
"Polkadot{.js} is not initialized"
|
|
378
|
-
);
|
|
379
|
-
await use(polkadotJS);
|
|
380
|
-
},
|
|
381
|
-
metamask: async ({ context }, use) => {
|
|
382
|
-
if (!withMetamask) {
|
|
383
|
-
throw Error(
|
|
384
|
-
"The Metamask wallet hasn't been loaded. Add it to the withWallets function."
|
|
385
|
-
);
|
|
386
|
-
}
|
|
387
|
-
const metamask = await initializeExtension(
|
|
388
|
-
context,
|
|
389
|
-
Metamask,
|
|
390
|
-
"Metamask is not initialized"
|
|
391
|
-
);
|
|
392
|
-
await use(metamask);
|
|
393
|
-
}
|
|
394
|
-
});
|
|
395
|
-
}
|
|
396
|
-
function cleanUserDataDir(userDataDir) {
|
|
397
|
-
if (import_fs.default.existsSync(userDataDir)) {
|
|
398
|
-
import_fs.default.rmSync(userDataDir, { recursive: true });
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
function ensureWalletExtensionExists(walletPath, walletName) {
|
|
402
|
-
if (!import_fs.default.existsSync(import_path.default.join(walletPath, "manifest.json"))) {
|
|
403
|
-
throw new Error(
|
|
404
|
-
`Cannot find ${walletName}. Please download it via 'npx w3wallets ${walletName}'.`
|
|
405
|
-
);
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
async function initializeExtension(context, ExtensionClass, notInitializedErrorMessage) {
|
|
409
|
-
const serviceWorkers = context.serviceWorkers();
|
|
410
|
-
let page = await context.newPage();
|
|
411
|
-
for (const worker of serviceWorkers) {
|
|
412
|
-
const extensionId = worker.url().split("/")[2];
|
|
413
|
-
if (!extensionId) {
|
|
414
|
-
continue;
|
|
415
|
-
}
|
|
416
|
-
const extension = new ExtensionClass(page, extensionId);
|
|
417
|
-
try {
|
|
418
|
-
await extension.gotoOnboardPage();
|
|
419
|
-
return extension;
|
|
420
|
-
} catch {
|
|
421
|
-
await page.close();
|
|
422
|
-
page = await context.newPage();
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
throw new Error(notInitializedErrorMessage);
|
|
426
|
-
}
|
|
440
|
+
// src/wallets/index.ts
|
|
441
|
+
var backpack = createWallet({
|
|
442
|
+
name: "backpack",
|
|
443
|
+
extensionDir: "backpack",
|
|
444
|
+
WalletClass: Backpack
|
|
445
|
+
});
|
|
446
|
+
var metamask = createWallet({
|
|
447
|
+
name: "metamask",
|
|
448
|
+
extensionDir: "metamask",
|
|
449
|
+
WalletClass: Metamask
|
|
450
|
+
});
|
|
451
|
+
var polkadotJS = createWallet({
|
|
452
|
+
name: "polkadotJS",
|
|
453
|
+
extensionDir: "polkadotjs",
|
|
454
|
+
WalletClass: PolkadotJS
|
|
455
|
+
});
|
|
427
456
|
// Annotate the CommonJS export names for ESM import in node:
|
|
428
457
|
0 && (module.exports = {
|
|
458
|
+
Backpack,
|
|
459
|
+
Metamask,
|
|
460
|
+
PolkadotJS,
|
|
461
|
+
backpack,
|
|
462
|
+
createWallet,
|
|
463
|
+
metamask,
|
|
464
|
+
polkadotJS,
|
|
429
465
|
withWallets
|
|
430
466
|
});
|