diff --git a/src/createWallet.ts b/src/createWallet.ts index a7ff90e..2c8b5cb 100644 --- a/src/createWallet.ts +++ b/src/createWallet.ts @@ -10,6 +10,7 @@ import { import * as chains from "viem/chains"; export type Wallet = ReturnType; +export type WalletRequest = Wallet["request"]; export function createWallet( account: LocalAccount, @@ -26,62 +27,70 @@ export function createWallet( method: string; params?: Array; }) => { - try { - const client = createWalletClient({ - account, - chain, - transport: transports?.[chain.id] ?? http(), + const client = createWalletClient({ + account, + chain, + transport: transports?.[chain.id] ?? http(), + }); + + if (method === "eth_accounts" || method === "eth_requestAccounts") { + return await client.getAddresses(); + } + + if ( + method === "wallet_requestPermissions" || + method === "wallet_revokePermissions" + ) { + return [{ parentCapability: "eth_accounts" }]; + } + + if (method === "wallet_getPermissions") return []; + + if (method === "wallet_switchEthereumChain") { + chain = getChain((params?.[0] as any).chainId); + return null; + } + + if (method === "personal_sign") { + return await client.account.signMessage({ + message: { + raw: params?.[0] as Hex, + }, }); + } - if (method === "eth_accounts" || method === "eth_requestAccounts") { - return await client.getAddresses(); - } - - if ( - method === "wallet_requestPermissions" || - method === "wallet_revokePermissions" - ) { - return [{ parentCapability: "eth_accounts" }]; - } - - if (method === "wallet_getPermissions") return []; - - if (method === "wallet_switchEthereumChain") { - chain = getChain((params?.[0] as any).chainId); - return null; - } - - if (method === "personal_sign") { - return await client.account.signMessage({ - message: { - raw: params?.[0] as Hex, - }, - }); - } - - if (method === "eth_sendTransaction") { - const from = (params?.[0] as any).from; - if (from !== account.address) throw new Error("Invalid from address"); - - return await client.sendTransaction({ - to: (params?.[0] as any).to, - data: (params?.[0] as any).data, - gas: (params?.[0] as any).gas, - gasPrice: (params?.[0] as any).gasPrice, - value: (params?.[0] as any).value, - maxFeePerGas: (params?.[0] as any).maxFeePerGas, - maxPriorityFeePerGas: (params?.[0] as any).maxPriorityFeePerGas, - }); - } - - return await client.request({ - method: method as any, - params: params as any, + if (method === "eth_signTypedData") { + throw new Error("eth_signTypedData is not yet supported"); + } + + if (method === "eth_signTypedData_v3") { + throw new Error("eth_signTypedData_v4 is not yet supported"); + } + + if (method === "eth_signTypedData_v4") { + throw new Error("eth_signTypedData_v4 is not yet supported"); + } + + if (method === "eth_sendTransaction") { + const from = (params?.[0] as any).from; + if (from !== account.address) throw new Error("Invalid from address"); + + return await client.sendTransaction({ + to: (params?.[0] as any).to, + data: (params?.[0] as any).data, + value: (params?.[0] as any).value, + // Let viem handle the gas calcutation + // gas: (params?.[0] as any).gas ?? (params?.[0] as any).gasLimit, + // gasPrice: (params?.[0] as any).gasPrice, + // maxFeePerGas: (params?.[0] as any).maxFeePerGas, + // maxPriorityFeePerGas: (params?.[0] as any).maxPriorityFeePerGas, }); - } catch (error) { - console.error("Error within Mock Wallet:", error); - return null; } + + return await client.request({ + method: method as any, + params: params as any, + }); }, }; } diff --git a/src/installMockWallet.ts b/src/installMockWallet.ts index e30e6ef..d17abcb 100644 --- a/src/installMockWallet.ts +++ b/src/installMockWallet.ts @@ -9,11 +9,13 @@ export async function installMockWallet({ account, transports, defaultChain, + debug, ...params }: { account: LocalAccount; - transports: Record; + transports?: Record; defaultChain?: Chain; + debug?: boolean; } & ({ page: Page } | { browserContext: BrowserContext })) { const browserOrPage = "browserContext" in params ? params.browserContext : params.page; @@ -26,7 +28,7 @@ export async function installMockWallet({ wallets.set(uuid, createWallet(account, transports, defaultChain)); await browserOrPage.addInitScript( - ({ uuid }) => { + ({ uuid, debug }) => { // This function needs to be declared in the browser context function announceMockWallet() { const provider: EIP1193Provider = { @@ -34,6 +36,7 @@ export async function installMockWallet({ return await eip1193Request({ ...request, uuid, + debug, }); }, on: () => {}, @@ -64,7 +67,7 @@ export async function installMockWallet({ announceMockWallet(); }); }, - { uuid }, + { uuid, debug }, ); } @@ -93,21 +96,46 @@ async function eip1193Request({ method, params, uuid, + debug, }: { method: string; params?: Array; uuid: string; + debug?: boolean; }) { const wallet = wallets.get(uuid); if (wallet == null) throw new Error("Account or transport not found"); - // console.log("eip1193Request", method, params); - - const result = await wallet.request({ - method, - params, - }); - - // console.log("eip1193Result", result); - return result; + try { + const result = await wallet.request({ + method, + params, + }); + + if (debug === true) { + console.log( + "WALLET", + uuid.substring(0, 8), + "REQUEST", + method, + params, + "RESULT", + result, + ); + } + return result; + } catch (e) { + if (debug === true) { + console.log( + "WALLET", + uuid.substring(0, 8), + "REQUEST", + method, + params, + "ERROR", + e, + ); + } + throw e; + } } diff --git a/tests/transaction.spec.ts b/tests/transaction.spec.ts index 604e3ab..9d5dc6b 100644 --- a/tests/transaction.spec.ts +++ b/tests/transaction.spec.ts @@ -11,21 +11,7 @@ test.beforeEach(async ({ page }) => { isHex(process.env.PRIVATE_KEY) ? process.env.PRIVATE_KEY : "0x", ), defaultChain: sepolia, - transports: { - [sepolia.id]: (config) => { - return custom({ - request: async ({ method, params }) => { - let result: unknown; - try { - result = await http()(config).request({ method, params }); - } finally { - console.log("METHOD", method, "PARAMS", params, "RESULT", result); - } - return result; - }, - })(config); - }, - }, + debug: true, }); }); @@ -39,5 +25,10 @@ test("Metamask Wallet Test Dapp", async ({ page }) => { ).toBeVisible(); await expect(page.getByText("Name: Mock Wallet")).toBeVisible(); - await page.pause(); + await page.locator("#personalSign").click(); + await expect( + page.getByText( + "0x7ac0fa03981bf136329ffaa21aed4f0ac7fa9a4837e966f16c5bf8783be7e43f41afe27bc4fb75", + ), + ).toBeVisible(); });