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 CHANGED
@@ -26,10 +26,46 @@ npm install -D w3wallets
26
26
  #### 1. Download wallets
27
27
 
28
28
  ```sh
29
- npx w3wallets backpack polkadotJS
29
+ npx w3wallets metamask backpack polkadotjs
30
30
  ```
31
31
 
32
- The unzipped files should be stored in the `.w3wallets/<wallet-name>` directory. Add them to `.gitignore`.
32
+ Short aliases are also supported:
33
+
34
+ ```sh
35
+ npx w3wallets mm bp pjs
36
+ ```
37
+
38
+ The unzipped files are stored in the `.w3wallets/<wallet-name>` directory. Add `.w3wallets` to `.gitignore`.
39
+
40
+ <details>
41
+ <summary>CLI Options</summary>
42
+
43
+ ```
44
+ USAGE:
45
+ npx w3wallets [OPTIONS] <targets...>
46
+
47
+ TARGETS:
48
+ Alias name Known wallet alias (metamask, backpack, polkadotjs)
49
+ Short alias Short form (mm, bp, pjs)
50
+ Extension ID 32-character Chrome extension ID
51
+ URL Chrome Web Store URL
52
+
53
+ OPTIONS:
54
+ -h, --help Show help message
55
+ -l, --list List available wallet aliases
56
+ -o, --output Output directory (default: .w3wallets)
57
+ -f, --force Force re-download even if already exists
58
+ --debug Save raw .crx file for debugging
59
+
60
+ EXAMPLES:
61
+ npx w3wallets metamask # Download MetaMask
62
+ npx w3wallets mm bp pjs # Download all wallets (short)
63
+ npx w3wallets --list # List available aliases
64
+ npx w3wallets -o ./extensions metamask # Custom output directory
65
+ npx w3wallets --force mm # Force re-download
66
+ ```
67
+
68
+ </details>
33
69
 
34
70
  #### 2. Wrap your fixture with `withWallets`
35
71
 
@@ -37,20 +73,10 @@ Install the required wallets into Chromium using `withWallets`.
37
73
 
38
74
  ```ts
39
75
  // your-fixture.ts
40
- import { withWallets } from "w3wallets";
76
+ import { withWallets, metamask, backpack, polkadotJS } from "w3wallets";
41
77
  import { test as base } from "@playwright/test";
42
78
 
43
- export const test = withWallets(
44
- base,
45
- "backpack",
46
- "polkadotJS",
47
- ).extend<BaseFixture>({
48
- magic: (_, use) => use(42),
49
- });
50
-
51
- type BaseFixture = {
52
- magic: number;
53
- };
79
+ export const test = withWallets(base, metamask, backpack, polkadotJS);
54
80
 
55
81
  export { expect } from "@playwright/test";
56
82
  ```
@@ -64,12 +90,18 @@ Most commonly, you will use the following methods:
64
90
  3. `deny`: for actions that reject or cancel operations
65
91
 
66
92
  ```ts
67
- import { test } from "./your-fixture";
93
+ import { test, expect } from "./your-fixture";
94
+
95
+ test("Can connect MetaMask to dApp", async ({ page, metamask }) => {
96
+ const mnemonic =
97
+ "test test test test test test test test test test test junk";
98
+
99
+ await metamask.onboard(mnemonic);
100
+ await page.goto("https://your-dapp.com");
68
101
 
69
- test("Can use wallet", async ({ page, backpack }) => {
70
- const privateKey =
71
- "4wDJd9Ds5ueTdS95ReAZGSBVkjMcNKbgZk47xcmqzpUJjCt7VoB2Cs7hqwXWRnopzXqE4mCP6BEDHCYrFttEcBw2";
102
+ await page.getByRole("button", { name: "Connect Wallet" }).click();
103
+ await metamask.approve();
72
104
 
73
- await backpack.onboard("Eclipse", privateKey);
105
+ await expect(page.getByText("Connected")).toBeVisible();
74
106
  });
75
107
  ```
package/dist/index.d.mts CHANGED
@@ -1,22 +1,87 @@
1
1
  import * as playwright_test from 'playwright/test';
2
2
  import { Page, test, BrowserContext } from '@playwright/test';
3
3
 
4
- /**
5
- * Represents the supported network types for the BackPack application.
6
- */
7
- type BackPackNetwork = "Solana" | "Eclipse" | "Ethereum" | "Polygon" | "Base" | "Arbitrum" | "Optimism";
8
-
9
- type WalletName = "backpack" | "polkadotJS" | "metamask";
10
- type NoDuplicates<T extends readonly unknown[], Acc extends readonly unknown[] = []> = T extends [infer Head, ...infer Tail] ? Head extends Acc[number] ? never : [Head, ...NoDuplicates<Tail, [...Acc, Head]>] : T;
11
4
  interface IWallet {
5
+ readonly page: Page;
12
6
  gotoOnboardPage(): Promise<void>;
7
+ approve(): Promise<void>;
8
+ deny(): Promise<void>;
13
9
  }
10
+ /**
11
+ * Configuration object for a wallet.
12
+ */
13
+ interface WalletConfig<TName extends string = string, TWallet extends IWallet = IWallet> {
14
+ /** Unique wallet identifier, used as fixture name */
15
+ name: TName;
16
+ /** Directory name under .w3wallets/ where extension is stored */
17
+ extensionDir: string;
18
+ /** Wallet class constructor */
19
+ WalletClass: new (page: Page, extensionId: string) => TWallet;
20
+ /**
21
+ * Chrome extension ID. If not provided, it will be derived from
22
+ * the manifest.json `key` field. Required for custom extensions
23
+ * that don't have a `key` field in their manifest.
24
+ */
25
+ extensionId?: string;
26
+ }
27
+ /**
28
+ * Creates a wallet configuration object.
29
+ *
30
+ * @example
31
+ * ```ts
32
+ * const myWallet = createWallet({
33
+ * name: "myWallet",
34
+ * extensionDir: "my-wallet",
35
+ * WalletClass: MyWalletClass,
36
+ * });
37
+ * ```
38
+ */
39
+ declare function createWallet<TName extends string, TWallet extends IWallet>(config: WalletConfig<TName, TWallet>): WalletConfig<TName, TWallet>;
40
+ /**
41
+ * Extracts fixture name from a wallet config.
42
+ */
43
+ type WalletConfigName<T> = T extends WalletConfig<infer N, IWallet> ? N : never;
44
+ /**
45
+ * Extracts wallet class instance type from a wallet config.
46
+ */
47
+ type WalletConfigInstance<T> = T extends WalletConfig<string, infer W> ? W : never;
48
+ /**
49
+ * Builds fixture types from an array of wallet configs.
50
+ */
51
+ type WalletFixturesFromConfigs<T extends readonly WalletConfig[]> = {
52
+ [K in T[number] as WalletConfigName<K>]: WalletConfigInstance<K>;
53
+ };
54
+ /**
55
+ * Supported blockchain networks.
56
+ * Common networks are listed for autocomplete, but any string is accepted.
57
+ */
58
+ type Network = "Solana" | "Eclipse" | "Ethereum" | "Polygon" | "Base" | "Arbitrum" | "Optimism" | (string & {});
59
+
60
+ /**
61
+ * Extends Playwright test with wallet fixtures.
62
+ *
63
+ * @example
64
+ * ```ts
65
+ * import { withWallets, metamask, backpack } from "w3wallets";
66
+ *
67
+ * const test = withWallets(base, metamask, backpack);
68
+ *
69
+ * test("can connect", async ({ metamask, backpack }) => {
70
+ * await metamask.onboard(mnemonic);
71
+ * });
72
+ * ```
73
+ */
74
+ declare function withWallets<const T extends readonly WalletConfig[]>(test: typeof test, ...wallets: T): playwright_test.TestType<playwright_test.PlaywrightTestArgs & playwright_test.PlaywrightTestOptions & WalletFixturesFromConfigs<T> & {
75
+ context: BrowserContext;
76
+ }, playwright_test.PlaywrightWorkerArgs & playwright_test.PlaywrightWorkerOptions>;
14
77
 
15
78
  declare abstract class Wallet implements IWallet {
16
- page: Page;
17
- protected extensionId: string;
79
+ readonly page: Page;
80
+ protected readonly extensionId: string;
18
81
  constructor(page: Page, extensionId: string);
19
82
  abstract gotoOnboardPage(): Promise<void>;
83
+ abstract approve(): Promise<void>;
84
+ abstract deny(): Promise<void>;
20
85
  }
21
86
 
22
87
  declare class Backpack extends Wallet {
@@ -24,15 +89,15 @@ declare class Backpack extends Wallet {
24
89
  private currentAccountId;
25
90
  private maxAccountId;
26
91
  gotoOnboardPage(): Promise<void>;
27
- onboard(network: BackPackNetwork, privateKey: string): Promise<void>;
28
- addAccount(network: BackPackNetwork, privateKey: string): Promise<void>;
92
+ onboard(network: Network, privateKey: string): Promise<void>;
93
+ addAccount(network: Network, privateKey: string): Promise<void>;
29
94
  /**
30
95
  * Switch account
31
96
  * @param id The first added account has id 1, the second – 2, and so on
32
97
  */
33
98
  switchAccount(id: number): Promise<void>;
34
99
  unlock(): Promise<void>;
35
- setRPC(network: BackPackNetwork, rpc: string): Promise<void>;
100
+ setRPC(network: Network, rpc: string): Promise<void>;
36
101
  ignoreAndProceed(): Promise<void>;
37
102
  approve(): Promise<void>;
38
103
  deny(): Promise<void>;
@@ -40,18 +105,6 @@ declare class Backpack extends Wallet {
40
105
  private _importAccount;
41
106
  }
42
107
 
43
- declare class PolkadotJS extends Wallet {
44
- private defaultPassword;
45
- gotoOnboardPage(): Promise<void>;
46
- onboard(seed: string, password?: string, name?: string): Promise<void>;
47
- selectAllAccounts(): Promise<void>;
48
- selectAccount(accountId: string): Promise<void>;
49
- enterPassword(password?: string): Promise<void>;
50
- approve(): Promise<void>;
51
- deny(): Promise<void>;
52
- private _getLabeledInput;
53
- }
54
-
55
108
  type NetworkSettings = {
56
109
  name: string;
57
110
  rpc: string;
@@ -63,30 +116,60 @@ declare class Metamask extends Wallet {
63
116
  private defaultPassword;
64
117
  gotoOnboardPage(): Promise<void>;
65
118
  /**
66
- *
67
- * @param mnemonic 12-word mnemonic seed phrase
119
+ * Onboard MetaMask with a mnemonic phrase
120
+ * @param mnemonic - 12 or 24 word recovery phrase
121
+ * @param password - Optional password (defaults to TestPassword123!)
68
122
  */
69
123
  onboard(mnemonic: string, password?: string): Promise<void>;
70
- switchAccount(accountName: {
71
- name: string;
72
- }): Promise<void>;
73
- importAccount(privateKey: string): Promise<void>;
74
- addAccount(accountName?: string): Promise<void>;
75
- getAccountName(): Promise<string>;
76
- connectToNetwork(networkName: string, networkType?: "Popular" | "Custom"): Promise<void>;
124
+ approve(): Promise<void>;
125
+ deny(): Promise<void>;
126
+ /**
127
+ * Lock the MetaMask wallet
128
+ */
129
+ lock(): Promise<void>;
130
+ /**
131
+ * Unlock MetaMask with password
132
+ */
133
+ unlock(password?: string): Promise<void>;
134
+ /**
135
+ * Switch to an existing network in MetaMask
136
+ * @param networkName - Name of the network to switch to (e.g., "Ethereum Mainnet", "Sepolia")
137
+ */
138
+ switchNetwork(networkName: string, networkType?: "Popular" | "Custom"): Promise<void>;
139
+ switchAccount(accountName: string): Promise<void>;
140
+ /**
141
+ * Add a custom network to MetaMask
142
+ */
143
+ addNetwork(network: NetworkSettings): Promise<void>;
77
144
  addCustomNetwork(settings: NetworkSettings): Promise<void>;
78
145
  enableTestNetworks(): Promise<void>;
146
+ importAccount(privateKey: string): Promise<void>;
147
+ accountNameIs(accountName: string): Promise<void>;
148
+ }
149
+
150
+ declare class PolkadotJS extends Wallet {
151
+ private defaultPassword;
152
+ gotoOnboardPage(): Promise<void>;
153
+ onboard(seed: string, password?: string, name?: string): Promise<void>;
154
+ selectAllAccounts(): Promise<void>;
155
+ selectAccount(accountId: string): Promise<void>;
156
+ enterPassword(password?: string): Promise<void>;
79
157
  approve(): Promise<void>;
80
158
  deny(): Promise<void>;
81
- private usingNotificationPage;
82
- private clickTopRightCornerToCloseAllTheMarketingBullshit;
159
+ private _getLabeledInput;
83
160
  }
84
161
 
85
- declare function withWallets<T extends readonly WalletName[]>(test: typeof test, ...config: NoDuplicates<T>): playwright_test.TestType<playwright_test.PlaywrightTestArgs & playwright_test.PlaywrightTestOptions & {
86
- context: BrowserContext;
87
- backpack: Backpack;
88
- polkadotJS: PolkadotJS;
89
- metamask: Metamask;
90
- }, playwright_test.PlaywrightWorkerArgs & playwright_test.PlaywrightWorkerOptions>;
162
+ /**
163
+ * Pre-built Backpack wallet configuration.
164
+ */
165
+ declare const backpack: WalletConfig<"backpack", Backpack>;
166
+ /**
167
+ * Pre-built MetaMask wallet configuration.
168
+ */
169
+ declare const metamask: WalletConfig<"metamask", Metamask>;
170
+ /**
171
+ * Pre-built Polkadot.js wallet configuration.
172
+ */
173
+ declare const polkadotJS: WalletConfig<"polkadotJS", PolkadotJS>;
91
174
 
92
- export { withWallets };
175
+ export { Backpack, type IWallet, Metamask, type Network, type NetworkSettings, PolkadotJS, type WalletConfig, backpack, createWallet, metamask, polkadotJS, withWallets };
package/dist/index.d.ts CHANGED
@@ -1,22 +1,87 @@
1
1
  import * as playwright_test from 'playwright/test';
2
2
  import { Page, test, BrowserContext } from '@playwright/test';
3
3
 
4
- /**
5
- * Represents the supported network types for the BackPack application.
6
- */
7
- type BackPackNetwork = "Solana" | "Eclipse" | "Ethereum" | "Polygon" | "Base" | "Arbitrum" | "Optimism";
8
-
9
- type WalletName = "backpack" | "polkadotJS" | "metamask";
10
- type NoDuplicates<T extends readonly unknown[], Acc extends readonly unknown[] = []> = T extends [infer Head, ...infer Tail] ? Head extends Acc[number] ? never : [Head, ...NoDuplicates<Tail, [...Acc, Head]>] : T;
11
4
  interface IWallet {
5
+ readonly page: Page;
12
6
  gotoOnboardPage(): Promise<void>;
7
+ approve(): Promise<void>;
8
+ deny(): Promise<void>;
13
9
  }
10
+ /**
11
+ * Configuration object for a wallet.
12
+ */
13
+ interface WalletConfig<TName extends string = string, TWallet extends IWallet = IWallet> {
14
+ /** Unique wallet identifier, used as fixture name */
15
+ name: TName;
16
+ /** Directory name under .w3wallets/ where extension is stored */
17
+ extensionDir: string;
18
+ /** Wallet class constructor */
19
+ WalletClass: new (page: Page, extensionId: string) => TWallet;
20
+ /**
21
+ * Chrome extension ID. If not provided, it will be derived from
22
+ * the manifest.json `key` field. Required for custom extensions
23
+ * that don't have a `key` field in their manifest.
24
+ */
25
+ extensionId?: string;
26
+ }
27
+ /**
28
+ * Creates a wallet configuration object.
29
+ *
30
+ * @example
31
+ * ```ts
32
+ * const myWallet = createWallet({
33
+ * name: "myWallet",
34
+ * extensionDir: "my-wallet",
35
+ * WalletClass: MyWalletClass,
36
+ * });
37
+ * ```
38
+ */
39
+ declare function createWallet<TName extends string, TWallet extends IWallet>(config: WalletConfig<TName, TWallet>): WalletConfig<TName, TWallet>;
40
+ /**
41
+ * Extracts fixture name from a wallet config.
42
+ */
43
+ type WalletConfigName<T> = T extends WalletConfig<infer N, IWallet> ? N : never;
44
+ /**
45
+ * Extracts wallet class instance type from a wallet config.
46
+ */
47
+ type WalletConfigInstance<T> = T extends WalletConfig<string, infer W> ? W : never;
48
+ /**
49
+ * Builds fixture types from an array of wallet configs.
50
+ */
51
+ type WalletFixturesFromConfigs<T extends readonly WalletConfig[]> = {
52
+ [K in T[number] as WalletConfigName<K>]: WalletConfigInstance<K>;
53
+ };
54
+ /**
55
+ * Supported blockchain networks.
56
+ * Common networks are listed for autocomplete, but any string is accepted.
57
+ */
58
+ type Network = "Solana" | "Eclipse" | "Ethereum" | "Polygon" | "Base" | "Arbitrum" | "Optimism" | (string & {});
59
+
60
+ /**
61
+ * Extends Playwright test with wallet fixtures.
62
+ *
63
+ * @example
64
+ * ```ts
65
+ * import { withWallets, metamask, backpack } from "w3wallets";
66
+ *
67
+ * const test = withWallets(base, metamask, backpack);
68
+ *
69
+ * test("can connect", async ({ metamask, backpack }) => {
70
+ * await metamask.onboard(mnemonic);
71
+ * });
72
+ * ```
73
+ */
74
+ declare function withWallets<const T extends readonly WalletConfig[]>(test: typeof test, ...wallets: T): playwright_test.TestType<playwright_test.PlaywrightTestArgs & playwright_test.PlaywrightTestOptions & WalletFixturesFromConfigs<T> & {
75
+ context: BrowserContext;
76
+ }, playwright_test.PlaywrightWorkerArgs & playwright_test.PlaywrightWorkerOptions>;
14
77
 
15
78
  declare abstract class Wallet implements IWallet {
16
- page: Page;
17
- protected extensionId: string;
79
+ readonly page: Page;
80
+ protected readonly extensionId: string;
18
81
  constructor(page: Page, extensionId: string);
19
82
  abstract gotoOnboardPage(): Promise<void>;
83
+ abstract approve(): Promise<void>;
84
+ abstract deny(): Promise<void>;
20
85
  }
21
86
 
22
87
  declare class Backpack extends Wallet {
@@ -24,15 +89,15 @@ declare class Backpack extends Wallet {
24
89
  private currentAccountId;
25
90
  private maxAccountId;
26
91
  gotoOnboardPage(): Promise<void>;
27
- onboard(network: BackPackNetwork, privateKey: string): Promise<void>;
28
- addAccount(network: BackPackNetwork, privateKey: string): Promise<void>;
92
+ onboard(network: Network, privateKey: string): Promise<void>;
93
+ addAccount(network: Network, privateKey: string): Promise<void>;
29
94
  /**
30
95
  * Switch account
31
96
  * @param id The first added account has id 1, the second – 2, and so on
32
97
  */
33
98
  switchAccount(id: number): Promise<void>;
34
99
  unlock(): Promise<void>;
35
- setRPC(network: BackPackNetwork, rpc: string): Promise<void>;
100
+ setRPC(network: Network, rpc: string): Promise<void>;
36
101
  ignoreAndProceed(): Promise<void>;
37
102
  approve(): Promise<void>;
38
103
  deny(): Promise<void>;
@@ -40,18 +105,6 @@ declare class Backpack extends Wallet {
40
105
  private _importAccount;
41
106
  }
42
107
 
43
- declare class PolkadotJS extends Wallet {
44
- private defaultPassword;
45
- gotoOnboardPage(): Promise<void>;
46
- onboard(seed: string, password?: string, name?: string): Promise<void>;
47
- selectAllAccounts(): Promise<void>;
48
- selectAccount(accountId: string): Promise<void>;
49
- enterPassword(password?: string): Promise<void>;
50
- approve(): Promise<void>;
51
- deny(): Promise<void>;
52
- private _getLabeledInput;
53
- }
54
-
55
108
  type NetworkSettings = {
56
109
  name: string;
57
110
  rpc: string;
@@ -63,30 +116,60 @@ declare class Metamask extends Wallet {
63
116
  private defaultPassword;
64
117
  gotoOnboardPage(): Promise<void>;
65
118
  /**
66
- *
67
- * @param mnemonic 12-word mnemonic seed phrase
119
+ * Onboard MetaMask with a mnemonic phrase
120
+ * @param mnemonic - 12 or 24 word recovery phrase
121
+ * @param password - Optional password (defaults to TestPassword123!)
68
122
  */
69
123
  onboard(mnemonic: string, password?: string): Promise<void>;
70
- switchAccount(accountName: {
71
- name: string;
72
- }): Promise<void>;
73
- importAccount(privateKey: string): Promise<void>;
74
- addAccount(accountName?: string): Promise<void>;
75
- getAccountName(): Promise<string>;
76
- connectToNetwork(networkName: string, networkType?: "Popular" | "Custom"): Promise<void>;
124
+ approve(): Promise<void>;
125
+ deny(): Promise<void>;
126
+ /**
127
+ * Lock the MetaMask wallet
128
+ */
129
+ lock(): Promise<void>;
130
+ /**
131
+ * Unlock MetaMask with password
132
+ */
133
+ unlock(password?: string): Promise<void>;
134
+ /**
135
+ * Switch to an existing network in MetaMask
136
+ * @param networkName - Name of the network to switch to (e.g., "Ethereum Mainnet", "Sepolia")
137
+ */
138
+ switchNetwork(networkName: string, networkType?: "Popular" | "Custom"): Promise<void>;
139
+ switchAccount(accountName: string): Promise<void>;
140
+ /**
141
+ * Add a custom network to MetaMask
142
+ */
143
+ addNetwork(network: NetworkSettings): Promise<void>;
77
144
  addCustomNetwork(settings: NetworkSettings): Promise<void>;
78
145
  enableTestNetworks(): Promise<void>;
146
+ importAccount(privateKey: string): Promise<void>;
147
+ accountNameIs(accountName: string): Promise<void>;
148
+ }
149
+
150
+ declare class PolkadotJS extends Wallet {
151
+ private defaultPassword;
152
+ gotoOnboardPage(): Promise<void>;
153
+ onboard(seed: string, password?: string, name?: string): Promise<void>;
154
+ selectAllAccounts(): Promise<void>;
155
+ selectAccount(accountId: string): Promise<void>;
156
+ enterPassword(password?: string): Promise<void>;
79
157
  approve(): Promise<void>;
80
158
  deny(): Promise<void>;
81
- private usingNotificationPage;
82
- private clickTopRightCornerToCloseAllTheMarketingBullshit;
159
+ private _getLabeledInput;
83
160
  }
84
161
 
85
- declare function withWallets<T extends readonly WalletName[]>(test: typeof test, ...config: NoDuplicates<T>): playwright_test.TestType<playwright_test.PlaywrightTestArgs & playwright_test.PlaywrightTestOptions & {
86
- context: BrowserContext;
87
- backpack: Backpack;
88
- polkadotJS: PolkadotJS;
89
- metamask: Metamask;
90
- }, playwright_test.PlaywrightWorkerArgs & playwright_test.PlaywrightWorkerOptions>;
162
+ /**
163
+ * Pre-built Backpack wallet configuration.
164
+ */
165
+ declare const backpack: WalletConfig<"backpack", Backpack>;
166
+ /**
167
+ * Pre-built MetaMask wallet configuration.
168
+ */
169
+ declare const metamask: WalletConfig<"metamask", Metamask>;
170
+ /**
171
+ * Pre-built Polkadot.js wallet configuration.
172
+ */
173
+ declare const polkadotJS: WalletConfig<"polkadotJS", PolkadotJS>;
91
174
 
92
- export { withWallets };
175
+ export { Backpack, type IWallet, Metamask, type Network, type NetworkSettings, PolkadotJS, type WalletConfig, backpack, createWallet, metamask, polkadotJS, withWallets };