@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.
- package/.env.example +26 -17
- package/LICENSE +21 -0
- package/README.md +167 -41
- package/dist/anvil.d.ts +90 -2
- package/dist/anvil.d.ts.map +1 -1
- package/dist/anvil.js +215 -13
- package/dist/anvil.js.map +1 -1
- package/dist/contracts/test-erc20.d.ts +227 -0
- package/dist/contracts/test-erc20.d.ts.map +1 -0
- package/dist/contracts/test-erc20.js +8 -0
- package/dist/contracts/test-erc20.js.map +1 -0
- package/dist/erc20.d.ts +38 -0
- package/dist/erc20.d.ts.map +1 -0
- package/dist/erc20.js +229 -0
- package/dist/erc20.js.map +1 -0
- package/dist/fixtures.d.ts +44 -2
- package/dist/fixtures.d.ts.map +1 -1
- package/dist/fixtures.js +162 -17
- package/dist/fixtures.js.map +1 -1
- package/dist/index.d.ts +17 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/injected-provider.d.ts.map +1 -1
- package/dist/injected-provider.js +142 -79
- package/dist/injected-provider.js.map +1 -1
- package/dist/live-fixtures.d.ts +32 -3
- package/dist/live-fixtures.d.ts.map +1 -1
- package/dist/live-fixtures.js +64 -27
- package/dist/live-fixtures.js.map +1 -1
- package/dist/matchers.d.ts +90 -0
- package/dist/matchers.d.ts.map +1 -0
- package/dist/matchers.js +268 -0
- package/dist/matchers.js.map +1 -0
- package/dist/metamask-extension.d.ts +34 -0
- package/dist/metamask-extension.d.ts.map +1 -0
- package/dist/metamask-extension.js +97 -0
- package/dist/metamask-extension.js.map +1 -0
- package/dist/mock-wallet-controller.d.ts +205 -3
- package/dist/mock-wallet-controller.d.ts.map +1 -1
- package/dist/mock-wallet-controller.js +843 -46
- package/dist/mock-wallet-controller.js.map +1 -1
- package/dist/private-key-rpc-client.d.ts +1730 -0
- package/dist/private-key-rpc-client.d.ts.map +1 -1
- package/dist/private-key-rpc-client.js +105 -12
- package/dist/private-key-rpc-client.js.map +1 -1
- package/dist/real-wallet-cache.d.ts +65 -0
- package/dist/real-wallet-cache.d.ts.map +1 -0
- package/dist/real-wallet-cache.js +245 -0
- package/dist/real-wallet-cache.js.map +1 -0
- package/dist/real-wallet-fixtures.d.ts +52 -0
- package/dist/real-wallet-fixtures.d.ts.map +1 -0
- package/dist/real-wallet-fixtures.js +73 -0
- package/dist/real-wallet-fixtures.js.map +1 -0
- package/dist/real-wallet.d.ts +123 -14
- package/dist/real-wallet.d.ts.map +1 -1
- package/dist/real-wallet.js +1336 -57
- package/dist/real-wallet.js.map +1 -1
- package/dist/transactions.d.ts +118 -0
- package/dist/transactions.d.ts.map +1 -0
- package/dist/transactions.js +207 -0
- package/dist/transactions.js.map +1 -0
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/walletconnect.d.ts +206 -0
- package/dist/walletconnect.d.ts.map +1 -0
- package/dist/walletconnect.js +359 -0
- package/dist/walletconnect.js.map +1 -0
- package/examples/live-sepolia.spec.ts +20 -1
- package/package.json +62 -6
- package/docs/API.md +0 -223
- package/docs/ARCHITECTURE.md +0 -81
- package/docs/CONSUMING_FROM_FJORD.md +0 -123
- package/docs/FJORD_LIVE_QA.md +0 -87
- package/docs/RELEASE_CHECKLIST.md +0 -55
package/dist/erc20.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type Address } from 'viem';
|
|
2
|
+
import type { RpcClient } from './types.js';
|
|
3
|
+
export { TEST_ERC20_ABI, TEST_ERC20_BYTECODE, TEST_ERC20_SOLC_VERSION, TEST_ERC20_SOURCE_SHA256, } from './contracts/test-erc20.js';
|
|
4
|
+
export type Erc20StorageLayout = 'solidity' | 'vyper';
|
|
5
|
+
export type Erc20SlotInfo = {
|
|
6
|
+
layout: Erc20StorageLayout;
|
|
7
|
+
/** Mapping base slot: a small integer, or an ERC-7201 namespace root. */
|
|
8
|
+
balanceSlot: bigint;
|
|
9
|
+
/** Discovered lazily on first adjustTotalSupply use. */
|
|
10
|
+
totalSupplySlot?: bigint;
|
|
11
|
+
};
|
|
12
|
+
export type DealErc20Options = {
|
|
13
|
+
/** forge-std deal(token,to,give,adjust) parity: shift totalSupply by the balance delta. Default false. */
|
|
14
|
+
adjustTotalSupply?: boolean;
|
|
15
|
+
/** Highest integer mapping base slot probed per layout. Default 64. */
|
|
16
|
+
maxSlot?: number;
|
|
17
|
+
/** Skip discovery with a known mapping base slot. */
|
|
18
|
+
slot?: bigint | number;
|
|
19
|
+
/** Layout used with `slot`. Default 'solidity'. */
|
|
20
|
+
layout?: Erc20StorageLayout;
|
|
21
|
+
/** Contract whose storage holds balances when it differs from `token`. */
|
|
22
|
+
storageAddress?: Address;
|
|
23
|
+
};
|
|
24
|
+
export declare class Erc20DealError extends Error {
|
|
25
|
+
readonly token: Address;
|
|
26
|
+
/** Candidate slots tried across both layouts. */
|
|
27
|
+
readonly probedSlots: number;
|
|
28
|
+
constructor(message: string, token: Address,
|
|
29
|
+
/** Candidate slots tried across both layouts. */
|
|
30
|
+
probedSlots: number);
|
|
31
|
+
}
|
|
32
|
+
export declare function discoverErc20BalanceSlot(client: RpcClient, token: Address, holder: Address, options?: {
|
|
33
|
+
maxSlot?: number;
|
|
34
|
+
storageAddress?: Address;
|
|
35
|
+
}): Promise<Erc20SlotInfo>;
|
|
36
|
+
export declare function getErc20Balance(client: RpcClient, token: Address, account: Address): Promise<bigint>;
|
|
37
|
+
export declare function dealErc20(client: RpcClient, token: Address, account: Address, amount: bigint, options?: DealErc20Options, cache?: Map<string, Erc20SlotInfo>): Promise<void>;
|
|
38
|
+
//# sourceMappingURL=erc20.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"erc20.d.ts","sourceRoot":"","sources":["../src/erc20.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,OAAO,EAEb,MAAM,MAAM,CAAC;AACd,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,2BAA2B,CAAC;AAEnC,MAAM,MAAM,kBAAkB,GAAG,UAAU,GAAG,OAAO,CAAC;AAEtD,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,yEAAyE;IACzE,WAAW,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,0GAA0G;IAC1G,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,mDAAmD;IACnD,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,0EAA0E;IAC1E,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,qBAAa,cAAe,SAAQ,KAAK;IAGrC,QAAQ,CAAC,KAAK,EAAE,OAAO;IACvB,iDAAiD;IACjD,QAAQ,CAAC,WAAW,EAAE,MAAM;gBAH5B,OAAO,EAAE,MAAM,EACN,KAAK,EAAE,OAAO;IACvB,iDAAiD;IACxC,WAAW,EAAE,MAAM;CAK/B;AAsFD,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,OAAO,EACf,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,OAAO,CAAA;CAAO,GAC3D,OAAO,CAAC,aAAa,CAAC,CAkDxB;AAED,wBAAsB,eAAe,CACnC,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,MAAM,CAAC,CAUjB;AAED,wBAAsB,SAAS,CAC7B,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,gBAAqB,EAC9B,KAAK,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,GACjC,OAAO,CAAC,IAAI,CAAC,CAoFf"}
|
package/dist/erc20.js
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { encodeAbiParameters, encodeFunctionData, erc20Abi, keccak256, toHex, } from 'viem';
|
|
2
|
+
export { TEST_ERC20_ABI, TEST_ERC20_BYTECODE, TEST_ERC20_SOLC_VERSION, TEST_ERC20_SOURCE_SHA256, } from './contracts/test-erc20.js';
|
|
3
|
+
export class Erc20DealError extends Error {
|
|
4
|
+
token;
|
|
5
|
+
probedSlots;
|
|
6
|
+
constructor(message, token,
|
|
7
|
+
/** Candidate slots tried across both layouts. */
|
|
8
|
+
probedSlots) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.token = token;
|
|
11
|
+
this.probedSlots = probedSlots;
|
|
12
|
+
this.name = 'Erc20DealError';
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
const MAX_UINT256 = 2n ** 256n - 1n;
|
|
16
|
+
// An improbable balance used as the discovery probe. Discovery never writes:
|
|
17
|
+
// candidates are tested with eth_call state overrides (stateDiff), so a
|
|
18
|
+
// crash mid-discovery cannot leave the chain dirty and probing is
|
|
19
|
+
// batch-parallel safe.
|
|
20
|
+
const PROBE_SENTINEL = 0xdea1dea1dea1dea1dea1dea1dea1dea1dea1dea1dea1dea1dea1dea1dea1dea1n;
|
|
21
|
+
// OZ v5 upgradeable ERC-20 (ERC-7201): _balances is the first struct member,
|
|
22
|
+
// so the mapping base IS the namespace root; _totalSupply sits at root+2.
|
|
23
|
+
const OZ_V5_ERC20_NAMESPACE_ROOT = 0x52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace00n;
|
|
24
|
+
const pad32 = (value) => toHex(value, { size: 32 });
|
|
25
|
+
const mappingSlot = (layout, holder, base) => layout === 'solidity'
|
|
26
|
+
? keccak256(encodeAbiParameters([{ type: 'address' }, { type: 'uint256' }], [holder, base]))
|
|
27
|
+
: keccak256(encodeAbiParameters([{ type: 'uint256' }, { type: 'address' }], [base, holder]));
|
|
28
|
+
const balanceOfData = (holder) => encodeFunctionData({ abi: erc20Abi, functionName: 'balanceOf', args: [holder] });
|
|
29
|
+
const totalSupplyData = () => encodeFunctionData({ abi: erc20Abi, functionName: 'totalSupply' });
|
|
30
|
+
// eth_call returning the first uint256 word, optionally under a stateDiff
|
|
31
|
+
// override; undefined on revert/empty (treated as "no signal").
|
|
32
|
+
const callUint = async (client, to, data, override) => {
|
|
33
|
+
const params = [{ to, data }, 'latest'];
|
|
34
|
+
if (override) {
|
|
35
|
+
params.push({ [override.address]: { stateDiff: { [override.slot]: override.value } } });
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
const result = await client.request({ method: 'eth_call', params });
|
|
39
|
+
if (typeof result !== 'string' || result.length < 66) {
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
return BigInt(result.slice(0, 66));
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
const getStorage = async (client, address, slot) => {
|
|
49
|
+
const result = await client.request({
|
|
50
|
+
method: 'eth_getStorageAt',
|
|
51
|
+
params: [address, slot, 'latest'],
|
|
52
|
+
});
|
|
53
|
+
return pad32(BigInt(String(result ?? '0x0')));
|
|
54
|
+
};
|
|
55
|
+
const setStorage = async (client, token, address, slot, value) => {
|
|
56
|
+
try {
|
|
57
|
+
await client.request({ method: 'anvil_setStorageAt', params: [address, slot, value] });
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
61
|
+
if (/not found|not supported|not available|does not exist|unknown method|unsupported/i.test(message)) {
|
|
62
|
+
throw new Erc20DealError('dealErc20 requires an anvil-backed client (the RPC rejected anvil_setStorageAt) — live chains cannot be dealt.', token, 0);
|
|
63
|
+
}
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
const probeSentinelFor = (current) => current === PROBE_SENTINEL ? PROBE_SENTINEL - 1n : PROBE_SENTINEL;
|
|
68
|
+
export async function discoverErc20BalanceSlot(client, token, holder, options = {}) {
|
|
69
|
+
const storageAddress = options.storageAddress ?? token;
|
|
70
|
+
const maxSlot = options.maxSlot ?? 64;
|
|
71
|
+
const data = balanceOfData(holder);
|
|
72
|
+
const current = await callUint(client, token, data);
|
|
73
|
+
if (current === undefined) {
|
|
74
|
+
throw new Erc20DealError(`${token} does not implement balanceOf — not an ERC-20?`, token, 0);
|
|
75
|
+
}
|
|
76
|
+
const sentinel = probeSentinelFor(current);
|
|
77
|
+
const candidates = [];
|
|
78
|
+
for (let base = 0n; base <= BigInt(maxSlot); base += 1n) {
|
|
79
|
+
candidates.push({ layout: 'solidity', base });
|
|
80
|
+
candidates.push({ layout: 'vyper', base });
|
|
81
|
+
}
|
|
82
|
+
candidates.push({ layout: 'solidity', base: OZ_V5_ERC20_NAMESPACE_ROOT });
|
|
83
|
+
const BATCH = 8;
|
|
84
|
+
for (let start = 0; start < candidates.length; start += BATCH) {
|
|
85
|
+
const hits = await Promise.all(candidates.slice(start, start + BATCH).map(async (candidate) => {
|
|
86
|
+
const slot = mappingSlot(candidate.layout, holder, candidate.base);
|
|
87
|
+
const observed = await callUint(client, token, data, {
|
|
88
|
+
address: storageAddress,
|
|
89
|
+
slot,
|
|
90
|
+
value: pad32(sentinel),
|
|
91
|
+
});
|
|
92
|
+
return observed === sentinel ? candidate : undefined;
|
|
93
|
+
}));
|
|
94
|
+
const hit = hits.find(Boolean);
|
|
95
|
+
if (hit) {
|
|
96
|
+
return { layout: hit.layout, balanceSlot: hit.base };
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
throw new Erc20DealError(`Could not find ${token}'s balance slot after probing ${candidates.length} candidates. ` +
|
|
100
|
+
'Rebasing/shares tokens (stETH, aTokens) compute balanceOf and cannot be dealt this way; ' +
|
|
101
|
+
'solady-style seeded layouts need chain.setStorageAt with a hand-computed slot; ' +
|
|
102
|
+
'external-storage proxies need { storageAddress }; deep layouts may need a higher { maxSlot }.', token, candidates.length);
|
|
103
|
+
}
|
|
104
|
+
export async function getErc20Balance(client, token, account) {
|
|
105
|
+
const balance = await callUint(client, token, balanceOfData(account));
|
|
106
|
+
if (balance === undefined) {
|
|
107
|
+
throw new Erc20DealError(`${token} does not implement balanceOf — not an ERC-20?`, token, 0);
|
|
108
|
+
}
|
|
109
|
+
return balance;
|
|
110
|
+
}
|
|
111
|
+
export async function dealErc20(client, token, account, amount, options = {}, cache) {
|
|
112
|
+
if (typeof amount !== 'bigint') {
|
|
113
|
+
throw new RangeError('dealErc20 amount must be a bigint.');
|
|
114
|
+
}
|
|
115
|
+
if (amount < 0n || amount > MAX_UINT256) {
|
|
116
|
+
throw new RangeError('dealErc20 amount must be in [0, 2^256).');
|
|
117
|
+
}
|
|
118
|
+
const storageAddress = options.storageAddress ?? token;
|
|
119
|
+
const cacheKey = storageAddress.toLowerCase();
|
|
120
|
+
const explicit = options.slot !== undefined
|
|
121
|
+
? { layout: options.layout ?? 'solidity', balanceSlot: BigInt(options.slot) }
|
|
122
|
+
: undefined;
|
|
123
|
+
let info = explicit ?? cache?.get(cacheKey);
|
|
124
|
+
let freshlyDiscovered = false;
|
|
125
|
+
if (!info) {
|
|
126
|
+
info = await discoverErc20BalanceSlot(client, token, account, options);
|
|
127
|
+
freshlyDiscovered = true;
|
|
128
|
+
}
|
|
129
|
+
const previousBalance = options.adjustTotalSupply
|
|
130
|
+
? ((await callUint(client, token, balanceOfData(account))) ?? 0n)
|
|
131
|
+
: 0n;
|
|
132
|
+
// The one real write, always verified; a non-verifying write is restored so
|
|
133
|
+
// the worker chain is never left dirty (it outlives this call when used
|
|
134
|
+
// outside the wallet fixture's snapshot/revert).
|
|
135
|
+
const writeAndVerify = async (slotInfo) => {
|
|
136
|
+
const slot = mappingSlot(slotInfo.layout, account, slotInfo.balanceSlot);
|
|
137
|
+
const previous = await getStorage(client, storageAddress, slot);
|
|
138
|
+
await setStorage(client, token, storageAddress, slot, pad32(amount));
|
|
139
|
+
if ((await callUint(client, token, balanceOfData(account))) === amount) {
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
await setStorage(client, token, storageAddress, slot, previous);
|
|
143
|
+
return false;
|
|
144
|
+
};
|
|
145
|
+
if (await writeAndVerify(info)) {
|
|
146
|
+
if (freshlyDiscovered) {
|
|
147
|
+
cache?.set(cacheKey, info);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
if (explicit) {
|
|
152
|
+
throw new Erc20DealError(`balanceOf does not reflect a write at the explicit slot — wrong { slot }/{ layout }, or ${token} computes balanceOf.`, token, 0);
|
|
153
|
+
}
|
|
154
|
+
if (freshlyDiscovered) {
|
|
155
|
+
throw new Erc20DealError(`Discovery matched a slot but the final write did not verify — ${token} likely computes balanceOf (shares/rebasing).`, token, 0);
|
|
156
|
+
}
|
|
157
|
+
// Stale cache: snapshot reverts reset deployer nonces, so a different
|
|
158
|
+
// contract can reuse a previously-cached address. Evict and rediscover
|
|
159
|
+
// once.
|
|
160
|
+
cache?.delete(cacheKey);
|
|
161
|
+
const rediscovered = await discoverErc20BalanceSlot(client, token, account, options);
|
|
162
|
+
if (!(await writeAndVerify(rediscovered))) {
|
|
163
|
+
throw new Erc20DealError(`Verification failed even after rediscovery — ${token} likely computes balanceOf (shares/rebasing).`, token, 0);
|
|
164
|
+
}
|
|
165
|
+
cache?.set(cacheKey, rediscovered);
|
|
166
|
+
info = rediscovered;
|
|
167
|
+
}
|
|
168
|
+
if (options.adjustTotalSupply) {
|
|
169
|
+
await adjustTotalSupply(client, token, storageAddress, info, amount - previousBalance, {
|
|
170
|
+
maxSlot: options.maxSlot ?? 64,
|
|
171
|
+
cache: explicit ? undefined : cache,
|
|
172
|
+
cacheKey,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
const adjustTotalSupply = async (client, token, storageAddress, info, delta, context) => {
|
|
177
|
+
if (delta === 0n) {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
const data = totalSupplyData();
|
|
181
|
+
const currentSupply = await callUint(client, token, data);
|
|
182
|
+
if (currentSupply === undefined) {
|
|
183
|
+
throw new Erc20DealError(`${token} does not implement totalSupply.`, token, 0);
|
|
184
|
+
}
|
|
185
|
+
const newSupply = currentSupply + delta;
|
|
186
|
+
if (newSupply < 0n) {
|
|
187
|
+
throw new Erc20DealError(`adjustTotalSupply would underflow: totalSupply ${currentSupply} with delta ${delta} (forge-std deal reverts here too).`, token, 0);
|
|
188
|
+
}
|
|
189
|
+
if (newSupply > MAX_UINT256) {
|
|
190
|
+
throw new Erc20DealError(`adjustTotalSupply would overflow uint256: totalSupply ${currentSupply} with delta ${delta}.`, token, 0);
|
|
191
|
+
}
|
|
192
|
+
let supplySlot = info.totalSupplySlot;
|
|
193
|
+
if (supplySlot === undefined) {
|
|
194
|
+
supplySlot = await discoverPlainSlot(client, token, storageAddress, data, currentSupply, info, context.maxSlot);
|
|
195
|
+
info.totalSupplySlot = supplySlot;
|
|
196
|
+
context.cache?.set(context.cacheKey, info);
|
|
197
|
+
}
|
|
198
|
+
const slot = pad32(supplySlot);
|
|
199
|
+
const previous = await getStorage(client, storageAddress, slot);
|
|
200
|
+
await setStorage(client, token, storageAddress, slot, pad32(newSupply));
|
|
201
|
+
if ((await callUint(client, token, data)) !== newSupply) {
|
|
202
|
+
await setStorage(client, token, storageAddress, slot, previous);
|
|
203
|
+
info.totalSupplySlot = undefined;
|
|
204
|
+
throw new Erc20DealError(`${token}'s totalSupply did not reflect the adjustment — it is likely computed.`, token, 0);
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
// Plain (unkeyed) slot discovery for totalSupply, also via state overrides.
|
|
208
|
+
const discoverPlainSlot = async (client, token, storageAddress, data, current, info, maxSlot) => {
|
|
209
|
+
const sentinel = probeSentinelFor(current);
|
|
210
|
+
const candidates = [];
|
|
211
|
+
if (info.balanceSlot === OZ_V5_ERC20_NAMESPACE_ROOT) {
|
|
212
|
+
candidates.push(info.balanceSlot + 1n, info.balanceSlot + 2n, info.balanceSlot + 3n);
|
|
213
|
+
}
|
|
214
|
+
for (let base = 0n; base <= BigInt(maxSlot); base += 1n) {
|
|
215
|
+
candidates.push(base);
|
|
216
|
+
}
|
|
217
|
+
for (const base of candidates) {
|
|
218
|
+
const observed = await callUint(client, token, data, {
|
|
219
|
+
address: storageAddress,
|
|
220
|
+
slot: pad32(base),
|
|
221
|
+
value: pad32(sentinel),
|
|
222
|
+
});
|
|
223
|
+
if (observed === sentinel) {
|
|
224
|
+
return base;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
throw new Erc20DealError(`Could not find ${token}'s totalSupply slot after probing ${candidates.length} candidates.`, token, candidates.length);
|
|
228
|
+
};
|
|
229
|
+
//# sourceMappingURL=erc20.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"erc20.js","sourceRoot":"","sources":["../src/erc20.ts"],"names":[],"mappings":"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"}
|
package/dist/fixtures.d.ts
CHANGED
|
@@ -1,15 +1,57 @@
|
|
|
1
|
+
import { type Browser, type BrowserContext, type Page } from '@playwright/test';
|
|
1
2
|
import { AnvilInstance, ChainController, type AnvilOptions } from './anvil.js';
|
|
2
3
|
import { MockWalletController, type MockWalletControllerOptions } from './mock-wallet-controller.js';
|
|
4
|
+
/** A second (third, …) user: its own browser context, page, and wallet. */
|
|
5
|
+
export type UserSession = {
|
|
6
|
+
context: BrowserContext;
|
|
7
|
+
page: Page;
|
|
8
|
+
wallet: MockWalletController;
|
|
9
|
+
/** Idempotent mid-test disposal ("user leaves"); also runs at teardown. */
|
|
10
|
+
close(): Promise<void>;
|
|
11
|
+
};
|
|
12
|
+
export type CreateUserOptions = MockWalletFixtureOptions & {
|
|
13
|
+
/**
|
|
14
|
+
* Passed to browser.newContext(); baseURL is forwarded by default. Other
|
|
15
|
+
* test.use context options (viewport, locale, storageState…) are NOT
|
|
16
|
+
* inherited — pass them here when a user needs them.
|
|
17
|
+
*/
|
|
18
|
+
contextOptions?: Parameters<Browser['newContext']>[0];
|
|
19
|
+
};
|
|
20
|
+
export type CreateUser = (options?: CreateUserOptions) => Promise<UserSession>;
|
|
3
21
|
export type Web3Fixtures = {
|
|
4
22
|
wallet: MockWalletController;
|
|
5
23
|
walletOptions: MockWalletFixtureOptions;
|
|
24
|
+
/** Factory: fresh context + page + wallet on the shared worker chain(s). */
|
|
25
|
+
createUser: CreateUser;
|
|
26
|
+
/**
|
|
27
|
+
* Internal plumbing: the single per-test snapshot/revert owner spanning
|
|
28
|
+
* every running chain; wallet and createUser both depend on it.
|
|
29
|
+
*/
|
|
30
|
+
_chainIsolation: void;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Spec for one extra per-worker Anvil chain. Port and host are
|
|
34
|
+
* fixture-managed; everything else defaults to the worker's anvilOptions
|
|
35
|
+
* (so docker runtime / custom executables apply to extras too).
|
|
36
|
+
*/
|
|
37
|
+
export type AnvilChainSpec = Omit<AnvilOptions, 'port' | 'host' | 'allowNonLoopbackHost'> & {
|
|
38
|
+
chainId: number;
|
|
6
39
|
};
|
|
7
40
|
export type Web3WorkerFixtures = {
|
|
8
41
|
anvil: AnvilInstance;
|
|
9
42
|
chain: ChainController;
|
|
10
43
|
anvilOptions: AnvilOptions;
|
|
44
|
+
/** Worker option, default []. One extra AnvilInstance is started per entry. */
|
|
45
|
+
extraChains: readonly AnvilChainSpec[];
|
|
46
|
+
/** Worker-scoped: extra chainId -> running AnvilInstance. */
|
|
47
|
+
extraAnvils: ReadonlyMap<number, AnvilInstance>;
|
|
48
|
+
/** Worker-scoped: chainId -> ChainController, INCLUDING the primary chain. */
|
|
49
|
+
chains: ReadonlyMap<number, ChainController>;
|
|
50
|
+
};
|
|
51
|
+
export type MockWalletFixtureOptions = Omit<Partial<MockWalletControllerOptions>, 'chainId'> & {
|
|
52
|
+
/** Indexes into chain.accounts(); mutually exclusive with `accounts`. */
|
|
53
|
+
accountIndexes?: readonly number[];
|
|
11
54
|
};
|
|
12
|
-
export type MockWalletFixtureOptions = Omit<Partial<MockWalletControllerOptions>, 'accounts' | 'chainId'>;
|
|
13
55
|
export declare const test: import("@playwright/test").TestType<import("@playwright/test").PlaywrightTestArgs & import("@playwright/test").PlaywrightTestOptions & Web3Fixtures, import("@playwright/test").PlaywrightWorkerArgs & import("@playwright/test").PlaywrightWorkerOptions & Web3WorkerFixtures>;
|
|
14
|
-
export { expect } from '
|
|
56
|
+
export { expect } from './matchers.js';
|
|
15
57
|
//# sourceMappingURL=fixtures.d.ts.map
|
package/dist/fixtures.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../src/fixtures.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../src/fixtures.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAK9F,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,KAAK,YAAY,EAAwB,MAAM,YAAY,CAAC;AACrG,OAAO,EAAE,oBAAoB,EAAE,KAAK,2BAA2B,EAAE,MAAM,6BAA6B,CAAC;AAErG,2EAA2E;AAC3E,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,cAAc,CAAC;IACxB,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,oBAAoB,CAAC;IAC7B,2EAA2E;IAC3E,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,wBAAwB,GAAG;IACzD;;;;OAIG;IACH,cAAc,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CACvD,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,CAAC,EAAE,iBAAiB,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;AAE/E,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,oBAAoB,CAAC;IAC7B,aAAa,EAAE,wBAAwB,CAAC;IACxC,4EAA4E;IAC5E,UAAU,EAAE,UAAU,CAAC;IACvB;;;OAGG;IACH,eAAe,EAAE,IAAI,CAAC;CACvB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,sBAAsB,CAAC,GAAG;IAC1F,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,aAAa,CAAC;IACrB,KAAK,EAAE,eAAe,CAAC;IACvB,YAAY,EAAE,YAAY,CAAC;IAC3B,+EAA+E;IAC/E,WAAW,EAAE,SAAS,cAAc,EAAE,CAAC;IACvC,6DAA6D;IAC7D,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAChD,8EAA8E;IAC9E,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC9C,CAAC;AAGF,MAAM,MAAM,wBAAwB,GAAG,IAAI,CAAC,OAAO,CAAC,2BAA2B,CAAC,EAAE,SAAS,CAAC,GAAG;IAC7F,yEAAyE;IACzE,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC,CAAC;AAiEF,eAAO,MAAM,IAAI,iRA4Mf,CAAC;AA2BH,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/fixtures.js
CHANGED
|
@@ -4,7 +4,41 @@ import { join } from 'node:path';
|
|
|
4
4
|
import { foundry } from 'viem/chains';
|
|
5
5
|
import { AnvilInstance, ChainController } from './anvil.js';
|
|
6
6
|
import { MockWalletController } from './mock-wallet-controller.js';
|
|
7
|
-
const
|
|
7
|
+
const resolveAccounts = async (chain, options, fallbackIndex) => {
|
|
8
|
+
if (options.accounts && options.accountIndexes) {
|
|
9
|
+
throw new Error('Pass either accounts or accountIndexes, not both.');
|
|
10
|
+
}
|
|
11
|
+
if (options.accounts) {
|
|
12
|
+
return [...options.accounts];
|
|
13
|
+
}
|
|
14
|
+
const available = await chain.accounts();
|
|
15
|
+
const pick = (index) => {
|
|
16
|
+
const account = available[index];
|
|
17
|
+
if (!account) {
|
|
18
|
+
throw new Error(`Account index ${index} is out of range: the node exposes ${available.length} accounts. ` +
|
|
19
|
+
'Raise anvilOptions: { accounts: n } to generate more.');
|
|
20
|
+
}
|
|
21
|
+
return account;
|
|
22
|
+
};
|
|
23
|
+
if (options.accountIndexes) {
|
|
24
|
+
return options.accountIndexes.map(pick);
|
|
25
|
+
}
|
|
26
|
+
return [pick(fallbackIndex)];
|
|
27
|
+
};
|
|
28
|
+
// Base defaults to 8645 rather than anvil's own 8545 so the fixture never
|
|
29
|
+
// collides with a developer-run dev node on the conventional port.
|
|
30
|
+
//
|
|
31
|
+
// Port bands (ANVIL_PORT shifts everything wholesale):
|
|
32
|
+
// primary anvil: base + workerIndex (8645, 8646, …)
|
|
33
|
+
// extraChains: base + 1000 + workerIndex*20 + index (9645+, 20/worker)
|
|
34
|
+
// Spec-managed anvils use their own bands with distinct mod-20 sub-offsets:
|
|
35
|
+
// tests/anvil.spec.ts 19100 + w*20 + {0..3}
|
|
36
|
+
// tests/private-key-rpc-client.spec.ts 19510 + w*20 + {0..2} (≡ 10..12)
|
|
37
|
+
// tests/mock-wallet-multichain.spec.ts 19700 + w*20 + {13..19}
|
|
38
|
+
// tests/erc20.spec.ts 19900 + w*20 + {4..5}
|
|
39
|
+
// The extras band assumes workerIndex < 1000.
|
|
40
|
+
const workerPort = (workerIndex) => Number(process.env.ANVIL_PORT ?? 8645) + workerIndex;
|
|
41
|
+
const extraChainPort = (workerIndex, index) => Number(process.env.ANVIL_PORT ?? 8645) + 1000 + workerIndex * 20 + index;
|
|
8
42
|
const resolveAnvilExecutable = () => {
|
|
9
43
|
if (process.env.ANVIL_EXECUTABLE) {
|
|
10
44
|
return process.env.ANVIL_EXECUTABLE;
|
|
@@ -29,6 +63,7 @@ export const test = base.extend({
|
|
|
29
63
|
executable: resolveAnvilExecutable(),
|
|
30
64
|
dockerImage: process.env.ANVIL_DOCKER_IMAGE,
|
|
31
65
|
host: process.env.ANVIL_HOST ?? '127.0.0.1',
|
|
66
|
+
allowNonLoopbackHost: process.env.ANVIL_ALLOW_NON_LOOPBACK === 'true',
|
|
32
67
|
chainId: Number(process.env.ANVIL_CHAIN_ID ?? foundry.id),
|
|
33
68
|
forkUrl: process.env.ANVIL_FORK_URL,
|
|
34
69
|
silent: process.env.ANVIL_SILENT !== 'false',
|
|
@@ -60,28 +95,138 @@ export const test = base.extend({
|
|
|
60
95
|
},
|
|
61
96
|
{ scope: 'worker' },
|
|
62
97
|
],
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
98
|
+
extraChains: [
|
|
99
|
+
async ({}, use) => {
|
|
100
|
+
await use([]);
|
|
101
|
+
},
|
|
102
|
+
{ scope: 'worker', option: true },
|
|
103
|
+
],
|
|
104
|
+
extraAnvils: [
|
|
105
|
+
async ({ anvil, anvilOptions, extraChains }, use, workerInfo) => {
|
|
106
|
+
const instances = new Map();
|
|
107
|
+
try {
|
|
108
|
+
const seenChainIds = new Set([anvil.chainId]);
|
|
109
|
+
for (const [index, spec] of extraChains.entries()) {
|
|
110
|
+
if (seenChainIds.has(spec.chainId)) {
|
|
111
|
+
throw new Error(`extraChains lists chain id ${spec.chainId} more than once (or it collides with the primary chain).`);
|
|
112
|
+
}
|
|
113
|
+
seenChainIds.add(spec.chainId);
|
|
114
|
+
// Extras inherit the worker anvilOptions (runtime, executable,
|
|
115
|
+
// docker image, host…) under the spec's own overrides; the port is
|
|
116
|
+
// fixture-managed in a dedicated band.
|
|
117
|
+
instances.set(spec.chainId, await AnvilInstance.start({
|
|
118
|
+
...anvilOptions,
|
|
119
|
+
...spec,
|
|
120
|
+
port: extraChainPort(workerInfo.workerIndex, index),
|
|
121
|
+
}));
|
|
122
|
+
}
|
|
123
|
+
await use(instances);
|
|
124
|
+
}
|
|
125
|
+
finally {
|
|
126
|
+
await Promise.all([...instances.values()].map((instance) => instance.stop()));
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
{ scope: 'worker' },
|
|
130
|
+
],
|
|
131
|
+
chains: [
|
|
132
|
+
async ({ anvil, chain, extraAnvils }, use) => {
|
|
133
|
+
const map = new Map();
|
|
134
|
+
map.set(anvil.chainId, chain);
|
|
135
|
+
for (const [chainId, instance] of extraAnvils) {
|
|
136
|
+
map.set(chainId, new ChainController({ rpcUrl: instance.rpcUrl, chainId }));
|
|
137
|
+
}
|
|
138
|
+
await use(map);
|
|
139
|
+
},
|
|
140
|
+
{ scope: 'worker' },
|
|
141
|
+
],
|
|
142
|
+
// The single per-test snapshot/revert owner. Playwright memoizes fixtures,
|
|
143
|
+
// so a test using both wallet and createUser takes exactly ONE snapshot
|
|
144
|
+
// per chain, and teardown runs dependents first — user contexts close
|
|
145
|
+
// before the single revert.
|
|
146
|
+
_chainIsolation: async ({ chains }, use) => {
|
|
147
|
+
const snapshots = new Map();
|
|
148
|
+
for (const controller of chains.values()) {
|
|
149
|
+
snapshots.set(controller, await controller.snapshot());
|
|
68
150
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
151
|
+
try {
|
|
152
|
+
await use(undefined);
|
|
153
|
+
}
|
|
154
|
+
finally {
|
|
155
|
+
for (const [controller, snapshotId] of snapshots) {
|
|
156
|
+
await controller.revert(snapshotId);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
wallet: async ({ page, chain, chains, walletOptions: customWalletOptions, _chainIsolation }, use) => {
|
|
161
|
+
void _chainIsolation;
|
|
162
|
+
const { accounts, accountIndexes, ...controllerOverrides } = customWalletOptions;
|
|
163
|
+
const resolvedAccounts = await resolveAccounts(chain, { accounts, accountIndexes }, 0);
|
|
164
|
+
const wallet = new MockWalletController(page, chain, buildControllerOptions(chain, chains, resolvedAccounts, controllerOverrides));
|
|
77
165
|
await wallet.injectMockProvider();
|
|
166
|
+
await use(wallet);
|
|
167
|
+
},
|
|
168
|
+
createUser: async ({ browser, chain, chains, baseURL, walletOptions: customWalletOptions, _chainIsolation }, use) => {
|
|
169
|
+
void _chainIsolation;
|
|
170
|
+
const sessions = [];
|
|
171
|
+
// Index 0 is the primary wallet fixture's default; users without
|
|
172
|
+
// explicit accounts take 1, 2, 3… in creation order.
|
|
173
|
+
let nextDefaultIndex = 1;
|
|
174
|
+
const factory = async (options = {}) => {
|
|
175
|
+
// The test's walletOptions are the base layer (so deny-mode or origin
|
|
176
|
+
// scoping applies to every user) under per-call overrides — except
|
|
177
|
+
// accounts/accountIndexes, which resolveAccounts owns per user.
|
|
178
|
+
const { accounts: _baseAccounts, accountIndexes: _baseIndexes, ...baseOptions } = customWalletOptions;
|
|
179
|
+
const merged = { ...baseOptions, ...options };
|
|
180
|
+
const { accounts, accountIndexes, contextOptions, ...controllerOverrides } = merged;
|
|
181
|
+
const resolvedAccounts = await resolveAccounts(chain, { accounts, accountIndexes }, nextDefaultIndex);
|
|
182
|
+
if (!accounts && !accountIndexes) {
|
|
183
|
+
nextDefaultIndex += 1;
|
|
184
|
+
}
|
|
185
|
+
const context = await browser.newContext({ baseURL, ...contextOptions });
|
|
186
|
+
const page = await context.newPage();
|
|
187
|
+
const wallet = new MockWalletController(page, chain, buildControllerOptions(chain, chains, resolvedAccounts, controllerOverrides));
|
|
188
|
+
await wallet.injectMockProvider();
|
|
189
|
+
let closed = false;
|
|
190
|
+
const session = {
|
|
191
|
+
context,
|
|
192
|
+
page,
|
|
193
|
+
wallet,
|
|
194
|
+
close: async () => {
|
|
195
|
+
if (closed) {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
closed = true;
|
|
199
|
+
await context.close().catch(() => undefined);
|
|
200
|
+
},
|
|
201
|
+
};
|
|
202
|
+
sessions.push(session);
|
|
203
|
+
return session;
|
|
204
|
+
};
|
|
78
205
|
try {
|
|
79
|
-
await use(
|
|
206
|
+
await use(factory);
|
|
80
207
|
}
|
|
81
208
|
finally {
|
|
82
|
-
|
|
209
|
+
for (const session of sessions) {
|
|
210
|
+
await session.close();
|
|
211
|
+
}
|
|
83
212
|
}
|
|
84
213
|
},
|
|
85
214
|
});
|
|
86
|
-
|
|
215
|
+
// The primary chain is the positional rpcClient; extras go in the chains
|
|
216
|
+
// option. User-supplied chains entries win per key, but fixture extras are
|
|
217
|
+
// never silently dropped (their Anvils keep running).
|
|
218
|
+
const buildControllerOptions = (chain, chains, accounts, overrides) => {
|
|
219
|
+
const extraBackends = Object.fromEntries([...chains].filter(([chainId]) => chainId !== chain.chainId));
|
|
220
|
+
const mergedChains = { ...extraBackends, ...overrides.chains };
|
|
221
|
+
return {
|
|
222
|
+
accounts,
|
|
223
|
+
chainId: chain.chainId,
|
|
224
|
+
autoApprove: true,
|
|
225
|
+
connected: true,
|
|
226
|
+
...overrides,
|
|
227
|
+
...(Object.keys(mergedChains).length > 0 ? { chains: mergedChains } : {}),
|
|
228
|
+
};
|
|
229
|
+
};
|
|
230
|
+
// The web3-extended expect: every matcher from ./matchers.js, zero migration.
|
|
231
|
+
export { expect } from './matchers.js';
|
|
87
232
|
//# sourceMappingURL=fixtures.js.map
|
package/dist/fixtures.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fixtures.js","sourceRoot":"","sources":["../src/fixtures.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,IAAI,IAAI,
|
|
1
|
+
{"version":3,"file":"fixtures.js","sourceRoot":"","sources":["../src/fixtures.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,23 @@
|
|
|
1
1
|
export { AnvilInstance, ChainController } from './anvil.js';
|
|
2
|
+
export { Erc20DealError, dealErc20, discoverErc20BalanceSlot, getErc20Balance, TEST_ERC20_ABI, TEST_ERC20_BYTECODE, } from './erc20.js';
|
|
3
|
+
export type { DealErc20Options, Erc20SlotInfo, Erc20StorageLayout } from './erc20.js';
|
|
4
|
+
export { anyValue, web3Matchers } from './matchers.js';
|
|
5
|
+
export type { BalanceChange, EventArgsExpectation, EventMatchOptions } from './matchers.js';
|
|
6
|
+
export { extractRevertInfo, waitForDecodedTransaction, web3Equals, web3Stringify, } from './transactions.js';
|
|
7
|
+
export type { ChainLike, DecodedTransaction, ReadClient, RevertInfo, RevertTarget, TransactionRef, TransactionTarget, } from './transactions.js';
|
|
2
8
|
export { test, expect } from './fixtures.js';
|
|
3
|
-
export { MockWalletController } from './mock-wallet-controller.js';
|
|
9
|
+
export { MockWalletController, httpRpcClient } from './mock-wallet-controller.js';
|
|
4
10
|
export { PrivateKeyRpcClient } from './private-key-rpc-client.js';
|
|
5
11
|
export { launchRealWallet, resolveRealWalletProfile } from './real-wallet.js';
|
|
6
|
-
export
|
|
7
|
-
export
|
|
8
|
-
export
|
|
12
|
+
export { DEFAULT_METAMASK_VERSION, prepareMetaMaskExtension, extensionManifestVersion, } from './metamask-extension.js';
|
|
13
|
+
export { buildWalletProfile, cloneWalletProfile, waitForExtensionStatePersisted, } from './real-wallet-cache.js';
|
|
14
|
+
export { DEFAULT_WALLET_PASSWORD } from './real-wallet-setup.js';
|
|
15
|
+
export type { AnvilOptions, AnvilSnapshotId, AnvilViemClient, ChainAuthorizationOptions, ChainControllerOptions, DelegateOptions, DeployContractOptions, DeployedContract, DeployedErc20, DeployErc20Options, } from './anvil.js';
|
|
16
|
+
export type { AtomicCapabilityStatus, CallsBatchRecord, ChainBackend, Eip5792Options, HeldRequest, HttpRpcClientOptions, MockWalletControllerOptions, RejectionRule, SentTransactionRecord, } from './mock-wallet-controller.js';
|
|
17
|
+
export type { JsonRpcRequest, MockWalletConfig, RpcClient, WalletProviderInfo, } from './types.js';
|
|
9
18
|
export type { PrivateKeyRpcClientOptions } from './private-key-rpc-client.js';
|
|
10
|
-
export type { RealWalletController, RealWalletGasSettings, RealWalletLaunchOptions, RealWalletProfile, RealWalletSession, RealWalletSetup, } from './real-wallet.js';
|
|
19
|
+
export type { RealWalletController, RealWalletGasSettings, RealWalletLaunchOptions, RealWalletNetwork, RealWalletProfile, RealWalletSession, RealWalletSetup, RealWalletToken, WalletGeneration, } from './real-wallet.js';
|
|
20
|
+
export type { PrepareMetaMaskExtensionOptions } from './metamask-extension.js';
|
|
21
|
+
export type { BuildWalletProfileOptions } from './real-wallet-cache.js';
|
|
22
|
+
export type { RealWalletFixtureOptions, RealWalletFixtures } from './real-wallet-fixtures.js';
|
|
11
23
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EACL,cAAc,EACd,SAAS,EACT,wBAAwB,EACxB,eAAe,EACf,cAAc,EACd,mBAAmB,GACpB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACtF,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AACvD,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC5F,OAAO,EACL,iBAAiB,EACjB,yBAAyB,EACzB,UAAU,EACV,aAAa,GACd,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,SAAS,EACT,kBAAkB,EAClB,UAAU,EACV,UAAU,EACV,YAAY,EACZ,cAAc,EACd,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAClF,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,8BAA8B,GAC/B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,YAAY,EACV,YAAY,EACZ,eAAe,EACf,eAAe,EACf,yBAAyB,EACzB,sBAAsB,EACtB,eAAe,EACf,qBAAqB,EACrB,gBAAgB,EAChB,aAAa,EACb,kBAAkB,GACnB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,sBAAsB,EACtB,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,WAAW,EACX,oBAAoB,EACpB,2BAA2B,EAC3B,aAAa,EACb,qBAAqB,GACtB,MAAM,6BAA6B,CAAC;AACrC,YAAY,EACV,cAAc,EACd,gBAAgB,EAChB,SAAS,EACT,kBAAkB,GACnB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AAC9E,YAAY,EACV,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,EACvB,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,+BAA+B,EAAE,MAAM,yBAAyB,CAAC;AAC/E,YAAY,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACxE,YAAY,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC"}
|