@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 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
- rpcPort = await (0, import_detect_port.detectPort)();
431
- const path = (0, import_node_child_process.execSync)(
432
- Path2.join(projectRoot(), `target/debug/argon-testing-bitcoin`),
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
- ).trim();
437
- const tmpDir = fs2.mkdtempSync("/tmp/argon-bitcoin-" + this.uuid);
438
- console.log("Starting bitcoin node at %s", tmpDir);
439
- this.#bitcoind = (0, import_node_child_process.spawn)(path, [
440
- "-regtest",
441
- "-fallbackfee=0.0001",
442
- "-listen=0",
443
- `-datadir=${tmpDir}`,
444
- "-blockfilterindex",
445
- "-txindex",
446
- `-rpcport=${rpcPort}`,
447
- "-rpcbind=0.0.0.0",
448
- "-rpcallowip=0.0.0.0/0",
449
- "-rpcuser=bitcoin",
450
- "-rpcpassword=bitcoin"
451
- ]);
452
- this.#bitcoinDir = tmpDir;
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
- rpcPort = await detectPort();
394
- const path2 = execSync2(
395
- Path2.join(projectRoot(), `target/debug/argon-testing-bitcoin`),
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
- ).trim();
400
- const tmpDir = fs2.mkdtempSync("/tmp/argon-bitcoin-" + this.uuid);
401
- console.log("Starting bitcoin node at %s", tmpDir);
402
- this.#bitcoind = spawn2(path2, [
403
- "-regtest",
404
- "-fallbackfee=0.0001",
405
- "-listen=0",
406
- `-datadir=${tmpDir}`,
407
- "-blockfilterindex",
408
- "-txindex",
409
- `-rpcport=${rpcPort}`,
410
- "-rpcbind=0.0.0.0",
411
- "-rpcallowip=0.0.0.0/0",
412
- "-rpcuser=bitcoin",
413
- "-rpcpassword=bitcoin"
414
- ]);
415
- this.#bitcoinDir = tmpDir;
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.1.0",
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.1.0",
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
  },