@marigoldlabs/web3-tester 0.1.2 → 0.4.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.
Files changed (75) hide show
  1. package/.env.example +26 -17
  2. package/LICENSE +21 -0
  3. package/README.md +167 -41
  4. package/dist/anvil.d.ts +90 -2
  5. package/dist/anvil.d.ts.map +1 -1
  6. package/dist/anvil.js +215 -13
  7. package/dist/anvil.js.map +1 -1
  8. package/dist/contracts/test-erc20.d.ts +227 -0
  9. package/dist/contracts/test-erc20.d.ts.map +1 -0
  10. package/dist/contracts/test-erc20.js +8 -0
  11. package/dist/contracts/test-erc20.js.map +1 -0
  12. package/dist/erc20.d.ts +38 -0
  13. package/dist/erc20.d.ts.map +1 -0
  14. package/dist/erc20.js +229 -0
  15. package/dist/erc20.js.map +1 -0
  16. package/dist/fixtures.d.ts +44 -2
  17. package/dist/fixtures.d.ts.map +1 -1
  18. package/dist/fixtures.js +162 -17
  19. package/dist/fixtures.js.map +1 -1
  20. package/dist/index.d.ts +17 -5
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +7 -1
  23. package/dist/index.js.map +1 -1
  24. package/dist/injected-provider.d.ts.map +1 -1
  25. package/dist/injected-provider.js +142 -79
  26. package/dist/injected-provider.js.map +1 -1
  27. package/dist/live-fixtures.d.ts +32 -3
  28. package/dist/live-fixtures.d.ts.map +1 -1
  29. package/dist/live-fixtures.js +64 -27
  30. package/dist/live-fixtures.js.map +1 -1
  31. package/dist/matchers.d.ts +90 -0
  32. package/dist/matchers.d.ts.map +1 -0
  33. package/dist/matchers.js +268 -0
  34. package/dist/matchers.js.map +1 -0
  35. package/dist/metamask-extension.d.ts +34 -0
  36. package/dist/metamask-extension.d.ts.map +1 -0
  37. package/dist/metamask-extension.js +97 -0
  38. package/dist/metamask-extension.js.map +1 -0
  39. package/dist/mock-wallet-controller.d.ts +205 -3
  40. package/dist/mock-wallet-controller.d.ts.map +1 -1
  41. package/dist/mock-wallet-controller.js +843 -46
  42. package/dist/mock-wallet-controller.js.map +1 -1
  43. package/dist/private-key-rpc-client.d.ts +1730 -0
  44. package/dist/private-key-rpc-client.d.ts.map +1 -1
  45. package/dist/private-key-rpc-client.js +105 -12
  46. package/dist/private-key-rpc-client.js.map +1 -1
  47. package/dist/real-wallet-cache.d.ts +65 -0
  48. package/dist/real-wallet-cache.d.ts.map +1 -0
  49. package/dist/real-wallet-cache.js +245 -0
  50. package/dist/real-wallet-cache.js.map +1 -0
  51. package/dist/real-wallet-fixtures.d.ts +52 -0
  52. package/dist/real-wallet-fixtures.d.ts.map +1 -0
  53. package/dist/real-wallet-fixtures.js +73 -0
  54. package/dist/real-wallet-fixtures.js.map +1 -0
  55. package/dist/real-wallet.d.ts +123 -14
  56. package/dist/real-wallet.d.ts.map +1 -1
  57. package/dist/real-wallet.js +1336 -57
  58. package/dist/real-wallet.js.map +1 -1
  59. package/dist/transactions.d.ts +118 -0
  60. package/dist/transactions.d.ts.map +1 -0
  61. package/dist/transactions.js +207 -0
  62. package/dist/transactions.js.map +1 -0
  63. package/dist/types.d.ts +1 -0
  64. package/dist/types.d.ts.map +1 -1
  65. package/dist/walletconnect.d.ts +206 -0
  66. package/dist/walletconnect.d.ts.map +1 -0
  67. package/dist/walletconnect.js +359 -0
  68. package/dist/walletconnect.js.map +1 -0
  69. package/examples/live-sepolia.spec.ts +20 -1
  70. package/package.json +62 -6
  71. package/docs/API.md +0 -223
  72. package/docs/ARCHITECTURE.md +0 -81
  73. package/docs/CONSUMING_FROM_FJORD.md +0 -123
  74. package/docs/FJORD_LIVE_QA.md +0 -87
  75. package/docs/RELEASE_CHECKLIST.md +0 -55
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AACzC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,MAAM,aAAa,GAAG,SAAS,OAAO,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;AAErF,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAC/B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GAC7B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,mBAAmB,CAAA;CAAE,CAAC;AAE9C,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACxD,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,OAAO,OAAO,CAAC;AAExC,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAC;IAC7B,OAAO,EAAE,GAAG,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,SAAS,kBAAkB,EAAE,CAAC;CAC1C,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,KAAK,GAAG;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AACzC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,MAAM,aAAa,GAAG,SAAS,OAAO,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;AAErF,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAC/B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GAC7B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,mBAAmB,CAAA;CAAE,CAAC;AAE9C,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACxD,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,OAAO,OAAO,CAAC;AAExC,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAC;IAC7B,OAAO,EAAE,GAAG,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACzC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,KAAK,GAAG;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC"}
@@ -0,0 +1,206 @@
1
+ import type { Page } from '@playwright/test';
2
+ import { type Hex } from 'viem';
3
+ import type { MockWalletController } from './mock-wallet-controller.js';
4
+ export type WalletConnectMetadata = {
5
+ name: string;
6
+ description: string;
7
+ url: string;
8
+ icons: string[];
9
+ };
10
+ /** Structural IKeyValueStorage (getKeys/getEntries/getItem/setItem/removeItem). */
11
+ export type WalletConnectStorage = {
12
+ getKeys(): Promise<string[]>;
13
+ getEntries<T = unknown>(): Promise<[string, T][]>;
14
+ getItem<T = unknown>(key: string): Promise<T | undefined>;
15
+ setItem<T = unknown>(key: string, value: T): Promise<void>;
16
+ removeItem(key: string): Promise<void>;
17
+ };
18
+ /** The slice of SignClient this module drives — the raw client is exposed as an escape hatch. */
19
+ export type WalletConnectSignClient = {
20
+ on(event: string, handler: (payload: never) => void): unknown;
21
+ off?(event: string, handler: (payload: never) => void): unknown;
22
+ removeListener?(event: string, handler: (payload: never) => void): unknown;
23
+ pair(args: {
24
+ uri: string;
25
+ }): Promise<unknown>;
26
+ approve(args: {
27
+ id: number;
28
+ namespaces: Record<string, unknown>;
29
+ }): Promise<{
30
+ topic: string;
31
+ acknowledged: () => Promise<{
32
+ namespaces?: Record<string, unknown>;
33
+ } | undefined>;
34
+ }>;
35
+ reject(args: {
36
+ id: number;
37
+ reason: unknown;
38
+ }): Promise<void>;
39
+ respond(args: {
40
+ topic: string;
41
+ response: unknown;
42
+ }): Promise<void>;
43
+ emit(args: {
44
+ topic: string;
45
+ event: {
46
+ name: string;
47
+ data: unknown;
48
+ };
49
+ chainId: string;
50
+ }): Promise<void>;
51
+ update(args: {
52
+ topic: string;
53
+ namespaces: Record<string, unknown>;
54
+ }): Promise<unknown>;
55
+ disconnect(args: {
56
+ topic: string;
57
+ reason: unknown;
58
+ }): Promise<void>;
59
+ core?: {
60
+ relayer?: {
61
+ transportClose?: () => Promise<void>;
62
+ };
63
+ heartbeat?: {
64
+ stop?: () => void;
65
+ };
66
+ };
67
+ };
68
+ export type WalletConnectWalletOptions = {
69
+ /**
70
+ * The mock/live controller. EVERY session proposal and session_request
71
+ * dispatches through its approval gating and transaction recording —
72
+ * approveNext/autoApprove/holdNextRequest/simulateRejection govern WC
73
+ * traffic exactly like injected traffic.
74
+ */
75
+ wallet: MockWalletController;
76
+ /** Reown dashboard project id (the public relay requires one). */
77
+ projectId: string;
78
+ /** Defaults to the SDK default (wss://relay.walletconnect.org). */
79
+ relayUrl?: string;
80
+ /** Chains offered in the approved eip155 namespace. Default: [wallet.currentChainId]. */
81
+ chains?: readonly (number | Hex)[];
82
+ /** Namespace methods. Default: DEFAULT_WALLETCONNECT_METHODS. */
83
+ methods?: readonly string[];
84
+ /** Namespace events. Default: ['chainChanged', 'accountsChanged']. */
85
+ events?: readonly string[];
86
+ /** Peer metadata shown in the dapp UI. */
87
+ metadata?: Partial<WalletConnectMetadata>;
88
+ /**
89
+ * Enforce the controller's allowedOrigins against the relay's
90
+ * verifyContext origin. Default true. Note: when Verify reports
91
+ * validation 'UNKNOWN' the origin derives from unattested proposer
92
+ * metadata — a hostile dapp can spoof it, so origin scoping over WC is
93
+ * weaker than the injected bridge. false dispatches with the controller's
94
+ * bypassOriginCheck opt-out (approval gating still applies).
95
+ */
96
+ enforceOrigins?: boolean;
97
+ /** SignClient storage override. Default: SDK in-memory (nothing on disk). */
98
+ storage?: WalletConnectStorage;
99
+ };
100
+ export type WalletConnectSession = {
101
+ topic: string;
102
+ namespaces: Record<string, unknown>;
103
+ peerMetadata: WalletConnectMetadata;
104
+ };
105
+ export type GetUriOptions = {
106
+ /** Default 15_000. */
107
+ timeoutMs?: number;
108
+ /** Default 'wui-qr-code' (AppKit's QR element; its uri attribute is what Reown's own E2E suite reads). */
109
+ selector?: string;
110
+ };
111
+ export declare const DEFAULT_WALLETCONNECT_METHODS: readonly string[];
112
+ /** @internal Test hook: stub the dynamic importer; call with no args to restore. */
113
+ export declare const __setWalletConnectModuleLoader: (loader?: (specifier: string) => Promise<unknown>) => void;
114
+ export type SessionRequestEvent = {
115
+ id: number;
116
+ topic: string;
117
+ params: {
118
+ request: {
119
+ method: string;
120
+ params?: unknown;
121
+ };
122
+ chainId: string;
123
+ };
124
+ verifyContext?: {
125
+ verified?: {
126
+ origin?: string;
127
+ validation?: string;
128
+ };
129
+ };
130
+ };
131
+ export type SessionRequestResponse = {
132
+ id: number;
133
+ jsonrpc: '2.0';
134
+ result?: unknown;
135
+ error?: {
136
+ code: number;
137
+ message: string;
138
+ data?: string;
139
+ };
140
+ };
141
+ /**
142
+ * The session_request loop, exported for hermetic tests: validates the CAIP
143
+ * chain against the approved set, switches the wallet when an approved
144
+ * non-active chain is requested (single-active-chain semantics, like a
145
+ * mobile wallet), and dispatches through the controller's gating. Errors map
146
+ * through serializeRpcError, so 4001/4100/4200/4902/-32602 cross the relay
147
+ * verbatim.
148
+ */
149
+ export declare const createSessionRequestHandler: (wallet: MockWalletController, config: {
150
+ chains: readonly Hex[];
151
+ enforceOrigins: boolean;
152
+ }, respond: (topic: string, response: SessionRequestResponse) => Promise<void>) => ((event: SessionRequestEvent) => Promise<void>);
153
+ /**
154
+ * Polls the AppKit/W3M modal for the pairing URI: Playwright CSS locators
155
+ * pierce the shadow DOM, and AppKit's w3m-connecting-wc-qrcode renders
156
+ * `<wui-qr-code uri=...>` as a real DOM attribute (the same contract
157
+ * Reown's own laboratory tests read). For non-AppKit modals pass a
158
+ * `selector` or use the connect() `getUri` hook.
159
+ */
160
+ export declare function getWalletConnectUri(page: Page, options?: GetUriOptions): Promise<string>;
161
+ export declare class WalletConnectWallet {
162
+ /** Underlying SignClient — escape hatch for protocol-level access. */
163
+ readonly client: WalletConnectSignClient;
164
+ private readonly wallet;
165
+ private readonly utils;
166
+ private chains;
167
+ private readonly methods;
168
+ private readonly events;
169
+ private readonly enforceOrigins;
170
+ private readonly sessionList;
171
+ private readonly requestHandler;
172
+ private readonly deleteHandler;
173
+ private readonly unsubscribeProviderEvents;
174
+ private closed;
175
+ private constructor();
176
+ /**
177
+ * Async factory: dynamically imports the optional peers and throws an
178
+ * install hint when they are missing.
179
+ */
180
+ static create(options: WalletConnectWalletOptions): Promise<WalletConnectWallet>;
181
+ get sessions(): readonly WalletConnectSession[];
182
+ /**
183
+ * Pairs with a wc: URI, gates the session proposal through the controller
184
+ * (as a synthetic eth_requestAccounts — approveNext('eth_requestAccounts')
185
+ * arms it; the match callback receives the proposal payload), builds the
186
+ * approved namespaces, and settles the session.
187
+ */
188
+ pair(options: {
189
+ uri: string;
190
+ timeoutMs?: number;
191
+ }): Promise<WalletConnectSession>;
192
+ /** Convenience: extract the URI from the dapp's modal, then pair(). */
193
+ connect(page: Page, options?: GetUriOptions & {
194
+ getUri?: (page: Page) => Promise<string>;
195
+ }): Promise<WalletConnectSession>;
196
+ /** Wallet-initiated disconnect; all sessions when topic is omitted. */
197
+ disconnect(topic?: string): Promise<void>;
198
+ /**
199
+ * Best-effort teardown: disconnect sessions (5s cap), unsubscribe the
200
+ * controller listener, close the relay transport, stop the heartbeat.
201
+ * Always call in finally / fixture teardown.
202
+ */
203
+ close(): Promise<void>;
204
+ private forwardProviderEvent;
205
+ }
206
+ //# sourceMappingURL=walletconnect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"walletconnect.d.ts","sourceRoot":"","sources":["../src/walletconnect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,359 @@
1
+ import { toHex } from 'viem';
2
+ import { serializeRpcError } from './errors.js';
3
+ export const DEFAULT_WALLETCONNECT_METHODS = [
4
+ 'eth_sendTransaction',
5
+ 'eth_sendRawTransaction',
6
+ 'personal_sign',
7
+ 'eth_sign',
8
+ 'eth_signTypedData',
9
+ 'eth_signTypedData_v3',
10
+ 'eth_signTypedData_v4',
11
+ 'eth_accounts',
12
+ 'eth_requestAccounts',
13
+ 'eth_chainId',
14
+ 'wallet_switchEthereumChain',
15
+ 'wallet_addEthereumChain',
16
+ 'wallet_getPermissions',
17
+ 'wallet_requestPermissions',
18
+ 'wallet_watchAsset',
19
+ ];
20
+ const DEFAULT_EVENTS = ['chainChanged', 'accountsChanged'];
21
+ // Injectable so the missing-optional-peer hint is hermetically testable
22
+ // (the peers are devDependencies here, so they always resolve in-repo).
23
+ let loadModule = (specifier) => import(specifier);
24
+ /** @internal Test hook: stub the dynamic importer; call with no args to restore. */
25
+ export const __setWalletConnectModuleLoader = (loader) => {
26
+ loadModule = loader ?? ((specifier) => import(specifier));
27
+ };
28
+ const parseCaipChainId = (caip) => {
29
+ const match = typeof caip === 'string' ? /^eip155:(\d+)$/.exec(caip) : null;
30
+ return match ? toHex(BigInt(match[1])) : undefined;
31
+ };
32
+ const toCaipChainId = (chainId) => `eip155:${Number(BigInt(chainId))}`;
33
+ /**
34
+ * The session_request loop, exported for hermetic tests: validates the CAIP
35
+ * chain against the approved set, switches the wallet when an approved
36
+ * non-active chain is requested (single-active-chain semantics, like a
37
+ * mobile wallet), and dispatches through the controller's gating. Errors map
38
+ * through serializeRpcError, so 4001/4100/4200/4902/-32602 cross the relay
39
+ * verbatim.
40
+ */
41
+ export const createSessionRequestHandler = (wallet, config, respond) => {
42
+ return async (event) => {
43
+ const { id, topic, params, verifyContext } = event;
44
+ try {
45
+ const chainId = parseCaipChainId(params.chainId);
46
+ if (!chainId || !config.chains.includes(chainId)) {
47
+ await respond(topic, {
48
+ id,
49
+ jsonrpc: '2.0',
50
+ error: { code: 5100, message: 'Requested chain is not approved for this session.' },
51
+ });
52
+ return;
53
+ }
54
+ if (chainId !== wallet.currentChainId) {
55
+ await wallet.switchNetwork(chainId);
56
+ }
57
+ const result = await wallet.handleExternalRequest({ method: params.request.method, params: params.request.params }, config.enforceOrigins
58
+ ? { origin: verifyContext?.verified?.origin }
59
+ : { bypassOriginCheck: true });
60
+ await respond(topic, { id, jsonrpc: '2.0', result });
61
+ }
62
+ catch (error) {
63
+ const serialized = serializeRpcError(error);
64
+ await respond(topic, {
65
+ id,
66
+ jsonrpc: '2.0',
67
+ error: {
68
+ code: serialized.code,
69
+ message: serialized.message,
70
+ ...(typeof serialized.data === 'string' ? { data: serialized.data } : {}),
71
+ },
72
+ });
73
+ }
74
+ };
75
+ };
76
+ /**
77
+ * Polls the AppKit/W3M modal for the pairing URI: Playwright CSS locators
78
+ * pierce the shadow DOM, and AppKit's w3m-connecting-wc-qrcode renders
79
+ * `<wui-qr-code uri=...>` as a real DOM attribute (the same contract
80
+ * Reown's own laboratory tests read). For non-AppKit modals pass a
81
+ * `selector` or use the connect() `getUri` hook.
82
+ */
83
+ export async function getWalletConnectUri(page, options = {}) {
84
+ const timeoutMs = options.timeoutMs ?? 15_000;
85
+ const selector = options.selector ?? 'wui-qr-code';
86
+ const deadline = Date.now() + timeoutMs;
87
+ while (Date.now() < deadline) {
88
+ // Bounded per attempt: getAttribute would otherwise auto-wait for the
89
+ // element with Playwright's default timeout.
90
+ const uri = await page
91
+ .locator(selector)
92
+ .first()
93
+ .getAttribute('uri', { timeout: 250 })
94
+ .catch(() => null);
95
+ if (uri?.startsWith('wc:')) {
96
+ return uri;
97
+ }
98
+ await new Promise((resolve) => setTimeout(resolve, 100));
99
+ }
100
+ throw new Error(`Timed out after ${timeoutMs}ms waiting for a wc: pairing URI on "${selector}". ` +
101
+ 'For non-AppKit modals pass { selector } or supply a getUri(page) hook to connect().');
102
+ }
103
+ export class WalletConnectWallet {
104
+ /** Underlying SignClient — escape hatch for protocol-level access. */
105
+ client;
106
+ wallet;
107
+ utils;
108
+ chains;
109
+ methods;
110
+ events;
111
+ enforceOrigins;
112
+ sessionList = [];
113
+ requestHandler;
114
+ deleteHandler;
115
+ unsubscribeProviderEvents;
116
+ closed = false;
117
+ constructor(client, utils, options) {
118
+ this.client = client;
119
+ this.utils = utils;
120
+ this.wallet = options.wallet;
121
+ this.chains = (options.chains ?? [options.wallet.currentChainId]).map((chainId) => toHex(typeof chainId === 'number' ? chainId : BigInt(chainId)));
122
+ this.methods = options.methods ?? DEFAULT_WALLETCONNECT_METHODS;
123
+ this.events = options.events ?? DEFAULT_EVENTS;
124
+ this.enforceOrigins = options.enforceOrigins ?? true;
125
+ // INVARIANT: never register a 'session_authenticate' listener. With zero
126
+ // listeners, sign-client routes One-Click Auth (SIWE) dapps through the
127
+ // wc_sessionPropose fallback — a plain session plus personal_sign —
128
+ // which this wallet handles. Subscribing would suppress that fallback.
129
+ this.requestHandler = createSessionRequestHandler(this.wallet, { chains: this.chains, enforceOrigins: this.enforceOrigins }, (topic, response) => this.client.respond({ topic, response }));
130
+ client.on('session_request', this.requestHandler);
131
+ this.deleteHandler = ({ topic }) => {
132
+ const index = this.sessionList.findIndex((session) => session.topic === topic);
133
+ if (index !== -1) {
134
+ this.sessionList.splice(index, 1);
135
+ }
136
+ };
137
+ client.on('session_delete', this.deleteHandler);
138
+ this.unsubscribeProviderEvents = this.wallet.onProviderEvent((event, payload) => {
139
+ void this.forwardProviderEvent(event, payload);
140
+ });
141
+ }
142
+ /**
143
+ * Async factory: dynamically imports the optional peers and throws an
144
+ * install hint when they are missing.
145
+ */
146
+ static async create(options) {
147
+ let signClientModule;
148
+ let utils;
149
+ try {
150
+ signClientModule = (await loadModule('@walletconnect/sign-client'));
151
+ utils = (await loadModule('@walletconnect/utils'));
152
+ }
153
+ catch (error) {
154
+ throw new Error("The './walletconnect' module requires optional peer dependencies. " +
155
+ 'Install with: npm i -D @walletconnect/sign-client @walletconnect/utils @walletconnect/types', { cause: error });
156
+ }
157
+ const SignClient = (signClientModule.SignClient ??
158
+ signClientModule.default ??
159
+ signClientModule);
160
+ const client = await SignClient.init({
161
+ projectId: options.projectId,
162
+ ...(options.relayUrl ? { relayUrl: options.relayUrl } : {}),
163
+ metadata: {
164
+ name: 'web3-tester Wallet',
165
+ description: 'Headless WalletConnect wallet for E2E tests',
166
+ url: 'https://github.com/AndyMarigoldLabs/web3-tester',
167
+ icons: [],
168
+ ...options.metadata,
169
+ },
170
+ // A request parked by holdNextRequest must not starve delivery of
171
+ // subsequent session_requests (sign-client serializes them by default).
172
+ signConfig: { disableRequestQueue: true },
173
+ // Nothing touches disk: the SDK default would persist ./walletconnect.db.
174
+ ...(options.storage ? { storage: options.storage } : { storageOptions: { database: ':memory:' } }),
175
+ });
176
+ return new WalletConnectWallet(client, utils, options);
177
+ }
178
+ get sessions() {
179
+ return [...this.sessionList];
180
+ }
181
+ /**
182
+ * Pairs with a wc: URI, gates the session proposal through the controller
183
+ * (as a synthetic eth_requestAccounts — approveNext('eth_requestAccounts')
184
+ * arms it; the match callback receives the proposal payload), builds the
185
+ * approved namespaces, and settles the session.
186
+ */
187
+ async pair(options) {
188
+ const timeoutMs = options.timeoutMs ?? 30_000;
189
+ const { topic: pairingTopic } = this.utils.parseUri(options.uri);
190
+ const proposal = await new Promise((resolve, reject) => {
191
+ const cleanup = () => {
192
+ clearTimeout(timer);
193
+ (this.client.off ?? this.client.removeListener)?.call(this.client, 'session_proposal', handler);
194
+ };
195
+ const timer = setTimeout(() => {
196
+ cleanup();
197
+ reject(new Error(`Timed out after ${timeoutMs}ms waiting for the session proposal.`));
198
+ }, timeoutMs);
199
+ const handler = (event) => {
200
+ if (event.params?.pairingTopic && event.params.pairingTopic !== pairingTopic) {
201
+ return;
202
+ }
203
+ cleanup();
204
+ resolve(event);
205
+ };
206
+ this.client.on('session_proposal', handler);
207
+ this.client.pair({ uri: options.uri }).catch((error) => {
208
+ cleanup();
209
+ reject(error instanceof Error ? error : new Error(String(error)));
210
+ });
211
+ });
212
+ // Gate the connect through the controller. Deny-by-default live mode,
213
+ // simulateRejection, and holds all apply with zero new machinery.
214
+ let accounts;
215
+ try {
216
+ accounts = (await this.wallet.handleExternalRequest({
217
+ method: 'eth_requestAccounts',
218
+ params: [
219
+ {
220
+ origin: proposal.verifyContext?.verified?.origin,
221
+ proposer: proposal.params?.proposer?.metadata,
222
+ requiredNamespaces: proposal.params?.requiredNamespaces,
223
+ optionalNamespaces: proposal.params?.optionalNamespaces,
224
+ },
225
+ ],
226
+ }, this.enforceOrigins
227
+ ? { origin: proposal.verifyContext?.verified?.origin }
228
+ : { bypassOriginCheck: true }));
229
+ }
230
+ catch (error) {
231
+ await this.client
232
+ .reject({ id: proposal.id, reason: this.utils.getSdkError('USER_REJECTED') })
233
+ .catch(() => undefined);
234
+ throw error;
235
+ }
236
+ let namespaces;
237
+ try {
238
+ namespaces = this.utils.buildApprovedNamespaces({
239
+ proposal: proposal.params,
240
+ supportedNamespaces: {
241
+ eip155: {
242
+ chains: this.chains.map(toCaipChainId),
243
+ methods: [...this.methods],
244
+ events: [...this.events],
245
+ accounts: this.chains.flatMap((chainId) => accounts.map((account) => `${toCaipChainId(chainId)}:${account}`)),
246
+ },
247
+ },
248
+ });
249
+ }
250
+ catch (error) {
251
+ await this.client
252
+ .reject({ id: proposal.id, reason: this.utils.getSdkError('UNSUPPORTED_CHAINS') })
253
+ .catch(() => undefined);
254
+ throw new Error("Could not satisfy the dapp's requested namespaces — pass the chains it needs in " +
255
+ `WalletConnectWalletOptions.chains. ${error instanceof Error ? error.message : String(error)}`, { cause: error });
256
+ }
257
+ const { topic, acknowledged } = await this.client.approve({ id: proposal.id, namespaces });
258
+ const settled = await acknowledged();
259
+ const session = {
260
+ topic,
261
+ namespaces: settled?.namespaces ?? namespaces,
262
+ peerMetadata: proposal.params?.proposer?.metadata ??
263
+ { name: '', description: '', url: '', icons: [] },
264
+ };
265
+ this.sessionList.push(session);
266
+ return session;
267
+ }
268
+ /** Convenience: extract the URI from the dapp's modal, then pair(). */
269
+ async connect(page, options = {}) {
270
+ const uri = options.getUri ? await options.getUri(page) : await getWalletConnectUri(page, options);
271
+ return this.pair({ uri, timeoutMs: options.timeoutMs });
272
+ }
273
+ /** Wallet-initiated disconnect; all sessions when topic is omitted. */
274
+ async disconnect(topic) {
275
+ const targets = this.sessionList.filter((session) => !topic || session.topic === topic);
276
+ for (const session of targets) {
277
+ await this.client
278
+ .disconnect({ topic: session.topic, reason: this.utils.getSdkError('USER_DISCONNECTED') })
279
+ .catch(() => undefined);
280
+ this.deleteHandler({ topic: session.topic });
281
+ }
282
+ }
283
+ /**
284
+ * Best-effort teardown: disconnect sessions (5s cap), unsubscribe the
285
+ * controller listener, close the relay transport, stop the heartbeat.
286
+ * Always call in finally / fixture teardown.
287
+ */
288
+ async close() {
289
+ if (this.closed) {
290
+ return;
291
+ }
292
+ this.closed = true;
293
+ await Promise.race([
294
+ this.disconnect(),
295
+ new Promise((resolve) => setTimeout(resolve, 5_000)),
296
+ ]).catch(() => undefined);
297
+ this.unsubscribeProviderEvents();
298
+ (this.client.off ?? this.client.removeListener)?.call(this.client, 'session_request', this.requestHandler);
299
+ (this.client.off ?? this.client.removeListener)?.call(this.client, 'session_delete', this.deleteHandler);
300
+ await this.client.core?.relayer?.transportClose?.().catch(() => undefined);
301
+ this.client.core?.heartbeat?.stop?.();
302
+ }
303
+ // Relay round-trips happen here, OFF the controller's await path — the
304
+ // onProviderEvent dispatch is fire-and-forget, so a dead relay can never
305
+ // hang wallet.switchNetwork()/disconnect().
306
+ async forwardProviderEvent(event, payload) {
307
+ for (const session of [...this.sessionList]) {
308
+ try {
309
+ if (event === 'chainChanged') {
310
+ const chainId = payload;
311
+ if (!this.chains.includes(chainId)) {
312
+ // Extend the session namespace first (MetaMask-mobile behavior).
313
+ this.chains = [...this.chains, chainId];
314
+ const namespaces = session.namespaces;
315
+ const eip155 = namespaces.eip155;
316
+ if (eip155) {
317
+ const caip = toCaipChainId(chainId);
318
+ const extended = {
319
+ ...namespaces,
320
+ eip155: {
321
+ ...eip155,
322
+ chains: [...(eip155.chains ?? []), caip],
323
+ accounts: [
324
+ ...(eip155.accounts ?? []),
325
+ ...this.wallet.currentAccounts.map((account) => `${caip}:${account}`),
326
+ ],
327
+ },
328
+ };
329
+ await this.client.update({ topic: session.topic, namespaces: extended });
330
+ session.namespaces = extended;
331
+ }
332
+ }
333
+ await this.client.emit({
334
+ topic: session.topic,
335
+ event: { name: 'chainChanged', data: Number(BigInt(chainId)) },
336
+ chainId: toCaipChainId(chainId),
337
+ });
338
+ }
339
+ else if (event === 'accountsChanged') {
340
+ await this.client.emit({
341
+ topic: session.topic,
342
+ event: { name: 'accountsChanged', data: payload },
343
+ chainId: toCaipChainId(this.wallet.currentChainId),
344
+ });
345
+ }
346
+ else if (event === 'disconnect') {
347
+ await this.client
348
+ .disconnect({ topic: session.topic, reason: this.utils.getSdkError('USER_DISCONNECTED') })
349
+ .catch(() => undefined);
350
+ this.deleteHandler({ topic: session.topic });
351
+ }
352
+ }
353
+ catch {
354
+ // Relay errors must never break wallet state transitions.
355
+ }
356
+ }
357
+ }
358
+ }
359
+ //# sourceMappingURL=walletconnect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"walletconnect.js","sourceRoot":"","sources":["../src/walletconnect.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,9 @@
1
1
  import { expect, test } from '@marigoldlabs/web3-tester/live-fixtures';
2
2
 
3
- test.skip(!process.env.FJORD_PRIVATE_KEY, 'FJORD_PRIVATE_KEY is required for live Sepolia tests.');
3
+ test.skip(
4
+ !process.env.WEB3_TESTER_PRIVATE_KEY,
5
+ 'WEB3_TESTER_PRIVATE_KEY is required for live Sepolia tests.',
6
+ );
4
7
 
5
8
  type EthereumProvider = {
6
9
  request: (args: { method: string; params?: unknown[] }) => Promise<unknown>;
@@ -19,3 +22,19 @@ test('loads a live Sepolia wallet', async ({ page, wallet }) => {
19
22
  )
20
23
  .toEqual([wallet.primaryAccount]);
21
24
  });
25
+
26
+ test('signs only after the test arms the request (deny-by-default)', async ({ page, wallet }) => {
27
+ await page.goto('/');
28
+
29
+ // Live wallets refuse signing until armed; arm exactly one personal_sign.
30
+ wallet.approveNext('personal_sign');
31
+
32
+ const signature = await page.evaluate(async () =>
33
+ (window as typeof window & { ethereum: EthereumProvider }).ethereum.request({
34
+ method: 'personal_sign',
35
+ params: ['0x68656c6c6f', null],
36
+ }),
37
+ );
38
+
39
+ expect(String(signature)).toMatch(/^0x/);
40
+ });