@argonprotocol/testing 1.1.0 → 1.3.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/lib/index.cjs +64 -42
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +2 -1
- package/lib/index.d.ts +2 -1
- package/lib/index.js +65 -50
- package/lib/index.js.map +1 -1
- package/package.json +4 -2
package/lib/index.cjs
CHANGED
|
@@ -45,6 +45,7 @@ __export(index_exports, {
|
|
|
45
45
|
projectRoot: () => projectRoot,
|
|
46
46
|
runOnTeardown: () => runOnTeardown,
|
|
47
47
|
runTestScript: () => runTestScript,
|
|
48
|
+
stringifyExt: () => stringifyExt,
|
|
48
49
|
sudo: () => sudo,
|
|
49
50
|
teardown: () => teardown
|
|
50
51
|
});
|
|
@@ -119,10 +120,7 @@ var TestNotary = class {
|
|
|
119
120
|
let tries = 10;
|
|
120
121
|
while (tries > 0) {
|
|
121
122
|
dbName = `notary_${uuid}`;
|
|
122
|
-
const result2 = await client.query(
|
|
123
|
-
"SELECT 1 FROM pg_database WHERE datname = $1",
|
|
124
|
-
[dbName]
|
|
125
|
-
);
|
|
123
|
+
const result2 = await client.query("SELECT 1 FROM pg_database WHERE datname = $1", [dbName]);
|
|
126
124
|
if (result2.rowCount === 0) {
|
|
127
125
|
break;
|
|
128
126
|
}
|
|
@@ -248,8 +246,10 @@ var readline2 = __toESM(require("readline"), 1);
|
|
|
248
246
|
var import_detect_port = require("detect-port");
|
|
249
247
|
var import_nanoid2 = require("nanoid");
|
|
250
248
|
var import_bitcoin_core = __toESM(require("bitcoin-core"), 1);
|
|
249
|
+
var lockfile = __toESM(require("proper-lockfile"), 1);
|
|
251
250
|
var import_mainchain2 = require("@argonprotocol/mainchain");
|
|
252
251
|
var nanoid2 = (0, import_nanoid2.customAlphabet)("0123456789abcdefghijklmnopqrstuvwxyz", 4);
|
|
252
|
+
var lockPath = Path2.join(process.cwd(), ".port-lock");
|
|
253
253
|
var TestMainchain = class {
|
|
254
254
|
ip = "127.0.0.1";
|
|
255
255
|
port;
|
|
@@ -294,12 +294,7 @@ var TestMainchain = class {
|
|
|
294
294
|
* @param options.bootnodes - bootnodes to use for the mainchain
|
|
295
295
|
*/
|
|
296
296
|
async launch(options) {
|
|
297
|
-
const {
|
|
298
|
-
miningThreads = 1,
|
|
299
|
-
bootnodes,
|
|
300
|
-
author = "alice",
|
|
301
|
-
launchBitcoin = false
|
|
302
|
-
} = options ?? {};
|
|
297
|
+
const { miningThreads = 1, bootnodes, author = "alice", launchBitcoin = false } = options ?? {};
|
|
303
298
|
let port = 0;
|
|
304
299
|
let rpcPort = 0;
|
|
305
300
|
let execArgs = [];
|
|
@@ -333,6 +328,7 @@ var TestMainchain = class {
|
|
|
333
328
|
`--port=${port}`,
|
|
334
329
|
`--rpc-port=${rpcPort}`,
|
|
335
330
|
"--rpc-external",
|
|
331
|
+
"--no-mdns",
|
|
336
332
|
"--no-telemetry",
|
|
337
333
|
"--no-prometheus",
|
|
338
334
|
"--unsafe-rpc-external",
|
|
@@ -427,29 +423,46 @@ var TestMainchain = class {
|
|
|
427
423
|
async startBitcoin(launchBitcoin) {
|
|
428
424
|
let rpcPort = 14338;
|
|
429
425
|
if (launchBitcoin) {
|
|
430
|
-
|
|
431
|
-
const
|
|
432
|
-
|
|
433
|
-
|
|
426
|
+
fs2.closeSync(fs2.openSync(lockPath, "w"));
|
|
427
|
+
const release = await lockfile.lock(lockPath, { retries: 10 });
|
|
428
|
+
try {
|
|
429
|
+
rpcPort = await (0, import_detect_port.detectPort)();
|
|
430
|
+
const path = (0, import_node_child_process.execSync)(Path2.join(projectRoot(), `target/debug/argon-testing-bitcoin`), {
|
|
434
431
|
encoding: "utf8"
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
432
|
+
}).trim();
|
|
433
|
+
const tmpDir = fs2.mkdtempSync("/tmp/argon-bitcoin-" + this.uuid);
|
|
434
|
+
console.log("Starting bitcoin node at %s. Data %s", path, tmpDir);
|
|
435
|
+
this.#bitcoind = (0, import_node_child_process.spawn)(
|
|
436
|
+
path,
|
|
437
|
+
[
|
|
438
|
+
"-regtest",
|
|
439
|
+
"-fallbackfee=0.0001",
|
|
440
|
+
"-listen=0",
|
|
441
|
+
`-datadir=${tmpDir}`,
|
|
442
|
+
"-blockfilterindex",
|
|
443
|
+
"-txindex",
|
|
444
|
+
`-rpcport=${rpcPort}`,
|
|
445
|
+
"-rpcbind=0.0.0.0",
|
|
446
|
+
"-rpcallowip=0.0.0.0/0",
|
|
447
|
+
"-rpcuser=bitcoin",
|
|
448
|
+
"-rpcpassword=bitcoin"
|
|
449
|
+
],
|
|
450
|
+
{
|
|
451
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
452
|
+
}
|
|
453
|
+
);
|
|
454
|
+
this.#bitcoind.stderr.setEncoding("utf8");
|
|
455
|
+
this.#bitcoind.stdout.setEncoding("utf8");
|
|
456
|
+
this.#bitcoind.stdout.on("data", (data) => {
|
|
457
|
+
console.log("Bitcoin >> %s", data);
|
|
458
|
+
});
|
|
459
|
+
this.#bitcoind.stderr.on("data", (data) => {
|
|
460
|
+
console.error("Bitcoin >> %s", data);
|
|
461
|
+
});
|
|
462
|
+
this.#bitcoinDir = tmpDir;
|
|
463
|
+
} finally {
|
|
464
|
+
await release();
|
|
465
|
+
}
|
|
453
466
|
}
|
|
454
467
|
this.bitcoinPort = rpcPort;
|
|
455
468
|
return cleanHostForDocker(`http://bitcoin:bitcoin@localhost:${rpcPort}`);
|
|
@@ -464,10 +477,7 @@ var TestBitcoinCli = class {
|
|
|
464
477
|
* Returns the localhost address of the notary (NOTE: not accessible from containers)
|
|
465
478
|
*/
|
|
466
479
|
static run(command) {
|
|
467
|
-
const binPath = Path3.join(
|
|
468
|
-
`${projectRoot()}`,
|
|
469
|
-
"target/debug/argon-bitcoin-cli"
|
|
470
|
-
);
|
|
480
|
+
const binPath = Path3.join(`${projectRoot()}`, "target/debug/argon-bitcoin-cli");
|
|
471
481
|
try {
|
|
472
482
|
return child_process2.execSync(`${binPath} ${command}`, {
|
|
473
483
|
encoding: "utf8"
|
|
@@ -500,9 +510,7 @@ var TestOracle = class _TestOracle {
|
|
|
500
510
|
async start(service, options) {
|
|
501
511
|
const { pathToBin, mainchainUrl, bitcoinRpcUrl } = options;
|
|
502
512
|
const operatorSuri = service == "bitcoin" ? _TestOracle.BitcoinOperator : _TestOracle.PriceIndexOperator;
|
|
503
|
-
this.operator = new import_mainchain3.Keyring({ type: "sr25519" }).createFromUri(
|
|
504
|
-
operatorSuri
|
|
505
|
-
);
|
|
513
|
+
this.operator = new import_mainchain3.Keyring({ type: "sr25519" }).createFromUri(operatorSuri);
|
|
506
514
|
const binPath = pathToBin ?? Path4.join(projectRoot(), "target/debug/argon-oracle");
|
|
507
515
|
if (!fs3.existsSync(binPath)) {
|
|
508
516
|
throw new Error(`Oracle binary not found at ${binPath}`);
|
|
@@ -588,6 +596,21 @@ async function getProxy() {
|
|
|
588
596
|
const port = proxyServer.address().port;
|
|
589
597
|
return `ws://host.docker.internal:${port}`;
|
|
590
598
|
}
|
|
599
|
+
function stringifyExt(obj) {
|
|
600
|
+
return JSON.stringify(
|
|
601
|
+
obj,
|
|
602
|
+
(_key, value) => {
|
|
603
|
+
if (typeof value === "bigint") {
|
|
604
|
+
return value.toString() + "n";
|
|
605
|
+
}
|
|
606
|
+
if (Buffer.isBuffer(value)) {
|
|
607
|
+
return `0x${Buffer.from(value).toString("hex")}`;
|
|
608
|
+
}
|
|
609
|
+
return value;
|
|
610
|
+
},
|
|
611
|
+
2
|
|
612
|
+
);
|
|
613
|
+
}
|
|
591
614
|
function projectRoot() {
|
|
592
615
|
if (process4.env.ARGON_PROJECT_ROOT) {
|
|
593
616
|
return Path5.join(process4.env.ARGON_PROJECT_ROOT);
|
|
@@ -637,9 +660,7 @@ async function activateNotary(sudo2, client, notary) {
|
|
|
637
660
|
await notary.register(client);
|
|
638
661
|
await new import_mainchain4.TxSubmitter(
|
|
639
662
|
client,
|
|
640
|
-
client.tx.sudo.sudo(
|
|
641
|
-
client.tx.notaries.activate(notary.operator.publicKey)
|
|
642
|
-
),
|
|
663
|
+
client.tx.sudo.sudo(client.tx.notaries.activate(notary.operator.publicKey)),
|
|
643
664
|
sudo2
|
|
644
665
|
).submit({ waitForBlock: true });
|
|
645
666
|
}
|
|
@@ -660,6 +681,7 @@ async function activateNotary(sudo2, client, notary) {
|
|
|
660
681
|
projectRoot,
|
|
661
682
|
runOnTeardown,
|
|
662
683
|
runTestScript,
|
|
684
|
+
stringifyExt,
|
|
663
685
|
sudo,
|
|
664
686
|
teardown
|
|
665
687
|
});
|
package/lib/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/TestNotary.ts","../src/TestMainchain.ts","../src/TestBitcoinCli.ts","../src/TestOracle.ts"],"sourcesContent":["import {\n ArgonClient,\n Keyring,\n KeyringPair,\n TxSubmitter,\n} from '@argonprotocol/mainchain';\nimport { describe, SuiteAPI } from 'vitest';\nimport * as process from 'node:process';\nimport HttpProxy from 'http-proxy';\nimport * as child_process from 'node:child_process';\nimport * as http from 'node:http';\nimport * as url from 'node:url';\nimport * as net from 'node:net';\nimport * as Path from 'node:path';\nimport TestNotary from './TestNotary';\nimport TestMainchain from './TestMainchain';\nimport TestBitcoinCli from './TestBitcoinCli';\nimport TestOracle from './TestOracle';\n\nexport { TestNotary, TestMainchain, TestBitcoinCli, TestOracle };\n\nexport interface ITeardownable {\n teardown(): Promise<void>;\n}\n\nconst toTeardown: ITeardownable[] = [];\n\nlet proxy: HttpProxy | null = null;\nlet proxyServer: http.Server | null = null;\nexport let describeIntegration: SuiteAPI = describe;\n\nif (process.env.SKIP_E2E === 'true' || process.env.SKIP_E2E === '1') {\n describeIntegration = describe.skip as any;\n}\n\nexport async function getProxy() {\n if (!proxy) {\n proxy = HttpProxy.createProxyServer({\n changeOrigin: true,\n ws: true,\n autoRewrite: true,\n });\n proxy.on('error', () => null);\n proxyServer = http.createServer(function (req, res) {\n //parse query string and get targetUrl\n const queryData = url.parse(req.url!, true).query;\n if (!queryData.target) {\n res.writeHead(500, { 'Content-Type': 'text/plain' });\n res.end('Target parameter is required');\n return;\n }\n console.log('Proxying http request', queryData.target);\n proxy?.web(req, res, { target: queryData.target as string });\n });\n proxyServer.on('upgrade', function (req, clientSocket, head) {\n const queryData = url.parse(req.url!, true).query;\n const target = url.parse(queryData.target as string);\n proxy?.ws(req, clientSocket, head, {\n target: target.href,\n ws: true,\n });\n clientSocket.on('error', console.error);\n });\n await new Promise<void>(resolve => proxyServer!.listen(0, resolve));\n toTeardown.push({\n teardown: () =>\n new Promise<void>(resolve => {\n proxy?.close();\n proxyServer?.close(_ => null);\n proxy = null;\n proxyServer = null;\n resolve();\n }),\n });\n }\n const port = (proxyServer!.address() as net.AddressInfo).port;\n return `ws://host.docker.internal:${port}`;\n}\n\nexport function projectRoot() {\n if (process.env.ARGON_PROJECT_ROOT) {\n return Path.join(process.env.ARGON_PROJECT_ROOT);\n }\n return Path.join(__dirname, `../../..`);\n}\n\n/**\n * Run a script from the project \"scripts\" folder\n * @param relativePath\n */\nexport async function runTestScript(relativePath: string): Promise<string> {\n const scriptPath = Path.resolve(projectRoot(), relativePath);\n return child_process.execSync(scriptPath, { encoding: 'utf8' }).trim();\n}\n\nexport async function getDockerPortMapping(\n containerName: string,\n port: number,\n): Promise<string | undefined> {\n return child_process\n .execSync(`docker port ${containerName} ${port}`, { encoding: 'utf8' })\n .trim()\n .split(':')\n .pop();\n}\n\nexport async function teardown() {\n for (const t of toTeardown) {\n try {\n await t.teardown().catch(console.error);\n } catch {}\n }\n toTeardown.length = 0;\n}\n\nexport function cleanHostForDocker(\n host: string,\n replacer = 'host.docker.internal',\n): string {\n if (process.env.ARGON_USE_DOCKER_BINS) {\n return host\n .replace('localhost', replacer)\n .replace('127.0.0.1', replacer)\n .replace('0.0.0.0', replacer);\n }\n return host;\n}\n\nexport function addTeardown(teardownable: ITeardownable) {\n toTeardown.push(teardownable);\n}\n\nexport function runOnTeardown(teardown: () => Promise<void>) {\n addTeardown({ teardown });\n}\n\nexport function closeOnTeardown<T extends { close(): Promise<void> }>(\n closeable: T,\n): T {\n addTeardown({ teardown: () => closeable.close() });\n return closeable;\n}\n\nexport function disconnectOnTeardown<T extends { disconnect(): Promise<void> }>(\n closeable: T,\n): T {\n addTeardown({ teardown: () => closeable.disconnect() });\n return closeable;\n}\n\nexport function sudo(): KeyringPair {\n return new Keyring({ type: 'sr25519' }).createFromUri('//Alice');\n}\n\nexport async function activateNotary(\n sudo: KeyringPair,\n client: ArgonClient,\n notary: TestNotary,\n) {\n await notary.register(client);\n await new TxSubmitter(\n client,\n client.tx.sudo.sudo(\n client.tx.notaries.activate(notary.operator!.publicKey),\n ),\n sudo,\n ).submit({ waitForBlock: true });\n}\n","import { customAlphabet } from 'nanoid';\nimport pg from 'pg';\nimport type { Client } from 'pg';\nimport * as child_process from 'node:child_process';\nimport {\n ArgonClient,\n Keyring,\n KeyringPair,\n TxSubmitter,\n} from '@argonprotocol/mainchain';\nimport * as fs from 'node:fs';\nimport * as readline from 'node:readline';\nimport {\n addTeardown,\n cleanHostForDocker,\n getDockerPortMapping,\n getProxy,\n ITeardownable,\n projectRoot,\n} from './index';\nimport * as process from 'node:process';\nimport { Readable } from 'node:stream';\nimport * as Path from 'node:path';\n\nconst { Client: PgClient } = pg;\n\nconst nanoid = customAlphabet('0123456789abcdefghijklmnopqrstuvwxyz', 4);\n\nexport function createUid(): string {\n return nanoid();\n}\n\nexport default class TestNotary implements ITeardownable {\n public operator?: KeyringPair;\n public ip = '127.0.0.1';\n public registeredPublicKey?: Uint8Array;\n public port?: string;\n public containerName?: string;\n public proxy?: string;\n #dbName?: string;\n #dbConnectionString: string;\n #childProcess?: child_process.ChildProcessByStdio<null, Readable, Readable>;\n #stdioInterface?: readline.Interface;\n\n public get address(): string {\n if (this.proxy) {\n const url = new URL(this.proxy);\n url.searchParams.set('target', `ws://${this.ip}:${this.port}`);\n return url.href;\n }\n return `ws://${this.ip}:${this.port}`;\n }\n\n constructor(dbConnectionString?: string) {\n this.#dbConnectionString =\n dbConnectionString ??\n process.env.NOTARY_DB_URL ??\n 'postgres://postgres:postgres@localhost:5432';\n addTeardown(this);\n }\n\n /**\n * Returns the localhost address of the notary (NOTE: not accessible from containers)\n */\n public async start(options: {\n mainchainUrl: string;\n uuid: string;\n pathToNotaryBin?: string;\n }): Promise<string> {\n const { pathToNotaryBin, uuid, mainchainUrl } = options;\n this.operator = new Keyring({ type: 'sr25519' }).createFromUri('//Bob');\n this.registeredPublicKey = new Keyring({ type: 'ed25519' }).createFromUri(\n '//Ferdie//notary',\n ).publicKey;\n\n let notaryPath =\n pathToNotaryBin ?? Path.join(projectRoot(), 'target/debug/argon-notary');\n if (process.env.ARGON_USE_DOCKER_BINS) {\n this.containerName = 'notary_' + uuid;\n const addHost = process.env.ADD_DOCKER_HOST\n ? ` --add-host=host.docker.internal:host-gateway`\n : '';\n\n notaryPath = `docker run --rm -p=0:9925${addHost} --name=${this.containerName} -e RUST_LOG=warn ghcr.io/argonprotocol/argon-notary:dev`;\n\n this.#dbConnectionString = cleanHostForDocker(this.#dbConnectionString);\n } else if (!fs.existsSync(notaryPath)) {\n throw new Error(`Notary binary not found at ${notaryPath}`);\n }\n\n const client = await this.connect();\n let dbName = '';\n try {\n let tries = 10;\n while (tries > 0) {\n dbName = `notary_${uuid}`;\n // check if the db path notary_{id} exists\n const result = await client.query(\n 'SELECT 1 FROM pg_database WHERE datname = $1',\n [dbName],\n );\n if (result.rowCount === 0) {\n break;\n }\n tries -= 1;\n }\n this.#dbName = dbName;\n await client.query(`CREATE DATABASE \"${dbName}\"`);\n } finally {\n await client.end();\n }\n\n let result = child_process.execSync(\n `${notaryPath} migrate --db-url ${this.#dbConnectionString}/${this.#dbName}`,\n {\n encoding: 'utf-8',\n },\n );\n if (result.trim().length) {\n console.log(result.trim());\n }\n console.log(\n \"Notary >> connecting to mainchain '%s', db %s\",\n mainchainUrl,\n `${this.#dbConnectionString}/${this.#dbName}`,\n );\n\n const bucketName = `notary-${uuid}`;\n const execArgs = [\n 'run',\n `--db-url=${this.#dbConnectionString}/${this.#dbName}`,\n `--dev`,\n `-t ${mainchainUrl}`,\n `--archive-bucket=${bucketName}`,\n `--operator-address=${this.operator.address}`,\n ];\n if (process.env.ARGON_USE_DOCKER_BINS) {\n process.env.AWS_S3_ENDPOINT = 'http://host.docker.internal:9000';\n execArgs.unshift(...notaryPath.replace('docker run', 'run').split(' '));\n execArgs.push('-b=0.0.0.0:9925');\n\n notaryPath = 'docker';\n }\n if (process.env.AWS_S3_ENDPOINT) {\n execArgs.push(`--archive-endpoint=${process.env.AWS_S3_ENDPOINT}`);\n }\n this.#childProcess = child_process.spawn(notaryPath, execArgs, {\n stdio: ['ignore', 'pipe', 'pipe'],\n env: { ...process.env, RUST_LOG: 'warn' },\n });\n this.#childProcess.stdout.setEncoding('utf8');\n this.#childProcess.stderr.setEncoding('utf8');\n this.port = await new Promise<string>((resolve, reject) => {\n const onProcessError = (err: Error): void => {\n console.warn('Error running notary', err);\n reject(err);\n };\n this.#childProcess!.once('error', onProcessError);\n this.#childProcess!.stderr.on('data', data => {\n console.warn('Notary >> %s', data);\n if (data.startsWith('WARNING')) return;\n this.#childProcess!.off('error', onProcessError);\n reject(data);\n });\n this.#stdioInterface = readline\n .createInterface({ input: this.#childProcess!.stdout })\n .on('line', line => {\n console.log('Notary >> %s', line);\n let match = line.match(/Listening on ([ws:/\\d.]+)/);\n if (match?.length ?? 0 > 0) {\n resolve(match![1].split(':').pop()!);\n }\n });\n });\n this.#childProcess.on('error', err => {\n throw err;\n });\n if (this.containerName) {\n this.port = await getDockerPortMapping(this.containerName, 9925);\n this.proxy = cleanHostForDocker(await getProxy());\n }\n\n return this.address;\n }\n\n public async register(client: ArgonClient): Promise<void> {\n let address = new URL(this.address);\n await new TxSubmitter(\n client,\n client.tx.notaries.propose({\n public: this.registeredPublicKey,\n hosts: [address.href],\n name: 'Test Notary',\n }),\n this.operator!,\n ).submit({ waitForBlock: true });\n }\n\n public async teardown(): Promise<void> {\n this.#childProcess?.kill();\n this.#stdioInterface?.close();\n const client = await this.connect();\n try {\n await client.query(`DROP DATABASE \"${this.#dbName}\" WITH (FORCE)`);\n } finally {\n await client.end();\n }\n if (this.containerName) {\n try {\n child_process.execSync(`docker rm -f ${this.containerName}`);\n } catch {}\n }\n }\n\n async connect(): Promise<Client> {\n const client = new PgClient({ connectionString: this.#dbConnectionString });\n try {\n await client.connect();\n } catch (err) {\n console.error('ERROR connecting to postgres client', err);\n throw err;\n }\n return client;\n }\n}\n","import * as fs from 'node:fs';\nimport { ChildProcess, execSync, spawn } from 'node:child_process';\nimport * as Path from 'node:path';\nimport * as readline from 'node:readline';\nimport {\n addTeardown,\n cleanHostForDocker,\n disconnectOnTeardown,\n getDockerPortMapping,\n getProxy,\n ITeardownable,\n projectRoot,\n} from './index';\nimport { detectPort } from 'detect-port';\nimport { customAlphabet } from 'nanoid';\nimport Client from 'bitcoin-core';\nimport { createUid } from './TestNotary';\nimport { type ArgonClient, getClient } from '@argonprotocol/mainchain';\n\nconst nanoid = customAlphabet('0123456789abcdefghijklmnopqrstuvwxyz', 4);\n\nexport default class TestMainchain implements ITeardownable {\n public ip = '127.0.0.1';\n public port?: string;\n public loglevel = 'warn';\n public uuid: string;\n #binPath: string;\n #process?: ChildProcess;\n #interfaces: readline.Interface[] = [];\n containerName?: string;\n proxy?: string;\n #bitcoind?: ChildProcess;\n bitcoinPort?: number;\n #bitcoinDir?: string;\n\n public get address(): string {\n if (this.proxy) {\n const url = new URL(this.proxy);\n url.searchParams.set('target', `ws://${this.ip}:${this.port}`);\n return url.href;\n }\n return `ws://${this.ip}:${this.port}`;\n }\n\n constructor(binPath?: string) {\n this.#binPath =\n binPath ?? Path.join(projectRoot(), `target/debug/argon-node`);\n this.#binPath = Path.resolve(this.#binPath);\n if (!process.env.ARGON_USE_DOCKER_BINS && !fs.existsSync(this.#binPath)) {\n throw new Error(`Mainchain binary not found at ${this.#binPath}`);\n }\n this.uuid = createUid();\n addTeardown(this);\n }\n\n public getBitcoinClient(): Client {\n return new Client({\n username: 'bitcoin',\n password: 'bitcoin',\n host: `http://localhost:${this.bitcoinPort}`,\n });\n }\n\n /**\n * Launch and return the localhost url. NOTE: this url will not work cross-docker. You need to use the containerAddress property\n * @param options\n * @param options.miningThreads - number of threads to use for mining\n * @param options.bootnodes - bootnodes to use for the mainchain\n */\n public async launch(options?: {\n miningThreads?: number;\n bootnodes?: string;\n author?: string;\n launchBitcoin?: boolean;\n }): Promise<string> {\n const {\n miningThreads = 1,\n bootnodes,\n author = 'alice',\n launchBitcoin = false,\n } = options ?? {};\n let port = 0;\n let rpcPort = 0;\n let execArgs: string[] = [];\n let containerName: string;\n if (process.env.ARGON_USE_DOCKER_BINS) {\n containerName = 'miner_' + nanoid();\n this.containerName = containerName;\n this.#binPath = 'docker';\n port = 33344;\n rpcPort = 9944;\n execArgs = [\n 'run',\n '--rm',\n `--name=${containerName}`,\n `-p=0:${port}`,\n `-p=0:${rpcPort}`,\n '-e',\n `RUST_LOG=${this.loglevel},sc_rpc_server=info`,\n 'ghcr.io/argonprotocol/argon-miner:dev',\n ];\n\n if (process.env.ADD_DOCKER_HOST) {\n execArgs.splice(2, 0, `--add-host=host.docker.internal:host-gateway`);\n }\n }\n\n const bitcoinRpcUrl = await this.startBitcoin(launchBitcoin);\n execArgs.push(\n '--dev',\n '--validator',\n `--${author}`,\n `--compute-miners=${miningThreads}`,\n `--port=${port}`,\n `--rpc-port=${rpcPort}`,\n '--rpc-external',\n '--no-telemetry',\n '--no-prometheus',\n '--unsafe-rpc-external',\n '--rpc-methods=unsafe',\n `--bitcoin-rpc-url=${bitcoinRpcUrl}`,\n `--notebook-archive-hosts=http://127.0.0.1:9000/${this.uuid}`,\n );\n if (bootnodes) {\n execArgs.push(`--bootnodes=${bootnodes}`);\n }\n this.#process = spawn(this.#binPath, execArgs, {\n stdio: ['ignore', 'pipe', 'pipe', 'ignore'],\n env: { ...process.env, RUST_LOG: `${this.loglevel},sc_rpc_server=info` },\n });\n\n this.#process.stderr!.setEncoding('utf8');\n this.#process.stdout!.setEncoding('utf8');\n this.#process.stdout!.on('data', data => {\n console.log('Main >> %s', data);\n });\n\n const int1 = readline\n .createInterface({ input: this.#process.stdout! })\n .on('line', line => {\n if (line) console.log('Main >> %s', line);\n });\n this.#interfaces.push(int1);\n\n this.port = await new Promise<string>((resolve, reject) => {\n this.#process!.on('error', err => {\n console.warn('Error running mainchain', err);\n reject(err);\n });\n\n const int2 = readline\n .createInterface({ input: this.#process!.stderr! })\n .on('line', line => {\n console.log('Main >> %s', line);\n let match = line.match(/Running JSON-RPC server: addr=([\\d.:]+)/);\n if (match) {\n let ipv4 = match[1].split(',').at(0);\n resolve(ipv4!.split(':').pop()!);\n }\n });\n this.#interfaces.push(int2);\n });\n if (this.containerName) {\n this.port = await getDockerPortMapping(this.containerName, rpcPort);\n this.proxy = cleanHostForDocker(await getProxy());\n }\n\n console.log(`argon Node listening at ${this.address}`);\n return this.address;\n }\n\n public async client(): Promise<ArgonClient> {\n const client = await getClient(this.address);\n disconnectOnTeardown(client);\n return client;\n }\n\n public async bootAddress(): Promise<string | undefined> {\n const client = await this.client();\n const bootAddress = await client.rpc.system.localListenAddresses();\n\n for (const address of bootAddress) {\n const addr = address.toString();\n if (addr.includes('127.0.0.1')) {\n return addr;\n }\n }\n return undefined;\n }\n\n public async teardown(): Promise<void> {\n if (process.env.ARGON_USE_DOCKER_BINS) {\n try {\n execSync(`docker rm -f ${this.containerName}`);\n } catch {}\n }\n const launchedProcess = this.#process;\n if (launchedProcess) {\n launchedProcess?.kill();\n try {\n launchedProcess.stdio.forEach(io => io?.destroy());\n } catch {}\n launchedProcess.unref();\n }\n\n this.#process?.kill();\n this.#process?.unref();\n this.#bitcoind?.kill();\n this.#bitcoind?.unref();\n if (this.#bitcoinDir) {\n await fs.promises.rm(this.#bitcoinDir, {\n recursive: true,\n force: true,\n });\n }\n for (const i of this.#interfaces) {\n i.close();\n }\n }\n\n private async startBitcoin(launchBitcoin: boolean): Promise<string> {\n let rpcPort = 14338;\n if (launchBitcoin) {\n rpcPort = await detectPort();\n const path = execSync(\n Path.join(projectRoot(), `target/debug/argon-testing-bitcoin`),\n {\n encoding: 'utf8',\n },\n ).trim();\n\n const tmpDir = fs.mkdtempSync('/tmp/argon-bitcoin-' + this.uuid);\n\n console.log('Starting bitcoin node at %s', tmpDir);\n this.#bitcoind = spawn(path, [\n '-regtest',\n '-fallbackfee=0.0001',\n '-listen=0',\n `-datadir=${tmpDir}`,\n '-blockfilterindex',\n '-txindex',\n `-rpcport=${rpcPort}`,\n '-rpcbind=0.0.0.0',\n '-rpcallowip=0.0.0.0/0',\n '-rpcuser=bitcoin',\n '-rpcpassword=bitcoin',\n ]);\n this.#bitcoinDir = tmpDir;\n }\n this.bitcoinPort = rpcPort;\n return cleanHostForDocker(`http://bitcoin:bitcoin@localhost:${rpcPort}`);\n }\n}\n","import * as child_process from 'node:child_process';\nimport { projectRoot } from './index';\nimport * as Path from 'node:path';\n\nexport default class TestBitcoinCli {\n /**\n * Returns the localhost address of the notary (NOTE: not accessible from containers)\n */\n public static run(command: string): string {\n const binPath = Path.join(\n `${projectRoot()}`,\n 'target/debug/argon-bitcoin-cli',\n );\n\n try {\n return child_process\n .execSync(`${binPath} ${command}`, {\n encoding: 'utf8',\n })\n .trim();\n } catch (e) {\n console.error(`Error running command: ${command}`);\n console.error((e as any).stdout);\n throw e;\n }\n }\n}\n","import * as child_process from 'node:child_process';\nimport { Keyring, KeyringPair } from '@argonprotocol/mainchain';\nimport * as fs from 'node:fs';\nimport * as readline from 'node:readline';\nimport { addTeardown, ITeardownable, projectRoot } from './index';\nimport * as process from 'node:process';\nimport * as Path from 'node:path';\nimport { Readable } from 'node:stream';\n\nexport default class TestOracle implements ITeardownable {\n public static BitcoinOperator = '//Dave';\n public static PriceIndexOperator = '//Eve';\n public operator?: KeyringPair;\n public port?: string;\n #childProcess?: child_process.ChildProcessByStdio<null, Readable, Readable>;\n #stdioInterface?: readline.Interface;\n\n constructor() {\n addTeardown(this);\n }\n\n public async start(\n service: 'price-index' | 'bitcoin',\n options: {\n mainchainUrl: string;\n bitcoinRpcUrl?: string;\n pathToBin?: string;\n env?: Record<string, string>;\n },\n ) {\n const { pathToBin, mainchainUrl, bitcoinRpcUrl } = options;\n const operatorSuri =\n service == 'bitcoin'\n ? TestOracle.BitcoinOperator\n : TestOracle.PriceIndexOperator;\n this.operator = new Keyring({ type: 'sr25519' }).createFromUri(\n operatorSuri,\n );\n const binPath =\n pathToBin ?? Path.join(projectRoot(), 'target/debug/argon-oracle');\n if (!fs.existsSync(binPath)) {\n throw new Error(`Oracle binary not found at ${binPath}`);\n }\n console.log(`Starting ${service} oracle`);\n\n const execArgs: string[] = ['--dev', '-t', mainchainUrl, service];\n if (service == 'bitcoin') {\n if (!bitcoinRpcUrl) {\n throw new Error('Bitcoin RPC URL is required for bitcoin oracle');\n }\n execArgs.push('--bitcoin-rpc-url', bitcoinRpcUrl);\n } else {\n execArgs.push('--simulate-prices');\n }\n this.#childProcess = child_process.spawn(binPath, execArgs, {\n stdio: ['ignore', 'pipe', 'pipe'],\n env: { ...process.env, RUST_LOG: 'info', ...options.env },\n });\n this.#childProcess.stdout.setEncoding('utf8');\n this.#childProcess.stderr.setEncoding('utf8');\n this.#childProcess!.stderr.on('data', data => {\n console.warn('%sOracle >> %s', service, data);\n });\n this.#stdioInterface = readline\n .createInterface({ input: this.#childProcess!.stdout })\n .on('line', line => {\n console.log('%sOracle >> %s', service, line);\n });\n\n this.#childProcess.on('error', err => {\n throw err;\n });\n }\n\n public async teardown(): Promise<void> {\n this.#childProcess?.kill();\n this.#stdioInterface?.close();\n }\n}\n"],"mappings":"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","names":["import_mainchain","process","child_process","Path","process","pg","url","result","resolve","fs","Path","readline","import_nanoid","import_mainchain","nanoid","url","Client","resolve","child_process","Path","child_process","import_mainchain","fs","readline","process","Path","HttpProxy","resolve","teardown","sudo"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/TestNotary.ts","../src/TestMainchain.ts","../src/TestBitcoinCli.ts","../src/TestOracle.ts"],"sourcesContent":["import { ArgonClient, Keyring, KeyringPair, TxSubmitter } from '@argonprotocol/mainchain';\nimport { describe, SuiteAPI } from 'vitest';\nimport * as process from 'node:process';\nimport HttpProxy from 'http-proxy';\nimport * as child_process from 'node:child_process';\nimport * as http from 'node:http';\nimport * as url from 'node:url';\nimport * as net from 'node:net';\nimport * as Path from 'node:path';\nimport TestNotary from './TestNotary';\nimport TestMainchain from './TestMainchain';\nimport TestBitcoinCli from './TestBitcoinCli';\nimport TestOracle from './TestOracle';\nimport * as util from 'node:util';\n\nexport { TestNotary, TestMainchain, TestBitcoinCli, TestOracle };\n\nexport interface ITeardownable {\n teardown(): Promise<void>;\n}\n\nconst toTeardown: ITeardownable[] = [];\n\nlet proxy: HttpProxy | null = null;\nlet proxyServer: http.Server | null = null;\nexport let describeIntegration: SuiteAPI = describe;\n\nif (process.env.SKIP_E2E === 'true' || process.env.SKIP_E2E === '1') {\n describeIntegration = describe.skip as any;\n}\n\nexport async function getProxy() {\n if (!proxy) {\n proxy = HttpProxy.createProxyServer({\n changeOrigin: true,\n ws: true,\n autoRewrite: true,\n });\n proxy.on('error', () => null);\n proxyServer = http.createServer(function (req, res) {\n //parse query string and get targetUrl\n const queryData = url.parse(req.url!, true).query;\n if (!queryData.target) {\n res.writeHead(500, { 'Content-Type': 'text/plain' });\n res.end('Target parameter is required');\n return;\n }\n console.log('Proxying http request', queryData.target);\n proxy?.web(req, res, { target: queryData.target as string });\n });\n proxyServer.on('upgrade', function (req, clientSocket, head) {\n const queryData = url.parse(req.url!, true).query;\n const target = url.parse(queryData.target as string);\n proxy?.ws(req, clientSocket, head, {\n target: target.href,\n ws: true,\n });\n clientSocket.on('error', console.error);\n });\n await new Promise<void>(resolve => proxyServer!.listen(0, resolve));\n toTeardown.push({\n teardown: () =>\n new Promise<void>(resolve => {\n proxy?.close();\n proxyServer?.close(_ => null);\n proxy = null;\n proxyServer = null;\n resolve();\n }),\n });\n }\n const port = (proxyServer!.address() as net.AddressInfo).port;\n return `ws://host.docker.internal:${port}`;\n}\n\nexport function stringifyExt(obj: any): any {\n return JSON.stringify(\n obj,\n (_key, value) => {\n if (typeof value === 'bigint') {\n return value.toString() + 'n'; // Append 'n' to indicate bigint\n }\n if (Buffer.isBuffer(value)) {\n return `0x${Buffer.from(value).toString('hex')}`; // Convert Buffer to hex string\n }\n return value;\n },\n 2,\n );\n}\n\nexport function projectRoot() {\n if (process.env.ARGON_PROJECT_ROOT) {\n return Path.join(process.env.ARGON_PROJECT_ROOT);\n }\n return Path.join(__dirname, `../../..`);\n}\n\n/**\n * Run a script from the project \"scripts\" folder\n * @param relativePath\n */\nexport async function runTestScript(relativePath: string): Promise<string> {\n const scriptPath = Path.resolve(projectRoot(), relativePath);\n return child_process.execSync(scriptPath, { encoding: 'utf8' }).trim();\n}\n\nexport async function getDockerPortMapping(\n containerName: string,\n port: number,\n): Promise<string | undefined> {\n return child_process\n .execSync(`docker port ${containerName} ${port}`, { encoding: 'utf8' })\n .trim()\n .split(':')\n .pop();\n}\n\nexport async function teardown() {\n for (const t of toTeardown) {\n try {\n await t.teardown().catch(console.error);\n } catch {}\n }\n toTeardown.length = 0;\n}\n\nexport function cleanHostForDocker(host: string, replacer = 'host.docker.internal'): string {\n if (process.env.ARGON_USE_DOCKER_BINS) {\n return host\n .replace('localhost', replacer)\n .replace('127.0.0.1', replacer)\n .replace('0.0.0.0', replacer);\n }\n return host;\n}\n\nexport function addTeardown(teardownable: ITeardownable) {\n toTeardown.push(teardownable);\n}\n\nexport function runOnTeardown(teardown: () => Promise<void>) {\n addTeardown({ teardown });\n}\n\nexport function closeOnTeardown<T extends { close(): Promise<void> }>(closeable: T): T {\n addTeardown({ teardown: () => closeable.close() });\n return closeable;\n}\n\nexport function disconnectOnTeardown<T extends { disconnect(): Promise<void> }>(closeable: T): T {\n addTeardown({ teardown: () => closeable.disconnect() });\n return closeable;\n}\n\nexport function sudo(): KeyringPair {\n return new Keyring({ type: 'sr25519' }).createFromUri('//Alice');\n}\n\nexport async function activateNotary(sudo: KeyringPair, client: ArgonClient, notary: TestNotary) {\n await notary.register(client);\n await new TxSubmitter(\n client,\n client.tx.sudo.sudo(client.tx.notaries.activate(notary.operator!.publicKey)),\n sudo,\n ).submit({ waitForBlock: true });\n}\n","import { customAlphabet } from 'nanoid';\nimport pg from 'pg';\nimport type { Client } from 'pg';\nimport * as child_process from 'node:child_process';\nimport { ArgonClient, Keyring, KeyringPair, TxSubmitter } from '@argonprotocol/mainchain';\nimport * as fs from 'node:fs';\nimport * as readline from 'node:readline';\nimport {\n addTeardown,\n cleanHostForDocker,\n getDockerPortMapping,\n getProxy,\n ITeardownable,\n projectRoot,\n} from './index';\nimport * as process from 'node:process';\nimport { Readable } from 'node:stream';\nimport * as Path from 'node:path';\n\nconst { Client: PgClient } = pg;\n\nconst nanoid = customAlphabet('0123456789abcdefghijklmnopqrstuvwxyz', 4);\n\nexport function createUid(): string {\n return nanoid();\n}\n\nexport default class TestNotary implements ITeardownable {\n public operator?: KeyringPair;\n public ip = '127.0.0.1';\n public registeredPublicKey?: Uint8Array;\n public port?: string;\n public containerName?: string;\n public proxy?: string;\n #dbName?: string;\n #dbConnectionString: string;\n #childProcess?: child_process.ChildProcessByStdio<null, Readable, Readable>;\n #stdioInterface?: readline.Interface;\n\n public get address(): string {\n if (this.proxy) {\n const url = new URL(this.proxy);\n url.searchParams.set('target', `ws://${this.ip}:${this.port}`);\n return url.href;\n }\n return `ws://${this.ip}:${this.port}`;\n }\n\n constructor(dbConnectionString?: string) {\n this.#dbConnectionString =\n dbConnectionString ??\n process.env.NOTARY_DB_URL ??\n 'postgres://postgres:postgres@localhost:5432';\n addTeardown(this);\n }\n\n /**\n * Returns the localhost address of the notary (NOTE: not accessible from containers)\n */\n public async start(options: {\n mainchainUrl: string;\n uuid: string;\n pathToNotaryBin?: string;\n }): Promise<string> {\n const { pathToNotaryBin, uuid, mainchainUrl } = options;\n this.operator = new Keyring({ type: 'sr25519' }).createFromUri('//Bob');\n this.registeredPublicKey = new Keyring({ type: 'ed25519' }).createFromUri(\n '//Ferdie//notary',\n ).publicKey;\n\n let notaryPath = pathToNotaryBin ?? Path.join(projectRoot(), 'target/debug/argon-notary');\n if (process.env.ARGON_USE_DOCKER_BINS) {\n this.containerName = 'notary_' + uuid;\n const addHost = process.env.ADD_DOCKER_HOST\n ? ` --add-host=host.docker.internal:host-gateway`\n : '';\n\n notaryPath = `docker run --rm -p=0:9925${addHost} --name=${this.containerName} -e RUST_LOG=warn ghcr.io/argonprotocol/argon-notary:dev`;\n\n this.#dbConnectionString = cleanHostForDocker(this.#dbConnectionString);\n } else if (!fs.existsSync(notaryPath)) {\n throw new Error(`Notary binary not found at ${notaryPath}`);\n }\n\n const client = await this.connect();\n let dbName = '';\n try {\n let tries = 10;\n while (tries > 0) {\n dbName = `notary_${uuid}`;\n // check if the db path notary_{id} exists\n const result = await client.query('SELECT 1 FROM pg_database WHERE datname = $1', [dbName]);\n if (result.rowCount === 0) {\n break;\n }\n tries -= 1;\n }\n this.#dbName = dbName;\n await client.query(`CREATE DATABASE \"${dbName}\"`);\n } finally {\n await client.end();\n }\n\n let result = child_process.execSync(\n `${notaryPath} migrate --db-url ${this.#dbConnectionString}/${this.#dbName}`,\n {\n encoding: 'utf-8',\n },\n );\n if (result.trim().length) {\n console.log(result.trim());\n }\n console.log(\n \"Notary >> connecting to mainchain '%s', db %s\",\n mainchainUrl,\n `${this.#dbConnectionString}/${this.#dbName}`,\n );\n\n const bucketName = `notary-${uuid}`;\n const execArgs = [\n 'run',\n `--db-url=${this.#dbConnectionString}/${this.#dbName}`,\n `--dev`,\n `-t ${mainchainUrl}`,\n `--archive-bucket=${bucketName}`,\n `--operator-address=${this.operator.address}`,\n ];\n if (process.env.ARGON_USE_DOCKER_BINS) {\n process.env.AWS_S3_ENDPOINT = 'http://host.docker.internal:9000';\n execArgs.unshift(...notaryPath.replace('docker run', 'run').split(' '));\n execArgs.push('-b=0.0.0.0:9925');\n\n notaryPath = 'docker';\n }\n if (process.env.AWS_S3_ENDPOINT) {\n execArgs.push(`--archive-endpoint=${process.env.AWS_S3_ENDPOINT}`);\n }\n this.#childProcess = child_process.spawn(notaryPath, execArgs, {\n stdio: ['ignore', 'pipe', 'pipe'],\n env: { ...process.env, RUST_LOG: 'warn' },\n });\n this.#childProcess.stdout.setEncoding('utf8');\n this.#childProcess.stderr.setEncoding('utf8');\n this.port = await new Promise<string>((resolve, reject) => {\n const onProcessError = (err: Error): void => {\n console.warn('Error running notary', err);\n reject(err);\n };\n this.#childProcess!.once('error', onProcessError);\n this.#childProcess!.stderr.on('data', data => {\n console.warn('Notary >> %s', data);\n if (data.startsWith('WARNING')) return;\n this.#childProcess!.off('error', onProcessError);\n reject(data);\n });\n this.#stdioInterface = readline\n .createInterface({ input: this.#childProcess!.stdout })\n .on('line', line => {\n console.log('Notary >> %s', line);\n let match = line.match(/Listening on ([ws:/\\d.]+)/);\n if (match?.length ?? 0 > 0) {\n resolve(match![1].split(':').pop()!);\n }\n });\n });\n this.#childProcess.on('error', err => {\n throw err;\n });\n if (this.containerName) {\n this.port = await getDockerPortMapping(this.containerName, 9925);\n this.proxy = cleanHostForDocker(await getProxy());\n }\n\n return this.address;\n }\n\n public async register(client: ArgonClient): Promise<void> {\n let address = new URL(this.address);\n await new TxSubmitter(\n client,\n client.tx.notaries.propose({\n public: this.registeredPublicKey,\n hosts: [address.href],\n name: 'Test Notary',\n }),\n this.operator!,\n ).submit({ waitForBlock: true });\n }\n\n public async teardown(): Promise<void> {\n this.#childProcess?.kill();\n this.#stdioInterface?.close();\n const client = await this.connect();\n try {\n await client.query(`DROP DATABASE \"${this.#dbName}\" WITH (FORCE)`);\n } finally {\n await client.end();\n }\n if (this.containerName) {\n try {\n child_process.execSync(`docker rm -f ${this.containerName}`);\n } catch {}\n }\n }\n\n async connect(): Promise<Client> {\n const client = new PgClient({ connectionString: this.#dbConnectionString });\n try {\n await client.connect();\n } catch (err) {\n console.error('ERROR connecting to postgres client', err);\n throw err;\n }\n return client;\n }\n}\n","import * as fs from 'node:fs';\nimport { ChildProcess, execSync, spawn } from 'node:child_process';\nimport * as Path from 'node:path';\nimport * as readline from 'node:readline';\nimport {\n addTeardown,\n cleanHostForDocker,\n disconnectOnTeardown,\n getDockerPortMapping,\n getProxy,\n ITeardownable,\n projectRoot,\n} from './index';\nimport { detectPort } from 'detect-port';\nimport { customAlphabet } from 'nanoid';\nimport Client from 'bitcoin-core';\nimport * as lockfile from 'proper-lockfile';\nimport { createUid } from './TestNotary';\nimport { type ArgonClient, getClient } from '@argonprotocol/mainchain';\n\nconst nanoid = customAlphabet('0123456789abcdefghijklmnopqrstuvwxyz', 4);\n\nconst lockPath = Path.join(process.cwd(), '.port-lock');\n\nexport default class TestMainchain implements ITeardownable {\n public ip = '127.0.0.1';\n public port?: string;\n public loglevel = 'warn';\n public uuid: string;\n #binPath: string;\n #process?: ChildProcess;\n #interfaces: readline.Interface[] = [];\n containerName?: string;\n proxy?: string;\n #bitcoind?: ChildProcess;\n bitcoinPort?: number;\n #bitcoinDir?: string;\n\n public get address(): string {\n if (this.proxy) {\n const url = new URL(this.proxy);\n url.searchParams.set('target', `ws://${this.ip}:${this.port}`);\n return url.href;\n }\n return `ws://${this.ip}:${this.port}`;\n }\n\n constructor(binPath?: string) {\n this.#binPath = binPath ?? Path.join(projectRoot(), `target/debug/argon-node`);\n this.#binPath = Path.resolve(this.#binPath);\n if (!process.env.ARGON_USE_DOCKER_BINS && !fs.existsSync(this.#binPath)) {\n throw new Error(`Mainchain binary not found at ${this.#binPath}`);\n }\n this.uuid = createUid();\n addTeardown(this);\n }\n\n public getBitcoinClient(): Client {\n return new Client({\n username: 'bitcoin',\n password: 'bitcoin',\n host: `http://localhost:${this.bitcoinPort}`,\n });\n }\n\n /**\n * Launch and return the localhost url. NOTE: this url will not work cross-docker. You need to use the containerAddress property\n * @param options\n * @param options.miningThreads - number of threads to use for mining\n * @param options.bootnodes - bootnodes to use for the mainchain\n */\n public async launch(options?: {\n miningThreads?: number;\n bootnodes?: string;\n author?: string;\n launchBitcoin?: boolean;\n }): Promise<string> {\n const { miningThreads = 1, bootnodes, author = 'alice', launchBitcoin = false } = options ?? {};\n let port = 0;\n let rpcPort = 0;\n let execArgs: string[] = [];\n let containerName: string;\n if (process.env.ARGON_USE_DOCKER_BINS) {\n containerName = 'miner_' + nanoid();\n this.containerName = containerName;\n this.#binPath = 'docker';\n port = 33344;\n rpcPort = 9944;\n execArgs = [\n 'run',\n '--rm',\n `--name=${containerName}`,\n `-p=0:${port}`,\n `-p=0:${rpcPort}`,\n '-e',\n `RUST_LOG=${this.loglevel},sc_rpc_server=info`,\n 'ghcr.io/argonprotocol/argon-miner:dev',\n ];\n\n if (process.env.ADD_DOCKER_HOST) {\n execArgs.splice(2, 0, `--add-host=host.docker.internal:host-gateway`);\n }\n }\n\n const bitcoinRpcUrl = await this.startBitcoin(launchBitcoin);\n execArgs.push(\n '--dev',\n '--validator',\n `--${author}`,\n `--compute-miners=${miningThreads}`,\n `--port=${port}`,\n `--rpc-port=${rpcPort}`,\n '--rpc-external',\n '--no-mdns',\n '--no-telemetry',\n '--no-prometheus',\n '--unsafe-rpc-external',\n '--rpc-methods=unsafe',\n `--bitcoin-rpc-url=${bitcoinRpcUrl}`,\n `--notebook-archive-hosts=http://127.0.0.1:9000/${this.uuid}`,\n );\n if (bootnodes) {\n execArgs.push(`--bootnodes=${bootnodes}`);\n }\n this.#process = spawn(this.#binPath, execArgs, {\n stdio: ['ignore', 'pipe', 'pipe', 'ignore'],\n env: { ...process.env, RUST_LOG: `${this.loglevel},sc_rpc_server=info` },\n });\n\n this.#process.stderr!.setEncoding('utf8');\n this.#process.stdout!.setEncoding('utf8');\n this.#process.stdout!.on('data', data => {\n console.log('Main >> %s', data);\n });\n\n const int1 = readline.createInterface({ input: this.#process.stdout! }).on('line', line => {\n if (line) console.log('Main >> %s', line);\n });\n this.#interfaces.push(int1);\n\n this.port = await new Promise<string>((resolve, reject) => {\n this.#process!.on('error', err => {\n console.warn('Error running mainchain', err);\n reject(err);\n });\n\n const int2 = readline.createInterface({ input: this.#process!.stderr! }).on('line', line => {\n console.log('Main >> %s', line);\n let match = line.match(/Running JSON-RPC server: addr=([\\d.:]+)/);\n if (match) {\n let ipv4 = match[1].split(',').at(0);\n resolve(ipv4!.split(':').pop()!);\n }\n });\n this.#interfaces.push(int2);\n });\n if (this.containerName) {\n this.port = await getDockerPortMapping(this.containerName, rpcPort);\n this.proxy = cleanHostForDocker(await getProxy());\n }\n\n console.log(`argon Node listening at ${this.address}`);\n return this.address;\n }\n\n public async client(): Promise<ArgonClient> {\n const client = await getClient(this.address);\n disconnectOnTeardown(client);\n return client;\n }\n\n public async bootAddress(): Promise<string | undefined> {\n const client = await this.client();\n const bootAddress = await client.rpc.system.localListenAddresses();\n\n for (const address of bootAddress) {\n const addr = address.toString();\n if (addr.includes('127.0.0.1')) {\n return addr;\n }\n }\n return undefined;\n }\n\n public async teardown(): Promise<void> {\n if (process.env.ARGON_USE_DOCKER_BINS) {\n try {\n execSync(`docker rm -f ${this.containerName}`);\n } catch {}\n }\n const launchedProcess = this.#process;\n if (launchedProcess) {\n launchedProcess?.kill();\n try {\n launchedProcess.stdio.forEach(io => io?.destroy());\n } catch {}\n launchedProcess.unref();\n }\n\n this.#process?.kill();\n this.#process?.unref();\n this.#bitcoind?.kill();\n this.#bitcoind?.unref();\n if (this.#bitcoinDir) {\n await fs.promises.rm(this.#bitcoinDir, {\n recursive: true,\n force: true,\n });\n }\n for (const i of this.#interfaces) {\n i.close();\n }\n }\n\n private async startBitcoin(launchBitcoin: boolean): Promise<string> {\n let rpcPort = 14338;\n if (launchBitcoin) {\n // Ensure lock file exists\n fs.closeSync(fs.openSync(lockPath, 'w'));\n const release = await lockfile.lock(lockPath, { retries: 10 });\n try {\n rpcPort = await detectPort();\n const path = execSync(Path.join(projectRoot(), `target/debug/argon-testing-bitcoin`), {\n encoding: 'utf8',\n }).trim();\n\n const tmpDir = fs.mkdtempSync('/tmp/argon-bitcoin-' + this.uuid);\n\n console.log('Starting bitcoin node at %s. Data %s', path, tmpDir);\n this.#bitcoind = spawn(\n path,\n [\n '-regtest',\n '-fallbackfee=0.0001',\n '-listen=0',\n `-datadir=${tmpDir}`,\n '-blockfilterindex',\n '-txindex',\n `-rpcport=${rpcPort}`,\n '-rpcbind=0.0.0.0',\n '-rpcallowip=0.0.0.0/0',\n '-rpcuser=bitcoin',\n '-rpcpassword=bitcoin',\n ],\n {\n stdio: ['ignore', 'pipe', 'pipe'],\n },\n );\n this.#bitcoind.stderr!.setEncoding('utf8');\n this.#bitcoind.stdout!.setEncoding('utf8');\n this.#bitcoind.stdout!.on('data', data => {\n console.log('Bitcoin >> %s', data);\n });\n this.#bitcoind.stderr!.on('data', data => {\n console.error('Bitcoin >> %s', data);\n });\n this.#bitcoinDir = tmpDir;\n } finally {\n // Release the lock file\n await release();\n }\n }\n this.bitcoinPort = rpcPort;\n return cleanHostForDocker(`http://bitcoin:bitcoin@localhost:${rpcPort}`);\n }\n}\n","import * as child_process from 'node:child_process';\nimport { projectRoot } from './index';\nimport * as Path from 'node:path';\n\nexport default class TestBitcoinCli {\n /**\n * Returns the localhost address of the notary (NOTE: not accessible from containers)\n */\n public static run(command: string): string {\n const binPath = Path.join(`${projectRoot()}`, 'target/debug/argon-bitcoin-cli');\n\n try {\n return child_process\n .execSync(`${binPath} ${command}`, {\n encoding: 'utf8',\n })\n .trim();\n } catch (e) {\n console.error(`Error running command: ${command}`);\n console.error((e as any).stdout);\n throw e;\n }\n }\n}\n","import * as child_process from 'node:child_process';\nimport { Keyring, KeyringPair } from '@argonprotocol/mainchain';\nimport * as fs from 'node:fs';\nimport * as readline from 'node:readline';\nimport { addTeardown, ITeardownable, projectRoot } from './index';\nimport * as process from 'node:process';\nimport * as Path from 'node:path';\nimport { Readable } from 'node:stream';\n\nexport default class TestOracle implements ITeardownable {\n public static BitcoinOperator = '//Dave';\n public static PriceIndexOperator = '//Eve';\n public operator?: KeyringPair;\n public port?: string;\n #childProcess?: child_process.ChildProcessByStdio<null, Readable, Readable>;\n #stdioInterface?: readline.Interface;\n\n constructor() {\n addTeardown(this);\n }\n\n public async start(\n service: 'price-index' | 'bitcoin',\n options: {\n mainchainUrl: string;\n bitcoinRpcUrl?: string;\n pathToBin?: string;\n env?: Record<string, string>;\n },\n ) {\n const { pathToBin, mainchainUrl, bitcoinRpcUrl } = options;\n const operatorSuri =\n service == 'bitcoin' ? TestOracle.BitcoinOperator : TestOracle.PriceIndexOperator;\n this.operator = new Keyring({ type: 'sr25519' }).createFromUri(operatorSuri);\n const binPath = pathToBin ?? Path.join(projectRoot(), 'target/debug/argon-oracle');\n if (!fs.existsSync(binPath)) {\n throw new Error(`Oracle binary not found at ${binPath}`);\n }\n console.log(`Starting ${service} oracle`);\n\n const execArgs: string[] = ['--dev', '-t', mainchainUrl, service];\n if (service == 'bitcoin') {\n if (!bitcoinRpcUrl) {\n throw new Error('Bitcoin RPC URL is required for bitcoin oracle');\n }\n execArgs.push('--bitcoin-rpc-url', bitcoinRpcUrl);\n } else {\n execArgs.push('--simulate-prices');\n }\n this.#childProcess = child_process.spawn(binPath, execArgs, {\n stdio: ['ignore', 'pipe', 'pipe'],\n env: { ...process.env, RUST_LOG: 'info', ...options.env },\n });\n this.#childProcess.stdout.setEncoding('utf8');\n this.#childProcess.stderr.setEncoding('utf8');\n this.#childProcess!.stderr.on('data', data => {\n console.warn('%sOracle >> %s', service, data);\n });\n this.#stdioInterface = readline\n .createInterface({ input: this.#childProcess!.stdout })\n .on('line', line => {\n console.log('%sOracle >> %s', service, line);\n });\n\n this.#childProcess.on('error', err => {\n throw err;\n });\n }\n\n public async teardown(): Promise<void> {\n this.#childProcess?.kill();\n this.#stdioInterface?.close();\n }\n}\n"],"mappings":"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","names":["import_mainchain","process","child_process","Path","process","pg","url","result","resolve","fs","Path","readline","import_nanoid","import_mainchain","nanoid","url","Client","resolve","child_process","Path","child_process","import_mainchain","fs","readline","process","Path","HttpProxy","resolve","teardown","sudo"]}
|
package/lib/index.d.cts
CHANGED
|
@@ -84,6 +84,7 @@ interface ITeardownable {
|
|
|
84
84
|
}
|
|
85
85
|
declare let describeIntegration: SuiteAPI;
|
|
86
86
|
declare function getProxy(): Promise<string>;
|
|
87
|
+
declare function stringifyExt(obj: any): any;
|
|
87
88
|
declare function projectRoot(): string;
|
|
88
89
|
/**
|
|
89
90
|
* Run a script from the project "scripts" folder
|
|
@@ -104,4 +105,4 @@ declare function disconnectOnTeardown<T extends {
|
|
|
104
105
|
declare function sudo(): KeyringPair;
|
|
105
106
|
declare function activateNotary(sudo: KeyringPair, client: ArgonClient, notary: TestNotary): Promise<void>;
|
|
106
107
|
|
|
107
|
-
export { type ITeardownable, TestBitcoinCli, TestMainchain, TestNotary, TestOracle, activateNotary, addTeardown, cleanHostForDocker, closeOnTeardown, describeIntegration, disconnectOnTeardown, getDockerPortMapping, getProxy, projectRoot, runOnTeardown, runTestScript, sudo, teardown };
|
|
108
|
+
export { type ITeardownable, TestBitcoinCli, TestMainchain, TestNotary, TestOracle, activateNotary, addTeardown, cleanHostForDocker, closeOnTeardown, describeIntegration, disconnectOnTeardown, getDockerPortMapping, getProxy, projectRoot, runOnTeardown, runTestScript, stringifyExt, sudo, teardown };
|
package/lib/index.d.ts
CHANGED
|
@@ -84,6 +84,7 @@ interface ITeardownable {
|
|
|
84
84
|
}
|
|
85
85
|
declare let describeIntegration: SuiteAPI;
|
|
86
86
|
declare function getProxy(): Promise<string>;
|
|
87
|
+
declare function stringifyExt(obj: any): any;
|
|
87
88
|
declare function projectRoot(): string;
|
|
88
89
|
/**
|
|
89
90
|
* Run a script from the project "scripts" folder
|
|
@@ -104,4 +105,4 @@ declare function disconnectOnTeardown<T extends {
|
|
|
104
105
|
declare function sudo(): KeyringPair;
|
|
105
106
|
declare function activateNotary(sudo: KeyringPair, client: ArgonClient, notary: TestNotary): Promise<void>;
|
|
106
107
|
|
|
107
|
-
export { type ITeardownable, TestBitcoinCli, TestMainchain, TestNotary, TestOracle, activateNotary, addTeardown, cleanHostForDocker, closeOnTeardown, describeIntegration, disconnectOnTeardown, getDockerPortMapping, getProxy, projectRoot, runOnTeardown, runTestScript, sudo, teardown };
|
|
108
|
+
export { type ITeardownable, TestBitcoinCli, TestMainchain, TestNotary, TestOracle, activateNotary, addTeardown, cleanHostForDocker, closeOnTeardown, describeIntegration, disconnectOnTeardown, getDockerPortMapping, getProxy, projectRoot, runOnTeardown, runTestScript, stringifyExt, sudo, teardown };
|
package/lib/index.js
CHANGED
|
@@ -6,10 +6,7 @@ var getDirname = () => path.dirname(getFilename());
|
|
|
6
6
|
var __dirname = /* @__PURE__ */ getDirname();
|
|
7
7
|
|
|
8
8
|
// src/index.ts
|
|
9
|
-
import {
|
|
10
|
-
Keyring as Keyring3,
|
|
11
|
-
TxSubmitter as TxSubmitter2
|
|
12
|
-
} from "@argonprotocol/mainchain";
|
|
9
|
+
import { Keyring as Keyring3, TxSubmitter as TxSubmitter2 } from "@argonprotocol/mainchain";
|
|
13
10
|
import { describe } from "vitest";
|
|
14
11
|
import * as process4 from "node:process";
|
|
15
12
|
import HttpProxy from "http-proxy";
|
|
@@ -22,10 +19,7 @@ import * as Path5 from "node:path";
|
|
|
22
19
|
import { customAlphabet } from "nanoid";
|
|
23
20
|
import pg from "pg";
|
|
24
21
|
import * as child_process from "node:child_process";
|
|
25
|
-
import {
|
|
26
|
-
Keyring,
|
|
27
|
-
TxSubmitter
|
|
28
|
-
} from "@argonprotocol/mainchain";
|
|
22
|
+
import { Keyring, TxSubmitter } from "@argonprotocol/mainchain";
|
|
29
23
|
import * as fs from "node:fs";
|
|
30
24
|
import * as readline from "node:readline";
|
|
31
25
|
import * as process2 from "node:process";
|
|
@@ -82,10 +76,7 @@ var TestNotary = class {
|
|
|
82
76
|
let tries = 10;
|
|
83
77
|
while (tries > 0) {
|
|
84
78
|
dbName = `notary_${uuid}`;
|
|
85
|
-
const result2 = await client.query(
|
|
86
|
-
"SELECT 1 FROM pg_database WHERE datname = $1",
|
|
87
|
-
[dbName]
|
|
88
|
-
);
|
|
79
|
+
const result2 = await client.query("SELECT 1 FROM pg_database WHERE datname = $1", [dbName]);
|
|
89
80
|
if (result2.rowCount === 0) {
|
|
90
81
|
break;
|
|
91
82
|
}
|
|
@@ -211,8 +202,10 @@ import * as readline2 from "node:readline";
|
|
|
211
202
|
import { detectPort } from "detect-port";
|
|
212
203
|
import { customAlphabet as customAlphabet2 } from "nanoid";
|
|
213
204
|
import Client from "bitcoin-core";
|
|
205
|
+
import * as lockfile from "proper-lockfile";
|
|
214
206
|
import { getClient } from "@argonprotocol/mainchain";
|
|
215
207
|
var nanoid2 = customAlphabet2("0123456789abcdefghijklmnopqrstuvwxyz", 4);
|
|
208
|
+
var lockPath = Path2.join(process.cwd(), ".port-lock");
|
|
216
209
|
var TestMainchain = class {
|
|
217
210
|
ip = "127.0.0.1";
|
|
218
211
|
port;
|
|
@@ -257,12 +250,7 @@ var TestMainchain = class {
|
|
|
257
250
|
* @param options.bootnodes - bootnodes to use for the mainchain
|
|
258
251
|
*/
|
|
259
252
|
async launch(options) {
|
|
260
|
-
const {
|
|
261
|
-
miningThreads = 1,
|
|
262
|
-
bootnodes,
|
|
263
|
-
author = "alice",
|
|
264
|
-
launchBitcoin = false
|
|
265
|
-
} = options ?? {};
|
|
253
|
+
const { miningThreads = 1, bootnodes, author = "alice", launchBitcoin = false } = options ?? {};
|
|
266
254
|
let port = 0;
|
|
267
255
|
let rpcPort = 0;
|
|
268
256
|
let execArgs = [];
|
|
@@ -296,6 +284,7 @@ var TestMainchain = class {
|
|
|
296
284
|
`--port=${port}`,
|
|
297
285
|
`--rpc-port=${rpcPort}`,
|
|
298
286
|
"--rpc-external",
|
|
287
|
+
"--no-mdns",
|
|
299
288
|
"--no-telemetry",
|
|
300
289
|
"--no-prometheus",
|
|
301
290
|
"--unsafe-rpc-external",
|
|
@@ -390,29 +379,46 @@ var TestMainchain = class {
|
|
|
390
379
|
async startBitcoin(launchBitcoin) {
|
|
391
380
|
let rpcPort = 14338;
|
|
392
381
|
if (launchBitcoin) {
|
|
393
|
-
|
|
394
|
-
const
|
|
395
|
-
|
|
396
|
-
|
|
382
|
+
fs2.closeSync(fs2.openSync(lockPath, "w"));
|
|
383
|
+
const release = await lockfile.lock(lockPath, { retries: 10 });
|
|
384
|
+
try {
|
|
385
|
+
rpcPort = await detectPort();
|
|
386
|
+
const path2 = execSync2(Path2.join(projectRoot(), `target/debug/argon-testing-bitcoin`), {
|
|
397
387
|
encoding: "utf8"
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
388
|
+
}).trim();
|
|
389
|
+
const tmpDir = fs2.mkdtempSync("/tmp/argon-bitcoin-" + this.uuid);
|
|
390
|
+
console.log("Starting bitcoin node at %s. Data %s", path2, tmpDir);
|
|
391
|
+
this.#bitcoind = spawn2(
|
|
392
|
+
path2,
|
|
393
|
+
[
|
|
394
|
+
"-regtest",
|
|
395
|
+
"-fallbackfee=0.0001",
|
|
396
|
+
"-listen=0",
|
|
397
|
+
`-datadir=${tmpDir}`,
|
|
398
|
+
"-blockfilterindex",
|
|
399
|
+
"-txindex",
|
|
400
|
+
`-rpcport=${rpcPort}`,
|
|
401
|
+
"-rpcbind=0.0.0.0",
|
|
402
|
+
"-rpcallowip=0.0.0.0/0",
|
|
403
|
+
"-rpcuser=bitcoin",
|
|
404
|
+
"-rpcpassword=bitcoin"
|
|
405
|
+
],
|
|
406
|
+
{
|
|
407
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
408
|
+
}
|
|
409
|
+
);
|
|
410
|
+
this.#bitcoind.stderr.setEncoding("utf8");
|
|
411
|
+
this.#bitcoind.stdout.setEncoding("utf8");
|
|
412
|
+
this.#bitcoind.stdout.on("data", (data) => {
|
|
413
|
+
console.log("Bitcoin >> %s", data);
|
|
414
|
+
});
|
|
415
|
+
this.#bitcoind.stderr.on("data", (data) => {
|
|
416
|
+
console.error("Bitcoin >> %s", data);
|
|
417
|
+
});
|
|
418
|
+
this.#bitcoinDir = tmpDir;
|
|
419
|
+
} finally {
|
|
420
|
+
await release();
|
|
421
|
+
}
|
|
416
422
|
}
|
|
417
423
|
this.bitcoinPort = rpcPort;
|
|
418
424
|
return cleanHostForDocker(`http://bitcoin:bitcoin@localhost:${rpcPort}`);
|
|
@@ -427,10 +433,7 @@ var TestBitcoinCli = class {
|
|
|
427
433
|
* Returns the localhost address of the notary (NOTE: not accessible from containers)
|
|
428
434
|
*/
|
|
429
435
|
static run(command) {
|
|
430
|
-
const binPath = Path3.join(
|
|
431
|
-
`${projectRoot()}`,
|
|
432
|
-
"target/debug/argon-bitcoin-cli"
|
|
433
|
-
);
|
|
436
|
+
const binPath = Path3.join(`${projectRoot()}`, "target/debug/argon-bitcoin-cli");
|
|
434
437
|
try {
|
|
435
438
|
return child_process2.execSync(`${binPath} ${command}`, {
|
|
436
439
|
encoding: "utf8"
|
|
@@ -463,9 +466,7 @@ var TestOracle = class _TestOracle {
|
|
|
463
466
|
async start(service, options) {
|
|
464
467
|
const { pathToBin, mainchainUrl, bitcoinRpcUrl } = options;
|
|
465
468
|
const operatorSuri = service == "bitcoin" ? _TestOracle.BitcoinOperator : _TestOracle.PriceIndexOperator;
|
|
466
|
-
this.operator = new Keyring2({ type: "sr25519" }).createFromUri(
|
|
467
|
-
operatorSuri
|
|
468
|
-
);
|
|
469
|
+
this.operator = new Keyring2({ type: "sr25519" }).createFromUri(operatorSuri);
|
|
469
470
|
const binPath = pathToBin ?? Path4.join(projectRoot(), "target/debug/argon-oracle");
|
|
470
471
|
if (!fs3.existsSync(binPath)) {
|
|
471
472
|
throw new Error(`Oracle binary not found at ${binPath}`);
|
|
@@ -551,6 +552,21 @@ async function getProxy() {
|
|
|
551
552
|
const port = proxyServer.address().port;
|
|
552
553
|
return `ws://host.docker.internal:${port}`;
|
|
553
554
|
}
|
|
555
|
+
function stringifyExt(obj) {
|
|
556
|
+
return JSON.stringify(
|
|
557
|
+
obj,
|
|
558
|
+
(_key, value) => {
|
|
559
|
+
if (typeof value === "bigint") {
|
|
560
|
+
return value.toString() + "n";
|
|
561
|
+
}
|
|
562
|
+
if (Buffer.isBuffer(value)) {
|
|
563
|
+
return `0x${Buffer.from(value).toString("hex")}`;
|
|
564
|
+
}
|
|
565
|
+
return value;
|
|
566
|
+
},
|
|
567
|
+
2
|
|
568
|
+
);
|
|
569
|
+
}
|
|
554
570
|
function projectRoot() {
|
|
555
571
|
if (process4.env.ARGON_PROJECT_ROOT) {
|
|
556
572
|
return Path5.join(process4.env.ARGON_PROJECT_ROOT);
|
|
@@ -600,9 +616,7 @@ async function activateNotary(sudo2, client, notary) {
|
|
|
600
616
|
await notary.register(client);
|
|
601
617
|
await new TxSubmitter2(
|
|
602
618
|
client,
|
|
603
|
-
client.tx.sudo.sudo(
|
|
604
|
-
client.tx.notaries.activate(notary.operator.publicKey)
|
|
605
|
-
),
|
|
619
|
+
client.tx.sudo.sudo(client.tx.notaries.activate(notary.operator.publicKey)),
|
|
606
620
|
sudo2
|
|
607
621
|
).submit({ waitForBlock: true });
|
|
608
622
|
}
|
|
@@ -622,6 +636,7 @@ export {
|
|
|
622
636
|
projectRoot,
|
|
623
637
|
runOnTeardown,
|
|
624
638
|
runTestScript,
|
|
639
|
+
stringifyExt,
|
|
625
640
|
sudo,
|
|
626
641
|
teardown
|
|
627
642
|
};
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/index.ts","../src/TestNotary.ts","../src/TestMainchain.ts","../src/TestBitcoinCli.ts","../src/TestOracle.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport { fileURLToPath } from 'url'\nimport path from 'path'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","import {\n ArgonClient,\n Keyring,\n KeyringPair,\n TxSubmitter,\n} from '@argonprotocol/mainchain';\nimport { describe, SuiteAPI } from 'vitest';\nimport * as process from 'node:process';\nimport HttpProxy from 'http-proxy';\nimport * as child_process from 'node:child_process';\nimport * as http from 'node:http';\nimport * as url from 'node:url';\nimport * as net from 'node:net';\nimport * as Path from 'node:path';\nimport TestNotary from './TestNotary';\nimport TestMainchain from './TestMainchain';\nimport TestBitcoinCli from './TestBitcoinCli';\nimport TestOracle from './TestOracle';\n\nexport { TestNotary, TestMainchain, TestBitcoinCli, TestOracle };\n\nexport interface ITeardownable {\n teardown(): Promise<void>;\n}\n\nconst toTeardown: ITeardownable[] = [];\n\nlet proxy: HttpProxy | null = null;\nlet proxyServer: http.Server | null = null;\nexport let describeIntegration: SuiteAPI = describe;\n\nif (process.env.SKIP_E2E === 'true' || process.env.SKIP_E2E === '1') {\n describeIntegration = describe.skip as any;\n}\n\nexport async function getProxy() {\n if (!proxy) {\n proxy = HttpProxy.createProxyServer({\n changeOrigin: true,\n ws: true,\n autoRewrite: true,\n });\n proxy.on('error', () => null);\n proxyServer = http.createServer(function (req, res) {\n //parse query string and get targetUrl\n const queryData = url.parse(req.url!, true).query;\n if (!queryData.target) {\n res.writeHead(500, { 'Content-Type': 'text/plain' });\n res.end('Target parameter is required');\n return;\n }\n console.log('Proxying http request', queryData.target);\n proxy?.web(req, res, { target: queryData.target as string });\n });\n proxyServer.on('upgrade', function (req, clientSocket, head) {\n const queryData = url.parse(req.url!, true).query;\n const target = url.parse(queryData.target as string);\n proxy?.ws(req, clientSocket, head, {\n target: target.href,\n ws: true,\n });\n clientSocket.on('error', console.error);\n });\n await new Promise<void>(resolve => proxyServer!.listen(0, resolve));\n toTeardown.push({\n teardown: () =>\n new Promise<void>(resolve => {\n proxy?.close();\n proxyServer?.close(_ => null);\n proxy = null;\n proxyServer = null;\n resolve();\n }),\n });\n }\n const port = (proxyServer!.address() as net.AddressInfo).port;\n return `ws://host.docker.internal:${port}`;\n}\n\nexport function projectRoot() {\n if (process.env.ARGON_PROJECT_ROOT) {\n return Path.join(process.env.ARGON_PROJECT_ROOT);\n }\n return Path.join(__dirname, `../../..`);\n}\n\n/**\n * Run a script from the project \"scripts\" folder\n * @param relativePath\n */\nexport async function runTestScript(relativePath: string): Promise<string> {\n const scriptPath = Path.resolve(projectRoot(), relativePath);\n return child_process.execSync(scriptPath, { encoding: 'utf8' }).trim();\n}\n\nexport async function getDockerPortMapping(\n containerName: string,\n port: number,\n): Promise<string | undefined> {\n return child_process\n .execSync(`docker port ${containerName} ${port}`, { encoding: 'utf8' })\n .trim()\n .split(':')\n .pop();\n}\n\nexport async function teardown() {\n for (const t of toTeardown) {\n try {\n await t.teardown().catch(console.error);\n } catch {}\n }\n toTeardown.length = 0;\n}\n\nexport function cleanHostForDocker(\n host: string,\n replacer = 'host.docker.internal',\n): string {\n if (process.env.ARGON_USE_DOCKER_BINS) {\n return host\n .replace('localhost', replacer)\n .replace('127.0.0.1', replacer)\n .replace('0.0.0.0', replacer);\n }\n return host;\n}\n\nexport function addTeardown(teardownable: ITeardownable) {\n toTeardown.push(teardownable);\n}\n\nexport function runOnTeardown(teardown: () => Promise<void>) {\n addTeardown({ teardown });\n}\n\nexport function closeOnTeardown<T extends { close(): Promise<void> }>(\n closeable: T,\n): T {\n addTeardown({ teardown: () => closeable.close() });\n return closeable;\n}\n\nexport function disconnectOnTeardown<T extends { disconnect(): Promise<void> }>(\n closeable: T,\n): T {\n addTeardown({ teardown: () => closeable.disconnect() });\n return closeable;\n}\n\nexport function sudo(): KeyringPair {\n return new Keyring({ type: 'sr25519' }).createFromUri('//Alice');\n}\n\nexport async function activateNotary(\n sudo: KeyringPair,\n client: ArgonClient,\n notary: TestNotary,\n) {\n await notary.register(client);\n await new TxSubmitter(\n client,\n client.tx.sudo.sudo(\n client.tx.notaries.activate(notary.operator!.publicKey),\n ),\n sudo,\n ).submit({ waitForBlock: true });\n}\n","import { customAlphabet } from 'nanoid';\nimport pg from 'pg';\nimport type { Client } from 'pg';\nimport * as child_process from 'node:child_process';\nimport {\n ArgonClient,\n Keyring,\n KeyringPair,\n TxSubmitter,\n} from '@argonprotocol/mainchain';\nimport * as fs from 'node:fs';\nimport * as readline from 'node:readline';\nimport {\n addTeardown,\n cleanHostForDocker,\n getDockerPortMapping,\n getProxy,\n ITeardownable,\n projectRoot,\n} from './index';\nimport * as process from 'node:process';\nimport { Readable } from 'node:stream';\nimport * as Path from 'node:path';\n\nconst { Client: PgClient } = pg;\n\nconst nanoid = customAlphabet('0123456789abcdefghijklmnopqrstuvwxyz', 4);\n\nexport function createUid(): string {\n return nanoid();\n}\n\nexport default class TestNotary implements ITeardownable {\n public operator?: KeyringPair;\n public ip = '127.0.0.1';\n public registeredPublicKey?: Uint8Array;\n public port?: string;\n public containerName?: string;\n public proxy?: string;\n #dbName?: string;\n #dbConnectionString: string;\n #childProcess?: child_process.ChildProcessByStdio<null, Readable, Readable>;\n #stdioInterface?: readline.Interface;\n\n public get address(): string {\n if (this.proxy) {\n const url = new URL(this.proxy);\n url.searchParams.set('target', `ws://${this.ip}:${this.port}`);\n return url.href;\n }\n return `ws://${this.ip}:${this.port}`;\n }\n\n constructor(dbConnectionString?: string) {\n this.#dbConnectionString =\n dbConnectionString ??\n process.env.NOTARY_DB_URL ??\n 'postgres://postgres:postgres@localhost:5432';\n addTeardown(this);\n }\n\n /**\n * Returns the localhost address of the notary (NOTE: not accessible from containers)\n */\n public async start(options: {\n mainchainUrl: string;\n uuid: string;\n pathToNotaryBin?: string;\n }): Promise<string> {\n const { pathToNotaryBin, uuid, mainchainUrl } = options;\n this.operator = new Keyring({ type: 'sr25519' }).createFromUri('//Bob');\n this.registeredPublicKey = new Keyring({ type: 'ed25519' }).createFromUri(\n '//Ferdie//notary',\n ).publicKey;\n\n let notaryPath =\n pathToNotaryBin ?? Path.join(projectRoot(), 'target/debug/argon-notary');\n if (process.env.ARGON_USE_DOCKER_BINS) {\n this.containerName = 'notary_' + uuid;\n const addHost = process.env.ADD_DOCKER_HOST\n ? ` --add-host=host.docker.internal:host-gateway`\n : '';\n\n notaryPath = `docker run --rm -p=0:9925${addHost} --name=${this.containerName} -e RUST_LOG=warn ghcr.io/argonprotocol/argon-notary:dev`;\n\n this.#dbConnectionString = cleanHostForDocker(this.#dbConnectionString);\n } else if (!fs.existsSync(notaryPath)) {\n throw new Error(`Notary binary not found at ${notaryPath}`);\n }\n\n const client = await this.connect();\n let dbName = '';\n try {\n let tries = 10;\n while (tries > 0) {\n dbName = `notary_${uuid}`;\n // check if the db path notary_{id} exists\n const result = await client.query(\n 'SELECT 1 FROM pg_database WHERE datname = $1',\n [dbName],\n );\n if (result.rowCount === 0) {\n break;\n }\n tries -= 1;\n }\n this.#dbName = dbName;\n await client.query(`CREATE DATABASE \"${dbName}\"`);\n } finally {\n await client.end();\n }\n\n let result = child_process.execSync(\n `${notaryPath} migrate --db-url ${this.#dbConnectionString}/${this.#dbName}`,\n {\n encoding: 'utf-8',\n },\n );\n if (result.trim().length) {\n console.log(result.trim());\n }\n console.log(\n \"Notary >> connecting to mainchain '%s', db %s\",\n mainchainUrl,\n `${this.#dbConnectionString}/${this.#dbName}`,\n );\n\n const bucketName = `notary-${uuid}`;\n const execArgs = [\n 'run',\n `--db-url=${this.#dbConnectionString}/${this.#dbName}`,\n `--dev`,\n `-t ${mainchainUrl}`,\n `--archive-bucket=${bucketName}`,\n `--operator-address=${this.operator.address}`,\n ];\n if (process.env.ARGON_USE_DOCKER_BINS) {\n process.env.AWS_S3_ENDPOINT = 'http://host.docker.internal:9000';\n execArgs.unshift(...notaryPath.replace('docker run', 'run').split(' '));\n execArgs.push('-b=0.0.0.0:9925');\n\n notaryPath = 'docker';\n }\n if (process.env.AWS_S3_ENDPOINT) {\n execArgs.push(`--archive-endpoint=${process.env.AWS_S3_ENDPOINT}`);\n }\n this.#childProcess = child_process.spawn(notaryPath, execArgs, {\n stdio: ['ignore', 'pipe', 'pipe'],\n env: { ...process.env, RUST_LOG: 'warn' },\n });\n this.#childProcess.stdout.setEncoding('utf8');\n this.#childProcess.stderr.setEncoding('utf8');\n this.port = await new Promise<string>((resolve, reject) => {\n const onProcessError = (err: Error): void => {\n console.warn('Error running notary', err);\n reject(err);\n };\n this.#childProcess!.once('error', onProcessError);\n this.#childProcess!.stderr.on('data', data => {\n console.warn('Notary >> %s', data);\n if (data.startsWith('WARNING')) return;\n this.#childProcess!.off('error', onProcessError);\n reject(data);\n });\n this.#stdioInterface = readline\n .createInterface({ input: this.#childProcess!.stdout })\n .on('line', line => {\n console.log('Notary >> %s', line);\n let match = line.match(/Listening on ([ws:/\\d.]+)/);\n if (match?.length ?? 0 > 0) {\n resolve(match![1].split(':').pop()!);\n }\n });\n });\n this.#childProcess.on('error', err => {\n throw err;\n });\n if (this.containerName) {\n this.port = await getDockerPortMapping(this.containerName, 9925);\n this.proxy = cleanHostForDocker(await getProxy());\n }\n\n return this.address;\n }\n\n public async register(client: ArgonClient): Promise<void> {\n let address = new URL(this.address);\n await new TxSubmitter(\n client,\n client.tx.notaries.propose({\n public: this.registeredPublicKey,\n hosts: [address.href],\n name: 'Test Notary',\n }),\n this.operator!,\n ).submit({ waitForBlock: true });\n }\n\n public async teardown(): Promise<void> {\n this.#childProcess?.kill();\n this.#stdioInterface?.close();\n const client = await this.connect();\n try {\n await client.query(`DROP DATABASE \"${this.#dbName}\" WITH (FORCE)`);\n } finally {\n await client.end();\n }\n if (this.containerName) {\n try {\n child_process.execSync(`docker rm -f ${this.containerName}`);\n } catch {}\n }\n }\n\n async connect(): Promise<Client> {\n const client = new PgClient({ connectionString: this.#dbConnectionString });\n try {\n await client.connect();\n } catch (err) {\n console.error('ERROR connecting to postgres client', err);\n throw err;\n }\n return client;\n }\n}\n","import * as fs from 'node:fs';\nimport { ChildProcess, execSync, spawn } from 'node:child_process';\nimport * as Path from 'node:path';\nimport * as readline from 'node:readline';\nimport {\n addTeardown,\n cleanHostForDocker,\n disconnectOnTeardown,\n getDockerPortMapping,\n getProxy,\n ITeardownable,\n projectRoot,\n} from './index';\nimport { detectPort } from 'detect-port';\nimport { customAlphabet } from 'nanoid';\nimport Client from 'bitcoin-core';\nimport { createUid } from './TestNotary';\nimport { type ArgonClient, getClient } from '@argonprotocol/mainchain';\n\nconst nanoid = customAlphabet('0123456789abcdefghijklmnopqrstuvwxyz', 4);\n\nexport default class TestMainchain implements ITeardownable {\n public ip = '127.0.0.1';\n public port?: string;\n public loglevel = 'warn';\n public uuid: string;\n #binPath: string;\n #process?: ChildProcess;\n #interfaces: readline.Interface[] = [];\n containerName?: string;\n proxy?: string;\n #bitcoind?: ChildProcess;\n bitcoinPort?: number;\n #bitcoinDir?: string;\n\n public get address(): string {\n if (this.proxy) {\n const url = new URL(this.proxy);\n url.searchParams.set('target', `ws://${this.ip}:${this.port}`);\n return url.href;\n }\n return `ws://${this.ip}:${this.port}`;\n }\n\n constructor(binPath?: string) {\n this.#binPath =\n binPath ?? Path.join(projectRoot(), `target/debug/argon-node`);\n this.#binPath = Path.resolve(this.#binPath);\n if (!process.env.ARGON_USE_DOCKER_BINS && !fs.existsSync(this.#binPath)) {\n throw new Error(`Mainchain binary not found at ${this.#binPath}`);\n }\n this.uuid = createUid();\n addTeardown(this);\n }\n\n public getBitcoinClient(): Client {\n return new Client({\n username: 'bitcoin',\n password: 'bitcoin',\n host: `http://localhost:${this.bitcoinPort}`,\n });\n }\n\n /**\n * Launch and return the localhost url. NOTE: this url will not work cross-docker. You need to use the containerAddress property\n * @param options\n * @param options.miningThreads - number of threads to use for mining\n * @param options.bootnodes - bootnodes to use for the mainchain\n */\n public async launch(options?: {\n miningThreads?: number;\n bootnodes?: string;\n author?: string;\n launchBitcoin?: boolean;\n }): Promise<string> {\n const {\n miningThreads = 1,\n bootnodes,\n author = 'alice',\n launchBitcoin = false,\n } = options ?? {};\n let port = 0;\n let rpcPort = 0;\n let execArgs: string[] = [];\n let containerName: string;\n if (process.env.ARGON_USE_DOCKER_BINS) {\n containerName = 'miner_' + nanoid();\n this.containerName = containerName;\n this.#binPath = 'docker';\n port = 33344;\n rpcPort = 9944;\n execArgs = [\n 'run',\n '--rm',\n `--name=${containerName}`,\n `-p=0:${port}`,\n `-p=0:${rpcPort}`,\n '-e',\n `RUST_LOG=${this.loglevel},sc_rpc_server=info`,\n 'ghcr.io/argonprotocol/argon-miner:dev',\n ];\n\n if (process.env.ADD_DOCKER_HOST) {\n execArgs.splice(2, 0, `--add-host=host.docker.internal:host-gateway`);\n }\n }\n\n const bitcoinRpcUrl = await this.startBitcoin(launchBitcoin);\n execArgs.push(\n '--dev',\n '--validator',\n `--${author}`,\n `--compute-miners=${miningThreads}`,\n `--port=${port}`,\n `--rpc-port=${rpcPort}`,\n '--rpc-external',\n '--no-telemetry',\n '--no-prometheus',\n '--unsafe-rpc-external',\n '--rpc-methods=unsafe',\n `--bitcoin-rpc-url=${bitcoinRpcUrl}`,\n `--notebook-archive-hosts=http://127.0.0.1:9000/${this.uuid}`,\n );\n if (bootnodes) {\n execArgs.push(`--bootnodes=${bootnodes}`);\n }\n this.#process = spawn(this.#binPath, execArgs, {\n stdio: ['ignore', 'pipe', 'pipe', 'ignore'],\n env: { ...process.env, RUST_LOG: `${this.loglevel},sc_rpc_server=info` },\n });\n\n this.#process.stderr!.setEncoding('utf8');\n this.#process.stdout!.setEncoding('utf8');\n this.#process.stdout!.on('data', data => {\n console.log('Main >> %s', data);\n });\n\n const int1 = readline\n .createInterface({ input: this.#process.stdout! })\n .on('line', line => {\n if (line) console.log('Main >> %s', line);\n });\n this.#interfaces.push(int1);\n\n this.port = await new Promise<string>((resolve, reject) => {\n this.#process!.on('error', err => {\n console.warn('Error running mainchain', err);\n reject(err);\n });\n\n const int2 = readline\n .createInterface({ input: this.#process!.stderr! })\n .on('line', line => {\n console.log('Main >> %s', line);\n let match = line.match(/Running JSON-RPC server: addr=([\\d.:]+)/);\n if (match) {\n let ipv4 = match[1].split(',').at(0);\n resolve(ipv4!.split(':').pop()!);\n }\n });\n this.#interfaces.push(int2);\n });\n if (this.containerName) {\n this.port = await getDockerPortMapping(this.containerName, rpcPort);\n this.proxy = cleanHostForDocker(await getProxy());\n }\n\n console.log(`argon Node listening at ${this.address}`);\n return this.address;\n }\n\n public async client(): Promise<ArgonClient> {\n const client = await getClient(this.address);\n disconnectOnTeardown(client);\n return client;\n }\n\n public async bootAddress(): Promise<string | undefined> {\n const client = await this.client();\n const bootAddress = await client.rpc.system.localListenAddresses();\n\n for (const address of bootAddress) {\n const addr = address.toString();\n if (addr.includes('127.0.0.1')) {\n return addr;\n }\n }\n return undefined;\n }\n\n public async teardown(): Promise<void> {\n if (process.env.ARGON_USE_DOCKER_BINS) {\n try {\n execSync(`docker rm -f ${this.containerName}`);\n } catch {}\n }\n const launchedProcess = this.#process;\n if (launchedProcess) {\n launchedProcess?.kill();\n try {\n launchedProcess.stdio.forEach(io => io?.destroy());\n } catch {}\n launchedProcess.unref();\n }\n\n this.#process?.kill();\n this.#process?.unref();\n this.#bitcoind?.kill();\n this.#bitcoind?.unref();\n if (this.#bitcoinDir) {\n await fs.promises.rm(this.#bitcoinDir, {\n recursive: true,\n force: true,\n });\n }\n for (const i of this.#interfaces) {\n i.close();\n }\n }\n\n private async startBitcoin(launchBitcoin: boolean): Promise<string> {\n let rpcPort = 14338;\n if (launchBitcoin) {\n rpcPort = await detectPort();\n const path = execSync(\n Path.join(projectRoot(), `target/debug/argon-testing-bitcoin`),\n {\n encoding: 'utf8',\n },\n ).trim();\n\n const tmpDir = fs.mkdtempSync('/tmp/argon-bitcoin-' + this.uuid);\n\n console.log('Starting bitcoin node at %s', tmpDir);\n this.#bitcoind = spawn(path, [\n '-regtest',\n '-fallbackfee=0.0001',\n '-listen=0',\n `-datadir=${tmpDir}`,\n '-blockfilterindex',\n '-txindex',\n `-rpcport=${rpcPort}`,\n '-rpcbind=0.0.0.0',\n '-rpcallowip=0.0.0.0/0',\n '-rpcuser=bitcoin',\n '-rpcpassword=bitcoin',\n ]);\n this.#bitcoinDir = tmpDir;\n }\n this.bitcoinPort = rpcPort;\n return cleanHostForDocker(`http://bitcoin:bitcoin@localhost:${rpcPort}`);\n }\n}\n","import * as child_process from 'node:child_process';\nimport { projectRoot } from './index';\nimport * as Path from 'node:path';\n\nexport default class TestBitcoinCli {\n /**\n * Returns the localhost address of the notary (NOTE: not accessible from containers)\n */\n public static run(command: string): string {\n const binPath = Path.join(\n `${projectRoot()}`,\n 'target/debug/argon-bitcoin-cli',\n );\n\n try {\n return child_process\n .execSync(`${binPath} ${command}`, {\n encoding: 'utf8',\n })\n .trim();\n } catch (e) {\n console.error(`Error running command: ${command}`);\n console.error((e as any).stdout);\n throw e;\n }\n }\n}\n","import * as child_process from 'node:child_process';\nimport { Keyring, KeyringPair } from '@argonprotocol/mainchain';\nimport * as fs from 'node:fs';\nimport * as readline from 'node:readline';\nimport { addTeardown, ITeardownable, projectRoot } from './index';\nimport * as process from 'node:process';\nimport * as Path from 'node:path';\nimport { Readable } from 'node:stream';\n\nexport default class TestOracle implements ITeardownable {\n public static BitcoinOperator = '//Dave';\n public static PriceIndexOperator = '//Eve';\n public operator?: KeyringPair;\n public port?: string;\n #childProcess?: child_process.ChildProcessByStdio<null, Readable, Readable>;\n #stdioInterface?: readline.Interface;\n\n constructor() {\n addTeardown(this);\n }\n\n public async start(\n service: 'price-index' | 'bitcoin',\n options: {\n mainchainUrl: string;\n bitcoinRpcUrl?: string;\n pathToBin?: string;\n env?: Record<string, string>;\n },\n ) {\n const { pathToBin, mainchainUrl, bitcoinRpcUrl } = options;\n const operatorSuri =\n service == 'bitcoin'\n ? TestOracle.BitcoinOperator\n : TestOracle.PriceIndexOperator;\n this.operator = new Keyring({ type: 'sr25519' }).createFromUri(\n operatorSuri,\n );\n const binPath =\n pathToBin ?? Path.join(projectRoot(), 'target/debug/argon-oracle');\n if (!fs.existsSync(binPath)) {\n throw new Error(`Oracle binary not found at ${binPath}`);\n }\n console.log(`Starting ${service} oracle`);\n\n const execArgs: string[] = ['--dev', '-t', mainchainUrl, service];\n if (service == 'bitcoin') {\n if (!bitcoinRpcUrl) {\n throw new Error('Bitcoin RPC URL is required for bitcoin oracle');\n }\n execArgs.push('--bitcoin-rpc-url', bitcoinRpcUrl);\n } else {\n execArgs.push('--simulate-prices');\n }\n this.#childProcess = child_process.spawn(binPath, execArgs, {\n stdio: ['ignore', 'pipe', 'pipe'],\n env: { ...process.env, RUST_LOG: 'info', ...options.env },\n });\n this.#childProcess.stdout.setEncoding('utf8');\n this.#childProcess.stderr.setEncoding('utf8');\n this.#childProcess!.stderr.on('data', data => {\n console.warn('%sOracle >> %s', service, data);\n });\n this.#stdioInterface = readline\n .createInterface({ input: this.#childProcess!.stdout })\n .on('line', line => {\n console.log('%sOracle >> %s', service, line);\n });\n\n this.#childProcess.on('error', err => {\n throw err;\n });\n }\n\n public async teardown(): Promise<void> {\n this.#childProcess?.kill();\n this.#stdioInterface?.close();\n }\n}\n"],"mappings":"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","names":["Keyring","TxSubmitter","process","child_process","Path","process","url","result","resolve","fs","execSync","spawn","Path","readline","customAlphabet","nanoid","customAlphabet","url","spawn","resolve","execSync","path","child_process","Path","child_process","Keyring","fs","readline","process","Path","Keyring","resolve","teardown","Keyring","sudo","TxSubmitter"]}
|
|
1
|
+
{"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/index.ts","../src/TestNotary.ts","../src/TestMainchain.ts","../src/TestBitcoinCli.ts","../src/TestOracle.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport { fileURLToPath } from 'url'\nimport path from 'path'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","import { ArgonClient, Keyring, KeyringPair, TxSubmitter } from '@argonprotocol/mainchain';\nimport { describe, SuiteAPI } from 'vitest';\nimport * as process from 'node:process';\nimport HttpProxy from 'http-proxy';\nimport * as child_process from 'node:child_process';\nimport * as http from 'node:http';\nimport * as url from 'node:url';\nimport * as net from 'node:net';\nimport * as Path from 'node:path';\nimport TestNotary from './TestNotary';\nimport TestMainchain from './TestMainchain';\nimport TestBitcoinCli from './TestBitcoinCli';\nimport TestOracle from './TestOracle';\nimport * as util from 'node:util';\n\nexport { TestNotary, TestMainchain, TestBitcoinCli, TestOracle };\n\nexport interface ITeardownable {\n teardown(): Promise<void>;\n}\n\nconst toTeardown: ITeardownable[] = [];\n\nlet proxy: HttpProxy | null = null;\nlet proxyServer: http.Server | null = null;\nexport let describeIntegration: SuiteAPI = describe;\n\nif (process.env.SKIP_E2E === 'true' || process.env.SKIP_E2E === '1') {\n describeIntegration = describe.skip as any;\n}\n\nexport async function getProxy() {\n if (!proxy) {\n proxy = HttpProxy.createProxyServer({\n changeOrigin: true,\n ws: true,\n autoRewrite: true,\n });\n proxy.on('error', () => null);\n proxyServer = http.createServer(function (req, res) {\n //parse query string and get targetUrl\n const queryData = url.parse(req.url!, true).query;\n if (!queryData.target) {\n res.writeHead(500, { 'Content-Type': 'text/plain' });\n res.end('Target parameter is required');\n return;\n }\n console.log('Proxying http request', queryData.target);\n proxy?.web(req, res, { target: queryData.target as string });\n });\n proxyServer.on('upgrade', function (req, clientSocket, head) {\n const queryData = url.parse(req.url!, true).query;\n const target = url.parse(queryData.target as string);\n proxy?.ws(req, clientSocket, head, {\n target: target.href,\n ws: true,\n });\n clientSocket.on('error', console.error);\n });\n await new Promise<void>(resolve => proxyServer!.listen(0, resolve));\n toTeardown.push({\n teardown: () =>\n new Promise<void>(resolve => {\n proxy?.close();\n proxyServer?.close(_ => null);\n proxy = null;\n proxyServer = null;\n resolve();\n }),\n });\n }\n const port = (proxyServer!.address() as net.AddressInfo).port;\n return `ws://host.docker.internal:${port}`;\n}\n\nexport function stringifyExt(obj: any): any {\n return JSON.stringify(\n obj,\n (_key, value) => {\n if (typeof value === 'bigint') {\n return value.toString() + 'n'; // Append 'n' to indicate bigint\n }\n if (Buffer.isBuffer(value)) {\n return `0x${Buffer.from(value).toString('hex')}`; // Convert Buffer to hex string\n }\n return value;\n },\n 2,\n );\n}\n\nexport function projectRoot() {\n if (process.env.ARGON_PROJECT_ROOT) {\n return Path.join(process.env.ARGON_PROJECT_ROOT);\n }\n return Path.join(__dirname, `../../..`);\n}\n\n/**\n * Run a script from the project \"scripts\" folder\n * @param relativePath\n */\nexport async function runTestScript(relativePath: string): Promise<string> {\n const scriptPath = Path.resolve(projectRoot(), relativePath);\n return child_process.execSync(scriptPath, { encoding: 'utf8' }).trim();\n}\n\nexport async function getDockerPortMapping(\n containerName: string,\n port: number,\n): Promise<string | undefined> {\n return child_process\n .execSync(`docker port ${containerName} ${port}`, { encoding: 'utf8' })\n .trim()\n .split(':')\n .pop();\n}\n\nexport async function teardown() {\n for (const t of toTeardown) {\n try {\n await t.teardown().catch(console.error);\n } catch {}\n }\n toTeardown.length = 0;\n}\n\nexport function cleanHostForDocker(host: string, replacer = 'host.docker.internal'): string {\n if (process.env.ARGON_USE_DOCKER_BINS) {\n return host\n .replace('localhost', replacer)\n .replace('127.0.0.1', replacer)\n .replace('0.0.0.0', replacer);\n }\n return host;\n}\n\nexport function addTeardown(teardownable: ITeardownable) {\n toTeardown.push(teardownable);\n}\n\nexport function runOnTeardown(teardown: () => Promise<void>) {\n addTeardown({ teardown });\n}\n\nexport function closeOnTeardown<T extends { close(): Promise<void> }>(closeable: T): T {\n addTeardown({ teardown: () => closeable.close() });\n return closeable;\n}\n\nexport function disconnectOnTeardown<T extends { disconnect(): Promise<void> }>(closeable: T): T {\n addTeardown({ teardown: () => closeable.disconnect() });\n return closeable;\n}\n\nexport function sudo(): KeyringPair {\n return new Keyring({ type: 'sr25519' }).createFromUri('//Alice');\n}\n\nexport async function activateNotary(sudo: KeyringPair, client: ArgonClient, notary: TestNotary) {\n await notary.register(client);\n await new TxSubmitter(\n client,\n client.tx.sudo.sudo(client.tx.notaries.activate(notary.operator!.publicKey)),\n sudo,\n ).submit({ waitForBlock: true });\n}\n","import { customAlphabet } from 'nanoid';\nimport pg from 'pg';\nimport type { Client } from 'pg';\nimport * as child_process from 'node:child_process';\nimport { ArgonClient, Keyring, KeyringPair, TxSubmitter } from '@argonprotocol/mainchain';\nimport * as fs from 'node:fs';\nimport * as readline from 'node:readline';\nimport {\n addTeardown,\n cleanHostForDocker,\n getDockerPortMapping,\n getProxy,\n ITeardownable,\n projectRoot,\n} from './index';\nimport * as process from 'node:process';\nimport { Readable } from 'node:stream';\nimport * as Path from 'node:path';\n\nconst { Client: PgClient } = pg;\n\nconst nanoid = customAlphabet('0123456789abcdefghijklmnopqrstuvwxyz', 4);\n\nexport function createUid(): string {\n return nanoid();\n}\n\nexport default class TestNotary implements ITeardownable {\n public operator?: KeyringPair;\n public ip = '127.0.0.1';\n public registeredPublicKey?: Uint8Array;\n public port?: string;\n public containerName?: string;\n public proxy?: string;\n #dbName?: string;\n #dbConnectionString: string;\n #childProcess?: child_process.ChildProcessByStdio<null, Readable, Readable>;\n #stdioInterface?: readline.Interface;\n\n public get address(): string {\n if (this.proxy) {\n const url = new URL(this.proxy);\n url.searchParams.set('target', `ws://${this.ip}:${this.port}`);\n return url.href;\n }\n return `ws://${this.ip}:${this.port}`;\n }\n\n constructor(dbConnectionString?: string) {\n this.#dbConnectionString =\n dbConnectionString ??\n process.env.NOTARY_DB_URL ??\n 'postgres://postgres:postgres@localhost:5432';\n addTeardown(this);\n }\n\n /**\n * Returns the localhost address of the notary (NOTE: not accessible from containers)\n */\n public async start(options: {\n mainchainUrl: string;\n uuid: string;\n pathToNotaryBin?: string;\n }): Promise<string> {\n const { pathToNotaryBin, uuid, mainchainUrl } = options;\n this.operator = new Keyring({ type: 'sr25519' }).createFromUri('//Bob');\n this.registeredPublicKey = new Keyring({ type: 'ed25519' }).createFromUri(\n '//Ferdie//notary',\n ).publicKey;\n\n let notaryPath = pathToNotaryBin ?? Path.join(projectRoot(), 'target/debug/argon-notary');\n if (process.env.ARGON_USE_DOCKER_BINS) {\n this.containerName = 'notary_' + uuid;\n const addHost = process.env.ADD_DOCKER_HOST\n ? ` --add-host=host.docker.internal:host-gateway`\n : '';\n\n notaryPath = `docker run --rm -p=0:9925${addHost} --name=${this.containerName} -e RUST_LOG=warn ghcr.io/argonprotocol/argon-notary:dev`;\n\n this.#dbConnectionString = cleanHostForDocker(this.#dbConnectionString);\n } else if (!fs.existsSync(notaryPath)) {\n throw new Error(`Notary binary not found at ${notaryPath}`);\n }\n\n const client = await this.connect();\n let dbName = '';\n try {\n let tries = 10;\n while (tries > 0) {\n dbName = `notary_${uuid}`;\n // check if the db path notary_{id} exists\n const result = await client.query('SELECT 1 FROM pg_database WHERE datname = $1', [dbName]);\n if (result.rowCount === 0) {\n break;\n }\n tries -= 1;\n }\n this.#dbName = dbName;\n await client.query(`CREATE DATABASE \"${dbName}\"`);\n } finally {\n await client.end();\n }\n\n let result = child_process.execSync(\n `${notaryPath} migrate --db-url ${this.#dbConnectionString}/${this.#dbName}`,\n {\n encoding: 'utf-8',\n },\n );\n if (result.trim().length) {\n console.log(result.trim());\n }\n console.log(\n \"Notary >> connecting to mainchain '%s', db %s\",\n mainchainUrl,\n `${this.#dbConnectionString}/${this.#dbName}`,\n );\n\n const bucketName = `notary-${uuid}`;\n const execArgs = [\n 'run',\n `--db-url=${this.#dbConnectionString}/${this.#dbName}`,\n `--dev`,\n `-t ${mainchainUrl}`,\n `--archive-bucket=${bucketName}`,\n `--operator-address=${this.operator.address}`,\n ];\n if (process.env.ARGON_USE_DOCKER_BINS) {\n process.env.AWS_S3_ENDPOINT = 'http://host.docker.internal:9000';\n execArgs.unshift(...notaryPath.replace('docker run', 'run').split(' '));\n execArgs.push('-b=0.0.0.0:9925');\n\n notaryPath = 'docker';\n }\n if (process.env.AWS_S3_ENDPOINT) {\n execArgs.push(`--archive-endpoint=${process.env.AWS_S3_ENDPOINT}`);\n }\n this.#childProcess = child_process.spawn(notaryPath, execArgs, {\n stdio: ['ignore', 'pipe', 'pipe'],\n env: { ...process.env, RUST_LOG: 'warn' },\n });\n this.#childProcess.stdout.setEncoding('utf8');\n this.#childProcess.stderr.setEncoding('utf8');\n this.port = await new Promise<string>((resolve, reject) => {\n const onProcessError = (err: Error): void => {\n console.warn('Error running notary', err);\n reject(err);\n };\n this.#childProcess!.once('error', onProcessError);\n this.#childProcess!.stderr.on('data', data => {\n console.warn('Notary >> %s', data);\n if (data.startsWith('WARNING')) return;\n this.#childProcess!.off('error', onProcessError);\n reject(data);\n });\n this.#stdioInterface = readline\n .createInterface({ input: this.#childProcess!.stdout })\n .on('line', line => {\n console.log('Notary >> %s', line);\n let match = line.match(/Listening on ([ws:/\\d.]+)/);\n if (match?.length ?? 0 > 0) {\n resolve(match![1].split(':').pop()!);\n }\n });\n });\n this.#childProcess.on('error', err => {\n throw err;\n });\n if (this.containerName) {\n this.port = await getDockerPortMapping(this.containerName, 9925);\n this.proxy = cleanHostForDocker(await getProxy());\n }\n\n return this.address;\n }\n\n public async register(client: ArgonClient): Promise<void> {\n let address = new URL(this.address);\n await new TxSubmitter(\n client,\n client.tx.notaries.propose({\n public: this.registeredPublicKey,\n hosts: [address.href],\n name: 'Test Notary',\n }),\n this.operator!,\n ).submit({ waitForBlock: true });\n }\n\n public async teardown(): Promise<void> {\n this.#childProcess?.kill();\n this.#stdioInterface?.close();\n const client = await this.connect();\n try {\n await client.query(`DROP DATABASE \"${this.#dbName}\" WITH (FORCE)`);\n } finally {\n await client.end();\n }\n if (this.containerName) {\n try {\n child_process.execSync(`docker rm -f ${this.containerName}`);\n } catch {}\n }\n }\n\n async connect(): Promise<Client> {\n const client = new PgClient({ connectionString: this.#dbConnectionString });\n try {\n await client.connect();\n } catch (err) {\n console.error('ERROR connecting to postgres client', err);\n throw err;\n }\n return client;\n }\n}\n","import * as fs from 'node:fs';\nimport { ChildProcess, execSync, spawn } from 'node:child_process';\nimport * as Path from 'node:path';\nimport * as readline from 'node:readline';\nimport {\n addTeardown,\n cleanHostForDocker,\n disconnectOnTeardown,\n getDockerPortMapping,\n getProxy,\n ITeardownable,\n projectRoot,\n} from './index';\nimport { detectPort } from 'detect-port';\nimport { customAlphabet } from 'nanoid';\nimport Client from 'bitcoin-core';\nimport * as lockfile from 'proper-lockfile';\nimport { createUid } from './TestNotary';\nimport { type ArgonClient, getClient } from '@argonprotocol/mainchain';\n\nconst nanoid = customAlphabet('0123456789abcdefghijklmnopqrstuvwxyz', 4);\n\nconst lockPath = Path.join(process.cwd(), '.port-lock');\n\nexport default class TestMainchain implements ITeardownable {\n public ip = '127.0.0.1';\n public port?: string;\n public loglevel = 'warn';\n public uuid: string;\n #binPath: string;\n #process?: ChildProcess;\n #interfaces: readline.Interface[] = [];\n containerName?: string;\n proxy?: string;\n #bitcoind?: ChildProcess;\n bitcoinPort?: number;\n #bitcoinDir?: string;\n\n public get address(): string {\n if (this.proxy) {\n const url = new URL(this.proxy);\n url.searchParams.set('target', `ws://${this.ip}:${this.port}`);\n return url.href;\n }\n return `ws://${this.ip}:${this.port}`;\n }\n\n constructor(binPath?: string) {\n this.#binPath = binPath ?? Path.join(projectRoot(), `target/debug/argon-node`);\n this.#binPath = Path.resolve(this.#binPath);\n if (!process.env.ARGON_USE_DOCKER_BINS && !fs.existsSync(this.#binPath)) {\n throw new Error(`Mainchain binary not found at ${this.#binPath}`);\n }\n this.uuid = createUid();\n addTeardown(this);\n }\n\n public getBitcoinClient(): Client {\n return new Client({\n username: 'bitcoin',\n password: 'bitcoin',\n host: `http://localhost:${this.bitcoinPort}`,\n });\n }\n\n /**\n * Launch and return the localhost url. NOTE: this url will not work cross-docker. You need to use the containerAddress property\n * @param options\n * @param options.miningThreads - number of threads to use for mining\n * @param options.bootnodes - bootnodes to use for the mainchain\n */\n public async launch(options?: {\n miningThreads?: number;\n bootnodes?: string;\n author?: string;\n launchBitcoin?: boolean;\n }): Promise<string> {\n const { miningThreads = 1, bootnodes, author = 'alice', launchBitcoin = false } = options ?? {};\n let port = 0;\n let rpcPort = 0;\n let execArgs: string[] = [];\n let containerName: string;\n if (process.env.ARGON_USE_DOCKER_BINS) {\n containerName = 'miner_' + nanoid();\n this.containerName = containerName;\n this.#binPath = 'docker';\n port = 33344;\n rpcPort = 9944;\n execArgs = [\n 'run',\n '--rm',\n `--name=${containerName}`,\n `-p=0:${port}`,\n `-p=0:${rpcPort}`,\n '-e',\n `RUST_LOG=${this.loglevel},sc_rpc_server=info`,\n 'ghcr.io/argonprotocol/argon-miner:dev',\n ];\n\n if (process.env.ADD_DOCKER_HOST) {\n execArgs.splice(2, 0, `--add-host=host.docker.internal:host-gateway`);\n }\n }\n\n const bitcoinRpcUrl = await this.startBitcoin(launchBitcoin);\n execArgs.push(\n '--dev',\n '--validator',\n `--${author}`,\n `--compute-miners=${miningThreads}`,\n `--port=${port}`,\n `--rpc-port=${rpcPort}`,\n '--rpc-external',\n '--no-mdns',\n '--no-telemetry',\n '--no-prometheus',\n '--unsafe-rpc-external',\n '--rpc-methods=unsafe',\n `--bitcoin-rpc-url=${bitcoinRpcUrl}`,\n `--notebook-archive-hosts=http://127.0.0.1:9000/${this.uuid}`,\n );\n if (bootnodes) {\n execArgs.push(`--bootnodes=${bootnodes}`);\n }\n this.#process = spawn(this.#binPath, execArgs, {\n stdio: ['ignore', 'pipe', 'pipe', 'ignore'],\n env: { ...process.env, RUST_LOG: `${this.loglevel},sc_rpc_server=info` },\n });\n\n this.#process.stderr!.setEncoding('utf8');\n this.#process.stdout!.setEncoding('utf8');\n this.#process.stdout!.on('data', data => {\n console.log('Main >> %s', data);\n });\n\n const int1 = readline.createInterface({ input: this.#process.stdout! }).on('line', line => {\n if (line) console.log('Main >> %s', line);\n });\n this.#interfaces.push(int1);\n\n this.port = await new Promise<string>((resolve, reject) => {\n this.#process!.on('error', err => {\n console.warn('Error running mainchain', err);\n reject(err);\n });\n\n const int2 = readline.createInterface({ input: this.#process!.stderr! }).on('line', line => {\n console.log('Main >> %s', line);\n let match = line.match(/Running JSON-RPC server: addr=([\\d.:]+)/);\n if (match) {\n let ipv4 = match[1].split(',').at(0);\n resolve(ipv4!.split(':').pop()!);\n }\n });\n this.#interfaces.push(int2);\n });\n if (this.containerName) {\n this.port = await getDockerPortMapping(this.containerName, rpcPort);\n this.proxy = cleanHostForDocker(await getProxy());\n }\n\n console.log(`argon Node listening at ${this.address}`);\n return this.address;\n }\n\n public async client(): Promise<ArgonClient> {\n const client = await getClient(this.address);\n disconnectOnTeardown(client);\n return client;\n }\n\n public async bootAddress(): Promise<string | undefined> {\n const client = await this.client();\n const bootAddress = await client.rpc.system.localListenAddresses();\n\n for (const address of bootAddress) {\n const addr = address.toString();\n if (addr.includes('127.0.0.1')) {\n return addr;\n }\n }\n return undefined;\n }\n\n public async teardown(): Promise<void> {\n if (process.env.ARGON_USE_DOCKER_BINS) {\n try {\n execSync(`docker rm -f ${this.containerName}`);\n } catch {}\n }\n const launchedProcess = this.#process;\n if (launchedProcess) {\n launchedProcess?.kill();\n try {\n launchedProcess.stdio.forEach(io => io?.destroy());\n } catch {}\n launchedProcess.unref();\n }\n\n this.#process?.kill();\n this.#process?.unref();\n this.#bitcoind?.kill();\n this.#bitcoind?.unref();\n if (this.#bitcoinDir) {\n await fs.promises.rm(this.#bitcoinDir, {\n recursive: true,\n force: true,\n });\n }\n for (const i of this.#interfaces) {\n i.close();\n }\n }\n\n private async startBitcoin(launchBitcoin: boolean): Promise<string> {\n let rpcPort = 14338;\n if (launchBitcoin) {\n // Ensure lock file exists\n fs.closeSync(fs.openSync(lockPath, 'w'));\n const release = await lockfile.lock(lockPath, { retries: 10 });\n try {\n rpcPort = await detectPort();\n const path = execSync(Path.join(projectRoot(), `target/debug/argon-testing-bitcoin`), {\n encoding: 'utf8',\n }).trim();\n\n const tmpDir = fs.mkdtempSync('/tmp/argon-bitcoin-' + this.uuid);\n\n console.log('Starting bitcoin node at %s. Data %s', path, tmpDir);\n this.#bitcoind = spawn(\n path,\n [\n '-regtest',\n '-fallbackfee=0.0001',\n '-listen=0',\n `-datadir=${tmpDir}`,\n '-blockfilterindex',\n '-txindex',\n `-rpcport=${rpcPort}`,\n '-rpcbind=0.0.0.0',\n '-rpcallowip=0.0.0.0/0',\n '-rpcuser=bitcoin',\n '-rpcpassword=bitcoin',\n ],\n {\n stdio: ['ignore', 'pipe', 'pipe'],\n },\n );\n this.#bitcoind.stderr!.setEncoding('utf8');\n this.#bitcoind.stdout!.setEncoding('utf8');\n this.#bitcoind.stdout!.on('data', data => {\n console.log('Bitcoin >> %s', data);\n });\n this.#bitcoind.stderr!.on('data', data => {\n console.error('Bitcoin >> %s', data);\n });\n this.#bitcoinDir = tmpDir;\n } finally {\n // Release the lock file\n await release();\n }\n }\n this.bitcoinPort = rpcPort;\n return cleanHostForDocker(`http://bitcoin:bitcoin@localhost:${rpcPort}`);\n }\n}\n","import * as child_process from 'node:child_process';\nimport { projectRoot } from './index';\nimport * as Path from 'node:path';\n\nexport default class TestBitcoinCli {\n /**\n * Returns the localhost address of the notary (NOTE: not accessible from containers)\n */\n public static run(command: string): string {\n const binPath = Path.join(`${projectRoot()}`, 'target/debug/argon-bitcoin-cli');\n\n try {\n return child_process\n .execSync(`${binPath} ${command}`, {\n encoding: 'utf8',\n })\n .trim();\n } catch (e) {\n console.error(`Error running command: ${command}`);\n console.error((e as any).stdout);\n throw e;\n }\n }\n}\n","import * as child_process from 'node:child_process';\nimport { Keyring, KeyringPair } from '@argonprotocol/mainchain';\nimport * as fs from 'node:fs';\nimport * as readline from 'node:readline';\nimport { addTeardown, ITeardownable, projectRoot } from './index';\nimport * as process from 'node:process';\nimport * as Path from 'node:path';\nimport { Readable } from 'node:stream';\n\nexport default class TestOracle implements ITeardownable {\n public static BitcoinOperator = '//Dave';\n public static PriceIndexOperator = '//Eve';\n public operator?: KeyringPair;\n public port?: string;\n #childProcess?: child_process.ChildProcessByStdio<null, Readable, Readable>;\n #stdioInterface?: readline.Interface;\n\n constructor() {\n addTeardown(this);\n }\n\n public async start(\n service: 'price-index' | 'bitcoin',\n options: {\n mainchainUrl: string;\n bitcoinRpcUrl?: string;\n pathToBin?: string;\n env?: Record<string, string>;\n },\n ) {\n const { pathToBin, mainchainUrl, bitcoinRpcUrl } = options;\n const operatorSuri =\n service == 'bitcoin' ? TestOracle.BitcoinOperator : TestOracle.PriceIndexOperator;\n this.operator = new Keyring({ type: 'sr25519' }).createFromUri(operatorSuri);\n const binPath = pathToBin ?? Path.join(projectRoot(), 'target/debug/argon-oracle');\n if (!fs.existsSync(binPath)) {\n throw new Error(`Oracle binary not found at ${binPath}`);\n }\n console.log(`Starting ${service} oracle`);\n\n const execArgs: string[] = ['--dev', '-t', mainchainUrl, service];\n if (service == 'bitcoin') {\n if (!bitcoinRpcUrl) {\n throw new Error('Bitcoin RPC URL is required for bitcoin oracle');\n }\n execArgs.push('--bitcoin-rpc-url', bitcoinRpcUrl);\n } else {\n execArgs.push('--simulate-prices');\n }\n this.#childProcess = child_process.spawn(binPath, execArgs, {\n stdio: ['ignore', 'pipe', 'pipe'],\n env: { ...process.env, RUST_LOG: 'info', ...options.env },\n });\n this.#childProcess.stdout.setEncoding('utf8');\n this.#childProcess.stderr.setEncoding('utf8');\n this.#childProcess!.stderr.on('data', data => {\n console.warn('%sOracle >> %s', service, data);\n });\n this.#stdioInterface = readline\n .createInterface({ input: this.#childProcess!.stdout })\n .on('line', line => {\n console.log('%sOracle >> %s', service, line);\n });\n\n this.#childProcess.on('error', err => {\n throw err;\n });\n }\n\n public async teardown(): Promise<void> {\n this.#childProcess?.kill();\n this.#stdioInterface?.close();\n }\n}\n"],"mappings":"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","names":["Keyring","TxSubmitter","process","child_process","Path","process","url","result","resolve","fs","execSync","spawn","Path","readline","customAlphabet","nanoid","customAlphabet","url","spawn","resolve","execSync","path","child_process","Path","child_process","Keyring","fs","readline","process","Path","Keyring","resolve","teardown","Keyring","sudo","TxSubmitter"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@argonprotocol/testing",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "A testing library to launch locally built binaries/dockers for Argon.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -35,18 +35,20 @@
|
|
|
35
35
|
}
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@argonprotocol/mainchain": "1.
|
|
38
|
+
"@argonprotocol/mainchain": "1.3.0",
|
|
39
39
|
"bitcoin-core": "^5.0.0",
|
|
40
40
|
"detect-port": "^2.1.0",
|
|
41
41
|
"http-proxy": "^1.18.1",
|
|
42
42
|
"nanoid": "^3.3.7",
|
|
43
43
|
"pg": "^8.11.3",
|
|
44
|
+
"proper-lockfile": "^4.1.2",
|
|
44
45
|
"vitest": "^3.1.1"
|
|
45
46
|
},
|
|
46
47
|
"devDependencies": {
|
|
47
48
|
"@types/http-proxy": "^1.17.16",
|
|
48
49
|
"@types/node": "^18.19.6",
|
|
49
50
|
"@types/pg": "^8.11.3",
|
|
51
|
+
"@types/proper-lockfile": "^4.1.4",
|
|
50
52
|
"tsup": "^8.4.0",
|
|
51
53
|
"typescript": "^5.8.3"
|
|
52
54
|
},
|