prool 0.0.25 → 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.
- package/{LICENSE → LICENSE.md} +1 -1
- package/README.md +46 -163
- package/{_lib/instance.d.ts → dist/Instance.d.ts} +28 -25
- package/dist/Instance.d.ts.map +1 -0
- package/{_lib/instance.js → dist/Instance.js} +9 -4
- package/dist/Instance.js.map +1 -0
- package/{_lib/pool.d.ts → dist/Pool.d.ts} +15 -13
- package/dist/Pool.d.ts.map +1 -0
- package/{_lib/pool.js → dist/Pool.js} +3 -3
- package/dist/Pool.js.map +1 -0
- package/{_lib/server.d.ts → dist/Server.d.ts} +7 -10
- package/dist/Server.d.ts.map +1 -0
- package/{_lib/server.js → dist/Server.js} +8 -9
- package/dist/Server.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/instances/alto.d.ts +452 -0
- package/dist/instances/alto.d.ts.map +1 -0
- package/{_lib → dist}/instances/alto.js +4 -4
- package/dist/instances/alto.js.map +1 -0
- package/dist/instances/anvil.d.ts +458 -0
- package/dist/instances/anvil.d.ts.map +1 -0
- package/{_lib → dist}/instances/anvil.js +4 -4
- package/dist/instances/anvil.js.map +1 -0
- package/dist/instances/tempo.d.ts +157 -0
- package/dist/instances/tempo.d.ts.map +1 -0
- package/dist/instances/tempo.js +187 -0
- package/dist/instances/tempo.js.map +1 -0
- package/dist/internal/utils.d.ts.map +1 -0
- package/{_lib → dist/internal}/utils.js +1 -1
- package/dist/internal/utils.js.map +1 -0
- package/{_lib → dist}/processes/execa.d.ts +11 -10
- package/dist/processes/execa.d.ts.map +1 -0
- package/{_lib → dist}/processes/execa.js +1 -1
- package/dist/processes/execa.js.map +1 -0
- package/package.json +17 -16
- package/{instance.test.ts → src/Instance.test.ts} +12 -12
- package/{instance.ts → src/Instance.ts} +51 -42
- package/{pool.test.ts → src/Pool.test.ts} +41 -55
- package/{pool.ts → src/Pool.ts} +21 -19
- package/{server.test.ts → src/Server.test.ts} +26 -149
- package/{server.ts → src/Server.ts} +9 -11
- package/src/index.ts +3 -0
- package/{instances → src/instances}/alto.test.ts +8 -11
- package/src/instances/alto.ts +289 -0
- package/{instances → src/instances}/anvil.test.ts +5 -6
- package/src/instances/anvil.ts +306 -0
- package/{instances/silius.test.ts → src/instances/tempo.test.ts} +20 -44
- package/src/instances/tempo.ts +278 -0
- package/{utils.test.ts → src/internal/utils.test.ts} +6 -6
- package/{utils.ts → src/internal/utils.ts} +1 -1
- package/{processes → src/processes}/execa.test.ts +6 -11
- package/{processes → src/processes}/execa.ts +19 -15
- package/src/processes/index.ts +1 -0
- package/CHANGELOG.md +0 -154
- package/_lib/exports/index.d.ts +0 -5
- package/_lib/exports/index.d.ts.map +0 -1
- package/_lib/exports/index.js +0 -5
- package/_lib/exports/index.js.map +0 -1
- package/_lib/exports/instances.d.ts +0 -7
- package/_lib/exports/instances.d.ts.map +0 -1
- package/_lib/exports/instances.js +0 -7
- package/_lib/exports/instances.js.map +0 -1
- package/_lib/exports/processes.d.ts +0 -2
- package/_lib/exports/processes.d.ts.map +0 -1
- package/_lib/exports/processes.js +0 -2
- package/_lib/exports/processes.js.map +0 -1
- package/_lib/instance.d.ts.map +0 -1
- package/_lib/instance.js.map +0 -1
- package/_lib/instances/alto.d.ts +0 -449
- package/_lib/instances/alto.d.ts.map +0 -1
- package/_lib/instances/alto.js.map +0 -1
- package/_lib/instances/anvil.d.ts +0 -455
- package/_lib/instances/anvil.d.ts.map +0 -1
- package/_lib/instances/anvil.js.map +0 -1
- package/_lib/instances/rundler.d.ts +0 -604
- package/_lib/instances/rundler.d.ts.map +0 -1
- package/_lib/instances/rundler.js +0 -86
- package/_lib/instances/rundler.js.map +0 -1
- package/_lib/instances/silius.d.ts +0 -224
- package/_lib/instances/silius.d.ts.map +0 -1
- package/_lib/instances/silius.js +0 -117
- package/_lib/instances/silius.js.map +0 -1
- package/_lib/instances/stackup.d.ts +0 -86
- package/_lib/instances/stackup.d.ts.map +0 -1
- package/_lib/instances/stackup.js +0 -89
- package/_lib/instances/stackup.js.map +0 -1
- package/_lib/pool.d.ts.map +0 -1
- package/_lib/pool.js.map +0 -1
- package/_lib/processes/execa.d.ts.map +0 -1
- package/_lib/processes/execa.js.map +0 -1
- package/_lib/server.d.ts.map +0 -1
- package/_lib/server.js.map +0 -1
- package/_lib/utils.d.ts.map +0 -1
- package/_lib/utils.js.map +0 -1
- package/exports/index.test.ts +0 -16
- package/exports/index.ts +0 -29
- package/exports/instances.test.ts +0 -15
- package/exports/instances.ts +0 -13
- package/exports/processes.test.ts +0 -10
- package/exports/processes.ts +0 -8
- package/instances/alto.ts +0 -280
- package/instances/anvil.ts +0 -304
- package/instances/package.json +0 -5
- package/instances/rundler.test.ts +0 -111
- package/instances/rundler.ts +0 -451
- package/instances/silius.ts +0 -347
- package/instances/stackup.test.ts +0 -106
- package/instances/stackup.ts +0 -162
- package/processes/package.json +0 -5
- package/tsconfig.build.tsbuildinfo +0 -1
- /package/{_lib → dist/internal}/utils.d.ts +0 -0
package/instances/silius.ts
DELETED
|
@@ -1,347 +0,0 @@
|
|
|
1
|
-
import { platform } from 'node:os'
|
|
2
|
-
|
|
3
|
-
import { rmSync } from 'node:fs'
|
|
4
|
-
import { defineInstance } from '../instance.js'
|
|
5
|
-
import { execa } from '../processes/execa.js'
|
|
6
|
-
import { toArgs } from '../utils.js'
|
|
7
|
-
|
|
8
|
-
export type SiliusParameters = {
|
|
9
|
-
/**
|
|
10
|
-
* The bundler beneficiary address.
|
|
11
|
-
*/
|
|
12
|
-
beneficiary?: string | undefined
|
|
13
|
-
/**
|
|
14
|
-
* The bundle interval in seconds.
|
|
15
|
-
* @default 10
|
|
16
|
-
*/
|
|
17
|
-
bundleInterval?: number | undefined
|
|
18
|
-
bundler?:
|
|
19
|
-
| {
|
|
20
|
-
/**
|
|
21
|
-
* Bundler gRPC address to listen on.
|
|
22
|
-
* @default '127.0.0.1'
|
|
23
|
-
*/
|
|
24
|
-
addr?: string | undefined
|
|
25
|
-
/**
|
|
26
|
-
* Bundler gRPC port to listen on.
|
|
27
|
-
* @default 3003
|
|
28
|
-
*/
|
|
29
|
-
port?: number | undefined
|
|
30
|
-
}
|
|
31
|
-
| undefined
|
|
32
|
-
/**
|
|
33
|
-
* The chain id.
|
|
34
|
-
* @default 1
|
|
35
|
-
*/
|
|
36
|
-
chain?: number | undefined
|
|
37
|
-
/**
|
|
38
|
-
* Path to the data directory.
|
|
39
|
-
*/
|
|
40
|
-
dataDir?: string | undefined
|
|
41
|
-
discovery?:
|
|
42
|
-
| {
|
|
43
|
-
/**
|
|
44
|
-
* The udp4 port to broadcast to peers in order to reach back for discovery.
|
|
45
|
-
* @default 9000
|
|
46
|
-
*/
|
|
47
|
-
port?: number | undefined
|
|
48
|
-
}
|
|
49
|
-
| undefined
|
|
50
|
-
/**
|
|
51
|
-
* Indicates whether the access list is enabled.
|
|
52
|
-
*/
|
|
53
|
-
enableAccessList?: boolean | undefined
|
|
54
|
-
/**
|
|
55
|
-
* Indicates whether the P2P mode is enabled.
|
|
56
|
-
*/
|
|
57
|
-
enableP2p?: boolean | undefined
|
|
58
|
-
/**
|
|
59
|
-
* Indicates whether the metrics are enabled.
|
|
60
|
-
*/
|
|
61
|
-
enableMetrics?: boolean | undefined
|
|
62
|
-
/**
|
|
63
|
-
* The entry points for the bundler.
|
|
64
|
-
*/
|
|
65
|
-
entryPoints?: string[] | undefined
|
|
66
|
-
/**
|
|
67
|
-
* RPC URL of the execution client.
|
|
68
|
-
*/
|
|
69
|
-
ethClientAddress?: string | undefined
|
|
70
|
-
/**
|
|
71
|
-
* Ethereum execution client proxy HTTP RPC endpoint.
|
|
72
|
-
*/
|
|
73
|
-
ethClientProxyAddress?: string | undefined
|
|
74
|
-
http?:
|
|
75
|
-
| {
|
|
76
|
-
/**
|
|
77
|
-
* HTTP address to listen on.
|
|
78
|
-
* @default '127.0.0.1'
|
|
79
|
-
*/
|
|
80
|
-
addr?: string | undefined
|
|
81
|
-
/**
|
|
82
|
-
* Configures the HTTP RPC API modules
|
|
83
|
-
* @default 'eth'
|
|
84
|
-
*/
|
|
85
|
-
api?: string[] | undefined
|
|
86
|
-
/**
|
|
87
|
-
* Configures the allowed CORS domains.
|
|
88
|
-
* @default '*'
|
|
89
|
-
*/
|
|
90
|
-
corsdomain?: string[] | undefined
|
|
91
|
-
/**
|
|
92
|
-
* HTTP port to listen on.
|
|
93
|
-
* @default 3000
|
|
94
|
-
*/
|
|
95
|
-
port?: number | undefined
|
|
96
|
-
}
|
|
97
|
-
| undefined
|
|
98
|
-
/**
|
|
99
|
-
* Maximum gas for verification.
|
|
100
|
-
* @default 5000000
|
|
101
|
-
*/
|
|
102
|
-
maxVerificationGas?: bigint | undefined
|
|
103
|
-
metrics?:
|
|
104
|
-
| {
|
|
105
|
-
/**
|
|
106
|
-
* Metrics address to listen on.
|
|
107
|
-
* @default '127.0.0.1'
|
|
108
|
-
*/
|
|
109
|
-
addr?: string | undefined
|
|
110
|
-
/**
|
|
111
|
-
* Metrics port to listen on.
|
|
112
|
-
* @default 3030
|
|
113
|
-
*/
|
|
114
|
-
port?: number | undefined
|
|
115
|
-
}
|
|
116
|
-
| undefined
|
|
117
|
-
/**
|
|
118
|
-
* Minimum balance for the beneficiary account.
|
|
119
|
-
* @default 100000000000000000 wei
|
|
120
|
-
*/
|
|
121
|
-
minBalance?: bigint | undefined
|
|
122
|
-
/**
|
|
123
|
-
* Minimum priority fee per gas.
|
|
124
|
-
* @default 0
|
|
125
|
-
*/
|
|
126
|
-
minPriorityFeePerGas?: bigint | undefined
|
|
127
|
-
/**
|
|
128
|
-
* Minimum stake required for entities.
|
|
129
|
-
* @default 1
|
|
130
|
-
*/
|
|
131
|
-
minStake?: number | undefined
|
|
132
|
-
/**
|
|
133
|
-
* Path to the mnemonic file.
|
|
134
|
-
*/
|
|
135
|
-
mnemonicPath: string | undefined
|
|
136
|
-
/**
|
|
137
|
-
* The path to the file where the p2p private key is stored.
|
|
138
|
-
*/
|
|
139
|
-
nodekey?: string | undefined
|
|
140
|
-
/**
|
|
141
|
-
* The path to the file where the p2p enr is stored.
|
|
142
|
-
*/
|
|
143
|
-
nodeenr?: string | undefined
|
|
144
|
-
p2p?:
|
|
145
|
-
| {
|
|
146
|
-
/**
|
|
147
|
-
* Sets the p2p listen address
|
|
148
|
-
* @default '0.0.0.0'
|
|
149
|
-
*/
|
|
150
|
-
addr?: string | undefined
|
|
151
|
-
/**
|
|
152
|
-
* The ipv4 address to broadcast to peers about which address we are listening on.
|
|
153
|
-
*/
|
|
154
|
-
baddr?: string | undefined
|
|
155
|
-
/**
|
|
156
|
-
* The tcp4 port to boardcast to peers in order to reach back for discovery.
|
|
157
|
-
* @default 9000
|
|
158
|
-
*/
|
|
159
|
-
bport?: number | undefined
|
|
160
|
-
}
|
|
161
|
-
| undefined
|
|
162
|
-
/**
|
|
163
|
-
* Poll interval event filters and pending transactions in milliseconds.
|
|
164
|
-
* @default 500
|
|
165
|
-
*/
|
|
166
|
-
pollInterval?: number | undefined
|
|
167
|
-
/**
|
|
168
|
-
* Port to start the instance on.
|
|
169
|
-
*/
|
|
170
|
-
port?: number | undefined
|
|
171
|
-
/**
|
|
172
|
-
* Sets the send bundle mode.
|
|
173
|
-
* @default "ethereum-client"
|
|
174
|
-
*/
|
|
175
|
-
sendBundleMode?: string | undefined
|
|
176
|
-
uopool?:
|
|
177
|
-
| {
|
|
178
|
-
/**
|
|
179
|
-
* UoPool gRPC address to listen on.
|
|
180
|
-
* @default '127.0.0.1'
|
|
181
|
-
*/
|
|
182
|
-
addr?: string | undefined
|
|
183
|
-
/**
|
|
184
|
-
* UoPool gRPC port to listen on.
|
|
185
|
-
* @default 3002
|
|
186
|
-
*/
|
|
187
|
-
port?: number | undefined
|
|
188
|
-
}
|
|
189
|
-
| undefined
|
|
190
|
-
/**
|
|
191
|
-
* Sets the UoPool mode.
|
|
192
|
-
*/
|
|
193
|
-
uopoolMode?: string | undefined
|
|
194
|
-
/**
|
|
195
|
-
* Sets the verbosity level.
|
|
196
|
-
* @default 2
|
|
197
|
-
*/
|
|
198
|
-
verbosity?: number | undefined
|
|
199
|
-
/**
|
|
200
|
-
* Addresses of whitelisted entities.
|
|
201
|
-
*/
|
|
202
|
-
whitelist?: string[] | undefined
|
|
203
|
-
ws?:
|
|
204
|
-
| {
|
|
205
|
-
/**
|
|
206
|
-
* WS address to listen on.
|
|
207
|
-
* @default '127.0.0.1'
|
|
208
|
-
*/
|
|
209
|
-
addr?: string | undefined
|
|
210
|
-
/**
|
|
211
|
-
* Configures the HTTP RPC API modules
|
|
212
|
-
* @default 'eth'
|
|
213
|
-
*/
|
|
214
|
-
api?: string[] | undefined
|
|
215
|
-
/**
|
|
216
|
-
* Configures the allowed WS origins.
|
|
217
|
-
* @default '*'
|
|
218
|
-
*/
|
|
219
|
-
origins?: string[] | undefined
|
|
220
|
-
/**
|
|
221
|
-
* WS port to listen on.
|
|
222
|
-
* @default 3001
|
|
223
|
-
*/
|
|
224
|
-
port?: number | undefined
|
|
225
|
-
}
|
|
226
|
-
| undefined
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
* Defines an Anvil instance.
|
|
231
|
-
*
|
|
232
|
-
* @example
|
|
233
|
-
* ```ts
|
|
234
|
-
* const instance = silius({
|
|
235
|
-
* port: 4337,
|
|
236
|
-
* })
|
|
237
|
-
* await instance.start()
|
|
238
|
-
* // ...
|
|
239
|
-
* await instance.stop()
|
|
240
|
-
* ```
|
|
241
|
-
*/
|
|
242
|
-
export const silius = defineInstance((parameters?: SiliusParameters) => {
|
|
243
|
-
const args = (parameters || {}) as SiliusParameters
|
|
244
|
-
const { dataDir = '.local', mnemonicPath, port: _, ...rest } = args
|
|
245
|
-
|
|
246
|
-
const host = 'localhost'
|
|
247
|
-
const name = 'silius'
|
|
248
|
-
const process = execa({ name })
|
|
249
|
-
let port = args.port ?? 4000
|
|
250
|
-
|
|
251
|
-
return {
|
|
252
|
-
_internal: {
|
|
253
|
-
args,
|
|
254
|
-
get process() {
|
|
255
|
-
return process._internal.process
|
|
256
|
-
},
|
|
257
|
-
},
|
|
258
|
-
host,
|
|
259
|
-
name,
|
|
260
|
-
port,
|
|
261
|
-
async start({ port: port_ = port }, options) {
|
|
262
|
-
port = port_
|
|
263
|
-
|
|
264
|
-
const args_ = [
|
|
265
|
-
...(platform() === 'linux' ? ['--net', 'host'] : []),
|
|
266
|
-
'--add-host',
|
|
267
|
-
'host.docker.internal:host-gateway',
|
|
268
|
-
'--add-host',
|
|
269
|
-
'localhost:host-gateway',
|
|
270
|
-
'-p',
|
|
271
|
-
`${port}:${port}`,
|
|
272
|
-
'-v',
|
|
273
|
-
`${mnemonicPath}:/data/silius/mnemonic`,
|
|
274
|
-
'-v',
|
|
275
|
-
`./${dataDir}/${port_}/db:/data/silius/db`,
|
|
276
|
-
'ghcr.io/silius-rs/silius:latest',
|
|
277
|
-
'node',
|
|
278
|
-
'--datadir',
|
|
279
|
-
'data/silius',
|
|
280
|
-
'--mnemonic-file',
|
|
281
|
-
'data/silius/mnemonic',
|
|
282
|
-
'--http',
|
|
283
|
-
'--ws',
|
|
284
|
-
...toArgs({
|
|
285
|
-
...rest,
|
|
286
|
-
beneficiary:
|
|
287
|
-
rest.beneficiary ?? '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
|
|
288
|
-
bundler: {
|
|
289
|
-
...rest.bundler,
|
|
290
|
-
addr: rest.bundler?.addr ?? '0.0.0.0',
|
|
291
|
-
},
|
|
292
|
-
entryPoints: rest.entryPoints ?? [
|
|
293
|
-
'0x0000000071727De22E5E9d8BAf0edAc6f37da032',
|
|
294
|
-
],
|
|
295
|
-
ethClientAddress: rest.ethClientAddress?.replaceAll(
|
|
296
|
-
/127\.0\.0\.1|0\.0\.0\.0/g,
|
|
297
|
-
'host.docker.internal',
|
|
298
|
-
),
|
|
299
|
-
ethClientProxyAddress: rest.ethClientProxyAddress?.replaceAll(
|
|
300
|
-
/127\.0\.0\.1|0\.0\.0\.0/g,
|
|
301
|
-
'host.docker.internal',
|
|
302
|
-
),
|
|
303
|
-
http: {
|
|
304
|
-
...rest.http,
|
|
305
|
-
addr: rest.http?.addr ?? '0.0.0.0',
|
|
306
|
-
api: rest.http?.api ?? ['eth', 'debug', 'web3'],
|
|
307
|
-
port,
|
|
308
|
-
},
|
|
309
|
-
metrics: {
|
|
310
|
-
...rest.metrics,
|
|
311
|
-
addr: rest.metrics?.addr ?? '0.0.0.0',
|
|
312
|
-
},
|
|
313
|
-
uopool: {
|
|
314
|
-
...rest.uopool,
|
|
315
|
-
addr: rest.uopool?.addr ?? '0.0.0.0',
|
|
316
|
-
},
|
|
317
|
-
ws: {
|
|
318
|
-
...rest.ws,
|
|
319
|
-
addr: rest.ws?.addr ?? '0.0.0.0',
|
|
320
|
-
api: rest.ws?.api ?? ['eth', 'debug', 'web3'],
|
|
321
|
-
port: rest.ws?.port ?? 4001,
|
|
322
|
-
},
|
|
323
|
-
} satisfies Partial<SiliusParameters>),
|
|
324
|
-
]
|
|
325
|
-
|
|
326
|
-
return await process.start(($) => $`docker run ${args_}`, {
|
|
327
|
-
...options,
|
|
328
|
-
resolver({ process, resolve, reject }) {
|
|
329
|
-
process.stdout.on('data', (data) => {
|
|
330
|
-
const message = data.toString()
|
|
331
|
-
if (message.includes('Started bundler JSON-RPC server')) resolve()
|
|
332
|
-
})
|
|
333
|
-
process.stderr.on('data', (data) => {
|
|
334
|
-
if (data.toString().includes('WARNING')) return
|
|
335
|
-
reject(data)
|
|
336
|
-
})
|
|
337
|
-
},
|
|
338
|
-
})
|
|
339
|
-
},
|
|
340
|
-
async stop() {
|
|
341
|
-
try {
|
|
342
|
-
rmSync(`${dataDir}/${port}`, { recursive: true, force: true })
|
|
343
|
-
} catch {}
|
|
344
|
-
await process.stop()
|
|
345
|
-
},
|
|
346
|
-
}
|
|
347
|
-
})
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import getPort from 'get-port'
|
|
2
|
-
import { afterEach, beforeAll, expect, test } from 'vitest'
|
|
3
|
-
|
|
4
|
-
import { stackupOptions } from '../../test/utils.js'
|
|
5
|
-
import type { Instance } from '../instance.js'
|
|
6
|
-
import { anvil } from './anvil.js'
|
|
7
|
-
import { type StackupParameters, stackup } from './stackup.js'
|
|
8
|
-
|
|
9
|
-
const instances: Instance[] = []
|
|
10
|
-
|
|
11
|
-
const port = await getPort()
|
|
12
|
-
|
|
13
|
-
const defineInstance = (parameters?: Partial<StackupParameters>) => {
|
|
14
|
-
const instance = stackup({
|
|
15
|
-
...stackupOptions({ port, pool: false }),
|
|
16
|
-
...parameters,
|
|
17
|
-
})
|
|
18
|
-
instances.push(instance)
|
|
19
|
-
return instance
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
beforeAll(() => anvil({ port }).start())
|
|
23
|
-
|
|
24
|
-
afterEach(async () => {
|
|
25
|
-
for (const instance of instances) await instance.stop().catch(() => {})
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
test('default', async () => {
|
|
29
|
-
const messages: string[] = []
|
|
30
|
-
const stdouts: string[] = []
|
|
31
|
-
|
|
32
|
-
const instance = defineInstance()
|
|
33
|
-
|
|
34
|
-
instance.on('message', (m) => messages.push(m))
|
|
35
|
-
instance.on('stdout', (m) => stdouts.push(m))
|
|
36
|
-
|
|
37
|
-
expect(instance.messages.get()).toMatchInlineSnapshot('[]')
|
|
38
|
-
|
|
39
|
-
await instance.start()
|
|
40
|
-
expect(instance.status).toEqual('started')
|
|
41
|
-
|
|
42
|
-
expect(messages.join('')).toBeDefined()
|
|
43
|
-
expect(stdouts.join('')).toBeDefined()
|
|
44
|
-
expect(instance.messages.get().join('')).toBeDefined()
|
|
45
|
-
|
|
46
|
-
await instance.stop()
|
|
47
|
-
expect(instance.status).toEqual('stopped')
|
|
48
|
-
|
|
49
|
-
expect(messages.join('')).toBeDefined()
|
|
50
|
-
expect(stdouts.join('')).toBeDefined()
|
|
51
|
-
expect(instance.messages.get()).toMatchInlineSnapshot('[]')
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
test('behavior: instance errored (duplicate ports)', async () => {
|
|
55
|
-
const instance_1 = defineInstance({
|
|
56
|
-
port: 1337,
|
|
57
|
-
})
|
|
58
|
-
const instance_2 = defineInstance({
|
|
59
|
-
port: 1337,
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
await instance_1.start()
|
|
63
|
-
await expect(() => instance_2.start()).rejects.toThrowError()
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
test('behavior: start and stop multiple times', async () => {
|
|
67
|
-
const instance = defineInstance()
|
|
68
|
-
|
|
69
|
-
await instance.start()
|
|
70
|
-
await instance.stop()
|
|
71
|
-
await instance.start()
|
|
72
|
-
await instance.stop()
|
|
73
|
-
await instance.start()
|
|
74
|
-
await instance.stop()
|
|
75
|
-
await instance.start()
|
|
76
|
-
await instance.stop()
|
|
77
|
-
})
|
|
78
|
-
|
|
79
|
-
test('behavior: can subscribe to stderr', async () => {
|
|
80
|
-
const messages: string[] = []
|
|
81
|
-
|
|
82
|
-
const instance_1 = defineInstance({ port: 1337 })
|
|
83
|
-
const instance_2 = defineInstance({ port: 1337 })
|
|
84
|
-
|
|
85
|
-
await instance_1.start()
|
|
86
|
-
instance_2.on('stderr', (message) => messages.push(message))
|
|
87
|
-
await expect(instance_2.start()).rejects.toThrowError()
|
|
88
|
-
})
|
|
89
|
-
|
|
90
|
-
test('behavior: exit', async () => {
|
|
91
|
-
const instance = defineInstance()
|
|
92
|
-
|
|
93
|
-
let exitCode: number | null | undefined = undefined
|
|
94
|
-
instance.on('exit', (code) => {
|
|
95
|
-
exitCode = code
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
await instance.start()
|
|
99
|
-
expect(instance.status).toEqual('started')
|
|
100
|
-
|
|
101
|
-
instance._internal.process.kill()
|
|
102
|
-
|
|
103
|
-
await new Promise<void>((res) => setTimeout(res, 100))
|
|
104
|
-
expect(instance.status).toEqual('stopped')
|
|
105
|
-
expect(typeof exitCode !== 'undefined').toBeTruthy()
|
|
106
|
-
})
|
package/instances/stackup.ts
DELETED
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
import { platform } from 'node:os'
|
|
2
|
-
import { defineInstance } from '../instance.js'
|
|
3
|
-
import { execa } from '../processes/execa.js'
|
|
4
|
-
|
|
5
|
-
export type StackupParameters = {
|
|
6
|
-
/**
|
|
7
|
-
* The name of the native tracer to use during validation. This will be "bundlerCollectorTracer" if using builds from ERC-4337 execution client repo.
|
|
8
|
-
* Defaults to address of `privateKey`.
|
|
9
|
-
*/
|
|
10
|
-
beneficiary?: string | undefined
|
|
11
|
-
/**
|
|
12
|
-
* Directory to store the embedded database.
|
|
13
|
-
* @default /tmp/stackup_bundler
|
|
14
|
-
*/
|
|
15
|
-
dataDirectory?: string | undefined
|
|
16
|
-
/**
|
|
17
|
-
* RPC url to the execution client.
|
|
18
|
-
*/
|
|
19
|
-
ethClientUrl: string
|
|
20
|
-
/**
|
|
21
|
-
* A boolean value for bundlers on an Arbitrum stack network to properly account for the L1 callData cost.
|
|
22
|
-
* @default false
|
|
23
|
-
*/
|
|
24
|
-
isArbStackNetwork?: boolean | undefined
|
|
25
|
-
/**
|
|
26
|
-
* A boolean value for bundlers on an OP stack network to properly account for the L1 callData cost.
|
|
27
|
-
* @default false
|
|
28
|
-
*/
|
|
29
|
-
isOpStackNetwork?: boolean | undefined
|
|
30
|
-
/**
|
|
31
|
-
* A boolean value for bundlers on a network that supports RIP-7212 precompile for secp256r1 signature verification.
|
|
32
|
-
* @default false
|
|
33
|
-
*/
|
|
34
|
-
isRip7212Supported?: boolean | undefined
|
|
35
|
-
/**
|
|
36
|
-
* The maximum gas limit that can be submitted per UserOperation batch.
|
|
37
|
-
* @default 18_000_000
|
|
38
|
-
*/
|
|
39
|
-
maxBatchGasLimit?: number | undefined
|
|
40
|
-
/**
|
|
41
|
-
* The maximum duration that a userOp can stay in the mempool before getting dropped.
|
|
42
|
-
* @default 180
|
|
43
|
-
*/
|
|
44
|
-
maxOpTtlSeconds?: number | undefined
|
|
45
|
-
/**
|
|
46
|
-
* The maximum verificationGasLimit on a received UserOperation.
|
|
47
|
-
* @default 6_000_000
|
|
48
|
-
*/
|
|
49
|
-
maxVerificationGas?: number | undefined
|
|
50
|
-
/**
|
|
51
|
-
* The maximum block range when looking up a User Operation with eth_getUserOperationReceipt or eth_getUserOperationByHash.
|
|
52
|
-
*
|
|
53
|
-
* Higher limits allow for fetching older User Operations but will result in higher request latency due to additional compute on the underlying node.
|
|
54
|
-
*
|
|
55
|
-
* @default 2_000
|
|
56
|
-
*/
|
|
57
|
-
opLookupLimit?: number | undefined
|
|
58
|
-
/**
|
|
59
|
-
* Port to start the instance on.
|
|
60
|
-
*/
|
|
61
|
-
port?: number | undefined
|
|
62
|
-
/**
|
|
63
|
-
* The private key for the EOA used to relay User Operation bundles to the EntryPoint.
|
|
64
|
-
*/
|
|
65
|
-
privateKey: string
|
|
66
|
-
/**
|
|
67
|
-
* EntryPoint addresses to support. The first address is the preferred EntryPoint.
|
|
68
|
-
*/
|
|
69
|
-
supportedEntryPoints?: string[]
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Defines an Anvil instance.
|
|
74
|
-
*
|
|
75
|
-
* @example
|
|
76
|
-
* ```ts
|
|
77
|
-
* const instance = stackup({
|
|
78
|
-
* ethClientUrl: 'http://localhost:8545',
|
|
79
|
-
* port: 4337,
|
|
80
|
-
* privateKey: '0x...'
|
|
81
|
-
* })
|
|
82
|
-
* await instance.start()
|
|
83
|
-
* // ...
|
|
84
|
-
* await instance.stop()
|
|
85
|
-
* ```
|
|
86
|
-
*/
|
|
87
|
-
export const stackup = defineInstance((parameters?: StackupParameters) => {
|
|
88
|
-
const args = (parameters || {}) as StackupParameters
|
|
89
|
-
|
|
90
|
-
const host = 'localhost'
|
|
91
|
-
const name = 'stackup'
|
|
92
|
-
const process = execa({ name })
|
|
93
|
-
|
|
94
|
-
return {
|
|
95
|
-
_internal: {
|
|
96
|
-
args,
|
|
97
|
-
get process() {
|
|
98
|
-
return process._internal.process
|
|
99
|
-
},
|
|
100
|
-
},
|
|
101
|
-
host,
|
|
102
|
-
name,
|
|
103
|
-
port: args.port ?? 4337,
|
|
104
|
-
async start({ port = args.port }, options) {
|
|
105
|
-
const args_ = [
|
|
106
|
-
...(platform() === 'linux' ? ['--net', 'host'] : []),
|
|
107
|
-
'--add-host',
|
|
108
|
-
'host.docker.internal:host-gateway',
|
|
109
|
-
'--add-host',
|
|
110
|
-
'localhost:host-gateway',
|
|
111
|
-
'-p',
|
|
112
|
-
`${port}:${port}`,
|
|
113
|
-
'-e',
|
|
114
|
-
`ERC4337_BUNDLER_PORT=${port}`,
|
|
115
|
-
...Object.entries(args).flatMap(([key, value]) => {
|
|
116
|
-
if (key === 'port') return []
|
|
117
|
-
if (value === undefined) return []
|
|
118
|
-
|
|
119
|
-
if (key === 'ethClientUrl')
|
|
120
|
-
value = (value as string).replaceAll(
|
|
121
|
-
/127\.0\.0\.1|0\.0\.0\.0/g,
|
|
122
|
-
'host.docker.internal',
|
|
123
|
-
)
|
|
124
|
-
if (key === 'privateKey') value = (value as string).replace('0x', '')
|
|
125
|
-
|
|
126
|
-
return [
|
|
127
|
-
'-e',
|
|
128
|
-
`ERC4337_BUNDLER_${key
|
|
129
|
-
.replace(/([a-z])([A-Z])/g, '$1_$2')
|
|
130
|
-
.toUpperCase()}=${value}`,
|
|
131
|
-
]
|
|
132
|
-
}),
|
|
133
|
-
'stackupwallet/stackup-bundler:latest',
|
|
134
|
-
'/app/stackup-bundler',
|
|
135
|
-
'start',
|
|
136
|
-
'--mode',
|
|
137
|
-
'private',
|
|
138
|
-
]
|
|
139
|
-
return await process.start(($) => $`docker run ${args_}`, {
|
|
140
|
-
...options,
|
|
141
|
-
resolver({ process, resolve, reject }) {
|
|
142
|
-
process.stderr.on('data', async (data) => {
|
|
143
|
-
const message = data.toString()
|
|
144
|
-
// For some reason, `stackup-bundler` logs to stderr. So we have to try
|
|
145
|
-
// and dissect what is an error, and what is not. 😅
|
|
146
|
-
if (message.includes('Set nextTxnTs to'))
|
|
147
|
-
setTimeout(() => resolve(), 100)
|
|
148
|
-
else if (
|
|
149
|
-
message
|
|
150
|
-
.toLowerCase()
|
|
151
|
-
.match(/panic|error|connection refused|address already in use/)
|
|
152
|
-
)
|
|
153
|
-
reject(data)
|
|
154
|
-
})
|
|
155
|
-
},
|
|
156
|
-
})
|
|
157
|
-
},
|
|
158
|
-
async stop() {
|
|
159
|
-
await process.stop()
|
|
160
|
-
},
|
|
161
|
-
}
|
|
162
|
-
})
|