Files
bch-js/test/unit/electrumx.js
T

422 lines
13 KiB
JavaScript
Raw Normal View History

2021-01-02 15:41:12 -08:00
const chai = require('chai')
2020-07-27 21:32:51 -07:00
const assert = chai.assert
2021-01-02 15:41:12 -08:00
const axios = require('axios')
const sinon = require('sinon')
2020-07-27 21:32:51 -07:00
2021-01-02 15:41:12 -08:00
const BCHJS = require('../../src/bch-js')
2020-07-27 21:32:51 -07:00
const bchjs = new BCHJS()
2021-01-02 15:41:12 -08:00
const mockData = require('./fixtures/electrumx-mock')
2020-07-27 21:32:51 -07:00
2021-01-02 15:41:12 -08:00
describe('#ElectrumX', () => {
2020-07-27 21:32:51 -07:00
let sandbox
beforeEach(() => (sandbox = sinon.createSandbox()))
afterEach(() => sandbox.restore())
2021-01-02 15:41:12 -08:00
describe('#utxo', () => {
it('should throw an error for improper input', async () => {
2020-07-27 21:32:51 -07:00
try {
const addr = 12345
await bchjs.Electrumx.utxo(addr)
2021-01-02 15:41:12 -08:00
assert.equal(true, false, 'Unexpected result!')
2020-07-27 21:32:51 -07:00
} catch (err) {
// console.log(`err: `, err)
assert.include(
err.message,
2021-01-02 15:41:12 -08:00
'Input address must be a string or array of strings'
2020-07-27 21:32:51 -07:00
)
}
})
2021-01-02 15:41:12 -08:00
it('should GET utxos for a single address', async () => {
2020-07-27 21:32:51 -07:00
// Stub the network call.
2021-01-02 15:41:12 -08:00
sandbox.stub(axios, 'get').resolves({ data: mockData.utxo })
2020-07-27 21:32:51 -07:00
2021-01-02 15:41:12 -08:00
const addr = 'bitcoincash:qqh793x9au6ehvh7r2zflzguanlme760wuzehgzjh9'
2020-07-27 21:32:51 -07:00
const result = await bchjs.Electrumx.utxo(addr)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
2021-01-02 15:41:12 -08:00
assert.property(result, 'success')
2020-07-27 21:32:51 -07:00
assert.equal(result.success, true)
2021-01-02 15:41:12 -08:00
assert.property(result, 'utxos')
2020-07-27 21:32:51 -07:00
assert.isArray(result.utxos)
2021-01-02 15:41:12 -08:00
assert.property(result.utxos[0], 'height')
assert.property(result.utxos[0], 'tx_hash')
assert.property(result.utxos[0], 'tx_pos')
assert.property(result.utxos[0], 'value')
2020-07-27 21:32:51 -07:00
})
2021-01-02 15:41:12 -08:00
it('should POST utxo details for an array of addresses', async () => {
2020-07-27 21:32:51 -07:00
// Stub the network call.
2021-01-02 15:41:12 -08:00
sandbox.stub(axios, 'post').resolves({ data: mockData.utxos })
2020-07-27 21:32:51 -07:00
const addr = [
2021-01-02 15:41:12 -08:00
'bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf',
'bitcoincash:qpdh9s677ya8tnx7zdhfrn8qfyvy22wj4qa7nwqa5v'
2020-07-27 21:32:51 -07:00
]
const result = await bchjs.Electrumx.utxo(addr)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
2021-01-02 15:41:12 -08:00
assert.property(result, 'success')
2020-07-27 21:32:51 -07:00
assert.equal(result.success, true)
2021-01-02 15:41:12 -08:00
assert.property(result, 'utxos')
2020-07-27 21:32:51 -07:00
assert.isArray(result.utxos)
2021-01-02 15:41:12 -08:00
assert.property(result.utxos[0], 'utxos')
2020-07-27 21:32:51 -07:00
assert.isArray(result.utxos[0].utxos)
2021-01-02 15:41:12 -08:00
assert.property(result.utxos[0], 'address')
2020-07-27 21:32:51 -07:00
2021-01-02 15:41:12 -08:00
assert.property(result.utxos[0].utxos[0], 'height')
assert.property(result.utxos[0].utxos[0], 'tx_hash')
assert.property(result.utxos[0].utxos[0], 'tx_pos')
assert.property(result.utxos[0].utxos[0], 'value')
2020-07-27 21:32:51 -07:00
})
})
2021-01-02 15:41:12 -08:00
describe('#balance', () => {
it('should throw an error for improper input', async () => {
2020-07-27 21:32:51 -07:00
try {
const addr = 12345
await bchjs.Electrumx.balance(addr)
2021-01-02 15:41:12 -08:00
assert.equal(true, false, 'Unexpected result!')
2020-07-27 21:32:51 -07:00
} catch (err) {
// console.log(`err: `, err)
assert.include(
err.message,
2021-01-02 15:41:12 -08:00
'Input address must be a string or array of strings'
2020-07-27 21:32:51 -07:00
)
}
})
2021-01-02 15:41:12 -08:00
it('should GET balance for a single address', async () => {
2020-07-27 21:32:51 -07:00
// Stub the network call.
2021-01-02 15:41:12 -08:00
sandbox.stub(axios, 'get').resolves({ data: mockData.balance })
2020-07-27 21:32:51 -07:00
2021-01-02 15:41:12 -08:00
const addr = 'bitcoincash:qqh793x9au6ehvh7r2zflzguanlme760wuzehgzjh9'
2020-07-27 21:32:51 -07:00
const result = await bchjs.Electrumx.balance(addr)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
2021-01-02 15:41:12 -08:00
assert.property(result, 'success')
2020-07-27 21:32:51 -07:00
assert.equal(result.success, true)
2021-01-02 15:41:12 -08:00
assert.property(result, 'balance')
assert.property(result.balance, 'confirmed')
assert.property(result.balance, 'unconfirmed')
2020-07-27 21:32:51 -07:00
})
2021-01-02 15:41:12 -08:00
it('should POST balance for an array of addresses', async () => {
2020-07-27 21:32:51 -07:00
// Stub the network call.
2021-01-02 15:41:12 -08:00
sandbox.stub(axios, 'post').resolves({ data: mockData.balances })
2020-07-27 21:32:51 -07:00
const addr = [
2021-01-02 15:41:12 -08:00
'bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf',
'bitcoincash:qpdh9s677ya8tnx7zdhfrn8qfyvy22wj4qa7nwqa5v'
2020-07-27 21:32:51 -07:00
]
const result = await bchjs.Electrumx.balance(addr)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
2021-01-02 15:41:12 -08:00
assert.property(result, 'success')
2020-07-27 21:32:51 -07:00
assert.equal(result.success, true)
2021-01-02 15:41:12 -08:00
assert.property(result, 'balances')
2020-07-27 21:32:51 -07:00
assert.isArray(result.balances)
2021-01-02 15:41:12 -08:00
assert.property(result.balances[0], 'address')
assert.property(result.balances[0], 'balance')
assert.property(result.balances[0].balance, 'confirmed')
assert.property(result.balances[0].balance, 'unconfirmed')
2020-07-27 21:32:51 -07:00
})
})
2021-01-02 15:41:12 -08:00
describe('#transactions', () => {
it('should throw an error for improper input', async () => {
2020-07-27 21:32:51 -07:00
try {
const addr = 12345
await bchjs.Electrumx.transactions(addr)
2021-01-02 15:41:12 -08:00
assert.equal(true, false, 'Unexpected result!')
2020-07-27 21:32:51 -07:00
} catch (err) {
// console.log(`err: `, err)
assert.include(
err.message,
2021-01-02 15:41:12 -08:00
'Input address must be a string or array of strings'
2020-07-27 21:32:51 -07:00
)
}
})
2021-01-02 15:41:12 -08:00
it('should GET transactions for a single address', async () => {
2020-07-27 21:32:51 -07:00
// Stub the network call.
2021-01-02 15:41:12 -08:00
sandbox.stub(axios, 'get').resolves({ data: mockData.transaction })
2020-07-27 21:32:51 -07:00
2021-01-02 15:41:12 -08:00
const addr = 'bitcoincash:qqh793x9au6ehvh7r2zflzguanlme760wuzehgzjh9'
2020-07-27 21:32:51 -07:00
const result = await bchjs.Electrumx.transactions(addr)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
2021-01-02 15:41:12 -08:00
assert.property(result, 'success')
2020-07-27 21:32:51 -07:00
assert.equal(result.success, true)
2021-01-02 15:41:12 -08:00
assert.property(result, 'transactions')
2020-07-27 21:32:51 -07:00
assert.isArray(result.transactions)
2021-01-02 15:41:12 -08:00
assert.property(result.transactions[0], 'height')
assert.property(result.transactions[0], 'tx_hash')
2020-07-27 21:32:51 -07:00
})
2021-01-02 15:41:12 -08:00
it('should POST transaction history for an array of addresses', async () => {
2020-07-27 21:32:51 -07:00
// Stub the network call.
2021-01-02 15:41:12 -08:00
sandbox.stub(axios, 'post').resolves({ data: mockData.transactions })
2020-07-27 21:32:51 -07:00
const addr = [
2021-01-02 15:41:12 -08:00
'bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf',
'bitcoincash:qpdh9s677ya8tnx7zdhfrn8qfyvy22wj4qa7nwqa5v'
2020-07-27 21:32:51 -07:00
]
const result = await bchjs.Electrumx.transactions(addr)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
2021-01-02 15:41:12 -08:00
assert.property(result, 'success')
2020-07-27 21:32:51 -07:00
assert.equal(result.success, true)
2021-01-02 15:41:12 -08:00
assert.property(result, 'transactions')
2020-07-27 21:32:51 -07:00
assert.isArray(result.transactions)
2021-01-02 15:41:12 -08:00
assert.property(result.transactions[0], 'address')
assert.property(result.transactions[0], 'transactions')
2020-07-27 21:32:51 -07:00
assert.isArray(result.transactions[0].transactions)
2021-01-02 15:41:12 -08:00
assert.property(result.transactions[0].transactions[0], 'height')
assert.property(result.transactions[0].transactions[0], 'tx_hash')
2020-07-27 21:32:51 -07:00
})
})
2020-08-04 22:58:22 +09:00
2021-01-02 15:41:12 -08:00
describe('#unconfirmed', () => {
it('should throw an error for improper input', async () => {
2020-08-04 22:58:22 +09:00
try {
const addr = 12345
await bchjs.Electrumx.unconfirmed(addr)
2021-01-02 15:41:12 -08:00
assert.equal(true, false, 'Unexpected result!')
2020-08-04 22:58:22 +09:00
} catch (err) {
// console.log(`err: `, err)
assert.include(
err.message,
2021-01-02 15:41:12 -08:00
'Input address must be a string or array of strings'
2020-08-04 22:58:22 +09:00
)
}
})
2021-01-02 15:41:12 -08:00
it('should GET unconfirmed utxos for a single address', async () => {
2020-08-04 22:58:22 +09:00
// Stub the network call.
2021-01-02 15:41:12 -08:00
sandbox.stub(axios, 'get').resolves({ data: mockData.unconfirmed })
2020-08-04 22:58:22 +09:00
2021-01-02 15:41:12 -08:00
const addr = 'bitcoincash:qqh793x9au6ehvh7r2zflzguanlme760wuzehgzjh9'
2020-08-04 22:58:22 +09:00
const result = await bchjs.Electrumx.unconfirmed(addr)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
2021-01-02 15:41:12 -08:00
assert.property(result, 'success')
2020-08-04 22:58:22 +09:00
assert.equal(result.success, true)
2021-01-02 15:41:12 -08:00
assert.property(result, 'utxos')
2020-08-04 22:58:22 +09:00
assert.isArray(result.utxos)
2021-01-02 15:41:12 -08:00
assert.property(result.utxos[0], 'height')
assert.property(result.utxos[0], 'tx_hash')
assert.property(result.utxos[0], 'fee')
2020-08-04 22:58:22 +09:00
})
2021-01-02 15:41:12 -08:00
it('should POST unconfirmed utxo details for an array of addresses', async () => {
2020-08-04 22:58:22 +09:00
// Stub the network call.
2021-01-02 15:41:12 -08:00
sandbox.stub(axios, 'post').resolves({ data: mockData.unconfirmedArray })
2020-08-04 22:58:22 +09:00
const addr = [
2021-01-02 15:41:12 -08:00
'bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf',
'bitcoincash:qpdh9s677ya8tnx7zdhfrn8qfyvy22wj4qa7nwqa5v'
2020-08-04 22:58:22 +09:00
]
const result = await bchjs.Electrumx.unconfirmed(addr)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
2021-01-02 15:41:12 -08:00
assert.property(result, 'success')
2020-08-04 22:58:22 +09:00
assert.equal(result.success, true)
2021-01-02 15:41:12 -08:00
assert.property(result, 'utxos')
2020-08-04 22:58:22 +09:00
assert.isArray(result.utxos)
2021-01-02 15:41:12 -08:00
assert.property(result.utxos[0], 'utxos')
2020-08-04 22:58:22 +09:00
assert.isArray(result.utxos[0].utxos)
2021-01-02 15:41:12 -08:00
assert.property(result.utxos[0], 'address')
2020-08-04 22:58:22 +09:00
2021-01-02 15:41:12 -08:00
assert.property(result.utxos[0].utxos[0], 'height')
assert.property(result.utxos[0].utxos[0], 'tx_hash')
assert.property(result.utxos[0].utxos[0], 'fee')
2020-08-04 22:58:22 +09:00
})
})
2021-01-02 15:41:12 -08:00
describe('#blockHeader', () => {
it('should throw an error for improper height input', async () => {
try {
// Mock network calls.
2021-01-02 15:41:12 -08:00
sandbox.stub(axios, 'get').rejects({
response: {
data: {
success: false,
2021-01-02 15:41:12 -08:00
error: 'height must be a positive number'
}
}
})
const height = -10
await bchjs.Electrumx.blockHeader(height)
2021-01-02 15:41:12 -08:00
assert.equal(true, false, 'Unexpected result!')
} catch (err) {
// console.log(`err: `, err)
2021-01-02 15:41:12 -08:00
assert.include(err.message, 'height must be a positive number')
}
})
2021-01-02 15:41:12 -08:00
it('should throw an error for improper count input', async () => {
try {
// Mock network calls.
2021-01-02 15:41:12 -08:00
sandbox.stub(axios, 'get').rejects({
response: {
data: {
success: false,
2021-01-02 15:41:12 -08:00
error: 'count must be a positive number'
}
}
})
const height = 42
const count = -10
await bchjs.Electrumx.blockHeader(height, count)
2021-01-02 15:41:12 -08:00
assert.equal(true, false, 'Unexpected result!')
} catch (err) {
// console.log(`err: `, err)
2021-01-02 15:41:12 -08:00
assert.include(err.message, 'count must be a positive number')
}
})
2021-01-02 15:41:12 -08:00
it('should GET block headers for a given height', async () => {
// Stub the network call.
2021-01-02 15:41:12 -08:00
sandbox.stub(axios, 'get').resolves({ data: mockData.blockHeaders })
const height = 42
const result = await bchjs.Electrumx.blockHeader(height)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.isArray(result)
assert.equal(result.length, 2)
})
})
2021-01-02 15:41:12 -08:00
describe('#txData', () => {
it('should throw an error for improper input', async () => {
try {
const txid = 12345
await bchjs.Electrumx.txData(txid)
2021-01-02 15:41:12 -08:00
assert.equal(true, false, 'Unexpected result!')
} catch (err) {
// console.log(`err: `, err)
assert.include(
err.message,
2021-01-02 15:41:12 -08:00
'Input txId must be a string or array of strings'
)
}
})
2021-01-02 15:41:12 -08:00
it('should GET details data for a single transaction', async () => {
// Stub the network call.
2021-01-02 15:41:12 -08:00
sandbox.stub(axios, 'get').resolves({ data: mockData.details })
const txid =
2021-01-02 15:41:12 -08:00
'4db095f34d632a4daf942142c291f1f2abb5ba2e1ccac919d85bdc2f671fb251'
const result = await bchjs.Electrumx.txData(txid)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
2021-01-02 15:41:12 -08:00
assert.property(result, 'success')
assert.equal(result.success, true)
2021-01-02 15:41:12 -08:00
assert.property(result, 'details')
assert.isObject(result.details)
2021-01-02 15:41:12 -08:00
assert.property(result.details, 'blockhash')
assert.property(result.details, 'hash')
assert.property(result.details, 'hex')
assert.property(result.details, 'vin')
assert.property(result.details, 'vout')
assert.equal(result.details.hash, txid)
})
2021-01-02 15:41:12 -08:00
it('should POST details for an array of transactions', async () => {
// Stub the network call.
2021-01-02 15:41:12 -08:00
sandbox.stub(axios, 'post').resolves({ data: mockData.detailsArray })
const txids = [
2021-01-02 15:41:12 -08:00
'4db095f34d632a4daf942142c291f1f2abb5ba2e1ccac919d85bdc2f671fb251',
'4db095f34d632a4daf942142c291f1f2abb5ba2e1ccac919d85bdc2f671fb251'
]
const result = await bchjs.Electrumx.txData(txids)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
2021-01-02 15:41:12 -08:00
assert.property(result, 'success')
assert.equal(result.success, true)
2021-01-02 15:41:12 -08:00
assert.property(result, 'transactions')
assert.isArray(result.transactions)
2021-01-02 15:41:12 -08:00
assert.property(result.transactions[0], 'txid')
assert.property(result.transactions[0], 'details')
2021-01-02 15:41:12 -08:00
assert.property(result.transactions[0].details, 'blockhash')
assert.property(result.transactions[0].details, 'hash')
assert.property(result.transactions[0].details, 'hex')
assert.property(result.transactions[0].details, 'vin')
assert.property(result.transactions[0].details, 'vout')
2021-01-02 15:41:12 -08:00
assert.equal(result.transactions.length, 2, '2 outputs for 2 inputs')
})
})
2021-01-02 15:41:12 -08:00
describe('#broadcast', () => {
it('should throw an error for improper input', async () => {
2020-10-07 17:14:30 +09:00
try {
const txHex = 12345
await bchjs.Electrumx.broadcast(txHex)
2021-01-02 15:41:12 -08:00
assert.equal(true, false, 'Unexpected result!')
2020-10-07 17:14:30 +09:00
} catch (err) {
// console.log(`err: `, err)
2021-01-02 15:41:12 -08:00
assert.include(err.message, 'Input txHex must be a string.')
2020-10-07 17:14:30 +09:00
}
})
2021-01-02 15:41:12 -08:00
it('should broadcast a single transaction', async () => {
2020-10-07 17:14:30 +09:00
// Stub the network call.
2021-01-02 15:41:12 -08:00
sandbox.stub(axios, 'post').resolves({ data: mockData.broadcast })
2020-10-07 17:14:30 +09:00
const tx = mockData.details
const txid = tx.details.txid
const result = await bchjs.Electrumx.broadcast(tx.details.hex)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
2021-01-02 15:41:12 -08:00
assert.property(result, 'success')
2020-10-07 17:14:30 +09:00
assert.equal(result.success, true)
2021-01-02 15:41:12 -08:00
assert.property(result, 'txid')
2020-10-07 17:14:30 +09:00
assert.equal(result.txid, txid)
})
})
2020-07-27 21:32:51 -07:00
})