@marigoldlabs/web3-tester 0.1.0

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.
Files changed (47) hide show
  1. package/.env.example +27 -0
  2. package/README.md +181 -0
  3. package/dist/anvil.d.ts +52 -0
  4. package/dist/anvil.d.ts.map +1 -0
  5. package/dist/anvil.js +203 -0
  6. package/dist/anvil.js.map +1 -0
  7. package/dist/errors.d.ts +4 -0
  8. package/dist/errors.d.ts.map +1 -0
  9. package/dist/errors.js +25 -0
  10. package/dist/errors.js.map +1 -0
  11. package/dist/fixtures.d.ts +15 -0
  12. package/dist/fixtures.d.ts.map +1 -0
  13. package/dist/fixtures.js +87 -0
  14. package/dist/fixtures.js.map +1 -0
  15. package/dist/index.d.ts +9 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +5 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/injected-provider.d.ts +5 -0
  20. package/dist/injected-provider.d.ts.map +1 -0
  21. package/dist/injected-provider.js +141 -0
  22. package/dist/injected-provider.js.map +1 -0
  23. package/dist/live-fixtures.d.ts +9 -0
  24. package/dist/live-fixtures.d.ts.map +1 -0
  25. package/dist/live-fixtures.js +33 -0
  26. package/dist/live-fixtures.js.map +1 -0
  27. package/dist/mock-wallet-controller.d.ts +41 -0
  28. package/dist/mock-wallet-controller.d.ts.map +1 -0
  29. package/dist/mock-wallet-controller.js +224 -0
  30. package/dist/mock-wallet-controller.js.map +1 -0
  31. package/dist/private-key-rpc-client.d.ts +23 -0
  32. package/dist/private-key-rpc-client.d.ts.map +1 -0
  33. package/dist/private-key-rpc-client.js +112 -0
  34. package/dist/private-key-rpc-client.js.map +1 -0
  35. package/dist/types.d.ts +41 -0
  36. package/dist/types.d.ts.map +1 -0
  37. package/dist/types.js +2 -0
  38. package/dist/types.js.map +1 -0
  39. package/docs/API.md +175 -0
  40. package/docs/ARCHITECTURE.md +81 -0
  41. package/docs/CONSUMING_FROM_FJORD.md +123 -0
  42. package/docs/FJORD_LIVE_QA.md +87 -0
  43. package/docs/RELEASE_CHECKLIST.md +49 -0
  44. package/examples/live-sepolia.spec.ts +21 -0
  45. package/examples/local-wallet.spec.ts +34 -0
  46. package/examples/playwright.config.ts +16 -0
  47. package/package.json +70 -0
@@ -0,0 +1,5 @@
1
+ import type { MockWalletConfig } from './types.js';
2
+ export declare const rpcBridgeName = "__invisibleWalletRpcBridge";
3
+ export declare const emitterName = "__invisibleWalletEmit";
4
+ export declare const buildInjectedProviderScript: (config: MockWalletConfig) => string;
5
+ //# sourceMappingURL=injected-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injected-provider.d.ts","sourceRoot":"","sources":["../src/injected-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAKnD,eAAO,MAAM,aAAa,+BAAc,CAAC;AACzC,eAAO,MAAM,WAAW,0BAAe,CAAC;AAExC,eAAO,MAAM,2BAA2B,WAAY,gBAAgB,KAAG,MAuItE,CAAC"}
@@ -0,0 +1,141 @@
1
+ const BRIDGE_NAME = '__invisibleWalletRpcBridge';
2
+ const EMITTER_NAME = '__invisibleWalletEmit';
3
+ export const rpcBridgeName = BRIDGE_NAME;
4
+ export const emitterName = EMITTER_NAME;
5
+ export const buildInjectedProviderScript = (config) => `
6
+ (() => {
7
+ const config = ${JSON.stringify(config)};
8
+ const listeners = new Map();
9
+
10
+ const getListeners = (event) => {
11
+ if (!listeners.has(event)) {
12
+ listeners.set(event, new Set());
13
+ }
14
+ return listeners.get(event);
15
+ };
16
+
17
+ const emit = (event, payload) => {
18
+ if (event === 'accountsChanged') {
19
+ provider.selectedAddress = Array.isArray(payload) && payload.length > 0 ? payload[0] : null;
20
+ }
21
+
22
+ if (event === 'chainChanged') {
23
+ provider.chainId = payload;
24
+ provider.networkVersion = String(Number(BigInt(payload)));
25
+ }
26
+
27
+ const callbacks = listeners.get(event);
28
+ if (!callbacks) {
29
+ return;
30
+ }
31
+
32
+ for (const callback of [...callbacks]) {
33
+ callback(payload);
34
+ }
35
+ };
36
+
37
+ const request = async (args) => {
38
+ if (!args || typeof args.method !== 'string') {
39
+ const error = new Error('Invalid EIP-1193 request');
40
+ error.code = -32600;
41
+ throw error;
42
+ }
43
+
44
+ const response = await window.${BRIDGE_NAME}({
45
+ method: args.method,
46
+ params: args.params ?? [],
47
+ });
48
+
49
+ if (!response.ok) {
50
+ const error = new Error(response.error.message);
51
+ error.code = response.error.code;
52
+ error.data = response.error.data;
53
+ throw error;
54
+ }
55
+
56
+ return response.result;
57
+ };
58
+
59
+ const provider = {
60
+ isMetaMask: true,
61
+ isMock: true,
62
+ selectedAddress: config.connected && config.accounts.length > 0 ? config.accounts[0] : null,
63
+ chainId: config.chainId,
64
+ networkVersion: String(Number(BigInt(config.chainId))),
65
+ request,
66
+ enable: () => request({ method: 'eth_requestAccounts' }),
67
+ send: (methodOrPayload, paramsOrCallback) => {
68
+ if (typeof methodOrPayload === 'string') {
69
+ return request({ method: methodOrPayload, params: paramsOrCallback });
70
+ }
71
+
72
+ const payload = methodOrPayload;
73
+ const callback = paramsOrCallback;
74
+ request(payload)
75
+ .then((result) => callback?.(null, { id: payload.id, jsonrpc: '2.0', result }))
76
+ .catch((error) => callback?.(error, null));
77
+ },
78
+ sendAsync: (payload, callback) => {
79
+ request(payload)
80
+ .then((result) => callback(null, { id: payload.id, jsonrpc: '2.0', result }))
81
+ .catch((error) => callback(error, null));
82
+ },
83
+ on: (event, handler) => {
84
+ getListeners(event).add(handler);
85
+ return provider;
86
+ },
87
+ once: (event, handler) => {
88
+ const wrapped = (payload) => {
89
+ provider.removeListener(event, wrapped);
90
+ handler(payload);
91
+ };
92
+ provider.on(event, wrapped);
93
+ return provider;
94
+ },
95
+ removeListener: (event, handler) => {
96
+ listeners.get(event)?.delete(handler);
97
+ return provider;
98
+ },
99
+ removeAllListeners: (event) => {
100
+ if (event) {
101
+ listeners.delete(event);
102
+ } else {
103
+ listeners.clear();
104
+ }
105
+ return provider;
106
+ },
107
+ _metamask: {
108
+ isUnlocked: async () => true,
109
+ },
110
+ };
111
+
112
+ const announceProviders = () => {
113
+ for (const info of config.providers) {
114
+ window.dispatchEvent(
115
+ new CustomEvent('eip6963:announceProvider', {
116
+ detail: {
117
+ info,
118
+ provider,
119
+ },
120
+ }),
121
+ );
122
+ }
123
+ };
124
+
125
+ Object.defineProperty(window, 'ethereum', {
126
+ value: provider,
127
+ configurable: true,
128
+ enumerable: true,
129
+ writable: true,
130
+ });
131
+
132
+ Object.defineProperty(window, '${EMITTER_NAME}', {
133
+ value: emit,
134
+ configurable: true,
135
+ });
136
+
137
+ window.addEventListener('eip6963:requestProvider', announceProviders);
138
+ queueMicrotask(announceProviders);
139
+ })();
140
+ `;
141
+ //# sourceMappingURL=injected-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injected-provider.js","sourceRoot":"","sources":["../src/injected-provider.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,GAAG,4BAA4B,CAAC;AACjD,MAAM,YAAY,GAAG,uBAAuB,CAAC;AAE7C,MAAM,CAAC,MAAM,aAAa,GAAG,WAAW,CAAC;AACzC,MAAM,CAAC,MAAM,WAAW,GAAG,YAAY,CAAC;AAExC,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,MAAwB,EAAU,EAAE,CAAC;;mBAE9D,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oCAqCL,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mCAwFZ,YAAY;;;;;;;;CAQ9C,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { MockWalletController } from './mock-wallet-controller.js';
2
+ import { PrivateKeyRpcClient } from './private-key-rpc-client.js';
3
+ export type LiveWeb3Fixtures = {
4
+ wallet: MockWalletController;
5
+ liveClient: PrivateKeyRpcClient;
6
+ };
7
+ export declare const test: import("@playwright/test").TestType<import("@playwright/test").PlaywrightTestArgs & import("@playwright/test").PlaywrightTestOptions & LiveWeb3Fixtures, import("@playwright/test").PlaywrightWorkerArgs & import("@playwright/test").PlaywrightWorkerOptions>;
8
+ export { expect } from '@playwright/test';
9
+ //# sourceMappingURL=live-fixtures.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"live-fixtures.d.ts","sourceRoot":"","sources":["../src/live-fixtures.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAElE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,oBAAoB,CAAC;IAC7B,UAAU,EAAE,mBAAmB,CAAC;CACjC,CAAC;AAEF,eAAO,MAAM,IAAI,gQA+Bf,CAAC;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { test as base } from '@playwright/test';
2
+ import { sepolia } from 'viem/chains';
3
+ import { MockWalletController } from './mock-wallet-controller.js';
4
+ import { PrivateKeyRpcClient } from './private-key-rpc-client.js';
5
+ export const test = base.extend({
6
+ liveClient: async ({}, use) => {
7
+ const privateKey = process.env.FJORD_PRIVATE_KEY;
8
+ if (!privateKey) {
9
+ throw new Error('FJORD_PRIVATE_KEY is required for live Sepolia Fjord tests.');
10
+ }
11
+ await use(new PrivateKeyRpcClient({
12
+ privateKey: privateKey,
13
+ chain: sepolia,
14
+ rpcUrl: process.env.SEPOLIA_RPC_URL,
15
+ }));
16
+ },
17
+ wallet: async ({ page, liveClient }, use) => {
18
+ const wallet = new MockWalletController(page, liveClient, {
19
+ accounts: [liveClient.account.address],
20
+ chainId: sepolia.id,
21
+ autoApprove: true,
22
+ connected: true,
23
+ providerInfo: {
24
+ name: 'MetaMask',
25
+ rdns: 'io.metamask',
26
+ },
27
+ });
28
+ await wallet.injectMockProvider();
29
+ await use(wallet);
30
+ },
31
+ });
32
+ export { expect } from '@playwright/test';
33
+ //# sourceMappingURL=live-fixtures.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"live-fixtures.js","sourceRoot":"","sources":["../src/live-fixtures.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,IAAI,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAOlE,MAAM,CAAC,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAmB;IAChD,UAAU,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE;QAC5B,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;QACjD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;QACjF,CAAC;QAED,MAAM,GAAG,CACP,IAAI,mBAAmB,CAAC;YACtB,UAAU,EAAE,UAA2B;YACvC,KAAK,EAAE,OAAO;YACd,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe;SACpC,CAAC,CACH,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,GAAG,EAAE,EAAE;QAC1C,MAAM,MAAM,GAAG,IAAI,oBAAoB,CAAC,IAAI,EAAE,UAAU,EAAE;YACxD,QAAQ,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC;YACtC,OAAO,EAAE,OAAO,CAAC,EAAE;YACnB,WAAW,EAAE,IAAI;YACjB,SAAS,EAAE,IAAI;YACf,YAAY,EAAE;gBACZ,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,aAAa;aACpB;SACF,CAAC,CAAC;QAEH,MAAM,MAAM,CAAC,kBAAkB,EAAE,CAAC;QAClC,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC;IACpB,CAAC;CACF,CAAC,CAAC;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,41 @@
1
+ import type { Page } from '@playwright/test';
2
+ import { type Address, type Hex } from 'viem';
3
+ import type { RpcClient, WalletProviderInfo } from './types.js';
4
+ export type RejectionRule = {
5
+ methods?: readonly string[];
6
+ message?: string;
7
+ };
8
+ export type MockWalletControllerOptions = {
9
+ accounts: readonly Address[];
10
+ chainId: number | Hex;
11
+ providerInfo?: Partial<WalletProviderInfo>;
12
+ additionalProviders?: readonly Partial<WalletProviderInfo>[];
13
+ autoApprove?: boolean;
14
+ connected?: boolean;
15
+ };
16
+ export declare class MockWalletController {
17
+ private readonly page;
18
+ private readonly rpcClient;
19
+ private accounts;
20
+ private chainId;
21
+ private connected;
22
+ private approveRequests;
23
+ private rejectionQueue;
24
+ constructor(page: Page, rpcClient: RpcClient, options: MockWalletControllerOptions);
25
+ readonly providerInfo: WalletProviderInfo;
26
+ readonly providerInfos: readonly WalletProviderInfo[];
27
+ get primaryAccount(): Address;
28
+ get currentChainId(): Hex;
29
+ injectMockProvider(): Promise<void>;
30
+ autoApprove(enabled?: boolean): void;
31
+ simulateRejection(methods?: string | readonly string[], message?: string): Promise<void>;
32
+ setAccounts(accounts: readonly Address[]): Promise<void>;
33
+ disconnect(): Promise<void>;
34
+ reconnect(): Promise<void>;
35
+ switchNetwork(chainId: number | Hex): Promise<void>;
36
+ private emit;
37
+ private consumeRejection;
38
+ private assertUserApproved;
39
+ private handleRpcRequest;
40
+ }
41
+ //# sourceMappingURL=mock-wallet-controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-wallet-controller.d.ts","sourceRoot":"","sources":["../src/mock-wallet-controller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAS,KAAK,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,MAAM,CAAC;AAOrD,OAAO,KAAK,EAKV,SAAS,EACT,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAC;IAC7B,OAAO,EAAE,MAAM,GAAG,GAAG,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAC3C,mBAAmB,CAAC,EAAE,SAAS,OAAO,CAAC,kBAAkB,CAAC,EAAE,CAAC;IAC7D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAgDF,qBAAa,oBAAoB;IAQ7B,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAR5B,OAAO,CAAC,QAAQ,CAAY;IAC5B,OAAO,CAAC,OAAO,CAAM;IACrB,OAAO,CAAC,SAAS,CAAU;IAC3B,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,cAAc,CAAuB;gBAG1B,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,SAAS,EACrC,OAAO,EAAE,2BAA2B;IA2BtC,QAAQ,CAAC,YAAY,EAAE,kBAAkB,CAAC;IAC1C,QAAQ,CAAC,aAAa,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAEtD,IAAI,cAAc,IAAI,OAAO,CAE5B;IAED,IAAI,cAAc,IAAI,GAAG,CAExB;IAEK,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IA0BzC,WAAW,CAAC,OAAO,UAAO,GAAG,IAAI;IAI3B,iBAAiB,CACrB,OAAO,GAAE,MAAM,GAAG,SAAS,MAAM,EAAyB,EAC1D,OAAO,SAA+B,GACrC,OAAO,CAAC,IAAI,CAAC;IAOV,WAAW,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAUxD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAM3B,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAM1B,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;YAK3C,IAAI;IAYlB,OAAO,CAAC,gBAAgB;IAaxB,OAAO,CAAC,kBAAkB;YAWZ,gBAAgB;CAgF/B"}
@@ -0,0 +1,224 @@
1
+ import { toHex } from 'viem';
2
+ import { providerError, serializeRpcError } from './errors.js';
3
+ import { buildInjectedProviderScript, emitterName, rpcBridgeName, } from './injected-provider.js';
4
+ const DEFAULT_PROVIDER_INFO = {
5
+ uuid: '00000000-0000-4000-8000-000000000001',
6
+ name: 'Mock Wallet',
7
+ icon: 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect width="64" height="64" rx="14" fill="%23111827"/><path d="M17 34h30v14H17z" fill="%2338bdf8"/><path d="M20 18h24v16H20z" fill="%23f59e0b"/><circle cx="43" cy="41" r="3" fill="%23111827"/></svg>',
8
+ rdns: 'dev.invisible-wallet.mock',
9
+ };
10
+ const defaultAdditionalProviderInfo = (index) => ({
11
+ uuid: `00000000-0000-4000-8000-${String(index + 2).padStart(12, '0')}`,
12
+ name: `Mock Wallet ${index + 2}`,
13
+ icon: DEFAULT_PROVIDER_INFO.icon,
14
+ rdns: `dev.invisible-wallet.mock.${index + 2}`,
15
+ });
16
+ const SIGNING_METHODS = new Set([
17
+ 'eth_sendTransaction',
18
+ 'eth_sign',
19
+ 'eth_signTypedData',
20
+ 'eth_signTypedData_v3',
21
+ 'eth_signTypedData_v4',
22
+ 'personal_sign',
23
+ ]);
24
+ const permissionResponse = [
25
+ {
26
+ parentCapability: 'eth_accounts',
27
+ caveats: [],
28
+ },
29
+ ];
30
+ const normalizeParams = (params) => {
31
+ if (params === undefined) {
32
+ return [];
33
+ }
34
+ if (Array.isArray(params)) {
35
+ return [...params];
36
+ }
37
+ return [params];
38
+ };
39
+ const normalizeChainId = (chainId) => typeof chainId === 'number' ? toHex(chainId) : chainId;
40
+ export class MockWalletController {
41
+ page;
42
+ rpcClient;
43
+ accounts;
44
+ chainId;
45
+ connected;
46
+ approveRequests;
47
+ rejectionQueue = [];
48
+ constructor(page, rpcClient, options) {
49
+ this.page = page;
50
+ this.rpcClient = rpcClient;
51
+ this.accounts = [...options.accounts];
52
+ this.chainId = normalizeChainId(options.chainId);
53
+ this.connected = options.connected ?? true;
54
+ this.approveRequests = options.autoApprove ?? true;
55
+ if (this.accounts.length === 0) {
56
+ throw new Error('MockWalletController requires at least one account.');
57
+ }
58
+ const primaryProviderInfo = {
59
+ ...DEFAULT_PROVIDER_INFO,
60
+ ...options.providerInfo,
61
+ };
62
+ this.providerInfos = [
63
+ primaryProviderInfo,
64
+ ...(options.additionalProviders ?? []).map((provider, index) => ({
65
+ ...defaultAdditionalProviderInfo(index),
66
+ ...provider,
67
+ })),
68
+ ];
69
+ this.providerInfo = primaryProviderInfo;
70
+ }
71
+ providerInfo;
72
+ providerInfos;
73
+ get primaryAccount() {
74
+ return this.accounts[0];
75
+ }
76
+ get currentChainId() {
77
+ return this.chainId;
78
+ }
79
+ async injectMockProvider() {
80
+ await this.page.exposeFunction(rpcBridgeName, async (request) => {
81
+ try {
82
+ const result = await this.handleRpcRequest(request);
83
+ return { ok: true, result };
84
+ }
85
+ catch (error) {
86
+ return { ok: false, error: serializeRpcError(error) };
87
+ }
88
+ });
89
+ const config = {
90
+ accounts: this.accounts,
91
+ autoApprove: this.approveRequests,
92
+ chainId: this.chainId,
93
+ connected: this.connected,
94
+ providers: this.providerInfos,
95
+ };
96
+ const providerScript = buildInjectedProviderScript(config);
97
+ await this.page.addInitScript(providerScript);
98
+ await this.page.evaluate(providerScript);
99
+ }
100
+ autoApprove(enabled = true) {
101
+ this.approveRequests = enabled;
102
+ }
103
+ async simulateRejection(methods = [...SIGNING_METHODS], message = 'User rejected the request.') {
104
+ this.rejectionQueue.push({
105
+ methods: typeof methods === 'string' ? [methods] : methods,
106
+ message,
107
+ });
108
+ }
109
+ async setAccounts(accounts) {
110
+ if (accounts.length === 0) {
111
+ throw new Error('setAccounts requires at least one account. Use disconnect() to expose no accounts.');
112
+ }
113
+ this.accounts = [...accounts];
114
+ this.connected = true;
115
+ await this.emit('accountsChanged', this.accounts);
116
+ }
117
+ async disconnect() {
118
+ this.connected = false;
119
+ await this.emit('accountsChanged', []);
120
+ await this.emit('disconnect', { code: 4900, message: 'Mock wallet disconnected.' });
121
+ }
122
+ async reconnect() {
123
+ this.connected = true;
124
+ await this.emit('connect', { chainId: this.chainId });
125
+ await this.emit('accountsChanged', this.accounts);
126
+ }
127
+ async switchNetwork(chainId) {
128
+ this.chainId = normalizeChainId(chainId);
129
+ await this.emit('chainChanged', this.chainId);
130
+ }
131
+ async emit(event, payload) {
132
+ await this.page.evaluate(({ emitter, eventName, eventPayload }) => {
133
+ const maybeEmitter = window[emitter];
134
+ if (typeof maybeEmitter === 'function') {
135
+ maybeEmitter(eventName, eventPayload);
136
+ }
137
+ }, { emitter: emitterName, eventName: event, eventPayload: payload });
138
+ }
139
+ consumeRejection(method) {
140
+ const index = this.rejectionQueue.findIndex((rule) => !rule.methods || rule.methods.includes(method));
141
+ if (index === -1) {
142
+ return undefined;
143
+ }
144
+ const [rule] = this.rejectionQueue.splice(index, 1);
145
+ return rule;
146
+ }
147
+ assertUserApproved(method) {
148
+ const forcedRejection = this.consumeRejection(method);
149
+ if (forcedRejection) {
150
+ throw providerError(4001, forcedRejection.message ?? 'User rejected the request.');
151
+ }
152
+ if (!this.approveRequests && (SIGNING_METHODS.has(method) || method === 'eth_requestAccounts')) {
153
+ throw providerError(4001, 'User rejected the request.');
154
+ }
155
+ }
156
+ async handleRpcRequest(request) {
157
+ const { method } = request;
158
+ const params = normalizeParams(request.params);
159
+ switch (method) {
160
+ case 'eth_accounts':
161
+ return this.connected ? this.accounts : [];
162
+ case 'eth_requestAccounts':
163
+ this.assertUserApproved(method);
164
+ if (!this.connected) {
165
+ this.connected = true;
166
+ await this.emit('connect', { chainId: this.chainId });
167
+ await this.emit('accountsChanged', this.accounts);
168
+ }
169
+ return this.accounts;
170
+ case 'eth_chainId':
171
+ return this.chainId;
172
+ case 'net_version':
173
+ return String(Number(BigInt(this.chainId)));
174
+ case 'wallet_getPermissions':
175
+ return this.connected ? permissionResponse : [];
176
+ case 'wallet_requestPermissions':
177
+ this.assertUserApproved(method);
178
+ this.connected = true;
179
+ await this.emit('accountsChanged', this.accounts);
180
+ return permissionResponse;
181
+ case 'wallet_switchEthereumChain': {
182
+ this.assertUserApproved(method);
183
+ const requestedChain = params[0];
184
+ if (!requestedChain?.chainId) {
185
+ throw providerError(-32602, 'wallet_switchEthereumChain requires a chainId.');
186
+ }
187
+ await this.switchNetwork(requestedChain.chainId);
188
+ return null;
189
+ }
190
+ case 'wallet_addEthereumChain':
191
+ this.assertUserApproved(method);
192
+ return null;
193
+ case 'wallet_watchAsset':
194
+ this.assertUserApproved(method);
195
+ return true;
196
+ case 'metamask_getProviderState':
197
+ return {
198
+ accounts: this.connected ? this.accounts : [],
199
+ chainId: this.chainId,
200
+ isUnlocked: true,
201
+ networkVersion: String(Number(BigInt(this.chainId))),
202
+ };
203
+ case 'eth_sendTransaction': {
204
+ this.assertUserApproved(method);
205
+ const transaction = { ...params[0] };
206
+ transaction.from ??= this.primaryAccount;
207
+ return this.rpcClient.request({
208
+ method,
209
+ params: [transaction],
210
+ });
211
+ }
212
+ case 'eth_sign':
213
+ case 'eth_signTypedData':
214
+ case 'eth_signTypedData_v3':
215
+ case 'eth_signTypedData_v4':
216
+ case 'personal_sign':
217
+ this.assertUserApproved(method);
218
+ return this.rpcClient.request({ method, params });
219
+ default:
220
+ return this.rpcClient.request({ method, params });
221
+ }
222
+ }
223
+ }
224
+ //# sourceMappingURL=mock-wallet-controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-wallet-controller.js","sourceRoot":"","sources":["../src/mock-wallet-controller.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { type Account, type Chain, type Hex } from 'viem';
2
+ import type { JsonRpcRequest, RpcClient } from './types.js';
3
+ export type PrivateKeyRpcClientOptions = {
4
+ privateKey: Hex;
5
+ chain?: Chain;
6
+ rpcUrl?: string;
7
+ };
8
+ export declare class PrivateKeyRpcClient implements RpcClient {
9
+ readonly account: Account;
10
+ readonly chain: Chain;
11
+ readonly sentTransactions: Hex[];
12
+ readonly sentTransactionRequests: Array<{
13
+ hash: Hex;
14
+ to?: Hex;
15
+ data?: Hex;
16
+ value?: string;
17
+ }>;
18
+ private readonly publicClient;
19
+ private readonly walletClient;
20
+ constructor(options: PrivateKeyRpcClientOptions);
21
+ request(request: JsonRpcRequest): Promise<unknown>;
22
+ }
23
+ //# sourceMappingURL=private-key-rpc-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"private-key-rpc-client.d.ts","sourceRoot":"","sources":["../src/private-key-rpc-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,OAAO,EACZ,KAAK,KAAK,EACV,KAAK,GAAG,EAET,MAAM,MAAM,CAAC;AAGd,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5D,MAAM,MAAM,0BAA0B,GAAG;IACvC,UAAU,EAAE,GAAG,CAAC;IAChB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AA0BF,qBAAa,mBAAoB,YAAW,SAAS;IACnD,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE,CAAM;IACtC,QAAQ,CAAC,uBAAuB,EAAE,KAAK,CAAC;QACtC,IAAI,EAAE,GAAG,CAAC;QACV,EAAE,CAAC,EAAE,GAAG,CAAC;QACT,IAAI,CAAC,EAAE,GAAG,CAAC;QACX,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC,CAAM;IAER,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;IAC9B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;gBAEhC,OAAO,EAAE,0BAA0B;IAgBzC,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;CA8EzD"}
@@ -0,0 +1,112 @@
1
+ import { createPublicClient, createWalletClient, hexToString, http, isAddress, } from 'viem';
2
+ import { privateKeyToAccount } from 'viem/accounts';
3
+ import { sepolia } from 'viem/chains';
4
+ const normalizePrivateKey = (privateKey) => {
5
+ const trimmed = privateKey.trim();
6
+ return trimmed.startsWith('0x') ? trimmed : `0x${trimmed}`;
7
+ };
8
+ const asHex = (value) => typeof value === 'string' && value.startsWith('0x') ? value : undefined;
9
+ const normalizeMessage = (message) => {
10
+ const hex = asHex(message);
11
+ if (!hex) {
12
+ return String(message ?? '');
13
+ }
14
+ try {
15
+ return hexToString(hex);
16
+ }
17
+ catch {
18
+ return { raw: hex };
19
+ }
20
+ };
21
+ const parseParams = (request) => Array.isArray(request.params) ? [...request.params] : [];
22
+ export class PrivateKeyRpcClient {
23
+ account;
24
+ chain;
25
+ sentTransactions = [];
26
+ sentTransactionRequests = [];
27
+ publicClient;
28
+ walletClient;
29
+ constructor(options) {
30
+ this.chain = options.chain ?? sepolia;
31
+ this.account = privateKeyToAccount(normalizePrivateKey(options.privateKey));
32
+ const transport = http(options.rpcUrl);
33
+ this.publicClient = createPublicClient({
34
+ chain: this.chain,
35
+ transport,
36
+ });
37
+ this.walletClient = createWalletClient({
38
+ account: this.account,
39
+ chain: this.chain,
40
+ transport,
41
+ });
42
+ }
43
+ async request(request) {
44
+ const params = parseParams(request);
45
+ switch (request.method) {
46
+ case 'personal_sign': {
47
+ const [first, second] = params;
48
+ const message = typeof first === 'string' && isAddress(first) && second !== undefined
49
+ ? second
50
+ : first;
51
+ return this.walletClient.signMessage({
52
+ account: this.account,
53
+ message: normalizeMessage(message),
54
+ });
55
+ }
56
+ case 'eth_sign': {
57
+ const [, message] = params;
58
+ return this.walletClient.signMessage({
59
+ account: this.account,
60
+ message: normalizeMessage(message),
61
+ });
62
+ }
63
+ case 'eth_signTypedData_v4': {
64
+ const [, typedData] = params;
65
+ const parsed = typeof typedData === 'string'
66
+ ? JSON.parse(typedData)
67
+ : typedData;
68
+ return this.walletClient.signTypedData({
69
+ account: this.account,
70
+ domain: parsed.domain,
71
+ message: parsed.message,
72
+ primaryType: parsed.primaryType,
73
+ types: parsed.types,
74
+ });
75
+ }
76
+ case 'eth_sendTransaction': {
77
+ const [transaction] = params;
78
+ if (!transaction) {
79
+ throw new Error('eth_sendTransaction requires a transaction object.');
80
+ }
81
+ const request = {
82
+ account: this.account,
83
+ chain: this.chain,
84
+ to: transaction.to,
85
+ data: transaction.data,
86
+ value: transaction.value ? BigInt(transaction.value) : undefined,
87
+ gas: transaction.gas ? BigInt(transaction.gas) : undefined,
88
+ gasPrice: transaction.gasPrice ? BigInt(transaction.gasPrice) : undefined,
89
+ nonce: transaction.nonce ? Number(BigInt(transaction.nonce)) : undefined,
90
+ maxFeePerGas: transaction.maxFeePerGas
91
+ ? BigInt(transaction.maxFeePerGas)
92
+ : undefined,
93
+ maxPriorityFeePerGas: transaction.maxPriorityFeePerGas
94
+ ? BigInt(transaction.maxPriorityFeePerGas)
95
+ : undefined,
96
+ };
97
+ const hash = await this.walletClient.sendTransaction(request);
98
+ this.sentTransactions.push(hash);
99
+ this.sentTransactionRequests.push({
100
+ hash,
101
+ to: transaction.to,
102
+ data: transaction.data,
103
+ value: transaction.value ? String(transaction.value) : undefined,
104
+ });
105
+ return hash;
106
+ }
107
+ default:
108
+ return this.publicClient.request(request);
109
+ }
110
+ }
111
+ }
112
+ //# sourceMappingURL=private-key-rpc-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"private-key-rpc-client.js","sourceRoot":"","sources":["../src/private-key-rpc-client.ts"],"names":[],"mappings":"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"}