w3wallets 1.0.0-beta.1 → 1.0.0-beta.3
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 +26 -10
- package/dist/index.d.mts +17 -29
- package/dist/index.d.ts +17 -29
- package/dist/index.js +35 -112
- package/dist/index.mjs +34 -110
- package/package.json +5 -8
- package/src/scripts/download.js +5 -11
package/README.md
CHANGED
|
@@ -15,24 +15,23 @@ npm install -D w3wallets
|
|
|
15
15
|
|
|
16
16
|
## Getting Started
|
|
17
17
|
|
|
18
|
-
`MetaMask
|
|
18
|
+
`MetaMask` and `Polkadot{.js}` wallets are currently supported.
|
|
19
19
|
|
|
20
20
|
<p align="center">
|
|
21
21
|
<img src="https://images.ctfassets.net/clixtyxoaeas/1ezuBGezqfIeifWdVtwU4c/d970d4cdf13b163efddddd5709164d2e/MetaMask-icon-Fox.svg" alt="Metamask Logo" width="60"/>
|
|
22
|
-
<img src="https://raw.githubusercontent.com/coral-xyz/backpack/refs/heads/master/assets/backpack.png" alt="Backpack Logo" width="60"/>
|
|
23
22
|
<img src="https://polkadot.js.org/logo.svg" alt="Polkadot JS Logo" width="60"/>
|
|
24
23
|
</p>
|
|
25
24
|
|
|
26
25
|
#### 1. Download wallets
|
|
27
26
|
|
|
28
27
|
```sh
|
|
29
|
-
npx w3wallets metamask
|
|
28
|
+
npx w3wallets metamask polkadotjs
|
|
30
29
|
```
|
|
31
30
|
|
|
32
31
|
Short aliases are also supported:
|
|
33
32
|
|
|
34
33
|
```sh
|
|
35
|
-
npx w3wallets mm
|
|
34
|
+
npx w3wallets mm pjs
|
|
36
35
|
```
|
|
37
36
|
|
|
38
37
|
The unzipped files are stored in the `.w3wallets/<wallet-name>` directory. Add `.w3wallets` to `.gitignore`.
|
|
@@ -45,8 +44,8 @@ USAGE:
|
|
|
45
44
|
npx w3wallets [OPTIONS] <targets...>
|
|
46
45
|
|
|
47
46
|
TARGETS:
|
|
48
|
-
Alias name Known wallet alias (metamask,
|
|
49
|
-
Short alias Short form (mm,
|
|
47
|
+
Alias name Known wallet alias (metamask, polkadotjs)
|
|
48
|
+
Short alias Short form (mm, pjs)
|
|
50
49
|
Extension ID 32-character Chrome extension ID
|
|
51
50
|
URL Chrome Web Store URL
|
|
52
51
|
|
|
@@ -59,7 +58,7 @@ OPTIONS:
|
|
|
59
58
|
|
|
60
59
|
EXAMPLES:
|
|
61
60
|
npx w3wallets metamask # Download MetaMask
|
|
62
|
-
npx w3wallets mm
|
|
61
|
+
npx w3wallets mm pjs # Download all wallets (short)
|
|
63
62
|
npx w3wallets --list # List available aliases
|
|
64
63
|
npx w3wallets -o ./extensions metamask # Custom output directory
|
|
65
64
|
npx w3wallets --force mm # Force re-download
|
|
@@ -73,10 +72,10 @@ Install the required wallets into Chromium using `withWallets`.
|
|
|
73
72
|
|
|
74
73
|
```ts
|
|
75
74
|
// your-fixture.ts
|
|
76
|
-
import { withWallets, metamask,
|
|
75
|
+
import { withWallets, metamask, polkadotJS } from "w3wallets";
|
|
77
76
|
import { test as base } from "@playwright/test";
|
|
78
77
|
|
|
79
|
-
export const test = withWallets(base, metamask,
|
|
78
|
+
export const test = withWallets(base, metamask, polkadotJS);
|
|
80
79
|
|
|
81
80
|
export { expect } from "@playwright/test";
|
|
82
81
|
```
|
|
@@ -94,7 +93,7 @@ import { test, expect } from "./your-fixture";
|
|
|
94
93
|
|
|
95
94
|
test("Can connect MetaMask to dApp", async ({ page, metamask }) => {
|
|
96
95
|
const mnemonic =
|
|
97
|
-
"
|
|
96
|
+
"set your seed phrase test test test test test test test junk";
|
|
98
97
|
|
|
99
98
|
await metamask.onboard(mnemonic);
|
|
100
99
|
await page.goto("https://your-dapp.com");
|
|
@@ -105,3 +104,20 @@ test("Can connect MetaMask to dApp", async ({ page, metamask }) => {
|
|
|
105
104
|
await expect(page.getByText("Connected")).toBeVisible();
|
|
106
105
|
});
|
|
107
106
|
```
|
|
107
|
+
|
|
108
|
+
## Configuration
|
|
109
|
+
|
|
110
|
+
Configure library behavior via environment variables:
|
|
111
|
+
|
|
112
|
+
| Variable | Description | Default |
|
|
113
|
+
| -------------------------- | ------------------------------------------------------------------------- | ----------- |
|
|
114
|
+
| `W3WALLETS_ACTION_TIMEOUT` | Timeout (ms) for all wallet actions (click, fill, navigation, assertions) | `undefined` |
|
|
115
|
+
|
|
116
|
+
Example:
|
|
117
|
+
|
|
118
|
+
```sh
|
|
119
|
+
# In .env or CI environment
|
|
120
|
+
W3WALLETS_ACTION_TIMEOUT=60000
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
This only affects w3wallets library code. Your own Playwright configuration remains independent.
|
package/dist/index.d.mts
CHANGED
|
@@ -62,11 +62,11 @@ type Network = "Solana" | "Eclipse" | "Ethereum" | "Polygon" | "Base" | "Arbitru
|
|
|
62
62
|
*
|
|
63
63
|
* @example
|
|
64
64
|
* ```ts
|
|
65
|
-
* import { withWallets, metamask,
|
|
65
|
+
* import { withWallets, metamask, polkadotJS } from "w3wallets";
|
|
66
66
|
*
|
|
67
|
-
* const test = withWallets(base, metamask,
|
|
67
|
+
* const test = withWallets(base, metamask, polkadotJS);
|
|
68
68
|
*
|
|
69
|
-
* test("can connect", async ({ metamask,
|
|
69
|
+
* test("can connect", async ({ metamask, polkadotJS }) => {
|
|
70
70
|
* await metamask.onboard(mnemonic);
|
|
71
71
|
* });
|
|
72
72
|
* ```
|
|
@@ -84,27 +84,6 @@ declare abstract class Wallet implements IWallet {
|
|
|
84
84
|
abstract deny(): Promise<void>;
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
declare class Backpack extends Wallet {
|
|
88
|
-
private defaultPassword;
|
|
89
|
-
private currentAccountId;
|
|
90
|
-
private maxAccountId;
|
|
91
|
-
gotoOnboardPage(): Promise<void>;
|
|
92
|
-
onboard(network: Network, privateKey: string): Promise<void>;
|
|
93
|
-
addAccount(network: Network, privateKey: string): Promise<void>;
|
|
94
|
-
/**
|
|
95
|
-
* Switch account
|
|
96
|
-
* @param id The first added account has id 1, the second – 2, and so on
|
|
97
|
-
*/
|
|
98
|
-
switchAccount(id: number): Promise<void>;
|
|
99
|
-
unlock(): Promise<void>;
|
|
100
|
-
setRPC(network: Network, rpc: string): Promise<void>;
|
|
101
|
-
ignoreAndProceed(): Promise<void>;
|
|
102
|
-
approve(): Promise<void>;
|
|
103
|
-
deny(): Promise<void>;
|
|
104
|
-
private _clickOnAccount;
|
|
105
|
-
private _importAccount;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
87
|
type NetworkSettings = {
|
|
109
88
|
name: string;
|
|
110
89
|
rpc: string;
|
|
@@ -159,10 +138,6 @@ declare class PolkadotJS extends Wallet {
|
|
|
159
138
|
private _getLabeledInput;
|
|
160
139
|
}
|
|
161
140
|
|
|
162
|
-
/**
|
|
163
|
-
* Pre-built Backpack wallet configuration.
|
|
164
|
-
*/
|
|
165
|
-
declare const backpack: WalletConfig<"backpack", Backpack>;
|
|
166
141
|
/**
|
|
167
142
|
* Pre-built MetaMask wallet configuration.
|
|
168
143
|
*/
|
|
@@ -172,4 +147,17 @@ declare const metamask: WalletConfig<"metamask", Metamask>;
|
|
|
172
147
|
*/
|
|
173
148
|
declare const polkadotJS: WalletConfig<"polkadotJS", PolkadotJS>;
|
|
174
149
|
|
|
175
|
-
|
|
150
|
+
/**
|
|
151
|
+
* Configuration for w3wallets library.
|
|
152
|
+
* Values can be overridden via environment variables.
|
|
153
|
+
*/
|
|
154
|
+
declare const config: {
|
|
155
|
+
/**
|
|
156
|
+
* Timeout for actions like click, fill, waitFor, goto.
|
|
157
|
+
* Set via W3WALLETS_ACTION_TIMEOUT env variable.
|
|
158
|
+
* @default 30000 (30 seconds)
|
|
159
|
+
*/
|
|
160
|
+
readonly actionTimeout: number | undefined;
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
export { type IWallet, Metamask, type Network, type NetworkSettings, PolkadotJS, type WalletConfig, config, createWallet, metamask, polkadotJS, withWallets };
|
package/dist/index.d.ts
CHANGED
|
@@ -62,11 +62,11 @@ type Network = "Solana" | "Eclipse" | "Ethereum" | "Polygon" | "Base" | "Arbitru
|
|
|
62
62
|
*
|
|
63
63
|
* @example
|
|
64
64
|
* ```ts
|
|
65
|
-
* import { withWallets, metamask,
|
|
65
|
+
* import { withWallets, metamask, polkadotJS } from "w3wallets";
|
|
66
66
|
*
|
|
67
|
-
* const test = withWallets(base, metamask,
|
|
67
|
+
* const test = withWallets(base, metamask, polkadotJS);
|
|
68
68
|
*
|
|
69
|
-
* test("can connect", async ({ metamask,
|
|
69
|
+
* test("can connect", async ({ metamask, polkadotJS }) => {
|
|
70
70
|
* await metamask.onboard(mnemonic);
|
|
71
71
|
* });
|
|
72
72
|
* ```
|
|
@@ -84,27 +84,6 @@ declare abstract class Wallet implements IWallet {
|
|
|
84
84
|
abstract deny(): Promise<void>;
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
declare class Backpack extends Wallet {
|
|
88
|
-
private defaultPassword;
|
|
89
|
-
private currentAccountId;
|
|
90
|
-
private maxAccountId;
|
|
91
|
-
gotoOnboardPage(): Promise<void>;
|
|
92
|
-
onboard(network: Network, privateKey: string): Promise<void>;
|
|
93
|
-
addAccount(network: Network, privateKey: string): Promise<void>;
|
|
94
|
-
/**
|
|
95
|
-
* Switch account
|
|
96
|
-
* @param id The first added account has id 1, the second – 2, and so on
|
|
97
|
-
*/
|
|
98
|
-
switchAccount(id: number): Promise<void>;
|
|
99
|
-
unlock(): Promise<void>;
|
|
100
|
-
setRPC(network: Network, rpc: string): Promise<void>;
|
|
101
|
-
ignoreAndProceed(): Promise<void>;
|
|
102
|
-
approve(): Promise<void>;
|
|
103
|
-
deny(): Promise<void>;
|
|
104
|
-
private _clickOnAccount;
|
|
105
|
-
private _importAccount;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
87
|
type NetworkSettings = {
|
|
109
88
|
name: string;
|
|
110
89
|
rpc: string;
|
|
@@ -159,10 +138,6 @@ declare class PolkadotJS extends Wallet {
|
|
|
159
138
|
private _getLabeledInput;
|
|
160
139
|
}
|
|
161
140
|
|
|
162
|
-
/**
|
|
163
|
-
* Pre-built Backpack wallet configuration.
|
|
164
|
-
*/
|
|
165
|
-
declare const backpack: WalletConfig<"backpack", Backpack>;
|
|
166
141
|
/**
|
|
167
142
|
* Pre-built MetaMask wallet configuration.
|
|
168
143
|
*/
|
|
@@ -172,4 +147,17 @@ declare const metamask: WalletConfig<"metamask", Metamask>;
|
|
|
172
147
|
*/
|
|
173
148
|
declare const polkadotJS: WalletConfig<"polkadotJS", PolkadotJS>;
|
|
174
149
|
|
|
175
|
-
|
|
150
|
+
/**
|
|
151
|
+
* Configuration for w3wallets library.
|
|
152
|
+
* Values can be overridden via environment variables.
|
|
153
|
+
*/
|
|
154
|
+
declare const config: {
|
|
155
|
+
/**
|
|
156
|
+
* Timeout for actions like click, fill, waitFor, goto.
|
|
157
|
+
* Set via W3WALLETS_ACTION_TIMEOUT env variable.
|
|
158
|
+
* @default 30000 (30 seconds)
|
|
159
|
+
*/
|
|
160
|
+
readonly actionTimeout: number | undefined;
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
export { type IWallet, Metamask, type Network, type NetworkSettings, PolkadotJS, type WalletConfig, config, createWallet, metamask, polkadotJS, withWallets };
|
package/dist/index.js
CHANGED
|
@@ -30,10 +30,9 @@ 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
33
|
Metamask: () => Metamask,
|
|
35
34
|
PolkadotJS: () => PolkadotJS,
|
|
36
|
-
|
|
35
|
+
config: () => config,
|
|
37
36
|
createWallet: () => createWallet,
|
|
38
37
|
metamask: () => metamask,
|
|
39
38
|
polkadotJS: () => polkadotJS,
|
|
@@ -78,7 +77,6 @@ function withWallets(test, ...wallets) {
|
|
|
78
77
|
while (context.serviceWorkers().length < extensionPaths.length) {
|
|
79
78
|
await sleep(1e3);
|
|
80
79
|
}
|
|
81
|
-
await Promise.all(context.pages().map((page) => page.close()));
|
|
82
80
|
await use(context);
|
|
83
81
|
await context.close();
|
|
84
82
|
}
|
|
@@ -142,119 +140,47 @@ async function initializeExtension(context, ExtensionClass, expectedExtensionId,
|
|
|
142
140
|
}
|
|
143
141
|
const page = await context.newPage();
|
|
144
142
|
const extension = new ExtensionClass(page, expectedExtensionId);
|
|
145
|
-
await extension.gotoOnboardPage();
|
|
146
143
|
return extension;
|
|
147
144
|
}
|
|
148
145
|
|
|
149
146
|
// src/core/types.ts
|
|
150
|
-
function createWallet(
|
|
151
|
-
return
|
|
147
|
+
function createWallet(config2) {
|
|
148
|
+
return config2;
|
|
152
149
|
}
|
|
153
150
|
|
|
154
|
-
// src/wallets/
|
|
151
|
+
// src/wallets/metamask/metamask.ts
|
|
155
152
|
var import_test2 = require("@playwright/test");
|
|
156
153
|
|
|
154
|
+
// src/config.ts
|
|
155
|
+
var config = {
|
|
156
|
+
/**
|
|
157
|
+
* Timeout for actions like click, fill, waitFor, goto.
|
|
158
|
+
* Set via W3WALLETS_ACTION_TIMEOUT env variable.
|
|
159
|
+
* @default 30000 (30 seconds)
|
|
160
|
+
*/
|
|
161
|
+
get actionTimeout() {
|
|
162
|
+
const value = process.env.W3WALLETS_ACTION_TIMEOUT;
|
|
163
|
+
return value ? parseInt(value, 10) : void 0;
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
|
|
157
167
|
// src/core/wallet.ts
|
|
158
168
|
var Wallet = class {
|
|
159
169
|
constructor(page, extensionId) {
|
|
160
170
|
this.page = page;
|
|
161
171
|
this.extensionId = extensionId;
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
// src/wallets/backpack/backpack.ts
|
|
166
|
-
var Backpack = class extends Wallet {
|
|
167
|
-
defaultPassword = "11111111";
|
|
168
|
-
currentAccountId = 0;
|
|
169
|
-
maxAccountId = 0;
|
|
170
|
-
async gotoOnboardPage() {
|
|
171
|
-
await this.page.goto(
|
|
172
|
-
`chrome-extension://${this.extensionId}/onboarding.html`
|
|
173
|
-
);
|
|
174
|
-
await (0, import_test2.expect)(this.page.getByText("Welcome to Backpack")).toBeVisible();
|
|
175
|
-
}
|
|
176
|
-
async onboard(network, privateKey) {
|
|
177
|
-
this.currentAccountId++;
|
|
178
|
-
this.maxAccountId++;
|
|
179
|
-
return this._importAccount(network, privateKey, true);
|
|
180
|
-
}
|
|
181
|
-
async addAccount(network, privateKey) {
|
|
182
|
-
this.maxAccountId++;
|
|
183
|
-
this.currentAccountId = this.maxAccountId;
|
|
184
|
-
await this.page.goto(
|
|
185
|
-
`chrome-extension://${this.extensionId}/onboarding.html?add-user-account=true`
|
|
186
|
-
);
|
|
187
|
-
await this._importAccount(network, privateKey, false);
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* Switch account
|
|
191
|
-
* @param id The first added account has id 1, the second – 2, and so on
|
|
192
|
-
*/
|
|
193
|
-
async switchAccount(id) {
|
|
194
|
-
await this.page.getByRole("button", { name: `A${this.currentAccountId}` }).click();
|
|
195
|
-
await this.page.getByRole("button", { name: `Account ${id}` }).click();
|
|
196
|
-
this.currentAccountId = id;
|
|
197
|
-
}
|
|
198
|
-
async unlock() {
|
|
199
|
-
await this.page.getByPlaceholder("Password").fill(this.defaultPassword);
|
|
200
|
-
await this.page.getByRole("button", { name: "Unlock" }).click();
|
|
201
|
-
}
|
|
202
|
-
async setRPC(network, rpc) {
|
|
203
|
-
await this._clickOnAccount();
|
|
204
|
-
await this.page.getByRole("button", { name: "Settings" }).click();
|
|
205
|
-
await this.page.getByRole("button", { name: network }).click();
|
|
206
|
-
await this.page.getByRole("button", { name: "RPC Connection" }).click();
|
|
207
|
-
await this.page.getByRole("button", { name: "Custom" }).click();
|
|
208
|
-
await this.page.getByPlaceholder("RPC URL").fill(rpc);
|
|
209
|
-
await this.page.keyboard.press("Enter");
|
|
210
|
-
}
|
|
211
|
-
async ignoreAndProceed() {
|
|
212
|
-
const ignoreButton = this.page.getByText("Ignore and proceed anyway.");
|
|
213
|
-
await ignoreButton.click();
|
|
214
|
-
}
|
|
215
|
-
async approve() {
|
|
216
|
-
await this.page.getByText("Approve", { exact: true }).click();
|
|
217
|
-
}
|
|
218
|
-
async deny() {
|
|
219
|
-
await this.page.getByText("Deny", { exact: true }).click();
|
|
220
|
-
}
|
|
221
|
-
async _clickOnAccount() {
|
|
222
|
-
return this.page.getByRole("button", { name: `A${this.currentAccountId}`, exact: true }).click();
|
|
223
|
-
}
|
|
224
|
-
async _importAccount(network, privateKey, isOnboard) {
|
|
225
|
-
{
|
|
226
|
-
await this.page.waitForTimeout(2e3);
|
|
227
|
-
if (await this.page.getByText("You're all good!").isVisible()) {
|
|
228
|
-
await this.page.getByLabel("Go back").click();
|
|
229
|
-
}
|
|
172
|
+
if (config.actionTimeout) {
|
|
173
|
+
page.setDefaultTimeout(config.actionTimeout);
|
|
230
174
|
}
|
|
231
|
-
await this.page.getByTestId("terms-of-service-checkbox").click();
|
|
232
|
-
await this.page.getByText("I already have a wallet").click();
|
|
233
|
-
await this.page.getByText(network).click();
|
|
234
|
-
await this.page.getByText("Private key").click();
|
|
235
|
-
await this.page.getByPlaceholder("Private key").fill(privateKey);
|
|
236
|
-
await this.page.waitForTimeout(1e3);
|
|
237
|
-
await this.page.getByText("Import", { exact: true }).click();
|
|
238
|
-
if (isOnboard) {
|
|
239
|
-
await this.page.getByRole("textbox").nth(0).fill(this.defaultPassword);
|
|
240
|
-
await this.page.getByRole("textbox").nth(1).fill(this.defaultPassword);
|
|
241
|
-
await this.page.getByText("Next", { exact: true }).click();
|
|
242
|
-
await (0, import_test2.expect)(this.page.getByText("You're all good!")).toBeVisible();
|
|
243
|
-
}
|
|
244
|
-
await this.page.goto(`chrome-extension://${this.extensionId}/popup.html`);
|
|
245
|
-
await this.page.getByTestId("__CAROUSEL_ITEM_0__").waitFor({ state: "visible" });
|
|
246
175
|
}
|
|
247
176
|
};
|
|
248
177
|
|
|
249
178
|
// src/wallets/metamask/metamask.ts
|
|
250
|
-
var import_test3 = require("@playwright/test");
|
|
251
179
|
var Metamask = class extends Wallet {
|
|
252
180
|
defaultPassword = "TestPassword123!";
|
|
253
181
|
async gotoOnboardPage() {
|
|
254
|
-
await this.page.goto(
|
|
255
|
-
|
|
256
|
-
);
|
|
257
|
-
await (0, import_test3.expect)(
|
|
182
|
+
await this.page.goto(`chrome-extension://${this.extensionId}/home.html`);
|
|
183
|
+
await (0, import_test2.expect)(
|
|
258
184
|
this.page.getByRole("button", { name: "I have an existing wallet" })
|
|
259
185
|
).toBeVisible();
|
|
260
186
|
}
|
|
@@ -265,11 +191,16 @@ var Metamask = class extends Wallet {
|
|
|
265
191
|
*/
|
|
266
192
|
async onboard(mnemonic, password) {
|
|
267
193
|
const pwd = password ?? this.defaultPassword;
|
|
194
|
+
await this.gotoOnboardPage();
|
|
268
195
|
await this.page.getByRole("button", { name: "I have an existing wallet" }).click();
|
|
269
196
|
await this.page.getByRole("button", { name: "Import using Secret Recovery Phrase" }).click();
|
|
270
197
|
const textbox = this.page.getByRole("textbox");
|
|
271
198
|
await textbox.click();
|
|
272
|
-
|
|
199
|
+
for (const word of mnemonic.split(" ")) {
|
|
200
|
+
await this.page.keyboard.type(word);
|
|
201
|
+
await this.page.keyboard.type(" ");
|
|
202
|
+
await this.page.waitForTimeout(30);
|
|
203
|
+
}
|
|
273
204
|
const continueBtn = this.page.getByTestId("import-srp-confirm");
|
|
274
205
|
await continueBtn.click();
|
|
275
206
|
const passwordInputs = this.page.locator('input[type="password"]');
|
|
@@ -278,21 +209,17 @@ var Metamask = class extends Wallet {
|
|
|
278
209
|
await this.page.getByRole("checkbox").click();
|
|
279
210
|
await this.page.getByRole("button", { name: "Create password" }).click();
|
|
280
211
|
const metametricsBtn = this.page.getByTestId("metametrics-i-agree");
|
|
281
|
-
await metametricsBtn.waitFor({ state: "visible", timeout: 3e4 });
|
|
282
212
|
await metametricsBtn.click();
|
|
283
213
|
const openWalletBtn = this.page.getByRole("button", {
|
|
284
214
|
name: /open wallet/i
|
|
285
215
|
});
|
|
286
|
-
await openWalletBtn.waitFor({ state: "visible", timeout: 3e4 });
|
|
287
216
|
await openWalletBtn.click();
|
|
288
217
|
await this.page.goto(
|
|
289
218
|
`chrome-extension://${this.extensionId}/sidepanel.html`
|
|
290
219
|
);
|
|
291
|
-
await this.page.getByTestId("account-options-menu-button").waitFor({ state: "visible", timeout: 3e4 });
|
|
292
220
|
}
|
|
293
221
|
async approve() {
|
|
294
222
|
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
223
|
}
|
|
297
224
|
async deny() {
|
|
298
225
|
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 }));
|
|
@@ -324,7 +251,7 @@ var Metamask = class extends Wallet {
|
|
|
324
251
|
await this.page.getByRole("tab", { name: "Custom" }).click();
|
|
325
252
|
}
|
|
326
253
|
await this.page.getByText(networkName).click();
|
|
327
|
-
await (0,
|
|
254
|
+
await (0, import_test2.expect)(this.page.getByTestId("sort-by-networks")).toHaveText(
|
|
328
255
|
networkName
|
|
329
256
|
);
|
|
330
257
|
}
|
|
@@ -373,23 +300,24 @@ var Metamask = class extends Wallet {
|
|
|
373
300
|
await this.page.getByRole("button", { name: "Back" }).click();
|
|
374
301
|
}
|
|
375
302
|
async accountNameIs(accountName) {
|
|
376
|
-
await (0,
|
|
303
|
+
await (0, import_test2.expect)(this.page.getByTestId("account-menu-icon")).toContainText(
|
|
377
304
|
accountName
|
|
378
305
|
);
|
|
379
306
|
}
|
|
380
307
|
};
|
|
381
308
|
|
|
382
309
|
// src/wallets/polkadot-js/polkadot-js.ts
|
|
383
|
-
var
|
|
310
|
+
var import_test3 = require("@playwright/test");
|
|
384
311
|
var PolkadotJS = class extends Wallet {
|
|
385
312
|
defaultPassword = "11111111";
|
|
386
313
|
async gotoOnboardPage() {
|
|
387
314
|
await this.page.goto(`chrome-extension://${this.extensionId}/index.html`);
|
|
388
|
-
await (0,
|
|
315
|
+
await (0, import_test3.expect)(
|
|
389
316
|
this.page.getByText("Before we start, just a couple of notes")
|
|
390
317
|
).toBeVisible();
|
|
391
318
|
}
|
|
392
319
|
async onboard(seed, password, name) {
|
|
320
|
+
await this.gotoOnboardPage();
|
|
393
321
|
await this.page.getByRole("button", { name: "Understood, let me continue" }).click();
|
|
394
322
|
await this.page.getByRole("button", { name: "I Understand" }).click();
|
|
395
323
|
await this.page.locator(".popupToggle").first().click();
|
|
@@ -411,7 +339,8 @@ var PolkadotJS = class extends Wallet {
|
|
|
411
339
|
await this.page.getByText("Select all").click();
|
|
412
340
|
}
|
|
413
341
|
async selectAccount(accountId) {
|
|
414
|
-
|
|
342
|
+
const cb = this.page.locator(".accountWichCheckbox").filter({ hasText: accountId }).locator(".accountTree-checkbox").locator("span");
|
|
343
|
+
await cb.check().catch(() => cb.check());
|
|
415
344
|
}
|
|
416
345
|
async enterPassword(password) {
|
|
417
346
|
await this._getLabeledInput("Password for this account").fill(
|
|
@@ -438,11 +367,6 @@ var PolkadotJS = class extends Wallet {
|
|
|
438
367
|
};
|
|
439
368
|
|
|
440
369
|
// src/wallets/index.ts
|
|
441
|
-
var backpack = createWallet({
|
|
442
|
-
name: "backpack",
|
|
443
|
-
extensionDir: "backpack",
|
|
444
|
-
WalletClass: Backpack
|
|
445
|
-
});
|
|
446
370
|
var metamask = createWallet({
|
|
447
371
|
name: "metamask",
|
|
448
372
|
extensionDir: "metamask",
|
|
@@ -455,10 +379,9 @@ var polkadotJS = createWallet({
|
|
|
455
379
|
});
|
|
456
380
|
// Annotate the CommonJS export names for ESM import in node:
|
|
457
381
|
0 && (module.exports = {
|
|
458
|
-
Backpack,
|
|
459
382
|
Metamask,
|
|
460
383
|
PolkadotJS,
|
|
461
|
-
|
|
384
|
+
config,
|
|
462
385
|
createWallet,
|
|
463
386
|
metamask,
|
|
464
387
|
polkadotJS,
|
package/dist/index.mjs
CHANGED
|
@@ -37,7 +37,6 @@ function withWallets(test, ...wallets) {
|
|
|
37
37
|
while (context.serviceWorkers().length < extensionPaths.length) {
|
|
38
38
|
await sleep(1e3);
|
|
39
39
|
}
|
|
40
|
-
await Promise.all(context.pages().map((page) => page.close()));
|
|
41
40
|
await use(context);
|
|
42
41
|
await context.close();
|
|
43
42
|
}
|
|
@@ -101,119 +100,47 @@ async function initializeExtension(context, ExtensionClass, expectedExtensionId,
|
|
|
101
100
|
}
|
|
102
101
|
const page = await context.newPage();
|
|
103
102
|
const extension = new ExtensionClass(page, expectedExtensionId);
|
|
104
|
-
await extension.gotoOnboardPage();
|
|
105
103
|
return extension;
|
|
106
104
|
}
|
|
107
105
|
|
|
108
106
|
// src/core/types.ts
|
|
109
|
-
function createWallet(
|
|
110
|
-
return
|
|
107
|
+
function createWallet(config2) {
|
|
108
|
+
return config2;
|
|
111
109
|
}
|
|
112
110
|
|
|
113
|
-
// src/wallets/
|
|
111
|
+
// src/wallets/metamask/metamask.ts
|
|
114
112
|
import { expect } from "@playwright/test";
|
|
115
113
|
|
|
114
|
+
// src/config.ts
|
|
115
|
+
var config = {
|
|
116
|
+
/**
|
|
117
|
+
* Timeout for actions like click, fill, waitFor, goto.
|
|
118
|
+
* Set via W3WALLETS_ACTION_TIMEOUT env variable.
|
|
119
|
+
* @default 30000 (30 seconds)
|
|
120
|
+
*/
|
|
121
|
+
get actionTimeout() {
|
|
122
|
+
const value = process.env.W3WALLETS_ACTION_TIMEOUT;
|
|
123
|
+
return value ? parseInt(value, 10) : void 0;
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
|
|
116
127
|
// src/core/wallet.ts
|
|
117
128
|
var Wallet = class {
|
|
118
129
|
constructor(page, extensionId) {
|
|
119
130
|
this.page = page;
|
|
120
131
|
this.extensionId = extensionId;
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
// src/wallets/backpack/backpack.ts
|
|
125
|
-
var Backpack = class extends Wallet {
|
|
126
|
-
defaultPassword = "11111111";
|
|
127
|
-
currentAccountId = 0;
|
|
128
|
-
maxAccountId = 0;
|
|
129
|
-
async gotoOnboardPage() {
|
|
130
|
-
await this.page.goto(
|
|
131
|
-
`chrome-extension://${this.extensionId}/onboarding.html`
|
|
132
|
-
);
|
|
133
|
-
await expect(this.page.getByText("Welcome to Backpack")).toBeVisible();
|
|
134
|
-
}
|
|
135
|
-
async onboard(network, privateKey) {
|
|
136
|
-
this.currentAccountId++;
|
|
137
|
-
this.maxAccountId++;
|
|
138
|
-
return this._importAccount(network, privateKey, true);
|
|
139
|
-
}
|
|
140
|
-
async addAccount(network, privateKey) {
|
|
141
|
-
this.maxAccountId++;
|
|
142
|
-
this.currentAccountId = this.maxAccountId;
|
|
143
|
-
await this.page.goto(
|
|
144
|
-
`chrome-extension://${this.extensionId}/onboarding.html?add-user-account=true`
|
|
145
|
-
);
|
|
146
|
-
await this._importAccount(network, privateKey, false);
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Switch account
|
|
150
|
-
* @param id The first added account has id 1, the second – 2, and so on
|
|
151
|
-
*/
|
|
152
|
-
async switchAccount(id) {
|
|
153
|
-
await this.page.getByRole("button", { name: `A${this.currentAccountId}` }).click();
|
|
154
|
-
await this.page.getByRole("button", { name: `Account ${id}` }).click();
|
|
155
|
-
this.currentAccountId = id;
|
|
156
|
-
}
|
|
157
|
-
async unlock() {
|
|
158
|
-
await this.page.getByPlaceholder("Password").fill(this.defaultPassword);
|
|
159
|
-
await this.page.getByRole("button", { name: "Unlock" }).click();
|
|
160
|
-
}
|
|
161
|
-
async setRPC(network, rpc) {
|
|
162
|
-
await this._clickOnAccount();
|
|
163
|
-
await this.page.getByRole("button", { name: "Settings" }).click();
|
|
164
|
-
await this.page.getByRole("button", { name: network }).click();
|
|
165
|
-
await this.page.getByRole("button", { name: "RPC Connection" }).click();
|
|
166
|
-
await this.page.getByRole("button", { name: "Custom" }).click();
|
|
167
|
-
await this.page.getByPlaceholder("RPC URL").fill(rpc);
|
|
168
|
-
await this.page.keyboard.press("Enter");
|
|
169
|
-
}
|
|
170
|
-
async ignoreAndProceed() {
|
|
171
|
-
const ignoreButton = this.page.getByText("Ignore and proceed anyway.");
|
|
172
|
-
await ignoreButton.click();
|
|
173
|
-
}
|
|
174
|
-
async approve() {
|
|
175
|
-
await this.page.getByText("Approve", { exact: true }).click();
|
|
176
|
-
}
|
|
177
|
-
async deny() {
|
|
178
|
-
await this.page.getByText("Deny", { exact: true }).click();
|
|
179
|
-
}
|
|
180
|
-
async _clickOnAccount() {
|
|
181
|
-
return this.page.getByRole("button", { name: `A${this.currentAccountId}`, exact: true }).click();
|
|
182
|
-
}
|
|
183
|
-
async _importAccount(network, privateKey, isOnboard) {
|
|
184
|
-
{
|
|
185
|
-
await this.page.waitForTimeout(2e3);
|
|
186
|
-
if (await this.page.getByText("You're all good!").isVisible()) {
|
|
187
|
-
await this.page.getByLabel("Go back").click();
|
|
188
|
-
}
|
|
132
|
+
if (config.actionTimeout) {
|
|
133
|
+
page.setDefaultTimeout(config.actionTimeout);
|
|
189
134
|
}
|
|
190
|
-
await this.page.getByTestId("terms-of-service-checkbox").click();
|
|
191
|
-
await this.page.getByText("I already have a wallet").click();
|
|
192
|
-
await this.page.getByText(network).click();
|
|
193
|
-
await this.page.getByText("Private key").click();
|
|
194
|
-
await this.page.getByPlaceholder("Private key").fill(privateKey);
|
|
195
|
-
await this.page.waitForTimeout(1e3);
|
|
196
|
-
await this.page.getByText("Import", { exact: true }).click();
|
|
197
|
-
if (isOnboard) {
|
|
198
|
-
await this.page.getByRole("textbox").nth(0).fill(this.defaultPassword);
|
|
199
|
-
await this.page.getByRole("textbox").nth(1).fill(this.defaultPassword);
|
|
200
|
-
await this.page.getByText("Next", { exact: true }).click();
|
|
201
|
-
await expect(this.page.getByText("You're all good!")).toBeVisible();
|
|
202
|
-
}
|
|
203
|
-
await this.page.goto(`chrome-extension://${this.extensionId}/popup.html`);
|
|
204
|
-
await this.page.getByTestId("__CAROUSEL_ITEM_0__").waitFor({ state: "visible" });
|
|
205
135
|
}
|
|
206
136
|
};
|
|
207
137
|
|
|
208
138
|
// src/wallets/metamask/metamask.ts
|
|
209
|
-
import { expect as expect2 } from "@playwright/test";
|
|
210
139
|
var Metamask = class extends Wallet {
|
|
211
140
|
defaultPassword = "TestPassword123!";
|
|
212
141
|
async gotoOnboardPage() {
|
|
213
|
-
await this.page.goto(
|
|
214
|
-
|
|
215
|
-
);
|
|
216
|
-
await expect2(
|
|
142
|
+
await this.page.goto(`chrome-extension://${this.extensionId}/home.html`);
|
|
143
|
+
await expect(
|
|
217
144
|
this.page.getByRole("button", { name: "I have an existing wallet" })
|
|
218
145
|
).toBeVisible();
|
|
219
146
|
}
|
|
@@ -224,11 +151,16 @@ var Metamask = class extends Wallet {
|
|
|
224
151
|
*/
|
|
225
152
|
async onboard(mnemonic, password) {
|
|
226
153
|
const pwd = password ?? this.defaultPassword;
|
|
154
|
+
await this.gotoOnboardPage();
|
|
227
155
|
await this.page.getByRole("button", { name: "I have an existing wallet" }).click();
|
|
228
156
|
await this.page.getByRole("button", { name: "Import using Secret Recovery Phrase" }).click();
|
|
229
157
|
const textbox = this.page.getByRole("textbox");
|
|
230
158
|
await textbox.click();
|
|
231
|
-
|
|
159
|
+
for (const word of mnemonic.split(" ")) {
|
|
160
|
+
await this.page.keyboard.type(word);
|
|
161
|
+
await this.page.keyboard.type(" ");
|
|
162
|
+
await this.page.waitForTimeout(30);
|
|
163
|
+
}
|
|
232
164
|
const continueBtn = this.page.getByTestId("import-srp-confirm");
|
|
233
165
|
await continueBtn.click();
|
|
234
166
|
const passwordInputs = this.page.locator('input[type="password"]');
|
|
@@ -237,21 +169,17 @@ var Metamask = class extends Wallet {
|
|
|
237
169
|
await this.page.getByRole("checkbox").click();
|
|
238
170
|
await this.page.getByRole("button", { name: "Create password" }).click();
|
|
239
171
|
const metametricsBtn = this.page.getByTestId("metametrics-i-agree");
|
|
240
|
-
await metametricsBtn.waitFor({ state: "visible", timeout: 3e4 });
|
|
241
172
|
await metametricsBtn.click();
|
|
242
173
|
const openWalletBtn = this.page.getByRole("button", {
|
|
243
174
|
name: /open wallet/i
|
|
244
175
|
});
|
|
245
|
-
await openWalletBtn.waitFor({ state: "visible", timeout: 3e4 });
|
|
246
176
|
await openWalletBtn.click();
|
|
247
177
|
await this.page.goto(
|
|
248
178
|
`chrome-extension://${this.extensionId}/sidepanel.html`
|
|
249
179
|
);
|
|
250
|
-
await this.page.getByTestId("account-options-menu-button").waitFor({ state: "visible", timeout: 3e4 });
|
|
251
180
|
}
|
|
252
181
|
async approve() {
|
|
253
182
|
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();
|
|
254
|
-
await this.page.getByTestId("account-options-menu-button").waitFor({ state: "visible", timeout: 3e4 });
|
|
255
183
|
}
|
|
256
184
|
async deny() {
|
|
257
185
|
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 }));
|
|
@@ -283,7 +211,7 @@ var Metamask = class extends Wallet {
|
|
|
283
211
|
await this.page.getByRole("tab", { name: "Custom" }).click();
|
|
284
212
|
}
|
|
285
213
|
await this.page.getByText(networkName).click();
|
|
286
|
-
await
|
|
214
|
+
await expect(this.page.getByTestId("sort-by-networks")).toHaveText(
|
|
287
215
|
networkName
|
|
288
216
|
);
|
|
289
217
|
}
|
|
@@ -332,23 +260,24 @@ var Metamask = class extends Wallet {
|
|
|
332
260
|
await this.page.getByRole("button", { name: "Back" }).click();
|
|
333
261
|
}
|
|
334
262
|
async accountNameIs(accountName) {
|
|
335
|
-
await
|
|
263
|
+
await expect(this.page.getByTestId("account-menu-icon")).toContainText(
|
|
336
264
|
accountName
|
|
337
265
|
);
|
|
338
266
|
}
|
|
339
267
|
};
|
|
340
268
|
|
|
341
269
|
// src/wallets/polkadot-js/polkadot-js.ts
|
|
342
|
-
import { expect as
|
|
270
|
+
import { expect as expect2 } from "@playwright/test";
|
|
343
271
|
var PolkadotJS = class extends Wallet {
|
|
344
272
|
defaultPassword = "11111111";
|
|
345
273
|
async gotoOnboardPage() {
|
|
346
274
|
await this.page.goto(`chrome-extension://${this.extensionId}/index.html`);
|
|
347
|
-
await
|
|
275
|
+
await expect2(
|
|
348
276
|
this.page.getByText("Before we start, just a couple of notes")
|
|
349
277
|
).toBeVisible();
|
|
350
278
|
}
|
|
351
279
|
async onboard(seed, password, name) {
|
|
280
|
+
await this.gotoOnboardPage();
|
|
352
281
|
await this.page.getByRole("button", { name: "Understood, let me continue" }).click();
|
|
353
282
|
await this.page.getByRole("button", { name: "I Understand" }).click();
|
|
354
283
|
await this.page.locator(".popupToggle").first().click();
|
|
@@ -370,7 +299,8 @@ var PolkadotJS = class extends Wallet {
|
|
|
370
299
|
await this.page.getByText("Select all").click();
|
|
371
300
|
}
|
|
372
301
|
async selectAccount(accountId) {
|
|
373
|
-
|
|
302
|
+
const cb = this.page.locator(".accountWichCheckbox").filter({ hasText: accountId }).locator(".accountTree-checkbox").locator("span");
|
|
303
|
+
await cb.check().catch(() => cb.check());
|
|
374
304
|
}
|
|
375
305
|
async enterPassword(password) {
|
|
376
306
|
await this._getLabeledInput("Password for this account").fill(
|
|
@@ -397,11 +327,6 @@ var PolkadotJS = class extends Wallet {
|
|
|
397
327
|
};
|
|
398
328
|
|
|
399
329
|
// src/wallets/index.ts
|
|
400
|
-
var backpack = createWallet({
|
|
401
|
-
name: "backpack",
|
|
402
|
-
extensionDir: "backpack",
|
|
403
|
-
WalletClass: Backpack
|
|
404
|
-
});
|
|
405
330
|
var metamask = createWallet({
|
|
406
331
|
name: "metamask",
|
|
407
332
|
extensionDir: "metamask",
|
|
@@ -413,10 +338,9 @@ var polkadotJS = createWallet({
|
|
|
413
338
|
WalletClass: PolkadotJS
|
|
414
339
|
});
|
|
415
340
|
export {
|
|
416
|
-
Backpack,
|
|
417
341
|
Metamask,
|
|
418
342
|
PolkadotJS,
|
|
419
|
-
|
|
343
|
+
config,
|
|
420
344
|
createWallet,
|
|
421
345
|
metamask,
|
|
422
346
|
polkadotJS,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "w3wallets",
|
|
3
3
|
"description": "browser wallets for playwright",
|
|
4
|
-
"version": "1.0.0-beta.
|
|
4
|
+
"version": "1.0.0-beta.3",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"homepage": "https://github.com/Maksandre/w3wallets",
|
|
@@ -16,12 +16,10 @@
|
|
|
16
16
|
"keywords": [
|
|
17
17
|
"e2e",
|
|
18
18
|
"playwright",
|
|
19
|
-
"backpack",
|
|
20
19
|
"metamask",
|
|
21
20
|
"testing",
|
|
22
21
|
"ethereum",
|
|
23
|
-
"polkadot"
|
|
24
|
-
"eclipse"
|
|
22
|
+
"polkadot"
|
|
25
23
|
],
|
|
26
24
|
"license": "MIT",
|
|
27
25
|
"publishConfig": {
|
|
@@ -32,8 +30,7 @@
|
|
|
32
30
|
],
|
|
33
31
|
"bin": "./src/scripts/download.js",
|
|
34
32
|
"scripts": {
|
|
35
|
-
"
|
|
36
|
-
"download-wallets": "npx w3wallets backpack polkadotJS metamask",
|
|
33
|
+
"download-wallets": "npx w3wallets pjs mm",
|
|
37
34
|
"test": "npx playwright test --project=local --workers=2",
|
|
38
35
|
"test:ci": "npx playwright test --project=ci",
|
|
39
36
|
"build": "tsup",
|
|
@@ -49,7 +46,7 @@
|
|
|
49
46
|
"devDependencies": {
|
|
50
47
|
"@arethetypeswrong/cli": "^0.17.2",
|
|
51
48
|
"@changesets/cli": "^2.27.11",
|
|
52
|
-
"@playwright/test": "
|
|
49
|
+
"@playwright/test": "1.57.0",
|
|
53
50
|
"@types/node": "^22.10.5",
|
|
54
51
|
"dotenv": "^16.4.7",
|
|
55
52
|
"prettier": "^3.4.2",
|
|
@@ -58,6 +55,6 @@
|
|
|
58
55
|
"typescript": "^5.7.2"
|
|
59
56
|
},
|
|
60
57
|
"peerDependencies": {
|
|
61
|
-
"@playwright/test": "^1.
|
|
58
|
+
"@playwright/test": "^1.57.0"
|
|
62
59
|
}
|
|
63
60
|
}
|
package/src/scripts/download.js
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* Downloads and extracts Chrome extensions from the Chrome Web Store.
|
|
5
5
|
*
|
|
6
6
|
* Usage:
|
|
7
|
-
* npx w3wallets metamask
|
|
8
|
-
* npx w3wallets mm
|
|
7
|
+
* npx w3wallets metamask polkadotjs # Download by alias
|
|
8
|
+
* npx w3wallets mm pjs # Short aliases
|
|
9
9
|
* npx w3wallets <extension-id> # Download by extension ID
|
|
10
10
|
* npx w3wallets --help # Show help
|
|
11
11
|
*/
|
|
@@ -19,10 +19,6 @@ const zlib = require("zlib");
|
|
|
19
19
|
// 1. Known aliases -> extension IDs (case-insensitive lookup)
|
|
20
20
|
// ---------------------------------------------------------------------
|
|
21
21
|
const EXTENSION_REGISTRY = {
|
|
22
|
-
// Backpack wallet
|
|
23
|
-
backpack: "aflkmfhebedbjioipglgcbcmnbpgliof",
|
|
24
|
-
bp: "aflkmfhebedbjioipglgcbcmnbpgliof",
|
|
25
|
-
|
|
26
22
|
// MetaMask wallet
|
|
27
23
|
metamask: "nkbihfbeogaeaoehlefnkodbefgpgknn",
|
|
28
24
|
mm: "nkbihfbeogaeaoehlefnkodbefgpgknn",
|
|
@@ -34,14 +30,12 @@ const EXTENSION_REGISTRY = {
|
|
|
34
30
|
|
|
35
31
|
// Human-readable names for display
|
|
36
32
|
const EXTENSION_NAMES = {
|
|
37
|
-
aflkmfhebedbjioipglgcbcmnbpgliof: "Backpack",
|
|
38
33
|
nkbihfbeogaeaoehlefnkodbefgpgknn: "MetaMask",
|
|
39
34
|
mopnmbcafieddcagagdcbnhejhlodfdd: "Polkadot.js",
|
|
40
35
|
};
|
|
41
36
|
|
|
42
37
|
// Canonical aliases for listing
|
|
43
38
|
const CANONICAL_ALIASES = [
|
|
44
|
-
{ name: "backpack", short: "bp", id: "aflkmfhebedbjioipglgcbcmnbpgliof" },
|
|
45
39
|
{ name: "metamask", short: "mm", id: "nkbihfbeogaeaoehlefnkodbefgpgknn" },
|
|
46
40
|
{ name: "polkadotjs", short: "pjs", id: "mopnmbcafieddcagagdcbnhejhlodfdd" },
|
|
47
41
|
];
|
|
@@ -95,8 +89,8 @@ USAGE:
|
|
|
95
89
|
npx w3wallets [OPTIONS] <targets...>
|
|
96
90
|
|
|
97
91
|
TARGETS:
|
|
98
|
-
Alias name Known wallet alias (e.g., metamask,
|
|
99
|
-
Short alias Short form (e.g., mm,
|
|
92
|
+
Alias name Known wallet alias (e.g., metamask, polkadotjs)
|
|
93
|
+
Short alias Short form (e.g., mm, pjs)
|
|
100
94
|
Extension ID 32-character Chrome extension ID
|
|
101
95
|
URL Chrome Web Store URL
|
|
102
96
|
|
|
@@ -109,7 +103,7 @@ OPTIONS:
|
|
|
109
103
|
|
|
110
104
|
EXAMPLES:
|
|
111
105
|
npx w3wallets metamask # Download MetaMask
|
|
112
|
-
npx w3wallets mm
|
|
106
|
+
npx w3wallets mm pjs # Download using short aliases
|
|
113
107
|
npx w3wallets --list # List available aliases
|
|
114
108
|
npx w3wallets -o ./extensions metamask # Custom output directory
|
|
115
109
|
npx w3wallets --force mm # Force re-download
|