@avalix/chroma 0.0.10 → 0.0.12
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 +21 -228
- package/dist/index.d.mts +1736 -45729
- package/dist/index.mjs +107 -101
- package/package.json +9 -4
- package/scripts/download-extensions.ts +3 -3
- package/src/context-playwright/index.ts +6 -9
- package/src/context-playwright/types.ts +8 -26
- package/src/context-playwright/wallet-factory.ts +60 -96
- package/src/utils/download-extension.integration.test.ts +95 -0
- package/src/utils/download-extension.test.ts +173 -0
- package/src/utils/download-extension.ts +1 -1
- package/src/wallets/talisman.ts +106 -52
package/dist/index.mjs
CHANGED
|
@@ -103,35 +103,63 @@ async function getTalismanExtensionPath() {
|
|
|
103
103
|
if (!fs.existsSync(extensionDir) || fs.readdirSync(extensionDir).length === 0) throw new Error(`Talisman extension not found at: ${extensionDir}\n\nPlease download the extension first by running:\n npx @avalix/chroma download-extensions\n`);
|
|
104
104
|
return extensionDir;
|
|
105
105
|
}
|
|
106
|
-
async function
|
|
106
|
+
async function findOnboardingPage(context, extensionId) {
|
|
107
|
+
const popupUrl = `chrome-extension://${extensionId}/dashboard.html`;
|
|
108
|
+
const newPage = await context.newPage();
|
|
109
|
+
await newPage.goto(popupUrl);
|
|
110
|
+
await newPage.waitForLoadState("domcontentloaded");
|
|
111
|
+
for (const p of context.pages()) if (p !== newPage && p.url().includes(`chrome-extension://${extensionId}/`)) await p.close();
|
|
112
|
+
return newPage;
|
|
113
|
+
}
|
|
114
|
+
async function completeOnboarding(extensionPage, password) {
|
|
115
|
+
await extensionPage.bringToFront();
|
|
116
|
+
await extensionPage.waitForLoadState("domcontentloaded");
|
|
117
|
+
if (await extensionPage.getByRole("button", { name: "Settings" }).isVisible()) {
|
|
118
|
+
await extensionPage.getByRole("button", { name: "Settings" }).click({ force: true });
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
await extensionPage.getByTestId("onboarding-get-started-button").click();
|
|
122
|
+
await extensionPage.getByRole("textbox", { name: "Enter password" }).fill(password);
|
|
123
|
+
await extensionPage.getByRole("textbox", { name: "Confirm password" }).fill(password);
|
|
124
|
+
await extensionPage.getByTestId("onboarding-password-confirm-button").click();
|
|
125
|
+
await extensionPage.getByRole("button", { name: "No thanks" }).click();
|
|
126
|
+
await extensionPage.getByTestId("onboarding-enter-talisman-button").click();
|
|
127
|
+
const extensionId = extensionPage.url().match(/chrome-extension:\/\/([^/]+)/)?.[1];
|
|
128
|
+
await extensionPage.goto(`chrome-extension://${extensionId}/dashboard.html#/settings/general`);
|
|
129
|
+
await extensionPage.waitForLoadState("domcontentloaded");
|
|
130
|
+
await extensionPage.getByRole("link", { name: "Security & Privacy" }).click();
|
|
131
|
+
await extensionPage.getByTestId("component-toggle-button").first().click();
|
|
132
|
+
}
|
|
133
|
+
async function importPolkadotMnemonic(page, { seed, name = "Test Account", password = "h3llop0lkadot!" }) {
|
|
107
134
|
const context = page.__extensionContext;
|
|
108
135
|
const extensionId = page.__extensionId;
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
136
|
+
const extensionPage = await findOnboardingPage(context, extensionId);
|
|
137
|
+
try {
|
|
138
|
+
await completeOnboarding(extensionPage, password);
|
|
139
|
+
await extensionPage.getByRole("link", { name: "Manage Accounts" }).click();
|
|
140
|
+
await extensionPage.getByRole("button", { name: "Get Started" }).click();
|
|
141
|
+
await extensionPage.getByRole("button", { name: "Add Account" }).click();
|
|
142
|
+
await extensionPage.getByRole("button", { name: "Import Import an existing" }).click();
|
|
143
|
+
await extensionPage.getByRole("button", { name: "Import via Recovery Phrase" }).click();
|
|
144
|
+
await extensionPage.getByRole("button", { name: "Polkadot Relay Chain, Asset" }).click();
|
|
145
|
+
await extensionPage.getByRole("textbox", { name: "Choose a name" }).fill(name);
|
|
146
|
+
await extensionPage.getByRole("textbox", { name: "Enter your 12 or 24 word" }).fill(seed);
|
|
147
|
+
await extensionPage.getByTestId("account-add-mnemonic-import-button").click();
|
|
148
|
+
await extensionPage.close();
|
|
149
|
+
} catch (error) {
|
|
150
|
+
console.error("❌ Error during Talisman Polkadot account import:", error);
|
|
151
|
+
throw error;
|
|
123
152
|
}
|
|
124
|
-
|
|
153
|
+
}
|
|
154
|
+
async function importEthPrivateKey(page, { seed, name = "Test Account", password = "h3llop0lkadot!" }) {
|
|
155
|
+
const context = page.__extensionContext;
|
|
156
|
+
const extensionId = page.__extensionId;
|
|
157
|
+
const extensionPage = await findOnboardingPage(context, extensionId);
|
|
125
158
|
try {
|
|
126
|
-
await extensionPage
|
|
127
|
-
await extensionPage.
|
|
128
|
-
await extensionPage.
|
|
129
|
-
await extensionPage.getByRole("
|
|
130
|
-
await extensionPage.getByRole("textbox", { name: "Confirm password" }).fill(password);
|
|
131
|
-
await extensionPage.getByTestId("onboarding-password-confirm-button").click();
|
|
132
|
-
await extensionPage.getByRole("button", { name: "No thanks" }).click();
|
|
133
|
-
await extensionPage.getByTestId("onboarding-enter-talisman-button").click();
|
|
134
|
-
await extensionPage.getByRole("button", { name: "Add account Create or import" }).click();
|
|
159
|
+
await completeOnboarding(extensionPage, password);
|
|
160
|
+
await extensionPage.getByRole("link", { name: "Manage Accounts" }).click();
|
|
161
|
+
await extensionPage.getByRole("button", { name: "Get Started" }).click();
|
|
162
|
+
await extensionPage.getByRole("button", { name: "Add Account" }).click();
|
|
135
163
|
await extensionPage.getByRole("button", { name: "Import Import an existing" }).click();
|
|
136
164
|
await extensionPage.getByRole("button", { name: "Import via Private Key" }).click();
|
|
137
165
|
await extensionPage.getByRole("button", { name: "Select account platform" }).click();
|
|
@@ -141,16 +169,20 @@ async function importEthPrivateKey(page, { seed, name = "Test Account", password
|
|
|
141
169
|
await extensionPage.getByRole("button", { name: "Save" }).click();
|
|
142
170
|
await extensionPage.close();
|
|
143
171
|
} catch (error) {
|
|
144
|
-
console.error("❌ Error during Talisman account import:", error);
|
|
172
|
+
console.error("❌ Error during Talisman Ethereum account import:", error);
|
|
145
173
|
throw error;
|
|
146
174
|
}
|
|
147
175
|
}
|
|
148
176
|
async function authorizeTalisman(page, options = {}) {
|
|
149
|
-
const { accountName = "Test Account" } = options;
|
|
150
177
|
const context = page.__extensionContext;
|
|
151
178
|
const extensionId = page.__extensionId;
|
|
179
|
+
const { accountName = "Test Account" } = options;
|
|
152
180
|
const extensionPopup = await findExtensionPopup(context, extensionId);
|
|
153
|
-
await extensionPopup.
|
|
181
|
+
await extensionPopup.waitForLoadState("domcontentloaded");
|
|
182
|
+
const accountButton = extensionPopup.getByRole("button", { name: accountName });
|
|
183
|
+
await accountButton.waitFor({ state: "visible" });
|
|
184
|
+
await accountButton.scrollIntoViewIfNeeded();
|
|
185
|
+
await accountButton.click({ force: true });
|
|
154
186
|
await extensionPopup.getByTestId("connection-connect-button").click();
|
|
155
187
|
try {
|
|
156
188
|
await (await findExtensionPopup(context, extensionId)).getByRole("button", { name: "Approve" }).click();
|
|
@@ -160,23 +192,16 @@ async function approveTalismanTx(page) {
|
|
|
160
192
|
const context = page.__extensionContext;
|
|
161
193
|
const extensionId = page.__extensionId;
|
|
162
194
|
const extensionPopup = await findExtensionPopup(context, extensionId);
|
|
163
|
-
|
|
164
|
-
await extensionPopup.getByRole("button", { name: "Yes" }).click();
|
|
165
|
-
} catch {
|
|
166
|
-
console.log("No another popup found, skipping");
|
|
167
|
-
}
|
|
195
|
+
if (await extensionPopup.getByRole("button", { name: "Yes" }).isVisible()) await extensionPopup.getByRole("button", { name: "Yes" }).click();
|
|
168
196
|
await extensionPopup.getByRole("button", { name: "Approve" }).click();
|
|
169
197
|
}
|
|
170
198
|
async function rejectTalismanTx(page) {
|
|
171
199
|
const context = page.__extensionContext;
|
|
172
200
|
const extensionId = page.__extensionId;
|
|
173
|
-
|
|
201
|
+
const extensionPopup = await findExtensionPopup(context, extensionId);
|
|
202
|
+
await extensionPopup.getByTestId("connection-reject-button").or(extensionPopup.getByRole("button", { name: "Cancel" })).click();
|
|
174
203
|
}
|
|
175
204
|
|
|
176
|
-
//#endregion
|
|
177
|
-
//#region src/context-playwright/types.ts
|
|
178
|
-
const WALLET_TYPES = ["polkadot-js", "talisman"];
|
|
179
|
-
|
|
180
205
|
//#endregion
|
|
181
206
|
//#region src/context-playwright/wallet-factory.ts
|
|
182
207
|
function createExtendedPage(page, context, extensionId) {
|
|
@@ -185,80 +210,58 @@ function createExtendedPage(page, context, extensionId) {
|
|
|
185
210
|
extPage.__extensionId = extensionId;
|
|
186
211
|
return extPage;
|
|
187
212
|
}
|
|
188
|
-
function
|
|
189
|
-
|
|
190
|
-
const baseInstance = {
|
|
213
|
+
function createPolkadotJsWallet(extensionId, context) {
|
|
214
|
+
return {
|
|
191
215
|
extensionId,
|
|
216
|
+
type: "polkadot-js",
|
|
192
217
|
importMnemonic: async (options) => {
|
|
218
|
+
await importPolkadotJSAccount(createExtendedPage(context.pages()[0] || await context.newPage(), context, extensionId), options);
|
|
219
|
+
},
|
|
220
|
+
authorize: async () => {
|
|
221
|
+
await authorizePolkadotJS(createExtendedPage(context.pages()[0] || await context.newPage(), context, extensionId));
|
|
222
|
+
},
|
|
223
|
+
approveTx: async (options = {}) => {
|
|
224
|
+
await approvePolkadotJSTx(createExtendedPage(context.pages()[0] || await context.newPage(), context, extensionId), options);
|
|
225
|
+
},
|
|
226
|
+
rejectTx: async () => {
|
|
227
|
+
await rejectPolkadotJSTx(createExtendedPage(context.pages()[0] || await context.newPage(), context, extensionId));
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
function createTalismanWallet(extensionId, context) {
|
|
232
|
+
let importedAccountName;
|
|
233
|
+
return {
|
|
234
|
+
extensionId,
|
|
235
|
+
type: "talisman",
|
|
236
|
+
importPolkadotMnemonic: async (options) => {
|
|
193
237
|
const extPage = createExtendedPage(context.pages()[0] || await context.newPage(), context, extensionId);
|
|
194
238
|
importedAccountName = options.name || "Test Account";
|
|
195
|
-
|
|
196
|
-
case "polkadot-js":
|
|
197
|
-
await importPolkadotJSAccount(extPage, options);
|
|
198
|
-
break;
|
|
199
|
-
case "talisman": throw new Error("Talisman importMnemonic is not yet implemented.");
|
|
200
|
-
default: throw new Error(`Unsupported wallet type: ${walletType}`);
|
|
201
|
-
}
|
|
239
|
+
await importPolkadotMnemonic(extPage, options);
|
|
202
240
|
},
|
|
203
|
-
|
|
241
|
+
importEthPrivateKey: async (options) => {
|
|
204
242
|
const extPage = createExtendedPage(context.pages()[0] || await context.newPage(), context, extensionId);
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
await authorizeTalisman(extPage, { accountName });
|
|
212
|
-
break;
|
|
213
|
-
default: throw new Error(`Unsupported wallet type: ${walletType}`);
|
|
214
|
-
}
|
|
243
|
+
importedAccountName = options.name || "Test Account";
|
|
244
|
+
await importEthPrivateKey(extPage, {
|
|
245
|
+
seed: options.privateKey,
|
|
246
|
+
name: options.name,
|
|
247
|
+
password: options.password
|
|
248
|
+
});
|
|
215
249
|
},
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
break;
|
|
222
|
-
case "talisman":
|
|
223
|
-
await approveTalismanTx(extPage);
|
|
224
|
-
break;
|
|
225
|
-
default: throw new Error(`Unsupported wallet type: ${walletType}`);
|
|
226
|
-
}
|
|
250
|
+
authorize: async (options = {}) => {
|
|
251
|
+
await authorizeTalisman(createExtendedPage(context.pages()[0] || await context.newPage(), context, extensionId), { accountName: options.accountName || importedAccountName });
|
|
252
|
+
},
|
|
253
|
+
approveTx: async () => {
|
|
254
|
+
await approveTalismanTx(createExtendedPage(context.pages()[0] || await context.newPage(), context, extensionId));
|
|
227
255
|
},
|
|
228
256
|
rejectTx: async () => {
|
|
229
|
-
|
|
230
|
-
switch (walletType) {
|
|
231
|
-
case "polkadot-js":
|
|
232
|
-
await rejectPolkadotJSTx(extPage);
|
|
233
|
-
break;
|
|
234
|
-
case "talisman":
|
|
235
|
-
await rejectTalismanTx(extPage);
|
|
236
|
-
break;
|
|
237
|
-
default: throw new Error(`Unsupported wallet type: ${walletType}`);
|
|
238
|
-
}
|
|
257
|
+
await rejectTalismanTx(createExtendedPage(context.pages()[0] || await context.newPage(), context, extensionId));
|
|
239
258
|
}
|
|
240
259
|
};
|
|
241
|
-
switch (walletType) {
|
|
242
|
-
case "polkadot-js": return {
|
|
243
|
-
...baseInstance,
|
|
244
|
-
type: "polkadot-js"
|
|
245
|
-
};
|
|
246
|
-
case "talisman": return {
|
|
247
|
-
...baseInstance,
|
|
248
|
-
type: "talisman",
|
|
249
|
-
importEthPrivateKey: async (options) => {
|
|
250
|
-
const extPage = createExtendedPage(context.pages()[0] || await context.newPage(), context, extensionId);
|
|
251
|
-
importedAccountName = options.name || "Test Account";
|
|
252
|
-
await importEthPrivateKey(extPage, {
|
|
253
|
-
seed: options.privateKey,
|
|
254
|
-
name: options.name,
|
|
255
|
-
password: options.password
|
|
256
|
-
});
|
|
257
|
-
}
|
|
258
|
-
};
|
|
259
|
-
default: throw new Error(`Unsupported wallet type: ${walletType}`);
|
|
260
|
-
}
|
|
261
260
|
}
|
|
261
|
+
const walletFactories = {
|
|
262
|
+
"polkadot-js": createPolkadotJsWallet,
|
|
263
|
+
"talisman": createTalismanWallet
|
|
264
|
+
};
|
|
262
265
|
|
|
263
266
|
//#endregion
|
|
264
267
|
//#region src/context-playwright/index.ts
|
|
@@ -306,7 +309,10 @@ function createWalletTest(options = {}) {
|
|
|
306
309
|
},
|
|
307
310
|
wallets: async ({ walletContext, walletExtensionIds }, use) => {
|
|
308
311
|
const walletMap = {};
|
|
309
|
-
for (const [walletType, extensionId] of walletExtensionIds)
|
|
312
|
+
for (const [walletType, extensionId] of walletExtensionIds) {
|
|
313
|
+
const factory = walletFactories[walletType];
|
|
314
|
+
if (factory) walletMap[walletType] = factory(extensionId, walletContext);
|
|
315
|
+
}
|
|
310
316
|
await use(walletMap);
|
|
311
317
|
}
|
|
312
318
|
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@avalix/chroma",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.12",
|
|
5
5
|
"description": "End-to-end testing library for Polkadot wallet interactions",
|
|
6
6
|
"author": "Avalix Labs",
|
|
7
7
|
"license": "MIT",
|
|
@@ -44,7 +44,11 @@
|
|
|
44
44
|
"lint": "eslint --fix .",
|
|
45
45
|
"prepublishOnly": "npm run build",
|
|
46
46
|
"download-extensions": "rm -rf .chroma && tsx scripts/download-extensions.ts",
|
|
47
|
-
"test": "playwright test
|
|
47
|
+
"test": "playwright test",
|
|
48
|
+
"test:ui": "playwright test --ui",
|
|
49
|
+
"test:unit": "vitest",
|
|
50
|
+
"test:unit:run": "vitest run",
|
|
51
|
+
"test:unit:coverage": "vitest run --coverage"
|
|
48
52
|
},
|
|
49
53
|
"peerDependencies": {
|
|
50
54
|
"@playwright/test": "^1.57.0"
|
|
@@ -58,8 +62,9 @@
|
|
|
58
62
|
"@types/node": "^24.10.2",
|
|
59
63
|
"@types/unzipper": "^0.10.11",
|
|
60
64
|
"eslint": "^9.39.1",
|
|
61
|
-
"tsdown": "
|
|
62
|
-
"tsx": "^4.21.0"
|
|
65
|
+
"tsdown": "^0.20.1",
|
|
66
|
+
"tsx": "^4.21.0",
|
|
67
|
+
"vitest": "^4.0.18"
|
|
63
68
|
},
|
|
64
69
|
"publishConfig": {
|
|
65
70
|
"access": "public"
|
|
@@ -19,15 +19,15 @@ async function clearChromaDir(): Promise<void> {
|
|
|
19
19
|
const chromaDir = path.resolve(process.cwd(), '.chroma')
|
|
20
20
|
|
|
21
21
|
if (fs.existsSync(chromaDir)) {
|
|
22
|
-
console.log('🗑️
|
|
22
|
+
console.log('🗑️ Clearing existing .chroma directory...')
|
|
23
23
|
await fs.promises.rm(chromaDir, { recursive: true, force: true })
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
async function main() {
|
|
28
28
|
const version = await getVersion()
|
|
29
|
-
console.log(
|
|
30
|
-
console.log('🚀 Downloading wallet extensions
|
|
29
|
+
console.log(`\n🎨 Chroma v${version}`)
|
|
30
|
+
console.log('🚀 Downloading wallet extensions...')
|
|
31
31
|
|
|
32
32
|
try {
|
|
33
33
|
// Clear existing .chroma directory
|
|
@@ -4,16 +4,13 @@ import type {
|
|
|
4
4
|
ExtendedPage,
|
|
5
5
|
WalletConfig,
|
|
6
6
|
WalletFixtures,
|
|
7
|
-
WalletInstance,
|
|
8
7
|
Wallets,
|
|
9
|
-
WalletType,
|
|
10
8
|
WalletWorkerFixtures,
|
|
11
9
|
} from './types.js'
|
|
12
10
|
import { test as base, chromium } from '@playwright/test'
|
|
13
11
|
import { getPolkadotJSExtensionPath } from '../wallets/polkadot-js.js'
|
|
14
12
|
import { getTalismanExtensionPath } from '../wallets/talisman.js'
|
|
15
|
-
import {
|
|
16
|
-
import { createWalletInstance } from './wallet-factory.js'
|
|
13
|
+
import { walletFactories } from './wallet-factory.js'
|
|
17
14
|
|
|
18
15
|
// Helper function to get extension path for a wallet config
|
|
19
16
|
async function getExtensionPathForWallet(config: WalletConfig): Promise<string> {
|
|
@@ -117,17 +114,17 @@ export function createWalletTest<const T extends readonly WalletConfig[]>(
|
|
|
117
114
|
|
|
118
115
|
// Wallet instances for each configured wallet
|
|
119
116
|
wallets: async ({ walletContext, walletExtensionIds }, use) => {
|
|
120
|
-
const walletMap
|
|
117
|
+
const walletMap = {} as ExpectedWallets
|
|
121
118
|
|
|
122
119
|
// Create wallet instance for each configured wallet
|
|
123
120
|
for (const [walletType, extensionId] of walletExtensionIds) {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
121
|
+
const factory = walletFactories[walletType as keyof typeof walletFactories]
|
|
122
|
+
if (factory) {
|
|
123
|
+
walletMap[walletType as keyof ExpectedWallets] = factory(extensionId, walletContext) as ExpectedWallets[keyof ExpectedWallets]
|
|
127
124
|
}
|
|
128
125
|
}
|
|
129
126
|
|
|
130
|
-
await use(walletMap
|
|
127
|
+
await use(walletMap)
|
|
131
128
|
},
|
|
132
129
|
})
|
|
133
130
|
}
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import type { BrowserContext, Page } from '@playwright/test'
|
|
2
|
+
import type {
|
|
3
|
+
PolkadotJsWalletInstance,
|
|
4
|
+
TalismanWalletInstance,
|
|
5
|
+
WalletInstance,
|
|
6
|
+
} from './wallet-factory.js'
|
|
7
|
+
|
|
8
|
+
// Re-export wallet instance types
|
|
9
|
+
export type { PolkadotJsWalletInstance, TalismanWalletInstance, WalletInstance }
|
|
2
10
|
|
|
3
11
|
// Wallet types - single source of truth
|
|
4
12
|
export type WalletType = 'polkadot-js' | 'talisman'
|
|
5
13
|
|
|
6
|
-
// Available wallet types as constant array
|
|
7
|
-
export const WALLET_TYPES: readonly WalletType[] = ['polkadot-js', 'talisman'] as const
|
|
8
|
-
|
|
9
14
|
// Wallet account configuration
|
|
10
15
|
export interface WalletAccount {
|
|
11
16
|
seed: string
|
|
@@ -19,29 +24,6 @@ export interface WalletConfig {
|
|
|
19
24
|
downloadUrl?: string
|
|
20
25
|
}
|
|
21
26
|
|
|
22
|
-
// Base wallet instance - common methods for all wallets
|
|
23
|
-
export interface BaseWalletInstance {
|
|
24
|
-
extensionId: string
|
|
25
|
-
importMnemonic: (options: WalletAccount) => Promise<void>
|
|
26
|
-
authorize: (options?: { accountName?: string }) => Promise<void>
|
|
27
|
-
approveTx: (options?: { password?: string }) => Promise<void>
|
|
28
|
-
rejectTx: () => Promise<void>
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Polkadot-JS specific wallet instance
|
|
32
|
-
export interface PolkadotJsWalletInstance extends BaseWalletInstance {
|
|
33
|
-
type: 'polkadot-js'
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// Talisman specific wallet instance (with additional methods)
|
|
37
|
-
export interface TalismanWalletInstance extends BaseWalletInstance {
|
|
38
|
-
type: 'talisman'
|
|
39
|
-
importEthPrivateKey: (options: { privateKey: string, name?: string, password?: string }) => Promise<void>
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Union type of all wallet instances
|
|
43
|
-
export type WalletInstance = PolkadotJsWalletInstance | TalismanWalletInstance
|
|
44
|
-
|
|
45
27
|
// Map wallet type to its instance
|
|
46
28
|
export interface WalletTypeMap {
|
|
47
29
|
'polkadot-js': PolkadotJsWalletInstance
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import type { BrowserContext, Page } from '@playwright/test'
|
|
2
|
-
import type {
|
|
3
|
-
BaseWalletInstance,
|
|
4
|
-
PolkadotJsWalletInstance,
|
|
5
|
-
TalismanWalletInstance,
|
|
6
|
-
WalletAccount,
|
|
7
|
-
WalletInstance,
|
|
8
|
-
} from './types.js'
|
|
2
|
+
import type { WalletAccount } from './types.js'
|
|
9
3
|
import {
|
|
10
4
|
approvePolkadotJSTx,
|
|
11
5
|
authorizePolkadotJS,
|
|
@@ -16,6 +10,7 @@ import {
|
|
|
16
10
|
approveTalismanTx,
|
|
17
11
|
authorizeTalisman,
|
|
18
12
|
importEthPrivateKey,
|
|
13
|
+
importPolkadotMnemonic,
|
|
19
14
|
rejectTalismanTx,
|
|
20
15
|
} from '../wallets/talisman.js'
|
|
21
16
|
|
|
@@ -27,114 +22,83 @@ function createExtendedPage(page: Page, context: BrowserContext, extensionId: st
|
|
|
27
22
|
return extPage
|
|
28
23
|
}
|
|
29
24
|
|
|
30
|
-
//
|
|
31
|
-
export function
|
|
32
|
-
|
|
33
|
-
extensionId: string,
|
|
34
|
-
context: BrowserContext,
|
|
35
|
-
): WalletInstance {
|
|
36
|
-
// Store the imported account name for later use
|
|
37
|
-
let importedAccountName: string | undefined
|
|
38
|
-
|
|
39
|
-
// Common methods for all wallets
|
|
40
|
-
const baseInstance: BaseWalletInstance = {
|
|
25
|
+
// Factory function for Polkadot-JS wallet
|
|
26
|
+
export function createPolkadotJsWallet(extensionId: string, context: BrowserContext) {
|
|
27
|
+
return {
|
|
41
28
|
extensionId,
|
|
29
|
+
type: 'polkadot-js' as const,
|
|
42
30
|
importMnemonic: async (options: WalletAccount) => {
|
|
43
31
|
const page = context.pages()[0] || await context.newPage()
|
|
44
32
|
const extPage = createExtendedPage(page, context, extensionId)
|
|
33
|
+
await importPolkadotJSAccount(extPage, options)
|
|
34
|
+
},
|
|
35
|
+
authorize: async () => {
|
|
36
|
+
const page = context.pages()[0] || await context.newPage()
|
|
37
|
+
const extPage = createExtendedPage(page, context, extensionId)
|
|
38
|
+
await authorizePolkadotJS(extPage)
|
|
39
|
+
},
|
|
40
|
+
approveTx: async (options: { password?: string } = {}) => {
|
|
41
|
+
const page = context.pages()[0] || await context.newPage()
|
|
42
|
+
const extPage = createExtendedPage(page, context, extensionId)
|
|
43
|
+
await approvePolkadotJSTx(extPage, options)
|
|
44
|
+
},
|
|
45
|
+
rejectTx: async () => {
|
|
46
|
+
const page = context.pages()[0] || await context.newPage()
|
|
47
|
+
const extPage = createExtendedPage(page, context, extensionId)
|
|
48
|
+
await rejectPolkadotJSTx(extPage)
|
|
49
|
+
},
|
|
50
|
+
}
|
|
51
|
+
}
|
|
45
52
|
|
|
46
|
-
|
|
47
|
-
|
|
53
|
+
// Factory function for Talisman wallet
|
|
54
|
+
export function createTalismanWallet(extensionId: string, context: BrowserContext) {
|
|
55
|
+
let importedAccountName: string | undefined
|
|
48
56
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
57
|
+
return {
|
|
58
|
+
extensionId,
|
|
59
|
+
type: 'talisman' as const,
|
|
60
|
+
importPolkadotMnemonic: async (options: WalletAccount) => {
|
|
61
|
+
const page = context.pages()[0] || await context.newPage()
|
|
62
|
+
const extPage = createExtendedPage(page, context, extensionId)
|
|
63
|
+
importedAccountName = options.name || 'Test Account'
|
|
64
|
+
await importPolkadotMnemonic(extPage, options)
|
|
65
|
+
},
|
|
66
|
+
importEthPrivateKey: async (options: { privateKey: string, name?: string, password?: string }) => {
|
|
67
|
+
const page = context.pages()[0] || await context.newPage()
|
|
68
|
+
const extPage = createExtendedPage(page, context, extensionId)
|
|
69
|
+
importedAccountName = options.name || 'Test Account'
|
|
70
|
+
await importEthPrivateKey(extPage, {
|
|
71
|
+
seed: options.privateKey,
|
|
72
|
+
name: options.name,
|
|
73
|
+
password: options.password,
|
|
74
|
+
})
|
|
58
75
|
},
|
|
59
76
|
authorize: async (options: { accountName?: string } = {}) => {
|
|
60
77
|
const page = context.pages()[0] || await context.newPage()
|
|
61
78
|
const extPage = createExtendedPage(page, context, extensionId)
|
|
62
|
-
|
|
63
|
-
// Use provided account name or fall back to the imported one
|
|
64
79
|
const accountName = options.accountName || importedAccountName
|
|
65
|
-
|
|
66
|
-
switch (walletType) {
|
|
67
|
-
case 'polkadot-js':
|
|
68
|
-
await authorizePolkadotJS(extPage)
|
|
69
|
-
break
|
|
70
|
-
case 'talisman':
|
|
71
|
-
await authorizeTalisman(extPage, { accountName })
|
|
72
|
-
break
|
|
73
|
-
default:
|
|
74
|
-
throw new Error(`Unsupported wallet type: ${walletType}`)
|
|
75
|
-
}
|
|
80
|
+
await authorizeTalisman(extPage, { accountName })
|
|
76
81
|
},
|
|
77
|
-
approveTx: async (
|
|
82
|
+
approveTx: async () => {
|
|
78
83
|
const page = context.pages()[0] || await context.newPage()
|
|
79
84
|
const extPage = createExtendedPage(page, context, extensionId)
|
|
80
|
-
|
|
81
|
-
switch (walletType) {
|
|
82
|
-
case 'polkadot-js':
|
|
83
|
-
await approvePolkadotJSTx(extPage, options)
|
|
84
|
-
break
|
|
85
|
-
case 'talisman':
|
|
86
|
-
await approveTalismanTx(extPage)
|
|
87
|
-
break
|
|
88
|
-
default:
|
|
89
|
-
throw new Error(`Unsupported wallet type: ${walletType}`)
|
|
90
|
-
}
|
|
85
|
+
await approveTalismanTx(extPage)
|
|
91
86
|
},
|
|
92
87
|
rejectTx: async () => {
|
|
93
88
|
const page = context.pages()[0] || await context.newPage()
|
|
94
89
|
const extPage = createExtendedPage(page, context, extensionId)
|
|
95
|
-
|
|
96
|
-
switch (walletType) {
|
|
97
|
-
case 'polkadot-js':
|
|
98
|
-
await rejectPolkadotJSTx(extPage)
|
|
99
|
-
break
|
|
100
|
-
case 'talisman':
|
|
101
|
-
await rejectTalismanTx(extPage)
|
|
102
|
-
break
|
|
103
|
-
default:
|
|
104
|
-
throw new Error(`Unsupported wallet type: ${walletType}`)
|
|
105
|
-
}
|
|
90
|
+
await rejectTalismanTx(extPage)
|
|
106
91
|
},
|
|
107
92
|
}
|
|
93
|
+
}
|
|
108
94
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
...baseInstance,
|
|
114
|
-
type: 'polkadot-js',
|
|
115
|
-
} as PolkadotJsWalletInstance
|
|
116
|
-
|
|
117
|
-
case 'talisman':
|
|
118
|
-
return {
|
|
119
|
-
...baseInstance,
|
|
120
|
-
type: 'talisman',
|
|
121
|
-
importEthPrivateKey: async (options: { privateKey: string, name?: string, password?: string }) => {
|
|
122
|
-
const page = context.pages()[0] || await context.newPage()
|
|
123
|
-
const extPage = createExtendedPage(page, context, extensionId)
|
|
124
|
-
|
|
125
|
-
// Store the account name for future authorize calls
|
|
126
|
-
importedAccountName = options.name || 'Test Account'
|
|
127
|
-
|
|
128
|
-
// Use the seed property to pass the private key
|
|
129
|
-
await importEthPrivateKey(extPage, {
|
|
130
|
-
seed: options.privateKey,
|
|
131
|
-
name: options.name,
|
|
132
|
-
password: options.password,
|
|
133
|
-
})
|
|
134
|
-
},
|
|
135
|
-
} as TalismanWalletInstance
|
|
136
|
-
|
|
137
|
-
default:
|
|
138
|
-
throw new Error(`Unsupported wallet type: ${walletType}`)
|
|
139
|
-
}
|
|
95
|
+
// Wallet factories map - auto-inferred types
|
|
96
|
+
export const walletFactories = {
|
|
97
|
+
'polkadot-js': createPolkadotJsWallet,
|
|
98
|
+
'talisman': createTalismanWallet,
|
|
140
99
|
}
|
|
100
|
+
|
|
101
|
+
// Auto-inferred types from factory functions
|
|
102
|
+
export type PolkadotJsWalletInstance = ReturnType<typeof createPolkadotJsWallet>
|
|
103
|
+
export type TalismanWalletInstance = ReturnType<typeof createTalismanWallet>
|
|
104
|
+
export type WalletInstance = PolkadotJsWalletInstance | TalismanWalletInstance
|