@argonprotocol/testing 1.1.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +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 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\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 = 2,\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 '--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 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 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 '-rpcuser=bitcoin',\n '-rpcpassword=bitcoin',\n ],\n {\n stdio: ['ignore', 'inherit', 'inherit', 'ignore'],\n },\n );\n addTeardown({\n async teardown() {\n await fs.promises.rm(tmpDir, {\n recursive: true,\n force: true,\n });\n },\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(\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","sudo"]}
@@ -0,0 +1,106 @@
1
+ import { KeyringPair, ArgonClient } from '@argonprotocol/mainchain';
2
+ import { SuiteAPI } from 'vitest';
3
+ import { Client } from 'pg';
4
+ import Client$1 from 'bitcoin-core';
5
+
6
+ declare class TestNotary implements ITeardownable {
7
+ #private;
8
+ operator?: KeyringPair;
9
+ ip: string;
10
+ registeredPublicKey?: Uint8Array;
11
+ port?: string;
12
+ containerName?: string;
13
+ proxy?: string;
14
+ get address(): string;
15
+ constructor(dbConnectionString?: string);
16
+ /**
17
+ * Returns the localhost address of the notary (NOTE: not accessible from containers)
18
+ */
19
+ start(options: {
20
+ mainchainUrl: string;
21
+ uuid: string;
22
+ pathToNotaryBin?: string;
23
+ }): Promise<string>;
24
+ register(client: ArgonClient): Promise<void>;
25
+ teardown(): Promise<void>;
26
+ connect(): Promise<Client>;
27
+ }
28
+
29
+ declare class TestMainchain implements ITeardownable {
30
+ #private;
31
+ ip: string;
32
+ port?: string;
33
+ loglevel: string;
34
+ uuid: string;
35
+ containerName?: string;
36
+ proxy?: string;
37
+ bitcoinPort?: number;
38
+ get address(): string;
39
+ constructor(binPath?: string);
40
+ getBitcoinClient(): Client$1;
41
+ /**
42
+ * Launch and return the localhost url. NOTE: this url will not work cross-docker. You need to use the containerAddress property
43
+ * @param options
44
+ * @param options.miningThreads - number of threads to use for mining
45
+ * @param options.bootnodes - bootnodes to use for the mainchain
46
+ */
47
+ launch(options?: {
48
+ miningThreads?: number;
49
+ bootnodes?: string;
50
+ author?: string;
51
+ launchBitcoin?: boolean;
52
+ }): Promise<string>;
53
+ client(): Promise<ArgonClient>;
54
+ bootAddress(): Promise<string | undefined>;
55
+ teardown(): Promise<void>;
56
+ private startBitcoin;
57
+ }
58
+
59
+ declare class TestBitcoinCli {
60
+ /**
61
+ * Returns the localhost address of the notary (NOTE: not accessible from containers)
62
+ */
63
+ static run(command: string): string;
64
+ }
65
+
66
+ declare class TestOracle implements ITeardownable {
67
+ #private;
68
+ static BitcoinOperator: string;
69
+ static PriceIndexOperator: string;
70
+ operator?: KeyringPair;
71
+ port?: string;
72
+ constructor();
73
+ start(service: 'price-index' | 'bitcoin', options: {
74
+ mainchainUrl: string;
75
+ bitcoinRpcUrl?: string;
76
+ pathToBin?: string;
77
+ env?: Record<string, string>;
78
+ }): Promise<void>;
79
+ teardown(): Promise<void>;
80
+ }
81
+
82
+ interface ITeardownable {
83
+ teardown(): Promise<void>;
84
+ }
85
+ declare let describeIntegration: SuiteAPI;
86
+ declare function getProxy(): Promise<string>;
87
+ declare function projectRoot(): string;
88
+ /**
89
+ * Run a script from the project "scripts" folder
90
+ * @param relativePath
91
+ */
92
+ declare function runTestScript(relativePath: string): Promise<string>;
93
+ declare function getDockerPortMapping(containerName: string, port: number): Promise<string | undefined>;
94
+ declare function teardown(): Promise<void>;
95
+ declare function cleanHostForDocker(host: string, replacer?: string): string;
96
+ declare function addTeardown(teardownable: ITeardownable): void;
97
+ declare function closeOnTeardown<T extends {
98
+ close(): Promise<void>;
99
+ }>(closeable: T): T;
100
+ declare function disconnectOnTeardown<T extends {
101
+ disconnect(): Promise<void>;
102
+ }>(closeable: T): T;
103
+ declare function sudo(): KeyringPair;
104
+ declare function activateNotary(sudo: KeyringPair, client: ArgonClient, notary: TestNotary): Promise<void>;
105
+
106
+ export { type ITeardownable, TestBitcoinCli, TestMainchain, TestNotary, TestOracle, activateNotary, addTeardown, cleanHostForDocker, closeOnTeardown, describeIntegration, disconnectOnTeardown, getDockerPortMapping, getProxy, projectRoot, runTestScript, sudo, teardown };
package/lib/index.d.ts ADDED
@@ -0,0 +1,106 @@
1
+ import { KeyringPair, ArgonClient } from '@argonprotocol/mainchain';
2
+ import { SuiteAPI } from 'vitest';
3
+ import { Client } from 'pg';
4
+ import Client$1 from 'bitcoin-core';
5
+
6
+ declare class TestNotary implements ITeardownable {
7
+ #private;
8
+ operator?: KeyringPair;
9
+ ip: string;
10
+ registeredPublicKey?: Uint8Array;
11
+ port?: string;
12
+ containerName?: string;
13
+ proxy?: string;
14
+ get address(): string;
15
+ constructor(dbConnectionString?: string);
16
+ /**
17
+ * Returns the localhost address of the notary (NOTE: not accessible from containers)
18
+ */
19
+ start(options: {
20
+ mainchainUrl: string;
21
+ uuid: string;
22
+ pathToNotaryBin?: string;
23
+ }): Promise<string>;
24
+ register(client: ArgonClient): Promise<void>;
25
+ teardown(): Promise<void>;
26
+ connect(): Promise<Client>;
27
+ }
28
+
29
+ declare class TestMainchain implements ITeardownable {
30
+ #private;
31
+ ip: string;
32
+ port?: string;
33
+ loglevel: string;
34
+ uuid: string;
35
+ containerName?: string;
36
+ proxy?: string;
37
+ bitcoinPort?: number;
38
+ get address(): string;
39
+ constructor(binPath?: string);
40
+ getBitcoinClient(): Client$1;
41
+ /**
42
+ * Launch and return the localhost url. NOTE: this url will not work cross-docker. You need to use the containerAddress property
43
+ * @param options
44
+ * @param options.miningThreads - number of threads to use for mining
45
+ * @param options.bootnodes - bootnodes to use for the mainchain
46
+ */
47
+ launch(options?: {
48
+ miningThreads?: number;
49
+ bootnodes?: string;
50
+ author?: string;
51
+ launchBitcoin?: boolean;
52
+ }): Promise<string>;
53
+ client(): Promise<ArgonClient>;
54
+ bootAddress(): Promise<string | undefined>;
55
+ teardown(): Promise<void>;
56
+ private startBitcoin;
57
+ }
58
+
59
+ declare class TestBitcoinCli {
60
+ /**
61
+ * Returns the localhost address of the notary (NOTE: not accessible from containers)
62
+ */
63
+ static run(command: string): string;
64
+ }
65
+
66
+ declare class TestOracle implements ITeardownable {
67
+ #private;
68
+ static BitcoinOperator: string;
69
+ static PriceIndexOperator: string;
70
+ operator?: KeyringPair;
71
+ port?: string;
72
+ constructor();
73
+ start(service: 'price-index' | 'bitcoin', options: {
74
+ mainchainUrl: string;
75
+ bitcoinRpcUrl?: string;
76
+ pathToBin?: string;
77
+ env?: Record<string, string>;
78
+ }): Promise<void>;
79
+ teardown(): Promise<void>;
80
+ }
81
+
82
+ interface ITeardownable {
83
+ teardown(): Promise<void>;
84
+ }
85
+ declare let describeIntegration: SuiteAPI;
86
+ declare function getProxy(): Promise<string>;
87
+ declare function projectRoot(): string;
88
+ /**
89
+ * Run a script from the project "scripts" folder
90
+ * @param relativePath
91
+ */
92
+ declare function runTestScript(relativePath: string): Promise<string>;
93
+ declare function getDockerPortMapping(containerName: string, port: number): Promise<string | undefined>;
94
+ declare function teardown(): Promise<void>;
95
+ declare function cleanHostForDocker(host: string, replacer?: string): string;
96
+ declare function addTeardown(teardownable: ITeardownable): void;
97
+ declare function closeOnTeardown<T extends {
98
+ close(): Promise<void>;
99
+ }>(closeable: T): T;
100
+ declare function disconnectOnTeardown<T extends {
101
+ disconnect(): Promise<void>;
102
+ }>(closeable: T): T;
103
+ declare function sudo(): KeyringPair;
104
+ declare function activateNotary(sudo: KeyringPair, client: ArgonClient, notary: TestNotary): Promise<void>;
105
+
106
+ export { type ITeardownable, TestBitcoinCli, TestMainchain, TestNotary, TestOracle, activateNotary, addTeardown, cleanHostForDocker, closeOnTeardown, describeIntegration, disconnectOnTeardown, getDockerPortMapping, getProxy, projectRoot, runTestScript, sudo, teardown };