@argonprotocol/testing 1.1.0-rc.2

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/lib/index.cjs ADDED
@@ -0,0 +1,662 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ TestBitcoinCli: () => TestBitcoinCli,
34
+ TestMainchain: () => TestMainchain,
35
+ TestNotary: () => TestNotary,
36
+ TestOracle: () => TestOracle,
37
+ activateNotary: () => activateNotary,
38
+ addTeardown: () => addTeardown,
39
+ cleanHostForDocker: () => cleanHostForDocker,
40
+ closeOnTeardown: () => closeOnTeardown,
41
+ describeIntegration: () => describeIntegration,
42
+ disconnectOnTeardown: () => disconnectOnTeardown,
43
+ getDockerPortMapping: () => getDockerPortMapping,
44
+ getProxy: () => getProxy,
45
+ projectRoot: () => projectRoot,
46
+ runTestScript: () => runTestScript,
47
+ sudo: () => sudo,
48
+ teardown: () => teardown
49
+ });
50
+ module.exports = __toCommonJS(index_exports);
51
+ var import_mainchain4 = require("@argonprotocol/mainchain");
52
+ var import_vitest = require("vitest");
53
+ var process4 = __toESM(require("process"), 1);
54
+ var import_http_proxy = __toESM(require("http-proxy"), 1);
55
+ var child_process4 = __toESM(require("child_process"), 1);
56
+ var http = __toESM(require("http"), 1);
57
+ var url = __toESM(require("url"), 1);
58
+ var Path5 = __toESM(require("path"), 1);
59
+
60
+ // src/TestNotary.ts
61
+ var import_nanoid = require("nanoid");
62
+ var import_pg = __toESM(require("pg"), 1);
63
+ var child_process = __toESM(require("child_process"), 1);
64
+ var import_mainchain = require("@argonprotocol/mainchain");
65
+ var fs = __toESM(require("fs"), 1);
66
+ var readline = __toESM(require("readline"), 1);
67
+ var process2 = __toESM(require("process"), 1);
68
+ var Path = __toESM(require("path"), 1);
69
+ var { Client: PgClient } = import_pg.default;
70
+ var nanoid = (0, import_nanoid.customAlphabet)("0123456789abcdefghijklmnopqrstuvwxyz", 4);
71
+ function createUid() {
72
+ return nanoid();
73
+ }
74
+ var TestNotary = class {
75
+ operator;
76
+ ip = "127.0.0.1";
77
+ registeredPublicKey;
78
+ port;
79
+ containerName;
80
+ proxy;
81
+ #dbName;
82
+ #dbConnectionString;
83
+ #childProcess;
84
+ #stdioInterface;
85
+ get address() {
86
+ if (this.proxy) {
87
+ const url2 = new URL(this.proxy);
88
+ url2.searchParams.set("target", `ws://${this.ip}:${this.port}`);
89
+ return url2.href;
90
+ }
91
+ return `ws://${this.ip}:${this.port}`;
92
+ }
93
+ constructor(dbConnectionString) {
94
+ this.#dbConnectionString = dbConnectionString ?? process2.env.NOTARY_DB_URL ?? "postgres://postgres:postgres@localhost:5432";
95
+ addTeardown(this);
96
+ }
97
+ /**
98
+ * Returns the localhost address of the notary (NOTE: not accessible from containers)
99
+ */
100
+ async start(options) {
101
+ const { pathToNotaryBin, uuid, mainchainUrl } = options;
102
+ this.operator = new import_mainchain.Keyring({ type: "sr25519" }).createFromUri("//Bob");
103
+ this.registeredPublicKey = new import_mainchain.Keyring({ type: "ed25519" }).createFromUri(
104
+ "//Ferdie//notary"
105
+ ).publicKey;
106
+ let notaryPath = pathToNotaryBin ?? Path.join(projectRoot(), "target/debug/argon-notary");
107
+ if (process2.env.ARGON_USE_DOCKER_BINS) {
108
+ this.containerName = "notary_" + uuid;
109
+ const addHost = process2.env.ADD_DOCKER_HOST ? ` --add-host=host.docker.internal:host-gateway` : "";
110
+ notaryPath = `docker run --rm -p=0:9925${addHost} --name=${this.containerName} -e RUST_LOG=warn ghcr.io/argonprotocol/argon-notary:dev`;
111
+ this.#dbConnectionString = cleanHostForDocker(this.#dbConnectionString);
112
+ } else if (!fs.existsSync(notaryPath)) {
113
+ throw new Error(`Notary binary not found at ${notaryPath}`);
114
+ }
115
+ const client = await this.connect();
116
+ let dbName = "";
117
+ try {
118
+ let tries = 10;
119
+ while (tries > 0) {
120
+ dbName = `notary_${uuid}`;
121
+ const result2 = await client.query(
122
+ "SELECT 1 FROM pg_database WHERE datname = $1",
123
+ [dbName]
124
+ );
125
+ if (result2.rowCount === 0) {
126
+ break;
127
+ }
128
+ tries -= 1;
129
+ }
130
+ this.#dbName = dbName;
131
+ await client.query(`CREATE DATABASE "${dbName}"`);
132
+ } finally {
133
+ await client.end();
134
+ }
135
+ let result = child_process.execSync(
136
+ `${notaryPath} migrate --db-url ${this.#dbConnectionString}/${this.#dbName}`,
137
+ {
138
+ encoding: "utf-8"
139
+ }
140
+ );
141
+ if (result.trim().length) {
142
+ console.log(result.trim());
143
+ }
144
+ console.log(
145
+ "Notary >> connecting to mainchain '%s', db %s",
146
+ mainchainUrl,
147
+ `${this.#dbConnectionString}/${this.#dbName}`
148
+ );
149
+ const bucketName = `notary-${uuid}`;
150
+ const execArgs = [
151
+ "run",
152
+ `--db-url=${this.#dbConnectionString}/${this.#dbName}`,
153
+ `--dev`,
154
+ `-t ${mainchainUrl}`,
155
+ `--archive-bucket=${bucketName}`,
156
+ `--operator-address=${this.operator.address}`
157
+ ];
158
+ if (process2.env.ARGON_USE_DOCKER_BINS) {
159
+ process2.env.AWS_S3_ENDPOINT = "http://host.docker.internal:9000";
160
+ execArgs.unshift(...notaryPath.replace("docker run", "run").split(" "));
161
+ execArgs.push("-b=0.0.0.0:9925");
162
+ notaryPath = "docker";
163
+ }
164
+ if (process2.env.AWS_S3_ENDPOINT) {
165
+ execArgs.push(`--archive-endpoint=${process2.env.AWS_S3_ENDPOINT}`);
166
+ }
167
+ this.#childProcess = child_process.spawn(notaryPath, execArgs, {
168
+ stdio: ["ignore", "pipe", "pipe"],
169
+ env: { ...process2.env, RUST_LOG: "warn" }
170
+ });
171
+ this.#childProcess.stdout.setEncoding("utf8");
172
+ this.#childProcess.stderr.setEncoding("utf8");
173
+ this.port = await new Promise((resolve3, reject) => {
174
+ const onProcessError = (err) => {
175
+ console.warn("Error running notary", err);
176
+ reject(err);
177
+ };
178
+ this.#childProcess.once("error", onProcessError);
179
+ this.#childProcess.stderr.on("data", (data) => {
180
+ console.warn("Notary >> %s", data);
181
+ if (data.startsWith("WARNING")) return;
182
+ this.#childProcess.off("error", onProcessError);
183
+ reject(data);
184
+ });
185
+ this.#stdioInterface = readline.createInterface({ input: this.#childProcess.stdout }).on("line", (line) => {
186
+ console.log("Notary >> %s", line);
187
+ let match = line.match(/Listening on ([ws:/\d.]+)/);
188
+ if (match?.length ?? 0 > 0) {
189
+ resolve3(match[1].split(":").pop());
190
+ }
191
+ });
192
+ });
193
+ this.#childProcess.on("error", (err) => {
194
+ throw err;
195
+ });
196
+ if (this.containerName) {
197
+ this.port = await getDockerPortMapping(this.containerName, 9925);
198
+ this.proxy = cleanHostForDocker(await getProxy());
199
+ }
200
+ return this.address;
201
+ }
202
+ async register(client) {
203
+ let address = new URL(this.address);
204
+ await new import_mainchain.TxSubmitter(
205
+ client,
206
+ client.tx.notaries.propose({
207
+ public: this.registeredPublicKey,
208
+ hosts: [address.href],
209
+ name: "Test Notary"
210
+ }),
211
+ this.operator
212
+ ).submit({ waitForBlock: true });
213
+ }
214
+ async teardown() {
215
+ this.#childProcess?.kill();
216
+ this.#stdioInterface?.close();
217
+ const client = await this.connect();
218
+ try {
219
+ await client.query(`DROP DATABASE "${this.#dbName}" WITH (FORCE)`);
220
+ } finally {
221
+ await client.end();
222
+ }
223
+ if (this.containerName) {
224
+ try {
225
+ child_process.execSync(`docker rm -f ${this.containerName}`);
226
+ } catch {
227
+ }
228
+ }
229
+ }
230
+ async connect() {
231
+ const client = new PgClient({ connectionString: this.#dbConnectionString });
232
+ try {
233
+ await client.connect();
234
+ } catch (err) {
235
+ console.error("ERROR connecting to postgres client", err);
236
+ throw err;
237
+ }
238
+ return client;
239
+ }
240
+ };
241
+
242
+ // src/TestMainchain.ts
243
+ var fs2 = __toESM(require("fs"), 1);
244
+ var import_node_child_process = require("child_process");
245
+ var Path2 = __toESM(require("path"), 1);
246
+ var readline2 = __toESM(require("readline"), 1);
247
+ var import_detect_port = require("detect-port");
248
+ var import_nanoid2 = require("nanoid");
249
+ var import_bitcoin_core = __toESM(require("bitcoin-core"), 1);
250
+ var import_mainchain2 = require("@argonprotocol/mainchain");
251
+ var nanoid2 = (0, import_nanoid2.customAlphabet)("0123456789abcdefghijklmnopqrstuvwxyz", 4);
252
+ var TestMainchain = class {
253
+ ip = "127.0.0.1";
254
+ port;
255
+ loglevel = "warn";
256
+ uuid;
257
+ #binPath;
258
+ #process;
259
+ #interfaces = [];
260
+ containerName;
261
+ proxy;
262
+ #bitcoind;
263
+ bitcoinPort;
264
+ get address() {
265
+ if (this.proxy) {
266
+ const url2 = new URL(this.proxy);
267
+ url2.searchParams.set("target", `ws://${this.ip}:${this.port}`);
268
+ return url2.href;
269
+ }
270
+ return `ws://${this.ip}:${this.port}`;
271
+ }
272
+ constructor(binPath) {
273
+ this.#binPath = binPath ?? Path2.join(projectRoot(), `target/debug/argon-node`);
274
+ this.#binPath = Path2.resolve(this.#binPath);
275
+ if (!process.env.ARGON_USE_DOCKER_BINS && !fs2.existsSync(this.#binPath)) {
276
+ throw new Error(`Mainchain binary not found at ${this.#binPath}`);
277
+ }
278
+ this.uuid = createUid();
279
+ addTeardown(this);
280
+ }
281
+ getBitcoinClient() {
282
+ return new import_bitcoin_core.default({
283
+ username: "bitcoin",
284
+ password: "bitcoin",
285
+ host: `http://localhost:${this.bitcoinPort}`
286
+ });
287
+ }
288
+ /**
289
+ * Launch and return the localhost url. NOTE: this url will not work cross-docker. You need to use the containerAddress property
290
+ * @param options
291
+ * @param options.miningThreads - number of threads to use for mining
292
+ * @param options.bootnodes - bootnodes to use for the mainchain
293
+ */
294
+ async launch(options) {
295
+ const {
296
+ miningThreads = 2,
297
+ bootnodes,
298
+ author = "alice",
299
+ launchBitcoin = false
300
+ } = options ?? {};
301
+ let port = 0;
302
+ let rpcPort = 0;
303
+ let execArgs = [];
304
+ let containerName;
305
+ if (process.env.ARGON_USE_DOCKER_BINS) {
306
+ containerName = "miner_" + nanoid2();
307
+ this.containerName = containerName;
308
+ this.#binPath = "docker";
309
+ port = 33344;
310
+ rpcPort = 9944;
311
+ execArgs = [
312
+ "run",
313
+ "--rm",
314
+ `--name=${containerName}`,
315
+ `-p=0:${port}`,
316
+ `-p=0:${rpcPort}`,
317
+ "-e",
318
+ `RUST_LOG=${this.loglevel},sc_rpc_server=info`,
319
+ "ghcr.io/argonprotocol/argon-miner:dev"
320
+ ];
321
+ if (process.env.ADD_DOCKER_HOST) {
322
+ execArgs.splice(2, 0, `--add-host=host.docker.internal:host-gateway`);
323
+ }
324
+ }
325
+ const bitcoinRpcUrl = await this.startBitcoin(launchBitcoin);
326
+ execArgs.push(
327
+ "--dev",
328
+ "--validator",
329
+ `--${author}`,
330
+ `--compute-miners=${miningThreads}`,
331
+ `--port=${port}`,
332
+ `--rpc-port=${rpcPort}`,
333
+ "--rpc-external",
334
+ "--unsafe-rpc-external",
335
+ "--rpc-methods=unsafe",
336
+ `--bitcoin-rpc-url=${bitcoinRpcUrl}`,
337
+ `--notebook-archive-hosts=http://127.0.0.1:9000/${this.uuid}`
338
+ );
339
+ if (bootnodes) {
340
+ execArgs.push(`--bootnodes=${bootnodes}`);
341
+ }
342
+ this.#process = (0, import_node_child_process.spawn)(this.#binPath, execArgs, {
343
+ stdio: ["ignore", "pipe", "pipe", "ignore"],
344
+ env: { ...process.env, RUST_LOG: `${this.loglevel},sc_rpc_server=info` }
345
+ });
346
+ this.#process.stderr.setEncoding("utf8");
347
+ this.#process.stdout.setEncoding("utf8");
348
+ this.#process.stdout.on("data", (data) => {
349
+ console.log("Main >> %s", data);
350
+ });
351
+ const int1 = readline2.createInterface({ input: this.#process.stdout }).on("line", (line) => {
352
+ if (line) console.log("Main >> %s", line);
353
+ });
354
+ this.#interfaces.push(int1);
355
+ this.port = await new Promise((resolve3, reject) => {
356
+ this.#process.on("error", (err) => {
357
+ console.warn("Error running mainchain", err);
358
+ reject(err);
359
+ });
360
+ const int2 = readline2.createInterface({ input: this.#process.stderr }).on("line", (line) => {
361
+ console.log("Main >> %s", line);
362
+ let match = line.match(/Running JSON-RPC server: addr=([\d.:]+)/);
363
+ if (match) {
364
+ let ipv4 = match[1].split(",").at(0);
365
+ resolve3(ipv4.split(":").pop());
366
+ }
367
+ });
368
+ this.#interfaces.push(int2);
369
+ });
370
+ if (this.containerName) {
371
+ this.port = await getDockerPortMapping(this.containerName, rpcPort);
372
+ this.proxy = cleanHostForDocker(await getProxy());
373
+ }
374
+ console.log(`argon Node listening at ${this.address}`);
375
+ return this.address;
376
+ }
377
+ async client() {
378
+ const client = await (0, import_mainchain2.getClient)(this.address);
379
+ disconnectOnTeardown(client);
380
+ return client;
381
+ }
382
+ async bootAddress() {
383
+ const client = await this.client();
384
+ const bootAddress = await client.rpc.system.localListenAddresses();
385
+ for (const address of bootAddress) {
386
+ const addr = address.toString();
387
+ if (addr.includes("127.0.0.1")) {
388
+ return addr;
389
+ }
390
+ }
391
+ return void 0;
392
+ }
393
+ async teardown() {
394
+ if (process.env.ARGON_USE_DOCKER_BINS) {
395
+ try {
396
+ (0, import_node_child_process.execSync)(`docker rm -f ${this.containerName}`);
397
+ } catch {
398
+ }
399
+ }
400
+ const launchedProcess = this.#process;
401
+ if (launchedProcess) {
402
+ launchedProcess?.kill();
403
+ try {
404
+ launchedProcess.stdio.forEach((io) => io?.destroy());
405
+ } catch {
406
+ }
407
+ launchedProcess.unref();
408
+ }
409
+ this.#process?.kill();
410
+ this.#process?.unref();
411
+ this.#bitcoind?.kill();
412
+ this.#bitcoind?.unref();
413
+ for (const i of this.#interfaces) {
414
+ i.close();
415
+ }
416
+ }
417
+ async startBitcoin(launchBitcoin) {
418
+ let rpcPort = 14338;
419
+ if (launchBitcoin) {
420
+ rpcPort = await (0, import_detect_port.detectPort)();
421
+ const path = (0, import_node_child_process.execSync)(
422
+ Path2.join(projectRoot(), `target/debug/argon-testing-bitcoin`),
423
+ {
424
+ encoding: "utf8"
425
+ }
426
+ ).trim();
427
+ const tmpDir = fs2.mkdtempSync("/tmp/argon-bitcoin-" + this.uuid);
428
+ this.#bitcoind = (0, import_node_child_process.spawn)(
429
+ path,
430
+ [
431
+ "-regtest",
432
+ "-fallbackfee=0.0001",
433
+ "-listen=0",
434
+ `-datadir=${tmpDir}`,
435
+ "-blockfilterindex",
436
+ "-txindex",
437
+ `-rpcport=${rpcPort}`,
438
+ "-rpcuser=bitcoin",
439
+ "-rpcpassword=bitcoin"
440
+ ],
441
+ {
442
+ stdio: ["ignore", "inherit", "inherit", "ignore"]
443
+ }
444
+ );
445
+ addTeardown({
446
+ async teardown() {
447
+ await fs2.promises.rm(tmpDir, {
448
+ recursive: true,
449
+ force: true
450
+ });
451
+ }
452
+ });
453
+ }
454
+ this.bitcoinPort = rpcPort;
455
+ return cleanHostForDocker(`http://bitcoin:bitcoin@localhost:${rpcPort}`);
456
+ }
457
+ };
458
+
459
+ // src/TestBitcoinCli.ts
460
+ var child_process2 = __toESM(require("child_process"), 1);
461
+ var Path3 = __toESM(require("path"), 1);
462
+ var TestBitcoinCli = class {
463
+ /**
464
+ * Returns the localhost address of the notary (NOTE: not accessible from containers)
465
+ */
466
+ static run(command) {
467
+ const binPath = Path3.join(
468
+ `${projectRoot()}`,
469
+ "target/debug/argon-bitcoin-cli"
470
+ );
471
+ try {
472
+ return child_process2.execSync(`${binPath} ${command}`, {
473
+ encoding: "utf8"
474
+ }).trim();
475
+ } catch (e) {
476
+ console.error(`Error running command: ${command}`);
477
+ console.error(e.stdout);
478
+ throw e;
479
+ }
480
+ }
481
+ };
482
+
483
+ // src/TestOracle.ts
484
+ var child_process3 = __toESM(require("child_process"), 1);
485
+ var import_mainchain3 = require("@argonprotocol/mainchain");
486
+ var fs3 = __toESM(require("fs"), 1);
487
+ var readline3 = __toESM(require("readline"), 1);
488
+ var process3 = __toESM(require("process"), 1);
489
+ var Path4 = __toESM(require("path"), 1);
490
+ var TestOracle = class _TestOracle {
491
+ static BitcoinOperator = "//Dave";
492
+ static PriceIndexOperator = "//Eve";
493
+ operator;
494
+ port;
495
+ #childProcess;
496
+ #stdioInterface;
497
+ constructor() {
498
+ addTeardown(this);
499
+ }
500
+ async start(service, options) {
501
+ const { pathToBin, mainchainUrl, bitcoinRpcUrl } = options;
502
+ const operatorSuri = service == "bitcoin" ? _TestOracle.BitcoinOperator : _TestOracle.PriceIndexOperator;
503
+ this.operator = new import_mainchain3.Keyring({ type: "sr25519" }).createFromUri(
504
+ operatorSuri
505
+ );
506
+ const binPath = pathToBin ?? Path4.join(projectRoot(), "target/debug/argon-oracle");
507
+ if (!fs3.existsSync(binPath)) {
508
+ throw new Error(`Oracle binary not found at ${binPath}`);
509
+ }
510
+ console.log(`Starting ${service} oracle`);
511
+ const execArgs = ["--dev", "-t", mainchainUrl, service];
512
+ if (service == "bitcoin") {
513
+ if (!bitcoinRpcUrl) {
514
+ throw new Error("Bitcoin RPC URL is required for bitcoin oracle");
515
+ }
516
+ execArgs.push("--bitcoin-rpc-url", bitcoinRpcUrl);
517
+ } else {
518
+ execArgs.push("--simulate-prices");
519
+ }
520
+ this.#childProcess = child_process3.spawn(binPath, execArgs, {
521
+ stdio: ["ignore", "pipe", "pipe"],
522
+ env: { ...process3.env, RUST_LOG: "info", ...options.env }
523
+ });
524
+ this.#childProcess.stdout.setEncoding("utf8");
525
+ this.#childProcess.stderr.setEncoding("utf8");
526
+ this.#childProcess.stderr.on("data", (data) => {
527
+ console.warn("%sOracle >> %s", service, data);
528
+ });
529
+ this.#stdioInterface = readline3.createInterface({ input: this.#childProcess.stdout }).on("line", (line) => {
530
+ console.log("%sOracle >> %s", service, line);
531
+ });
532
+ this.#childProcess.on("error", (err) => {
533
+ throw err;
534
+ });
535
+ }
536
+ async teardown() {
537
+ this.#childProcess?.kill();
538
+ this.#stdioInterface?.close();
539
+ }
540
+ };
541
+
542
+ // src/index.ts
543
+ var toTeardown = [];
544
+ var proxy = null;
545
+ var proxyServer = null;
546
+ var describeIntegration = import_vitest.describe;
547
+ if (process4.env.SKIP_E2E === "true" || process4.env.SKIP_E2E === "1") {
548
+ describeIntegration = import_vitest.describe.skip;
549
+ }
550
+ async function getProxy() {
551
+ if (!proxy) {
552
+ proxy = import_http_proxy.default.createProxyServer({
553
+ changeOrigin: true,
554
+ ws: true,
555
+ autoRewrite: true
556
+ });
557
+ proxy.on("error", () => null);
558
+ proxyServer = http.createServer(function(req, res) {
559
+ const queryData = url.parse(req.url, true).query;
560
+ if (!queryData.target) {
561
+ res.writeHead(500, { "Content-Type": "text/plain" });
562
+ res.end("Target parameter is required");
563
+ return;
564
+ }
565
+ console.log("Proxying http request", queryData.target);
566
+ proxy?.web(req, res, { target: queryData.target });
567
+ });
568
+ proxyServer.on("upgrade", function(req, clientSocket, head) {
569
+ const queryData = url.parse(req.url, true).query;
570
+ const target = url.parse(queryData.target);
571
+ proxy?.ws(req, clientSocket, head, {
572
+ target: target.href,
573
+ ws: true
574
+ });
575
+ clientSocket.on("error", console.error);
576
+ });
577
+ await new Promise((resolve3) => proxyServer.listen(0, resolve3));
578
+ toTeardown.push({
579
+ teardown: () => new Promise((resolve3) => {
580
+ proxy?.close();
581
+ proxyServer?.close((_) => null);
582
+ proxy = null;
583
+ proxyServer = null;
584
+ resolve3();
585
+ })
586
+ });
587
+ }
588
+ const port = proxyServer.address().port;
589
+ return `ws://host.docker.internal:${port}`;
590
+ }
591
+ function projectRoot() {
592
+ if (process4.env.ARGON_PROJECT_ROOT) {
593
+ return Path5.join(process4.env.ARGON_PROJECT_ROOT);
594
+ }
595
+ return Path5.join(__dirname, `../../..`);
596
+ }
597
+ async function runTestScript(relativePath) {
598
+ const scriptPath = Path5.resolve(projectRoot(), relativePath);
599
+ return child_process4.execSync(scriptPath, { encoding: "utf8" }).trim();
600
+ }
601
+ async function getDockerPortMapping(containerName, port) {
602
+ return child_process4.execSync(`docker port ${containerName} ${port}`, { encoding: "utf8" }).trim().split(":").pop();
603
+ }
604
+ async function teardown() {
605
+ for (const t of toTeardown) {
606
+ try {
607
+ await t.teardown().catch(console.error);
608
+ } catch {
609
+ }
610
+ }
611
+ toTeardown.length = 0;
612
+ }
613
+ function cleanHostForDocker(host, replacer = "host.docker.internal") {
614
+ if (process4.env.ARGON_USE_DOCKER_BINS) {
615
+ return host.replace("localhost", replacer).replace("127.0.0.1", replacer).replace("0.0.0.0", replacer);
616
+ }
617
+ return host;
618
+ }
619
+ function addTeardown(teardownable) {
620
+ toTeardown.push(teardownable);
621
+ }
622
+ function closeOnTeardown(closeable) {
623
+ addTeardown({ teardown: () => closeable.close() });
624
+ return closeable;
625
+ }
626
+ function disconnectOnTeardown(closeable) {
627
+ addTeardown({ teardown: () => closeable.disconnect() });
628
+ return closeable;
629
+ }
630
+ function sudo() {
631
+ return new import_mainchain4.Keyring({ type: "sr25519" }).createFromUri("//Alice");
632
+ }
633
+ async function activateNotary(sudo2, client, notary) {
634
+ await notary.register(client);
635
+ await new import_mainchain4.TxSubmitter(
636
+ client,
637
+ client.tx.sudo.sudo(
638
+ client.tx.notaries.activate(notary.operator.publicKey)
639
+ ),
640
+ sudo2
641
+ ).submit({ waitForBlock: true });
642
+ }
643
+ // Annotate the CommonJS export names for ESM import in node:
644
+ 0 && (module.exports = {
645
+ TestBitcoinCli,
646
+ TestMainchain,
647
+ TestNotary,
648
+ TestOracle,
649
+ activateNotary,
650
+ addTeardown,
651
+ cleanHostForDocker,
652
+ closeOnTeardown,
653
+ describeIntegration,
654
+ disconnectOnTeardown,
655
+ getDockerPortMapping,
656
+ getProxy,
657
+ projectRoot,
658
+ runTestScript,
659
+ sudo,
660
+ teardown
661
+ });
662
+ //# sourceMappingURL=index.cjs.map