diff --git a/package.json b/package.json index 3e4ea02..e0d0142 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ ], "main": "src/bch-js", "scripts": { - "test": "nyc mocha --timeout 30000 test/unit/", + "test": "nyc mocha --trace-warnings --unhandled-rejections=strict --timeout 30000 test/unit/", "test:integration": "bash test/integration/test-bchn-integration.sh", "test:integration:bchn": "bash test/integration/test-bchn-integration.sh", "test:integration:abc": "RESTURL=https://abc.fullstack.cash/v4/ IS_USING_FREE_TIER=true mocha --timeout 30000 test/integration/", diff --git a/test/unit/address.js b/test/unit/address.js index 1a48a5c..56a7224 100644 --- a/test/unit/address.js +++ b/test/unit/address.js @@ -1,9 +1,16 @@ -const fixtures = require("./fixtures/address.json") +// Public npm libraries. const assert = require("assert") -const BCHJS = require("../../src/bch-js") -const bchjs = new BCHJS() const Bitcoin = require("bitcoincashjs-lib") +// Mocks +const fixtures = require("./fixtures/address.json") + +// Unit under test (uut) +const BCHJS = require("../../src/bch-js") +let bchjs + +console.log("ping01") + function flatten(arrays) { return [].concat.apply([], arrays) } @@ -74,832 +81,859 @@ const P2SH_ADDRESSES = flatten([ fixtures.cashaddrMainnetP2SH ]) -describe("#addressConversion", () => { - describe("#toLegacyAddress", () => { - it("should translate legacy address format to itself correctly", () => { - assert.deepEqual( - LEGACY_ADDRESSES.map(address => bchjs.Address.toLegacyAddress(address)), - LEGACY_ADDRESSES - ) +console.log("ping02") + +describe("#address.js", () => { + beforeEach(() => { + bchjs = new BCHJS() + }) + + describe("#addressConversion", () => { + describe("#toLegacyAddress", () => { + it("should translate legacy address format to itself correctly", () => { + assert.deepEqual( + LEGACY_ADDRESSES.map(address => + bchjs.Address.toLegacyAddress(address) + ), + LEGACY_ADDRESSES + ) + }) + + it("should convert cashaddr address to legacy base58Check", () => { + assert.deepEqual( + CASHADDR_ADDRESSES.map(address => + bchjs.Address.toLegacyAddress(address) + ), + LEGACY_ADDRESSES + ) + }) + + it("should convert cashaddr regtest address to legacy base58Check", () => { + assert.deepEqual( + REGTEST_ADDRESSES.map(address => + bchjs.Address.toLegacyAddress(address) + ), + fixtures.legacyTestnetP2PKH + ) + }) + + describe("errors", () => { + it("should fail when called with an invalid address", () => { + assert.throws(() => { + bchjs.Address.toLegacyAddress() + }, bchjs.BitcoinCash.InvalidAddressError) + assert.throws(() => { + bchjs.Address.toLegacyAddress("some invalid address") + }, bchjs.BitcoinCash.InvalidAddressError) + }) + }) }) - it("should convert cashaddr address to legacy base58Check", () => { - assert.deepEqual( - CASHADDR_ADDRESSES.map(address => - bchjs.Address.toLegacyAddress(address) - ), - LEGACY_ADDRESSES - ) + describe("#toCashAddress", () => { + it("should convert legacy base58Check address to cashaddr", () => { + assert.deepEqual( + LEGACY_ADDRESSES.map(address => + bchjs.Address.toCashAddress(address, true) + ), + CASHADDR_ADDRESSES + ) + }) + + it("should convert legacy base58Check address to regtest cashaddr", () => { + assert.deepEqual( + fixtures.legacyTestnetP2PKH.map(address => + bchjs.Address.toCashAddress(address, true, true) + ), + REGTEST_ADDRESSES + ) + }) + + it("should translate cashaddr address format to itself correctly", () => { + assert.deepEqual( + CASHADDR_ADDRESSES.map(address => + bchjs.Address.toCashAddress(address, true) + ), + CASHADDR_ADDRESSES + ) + }) + + it("should translate regtest cashaddr address format to itself correctly", () => { + assert.deepEqual( + REGTEST_ADDRESSES.map(address => + bchjs.Address.toCashAddress(address, true, true) + ), + REGTEST_ADDRESSES + ) + }) + + it("should translate no-prefix cashaddr address format to itself correctly", () => { + assert.deepEqual( + CASHADDR_ADDRESSES_NO_PREFIX.map(address => + bchjs.Address.toCashAddress(address, true) + ), + CASHADDR_ADDRESSES + ) + }) + + it("should translate no-prefix regtest cashaddr address format to itself correctly", () => { + assert.deepEqual( + REGTEST_ADDRESSES_NO_PREFIX.map(address => + bchjs.Address.toCashAddress(address, true, true) + ), + REGTEST_ADDRESSES + ) + }) + + it("should translate cashaddr address format to itself of no-prefix correctly", () => { + CASHADDR_ADDRESSES.forEach(address => { + const noPrefix = bchjs.Address.toCashAddress(address, false) + assert.equal(address.split(":")[1], noPrefix) + }) + }) + + it("should translate regtest cashaddr address format to itself of no-prefix correctly", () => { + REGTEST_ADDRESSES.forEach(address => { + const noPrefix = bchjs.Address.toCashAddress(address, false, true) + assert.equal(address.split(":")[1], noPrefix) + }) + }) + + describe("errors", () => { + it("should fail when called with an invalid address", () => { + assert.throws(() => { + bchjs.BitcoinCash.Address.toCashAddress() + }, bchjs.BitcoinCash.InvalidAddressError) + assert.throws(() => { + bchjs.BitcoinCash.Address.toCashAddress("some invalid address") + }, bchjs.BitcoinCash.InvalidAddressError) + }) + }) }) - it("should convert cashaddr regtest address to legacy base58Check", () => { - assert.deepEqual( - REGTEST_ADDRESSES.map(address => - bchjs.Address.toLegacyAddress(address) - ), - fixtures.legacyTestnetP2PKH - ) + describe("#toHash160", () => { + it("should convert legacy base58check address to hash160", () => { + assert.deepEqual( + LEGACY_ADDRESSES.map(address => bchjs.Address.toHash160(address)), + HASH160_HASHES + ) + }) + + it("should convert cashaddr address to hash160", () => { + assert.deepEqual( + CASHADDR_ADDRESSES.map(address => bchjs.Address.toHash160(address)), + HASH160_HASHES + ) + }) + + it("should convert regtest cashaddr address to hash160", () => { + assert.deepEqual( + REGTEST_ADDRESSES.map(address => bchjs.Address.toHash160(address)), + fixtures.hash160TestnetP2PKH + ) + }) + + describe("errors", () => { + it("should fail when called with an invalid address", () => { + assert.throws(() => { + bchjs.Address.toHash160() + }, bchjs.BitcoinCash.InvalidAddressError) + assert.throws(() => { + bchjs.Address.toHash160("some invalid address") + }, bchjs.BitcoinCash.InvalidAddressError) + }) + }) }) - describe("errors", () => { - it("should fail when called with an invalid address", () => { - assert.throws(() => { - bchjs.Address.toLegacyAddress() - }, bchjs.BitcoinCash.InvalidAddressError) - assert.throws(() => { - bchjs.Address.toLegacyAddress("some invalid address") - }, bchjs.BitcoinCash.InvalidAddressError) + describe("#fromHash160", () => { + it("should convert hash160 to mainnet P2PKH legacy base58check address", () => { + assert.deepEqual( + fixtures.hash160MainnetP2PKH.map(hash160 => + bchjs.Address.hash160ToLegacy(hash160) + ), + fixtures.legacyMainnetP2PKH + ) + }) + + it("should convert hash160 to mainnet P2SH legacy base58check address", () => { + assert.deepEqual( + fixtures.hash160MainnetP2SH.map(hash160 => + bchjs.Address.hash160ToLegacy( + hash160, + Bitcoin.networks.bitcoin.scriptHash + ) + ), + fixtures.legacyMainnetP2SH + ) + }) + + it("should convert hash160 to testnet P2PKH legacy base58check address", () => { + assert.deepEqual( + fixtures.hash160TestnetP2PKH.map(hash160 => + bchjs.Address.hash160ToLegacy( + hash160, + Bitcoin.networks.testnet.pubKeyHash + ) + ), + fixtures.legacyTestnetP2PKH + ) + }) + + it("should convert hash160 to mainnet P2PKH cash address", () => { + assert.deepEqual( + fixtures.hash160MainnetP2PKH.map(hash160 => + bchjs.Address.hash160ToCash(hash160) + ), + fixtures.cashaddrMainnetP2PKH + ) + }) + + it("should convert hash160 to mainnet P2SH cash address", () => { + assert.deepEqual( + fixtures.hash160MainnetP2SH.map(hash160 => + bchjs.Address.hash160ToCash( + hash160, + Bitcoin.networks.bitcoin.scriptHash + ) + ), + fixtures.cashaddrMainnetP2SH + ) + }) + + it("should convert hash160 to testnet P2PKH cash address", () => { + assert.deepEqual( + fixtures.hash160TestnetP2PKH.map(hash160 => + bchjs.Address.hash160ToCash( + hash160, + Bitcoin.networks.testnet.pubKeyHash + ) + ), + fixtures.cashaddrTestnetP2PKH + ) + }) + + it("should convert hash160 to regtest P2PKH cash address", () => { + assert.deepEqual( + fixtures.hash160TestnetP2PKH.map(hash160 => + bchjs.Address.hash160ToCash( + hash160, + Bitcoin.networks.testnet.pubKeyHash, + true + ) + ), + REGTEST_ADDRESSES + ) + }) + + describe("errors", () => { + it("should fail when called with an invalid address", () => { + assert.throws(() => { + bchjs.Address.hash160ToLegacy() + }, bchjs.BitcoinCash.InvalidAddressError) + assert.throws(() => { + bchjs.Address.hash160ToLegacy("some invalid address") + }, bchjs.BitcoinCash.InvalidAddressError) + assert.throws(() => { + bchjs.Address.hash160ToCash() + }, bchjs.BitcoinCash.InvalidAddressError) + assert.throws(() => { + bchjs.Address.hash160ToCash("some invalid address") + }, bchjs.BitcoinCash.InvalidAddressError) + }) }) }) }) - describe("#toCashAddress", () => { - it("should convert legacy base58Check address to cashaddr", () => { - assert.deepEqual( - LEGACY_ADDRESSES.map(address => - bchjs.Address.toCashAddress(address, true) - ), - CASHADDR_ADDRESSES - ) + describe("address format detection", () => { + describe("#isLegacyAddress", () => { + describe("is legacy", () => { + LEGACY_ADDRESSES.forEach(address => { + it(`should detect ${address} is a legacy base58Check address`, () => { + const isBase58Check = bchjs.Address.isLegacyAddress(address) + assert.equal(isBase58Check, true) + }) + }) + }) + describe("is not legacy", () => { + CASHADDR_ADDRESSES.forEach(address => { + it(`should detect ${address} is not a legacy address`, () => { + const isBase58Check = bchjs.Address.isLegacyAddress(address) + assert.equal(isBase58Check, false) + }) + }) + + REGTEST_ADDRESSES.forEach(address => { + it(`should detect ${address} is not a legacy address`, () => { + const isBase58Check = bchjs.Address.isLegacyAddress(address) + assert.equal(isBase58Check, false) + }) + }) + }) + + describe("errors", () => { + it("should fail when called with an invalid address", () => { + assert.throws(() => { + bchjs.Address.isLegacyAddress() + }, bchjs.BitcoinCash.InvalidAddressError) + assert.throws(() => { + bchjs.Address.isLegacyAddress("some invalid address") + }, bchjs.BitcoinCash.InvalidAddressError) + }) + }) }) - it("should convert legacy base58Check address to regtest cashaddr", () => { - assert.deepEqual( - fixtures.legacyTestnetP2PKH.map(address => - bchjs.Address.toCashAddress(address, true, true) - ), - REGTEST_ADDRESSES - ) + describe("#isCashAddress", () => { + describe("is cashaddr", () => { + CASHADDR_ADDRESSES.forEach(address => { + it(`should detect ${address} is a cashaddr address`, () => { + const isCashaddr = bchjs.Address.isCashAddress(address) + assert.equal(isCashaddr, true) + }) + }) + + REGTEST_ADDRESSES.forEach(address => { + it(`should detect ${address} is a cashaddr address`, () => { + const isCashaddr = bchjs.Address.isCashAddress(address) + assert.equal(isCashaddr, true) + }) + }) + }) + + describe("is not cashaddr", () => { + LEGACY_ADDRESSES.forEach(address => { + it(`should detect ${address} is not a cashaddr address`, () => { + const isCashaddr = bchjs.Address.isCashAddress(address) + assert.equal(isCashaddr, false) + }) + }) + }) + + describe("errors", () => { + it("should fail when called with an invalid address", () => { + assert.throws(() => { + bchjs.Address.isCashAddress() + }, bchjs.BitcoinCash.InvalidAddressError) + assert.throws(() => { + bchjs.Address.isCashAddress("some invalid address") + }, bchjs.BitcoinCash.InvalidAddressError) + }) + }) + }) + describe("#isHash160", () => { + describe("is hash160", () => { + HASH160_HASHES.forEach(address => { + it(`should detect ${address} is a hash160 hash`, () => { + const isHash160 = bchjs.Address.isHash160(address) + assert.equal(isHash160, true) + }) + }) + }) + describe("is not hash160", () => { + LEGACY_ADDRESSES.forEach(address => { + it(`should detect ${address} is not a hash160 hash`, () => { + const isHash160 = bchjs.Address.isHash160(address) + assert.equal(isHash160, false) + }) + }) + + CASHADDR_ADDRESSES.forEach(address => { + it(`should detect ${address} is not a hash160 hash`, () => { + const isHash160 = bchjs.Address.isHash160(address) + assert.equal(isHash160, false) + }) + }) + + REGTEST_ADDRESSES.forEach(address => { + it(`should detect ${address} is not a legacy address`, () => { + const isHash160 = bchjs.Address.isHash160(address) + assert.equal(isHash160, false) + }) + }) + }) + + describe("errors", () => { + it("should fail when called with an invalid address", () => { + assert.throws(() => { + bchjs.Address.isHash160() + }, bchjs.BitcoinCash.InvalidAddressError) + assert.throws(() => { + bchjs.Address.isHash160("some invalid address") + }, bchjs.BitcoinCash.InvalidAddressError) + }) + }) + }) + }) + + describe("network detection", () => { + describe("#isMainnetAddress", () => { + describe("is mainnet", () => { + MAINNET_ADDRESSES.forEach(address => { + it(`should detect ${address} is a mainnet address`, () => { + const isMainnet = bchjs.Address.isMainnetAddress(address) + assert.equal(isMainnet, true) + }) + }) + }) + + describe("is not mainnet", () => { + TESTNET_ADDRESSES.forEach(address => { + it(`should detect ${address} is not a mainnet address`, () => { + const isMainnet = bchjs.Address.isMainnetAddress(address) + assert.equal(isMainnet, false) + }) + }) + + REGTEST_ADDRESSES.forEach(address => { + it(`should detect ${address} is not a mainnet address`, () => { + const isMainnet = bchjs.Address.isMainnetAddress(address) + assert.equal(isMainnet, false) + }) + }) + }) + + describe("errors", () => { + it("should fail when called with an invalid address", () => { + assert.throws(() => { + bchjs.Address.isMainnetAddress() + }, bchjs.BitcoinCash.InvalidAddressError) + assert.throws(() => { + bchjs.Address.isMainnetAddress("some invalid address") + }, bchjs.BitcoinCash.InvalidAddressError) + }) + }) }) - it("should translate cashaddr address format to itself correctly", () => { - assert.deepEqual( - CASHADDR_ADDRESSES.map(address => - bchjs.Address.toCashAddress(address, true) - ), - CASHADDR_ADDRESSES - ) + describe("#isTestnetAddress", () => { + describe("is testnet", () => { + TESTNET_ADDRESSES.forEach(address => { + it(`should detect ${address} is a testnet address`, () => { + const isTestnet = bchjs.Address.isTestnetAddress(address) + assert.equal(isTestnet, true) + }) + }) + }) + + describe("is not testnet", () => { + MAINNET_ADDRESSES.forEach(address => { + it(`should detect ${address} is not a testnet address`, () => { + const isTestnet = bchjs.Address.isTestnetAddress(address) + assert.equal(isTestnet, false) + }) + }) + + REGTEST_ADDRESSES.forEach(address => { + it(`should detect ${address} is not a testnet address`, () => { + const isTestnet = bchjs.Address.isTestnetAddress(address) + assert.equal(isTestnet, false) + }) + }) + }) + + describe("errors", () => { + it("should fail when called with an invalid address", () => { + assert.throws(() => { + bchjs.Address.isTestnetAddress() + }, bchjs.BitcoinCash.InvalidAddressError) + assert.throws(() => { + bchjs.Address.isTestnetAddress("some invalid address") + }, bchjs.BitcoinCash.InvalidAddressError) + }) + }) }) - it("should translate regtest cashaddr address format to itself correctly", () => { - assert.deepEqual( - REGTEST_ADDRESSES.map(address => - bchjs.Address.toCashAddress(address, true, true) - ), - REGTEST_ADDRESSES - ) + describe("#isRegTestAddress", () => { + describe("is testnet", () => { + REGTEST_ADDRESSES.forEach(address => { + it(`should detect ${address} is a regtest address`, () => { + const isRegTest = bchjs.Address.isRegTestAddress(address) + assert.equal(isRegTest, true) + }) + }) + }) + + describe("is not testnet", () => { + MAINNET_ADDRESSES.forEach(address => { + it(`should detect ${address} is not a regtest address`, () => { + const isRegTest = bchjs.Address.isRegTestAddress(address) + assert.equal(isRegTest, false) + }) + }) + + TESTNET_ADDRESSES.forEach(address => { + it(`should detect ${address} is not a regtest address`, () => { + const isRegTest = bchjs.Address.isRegTestAddress(address) + assert.equal(isRegTest, false) + }) + }) + }) + + describe("errors", () => { + it("should fail when called with an invalid address", () => { + assert.throws(() => { + bchjs.Address.isRegTestAddress() + }, bchjs.BitcoinCash.InvalidAddressError) + assert.throws(() => { + bchjs.Address.isRegTestAddress("some invalid address") + }, bchjs.BitcoinCash.InvalidAddressError) + }) + }) + }) + }) + + describe("address type detection", () => { + describe("#isP2PKHAddress", () => { + describe("is P2PKH", () => { + P2PKH_ADDRESSES.forEach(address => { + it(`should detect ${address} is a P2PKH address`, () => { + const isP2PKH = bchjs.Address.isP2PKHAddress(address) + assert.equal(isP2PKH, true) + }) + }) + }) + + describe("is not P2PKH", () => { + P2SH_ADDRESSES.forEach(address => { + it(`should detect ${address} is not a P2PKH address`, () => { + const isP2PKH = bchjs.Address.isP2PKHAddress(address) + assert.equal(isP2PKH, false) + }) + }) + }) + + describe("errors", () => { + it("should fail when called with an invalid address", () => { + assert.throws(() => { + bchjs.Address.isP2PKHAddress() + }, bchjs.BitcoinCash.InvalidAddressError) + assert.throws(() => { + bchjs.Address.isP2PKHAddress("some invalid address") + }, bchjs.BitcoinCash.InvalidAddressError) + }) + }) }) - it("should translate no-prefix cashaddr address format to itself correctly", () => { + describe("#isP2SHAddress", () => { + describe("is P2SH", () => { + P2SH_ADDRESSES.forEach(address => { + it(`should detect ${address} is a P2SH address`, () => { + const isP2SH = bchjs.Address.isP2SHAddress(address) + assert.equal(isP2SH, true) + }) + }) + }) + + describe("is not P2SH", () => { + P2PKH_ADDRESSES.forEach(address => { + it(`should detect ${address} is not a P2SH address`, () => { + const isP2SH = bchjs.Address.isP2SHAddress(address) + assert.equal(isP2SH, false) + }) + }) + }) + + describe("errors", () => { + it("should fail when called with an invalid address", () => { + assert.throws(() => { + bchjs.Address.isP2SHAddress() + }, bchjs.BitcoinCash.InvalidAddressError) + assert.throws(() => { + bchjs.Address.isP2SHAddress("some invalid address") + }, bchjs.BitcoinCash.InvalidAddressError) + }) + }) + }) + }) + + describe("cashaddr prefix detection", () => { + it("should return the same result for detectAddressFormat", () => { assert.deepEqual( CASHADDR_ADDRESSES_NO_PREFIX.map(address => - bchjs.Address.toCashAddress(address, true) + bchjs.Address.detectAddressFormat(address) ), - CASHADDR_ADDRESSES + CASHADDR_ADDRESSES.map(address => + bchjs.Address.detectAddressFormat(address) + ) ) - }) - - it("should translate no-prefix regtest cashaddr address format to itself correctly", () => { assert.deepEqual( REGTEST_ADDRESSES_NO_PREFIX.map(address => - bchjs.Address.toCashAddress(address, true, true) + bchjs.Address.detectAddressFormat(address) ), - REGTEST_ADDRESSES + REGTEST_ADDRESSES.map(address => + bchjs.Address.detectAddressFormat(address) + ) ) }) - - it("should translate cashaddr address format to itself of no-prefix correctly", () => { - CASHADDR_ADDRESSES.forEach(address => { - const noPrefix = bchjs.Address.toCashAddress(address, false) - assert.equal(address.split(":")[1], noPrefix) - }) - }) - - it("should translate regtest cashaddr address format to itself of no-prefix correctly", () => { - REGTEST_ADDRESSES.forEach(address => { - const noPrefix = bchjs.Address.toCashAddress(address, false, true) - assert.equal(address.split(":")[1], noPrefix) - }) - }) - - describe("errors", () => { - it("should fail when called with an invalid address", () => { - assert.throws(() => { - bchjs.BitcoinCash.Address.toCashAddress() - }, bchjs.BitcoinCash.InvalidAddressError) - assert.throws(() => { - bchjs.BitcoinCash.Address.toCashAddress("some invalid address") - }, bchjs.BitcoinCash.InvalidAddressError) - }) - }) - }) - describe("#toHash160", () => { - it("should convert legacy base58check address to hash160", () => { + it("should return the same result for detectAddressNetwork", () => { assert.deepEqual( - LEGACY_ADDRESSES.map(address => bchjs.Address.toHash160(address)), - HASH160_HASHES - ) - }) - - it("should convert cashaddr address to hash160", () => { - assert.deepEqual( - CASHADDR_ADDRESSES.map(address => bchjs.Address.toHash160(address)), - HASH160_HASHES - ) - }) - - it("should convert regtest cashaddr address to hash160", () => { - assert.deepEqual( - REGTEST_ADDRESSES.map(address => bchjs.Address.toHash160(address)), - fixtures.hash160TestnetP2PKH - ) - }) - - describe("errors", () => { - it("should fail when called with an invalid address", () => { - assert.throws(() => { - bchjs.Address.toHash160() - }, bchjs.BitcoinCash.InvalidAddressError) - assert.throws(() => { - bchjs.Address.toHash160("some invalid address") - }, bchjs.BitcoinCash.InvalidAddressError) - }) - }) - }) - describe("#fromHash160", () => { - it("should convert hash160 to mainnet P2PKH legacy base58check address", () => { - assert.deepEqual( - fixtures.hash160MainnetP2PKH.map(hash160 => - bchjs.Address.hash160ToLegacy(hash160) + CASHADDR_ADDRESSES_NO_PREFIX.map(address => + bchjs.Address.detectAddressNetwork(address) ), - fixtures.legacyMainnetP2PKH + CASHADDR_ADDRESSES.map(address => + bchjs.Address.detectAddressNetwork(address) + ) ) - }) - - it("should convert hash160 to mainnet P2SH legacy base58check address", () => { assert.deepEqual( - fixtures.hash160MainnetP2SH.map(hash160 => - bchjs.Address.hash160ToLegacy( - hash160, - Bitcoin.networks.bitcoin.scriptHash - ) + REGTEST_ADDRESSES_NO_PREFIX.map(address => + bchjs.Address.detectAddressNetwork(address) ), - fixtures.legacyMainnetP2SH + REGTEST_ADDRESSES.map(address => + bchjs.Address.detectAddressNetwork(address) + ) ) }) - - it("should convert hash160 to testnet P2PKH legacy base58check address", () => { + it("should return the same result for detectAddressType", () => { assert.deepEqual( - fixtures.hash160TestnetP2PKH.map(hash160 => - bchjs.Address.hash160ToLegacy( - hash160, - Bitcoin.networks.testnet.pubKeyHash - ) + CASHADDR_ADDRESSES_NO_PREFIX.map(address => + bchjs.Address.detectAddressType(address) ), - fixtures.legacyTestnetP2PKH + CASHADDR_ADDRESSES.map(address => + bchjs.Address.detectAddressType(address) + ) ) - }) - - it("should convert hash160 to mainnet P2PKH cash address", () => { assert.deepEqual( - fixtures.hash160MainnetP2PKH.map(hash160 => - bchjs.Address.hash160ToCash(hash160) + REGTEST_ADDRESSES_NO_PREFIX.map(address => + bchjs.Address.detectAddressType(address) ), - fixtures.cashaddrMainnetP2PKH + REGTEST_ADDRESSES.map(address => + bchjs.Address.detectAddressType(address) + ) ) }) - - it("should convert hash160 to mainnet P2SH cash address", () => { + it("should return the same result for toLegacyAddress", () => { assert.deepEqual( - fixtures.hash160MainnetP2SH.map(hash160 => - bchjs.Address.hash160ToCash( - hash160, - Bitcoin.networks.bitcoin.scriptHash - ) + CASHADDR_ADDRESSES_NO_PREFIX.map(address => + bchjs.Address.toLegacyAddress(address) ), - fixtures.cashaddrMainnetP2SH + CASHADDR_ADDRESSES.map(address => + bchjs.Address.toLegacyAddress(address) + ) ) - }) - - it("should convert hash160 to testnet P2PKH cash address", () => { assert.deepEqual( - fixtures.hash160TestnetP2PKH.map(hash160 => - bchjs.Address.hash160ToCash( - hash160, - Bitcoin.networks.testnet.pubKeyHash - ) + REGTEST_ADDRESSES_NO_PREFIX.map(address => + bchjs.Address.toLegacyAddress(address) ), - fixtures.cashaddrTestnetP2PKH + REGTEST_ADDRESSES.map(address => bchjs.Address.toLegacyAddress(address)) ) }) - - it("should convert hash160 to regtest P2PKH cash address", () => { + it("should return the same result for isLegacyAddress", () => { assert.deepEqual( - fixtures.hash160TestnetP2PKH.map(hash160 => - bchjs.Address.hash160ToCash( - hash160, - Bitcoin.networks.testnet.pubKeyHash, - true - ) + CASHADDR_ADDRESSES_NO_PREFIX.map(address => + bchjs.Address.isLegacyAddress(address) ), - REGTEST_ADDRESSES + CASHADDR_ADDRESSES.map(address => + bchjs.Address.isLegacyAddress(address) + ) + ) + assert.deepEqual( + REGTEST_ADDRESSES_NO_PREFIX.map(address => + bchjs.Address.isLegacyAddress(address) + ), + REGTEST_ADDRESSES.map(address => bchjs.Address.isLegacyAddress(address)) ) }) - - describe("errors", () => { - it("should fail when called with an invalid address", () => { - assert.throws(() => { - bchjs.Address.hash160ToLegacy() - }, bchjs.BitcoinCash.InvalidAddressError) - assert.throws(() => { - bchjs.Address.hash160ToLegacy("some invalid address") - }, bchjs.BitcoinCash.InvalidAddressError) - assert.throws(() => { - bchjs.Address.hash160ToCash() - }, bchjs.BitcoinCash.InvalidAddressError) - assert.throws(() => { - bchjs.Address.hash160ToCash("some invalid address") - }, bchjs.BitcoinCash.InvalidAddressError) - }) - }) - }) -}) - -describe("address format detection", () => { - describe("#isLegacyAddress", () => { - describe("is legacy", () => { - LEGACY_ADDRESSES.forEach(address => { - it(`should detect ${address} is a legacy base58Check address`, () => { - const isBase58Check = bchjs.Address.isLegacyAddress(address) - assert.equal(isBase58Check, true) - }) - }) - }) - describe("is not legacy", () => { - CASHADDR_ADDRESSES.forEach(address => { - it(`should detect ${address} is not a legacy address`, () => { - const isBase58Check = bchjs.Address.isLegacyAddress(address) - assert.equal(isBase58Check, false) - }) - }) - - REGTEST_ADDRESSES.forEach(address => { - it(`should detect ${address} is not a legacy address`, () => { - const isBase58Check = bchjs.Address.isLegacyAddress(address) - assert.equal(isBase58Check, false) - }) - }) - }) - - describe("errors", () => { - it("should fail when called with an invalid address", () => { - assert.throws(() => { - bchjs.Address.isLegacyAddress() - }, bchjs.BitcoinCash.InvalidAddressError) - assert.throws(() => { - bchjs.Address.isLegacyAddress("some invalid address") - }, bchjs.BitcoinCash.InvalidAddressError) - }) - }) - }) - - describe("#isCashAddress", () => { - describe("is cashaddr", () => { - CASHADDR_ADDRESSES.forEach(address => { - it(`should detect ${address} is a cashaddr address`, () => { - const isCashaddr = bchjs.Address.isCashAddress(address) - assert.equal(isCashaddr, true) - }) - }) - - REGTEST_ADDRESSES.forEach(address => { - it(`should detect ${address} is a cashaddr address`, () => { - const isCashaddr = bchjs.Address.isCashAddress(address) - assert.equal(isCashaddr, true) - }) - }) - }) - - describe("is not cashaddr", () => { - LEGACY_ADDRESSES.forEach(address => { - it(`should detect ${address} is not a cashaddr address`, () => { - const isCashaddr = bchjs.Address.isCashAddress(address) - assert.equal(isCashaddr, false) - }) - }) - }) - - describe("errors", () => { - it("should fail when called with an invalid address", () => { - assert.throws(() => { - bchjs.Address.isCashAddress() - }, bchjs.BitcoinCash.InvalidAddressError) - assert.throws(() => { - bchjs.Address.isCashAddress("some invalid address") - }, bchjs.BitcoinCash.InvalidAddressError) - }) - }) - }) - describe("#isHash160", () => { - describe("is hash160", () => { - HASH160_HASHES.forEach(address => { - it(`should detect ${address} is a hash160 hash`, () => { - const isHash160 = bchjs.Address.isHash160(address) - assert.equal(isHash160, true) - }) - }) - }) - describe("is not hash160", () => { - LEGACY_ADDRESSES.forEach(address => { - it(`should detect ${address} is not a hash160 hash`, () => { - const isHash160 = bchjs.Address.isHash160(address) - assert.equal(isHash160, false) - }) - }) - - CASHADDR_ADDRESSES.forEach(address => { - it(`should detect ${address} is not a hash160 hash`, () => { - const isHash160 = bchjs.Address.isHash160(address) - assert.equal(isHash160, false) - }) - }) - - REGTEST_ADDRESSES.forEach(address => { - it(`should detect ${address} is not a legacy address`, () => { - const isHash160 = bchjs.Address.isHash160(address) - assert.equal(isHash160, false) - }) - }) - }) - - describe("errors", () => { - it("should fail when called with an invalid address", () => { - assert.throws(() => { - bchjs.Address.isHash160() - }, bchjs.BitcoinCash.InvalidAddressError) - assert.throws(() => { - bchjs.Address.isHash160("some invalid address") - }, bchjs.BitcoinCash.InvalidAddressError) - }) - }) - }) -}) - -describe("network detection", () => { - describe("#isMainnetAddress", () => { - describe("is mainnet", () => { - MAINNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is a mainnet address`, () => { - const isMainnet = bchjs.Address.isMainnetAddress(address) - assert.equal(isMainnet, true) - }) - }) - }) - - describe("is not mainnet", () => { - TESTNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is not a mainnet address`, () => { - const isMainnet = bchjs.Address.isMainnetAddress(address) - assert.equal(isMainnet, false) - }) - }) - - REGTEST_ADDRESSES.forEach(address => { - it(`should detect ${address} is not a mainnet address`, () => { - const isMainnet = bchjs.Address.isMainnetAddress(address) - assert.equal(isMainnet, false) - }) - }) - }) - - describe("errors", () => { - it("should fail when called with an invalid address", () => { - assert.throws(() => { - bchjs.Address.isMainnetAddress() - }, bchjs.BitcoinCash.InvalidAddressError) - assert.throws(() => { - bchjs.Address.isMainnetAddress("some invalid address") - }, bchjs.BitcoinCash.InvalidAddressError) - }) - }) - }) - - describe("#isTestnetAddress", () => { - describe("is testnet", () => { - TESTNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is a testnet address`, () => { - const isTestnet = bchjs.Address.isTestnetAddress(address) - assert.equal(isTestnet, true) - }) - }) - }) - - describe("is not testnet", () => { - MAINNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is not a testnet address`, () => { - const isTestnet = bchjs.Address.isTestnetAddress(address) - assert.equal(isTestnet, false) - }) - }) - - REGTEST_ADDRESSES.forEach(address => { - it(`should detect ${address} is not a testnet address`, () => { - const isTestnet = bchjs.Address.isTestnetAddress(address) - assert.equal(isTestnet, false) - }) - }) - }) - - describe("errors", () => { - it("should fail when called with an invalid address", () => { - assert.throws(() => { - bchjs.Address.isTestnetAddress() - }, bchjs.BitcoinCash.InvalidAddressError) - assert.throws(() => { - bchjs.Address.isTestnetAddress("some invalid address") - }, bchjs.BitcoinCash.InvalidAddressError) - }) - }) - }) - - describe("#isRegTestAddress", () => { - describe("is testnet", () => { - REGTEST_ADDRESSES.forEach(address => { - it(`should detect ${address} is a regtest address`, () => { - const isRegTest = bchjs.Address.isRegTestAddress(address) - assert.equal(isRegTest, true) - }) - }) - }) - - describe("is not testnet", () => { - MAINNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is not a regtest address`, () => { - const isRegTest = bchjs.Address.isRegTestAddress(address) - assert.equal(isRegTest, false) - }) - }) - - TESTNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is not a regtest address`, () => { - const isRegTest = bchjs.Address.isRegTestAddress(address) - assert.equal(isRegTest, false) - }) - }) - }) - - describe("errors", () => { - it("should fail when called with an invalid address", () => { - assert.throws(() => { - bchjs.Address.isRegTestAddress() - }, bchjs.BitcoinCash.InvalidAddressError) - assert.throws(() => { - bchjs.Address.isRegTestAddress("some invalid address") - }, bchjs.BitcoinCash.InvalidAddressError) - }) - }) - }) -}) - -describe("address type detection", () => { - describe("#isP2PKHAddress", () => { - describe("is P2PKH", () => { - P2PKH_ADDRESSES.forEach(address => { - it(`should detect ${address} is a P2PKH address`, () => { - const isP2PKH = bchjs.Address.isP2PKHAddress(address) - assert.equal(isP2PKH, true) - }) - }) - }) - - describe("is not P2PKH", () => { - P2SH_ADDRESSES.forEach(address => { - it(`should detect ${address} is not a P2PKH address`, () => { - const isP2PKH = bchjs.Address.isP2PKHAddress(address) - assert.equal(isP2PKH, false) - }) - }) - }) - - describe("errors", () => { - it("should fail when called with an invalid address", () => { - assert.throws(() => { - bchjs.Address.isP2PKHAddress() - }, bchjs.BitcoinCash.InvalidAddressError) - assert.throws(() => { - bchjs.Address.isP2PKHAddress("some invalid address") - }, bchjs.BitcoinCash.InvalidAddressError) - }) - }) - }) - - describe("#isP2SHAddress", () => { - describe("is P2SH", () => { - P2SH_ADDRESSES.forEach(address => { - it(`should detect ${address} is a P2SH address`, () => { - const isP2SH = bchjs.Address.isP2SHAddress(address) - assert.equal(isP2SH, true) - }) - }) - }) - - describe("is not P2SH", () => { - P2PKH_ADDRESSES.forEach(address => { - it(`should detect ${address} is not a P2SH address`, () => { - const isP2SH = bchjs.Address.isP2SHAddress(address) - assert.equal(isP2SH, false) - }) - }) - }) - - describe("errors", () => { - it("should fail when called with an invalid address", () => { - assert.throws(() => { - bchjs.Address.isP2SHAddress() - }, bchjs.BitcoinCash.InvalidAddressError) - assert.throws(() => { - bchjs.Address.isP2SHAddress("some invalid address") - }, bchjs.BitcoinCash.InvalidAddressError) - }) - }) - }) -}) - -describe("cashaddr prefix detection", () => { - it("should return the same result for detectAddressFormat", () => { - assert.deepEqual( - CASHADDR_ADDRESSES_NO_PREFIX.map(address => - bchjs.Address.detectAddressFormat(address) - ), - CASHADDR_ADDRESSES.map(address => - bchjs.Address.detectAddressFormat(address) + it("should return the same result for isCashAddress", () => { + assert.deepEqual( + CASHADDR_ADDRESSES_NO_PREFIX.map(address => + bchjs.Address.isCashAddress(address) + ), + CASHADDR_ADDRESSES.map(address => bchjs.Address.isCashAddress(address)) ) - ) - assert.deepEqual( - REGTEST_ADDRESSES_NO_PREFIX.map(address => - bchjs.Address.detectAddressFormat(address) - ), - REGTEST_ADDRESSES.map(address => - bchjs.Address.detectAddressFormat(address) + assert.deepEqual( + REGTEST_ADDRESSES_NO_PREFIX.map(address => + bchjs.Address.isCashAddress(address) + ), + REGTEST_ADDRESSES.map(address => bchjs.Address.isCashAddress(address)) ) - ) - }) - it("should return the same result for detectAddressNetwork", () => { - assert.deepEqual( - CASHADDR_ADDRESSES_NO_PREFIX.map(address => - bchjs.Address.detectAddressNetwork(address) - ), - CASHADDR_ADDRESSES.map(address => - bchjs.Address.detectAddressNetwork(address) + }) + it("should return the same result for isMainnetAddress", () => { + assert.deepEqual( + CASHADDR_ADDRESSES_NO_PREFIX.map(address => + bchjs.Address.isMainnetAddress(address) + ), + CASHADDR_ADDRESSES.map(address => + bchjs.Address.isMainnetAddress(address) + ) ) - ) - assert.deepEqual( - REGTEST_ADDRESSES_NO_PREFIX.map(address => - bchjs.Address.detectAddressNetwork(address) - ), - REGTEST_ADDRESSES.map(address => - bchjs.Address.detectAddressNetwork(address) + assert.deepEqual( + REGTEST_ADDRESSES_NO_PREFIX.map(address => + bchjs.Address.isMainnetAddress(address) + ), + REGTEST_ADDRESSES.map(address => + bchjs.Address.isMainnetAddress(address) + ) ) - ) - }) - it("should return the same result for detectAddressType", () => { - assert.deepEqual( - CASHADDR_ADDRESSES_NO_PREFIX.map(address => - bchjs.Address.detectAddressType(address) - ), - CASHADDR_ADDRESSES.map(address => - bchjs.Address.detectAddressType(address) + }) + it("should return the same result for isTestnetAddress", () => { + assert.deepEqual( + CASHADDR_ADDRESSES_NO_PREFIX.map(address => + bchjs.Address.isTestnetAddress(address) + ), + CASHADDR_ADDRESSES.map(address => + bchjs.Address.isTestnetAddress(address) + ) + ) + assert.deepEqual( + REGTEST_ADDRESSES_NO_PREFIX.map(address => + bchjs.Address.isTestnetAddress(address) + ), + REGTEST_ADDRESSES.map(address => + bchjs.Address.isTestnetAddress(address) + ) + ) + }) + it("should return the same result for isP2PKHAddress", () => { + assert.deepEqual( + CASHADDR_ADDRESSES_NO_PREFIX.map(address => + bchjs.Address.isP2PKHAddress(address) + ), + CASHADDR_ADDRESSES.map(address => bchjs.Address.isP2PKHAddress(address)) + ) + assert.deepEqual( + REGTEST_ADDRESSES_NO_PREFIX.map(address => + bchjs.Address.isP2PKHAddress(address) + ), + REGTEST_ADDRESSES.map(address => bchjs.Address.isP2PKHAddress(address)) + ) + }) + it("should return the same result for isP2SHAddress", () => { + assert.deepEqual( + CASHADDR_ADDRESSES_NO_PREFIX.map(address => + bchjs.Address.isP2SHAddress(address) + ), + CASHADDR_ADDRESSES.map(address => bchjs.Address.isP2SHAddress(address)) + ) + assert.deepEqual( + REGTEST_ADDRESSES_NO_PREFIX.map(address => + bchjs.Address.isP2SHAddress(address) + ), + REGTEST_ADDRESSES.map(address => bchjs.Address.isP2SHAddress(address)) ) - ) - assert.deepEqual( - REGTEST_ADDRESSES_NO_PREFIX.map(address => - bchjs.Address.detectAddressType(address) - ), - REGTEST_ADDRESSES.map(address => bchjs.Address.detectAddressType(address)) - ) - }) - it("should return the same result for toLegacyAddress", () => { - assert.deepEqual( - CASHADDR_ADDRESSES_NO_PREFIX.map(address => - bchjs.Address.toLegacyAddress(address) - ), - CASHADDR_ADDRESSES.map(address => bchjs.Address.toLegacyAddress(address)) - ) - assert.deepEqual( - REGTEST_ADDRESSES_NO_PREFIX.map(address => - bchjs.Address.toLegacyAddress(address) - ), - REGTEST_ADDRESSES.map(address => bchjs.Address.toLegacyAddress(address)) - ) - }) - it("should return the same result for isLegacyAddress", () => { - assert.deepEqual( - CASHADDR_ADDRESSES_NO_PREFIX.map(address => - bchjs.Address.isLegacyAddress(address) - ), - CASHADDR_ADDRESSES.map(address => bchjs.Address.isLegacyAddress(address)) - ) - assert.deepEqual( - REGTEST_ADDRESSES_NO_PREFIX.map(address => - bchjs.Address.isLegacyAddress(address) - ), - REGTEST_ADDRESSES.map(address => bchjs.Address.isLegacyAddress(address)) - ) - }) - it("should return the same result for isCashAddress", () => { - assert.deepEqual( - CASHADDR_ADDRESSES_NO_PREFIX.map(address => - bchjs.Address.isCashAddress(address) - ), - CASHADDR_ADDRESSES.map(address => bchjs.Address.isCashAddress(address)) - ) - assert.deepEqual( - REGTEST_ADDRESSES_NO_PREFIX.map(address => - bchjs.Address.isCashAddress(address) - ), - REGTEST_ADDRESSES.map(address => bchjs.Address.isCashAddress(address)) - ) - }) - it("should return the same result for isMainnetAddress", () => { - assert.deepEqual( - CASHADDR_ADDRESSES_NO_PREFIX.map(address => - bchjs.Address.isMainnetAddress(address) - ), - CASHADDR_ADDRESSES.map(address => bchjs.Address.isMainnetAddress(address)) - ) - assert.deepEqual( - REGTEST_ADDRESSES_NO_PREFIX.map(address => - bchjs.Address.isMainnetAddress(address) - ), - REGTEST_ADDRESSES.map(address => bchjs.Address.isMainnetAddress(address)) - ) - }) - it("should return the same result for isTestnetAddress", () => { - assert.deepEqual( - CASHADDR_ADDRESSES_NO_PREFIX.map(address => - bchjs.Address.isTestnetAddress(address) - ), - CASHADDR_ADDRESSES.map(address => bchjs.Address.isTestnetAddress(address)) - ) - assert.deepEqual( - REGTEST_ADDRESSES_NO_PREFIX.map(address => - bchjs.Address.isTestnetAddress(address) - ), - REGTEST_ADDRESSES.map(address => bchjs.Address.isTestnetAddress(address)) - ) - }) - it("should return the same result for isP2PKHAddress", () => { - assert.deepEqual( - CASHADDR_ADDRESSES_NO_PREFIX.map(address => - bchjs.Address.isP2PKHAddress(address) - ), - CASHADDR_ADDRESSES.map(address => bchjs.Address.isP2PKHAddress(address)) - ) - assert.deepEqual( - REGTEST_ADDRESSES_NO_PREFIX.map(address => - bchjs.Address.isP2PKHAddress(address) - ), - REGTEST_ADDRESSES.map(address => bchjs.Address.isP2PKHAddress(address)) - ) - }) - it("should return the same result for isP2SHAddress", () => { - assert.deepEqual( - CASHADDR_ADDRESSES_NO_PREFIX.map(address => - bchjs.Address.isP2SHAddress(address) - ), - CASHADDR_ADDRESSES.map(address => bchjs.Address.isP2SHAddress(address)) - ) - assert.deepEqual( - REGTEST_ADDRESSES_NO_PREFIX.map(address => - bchjs.Address.isP2SHAddress(address) - ), - REGTEST_ADDRESSES.map(address => bchjs.Address.isP2SHAddress(address)) - ) - }) -}) - -describe("#detectAddressFormat", () => { - LEGACY_ADDRESSES.forEach(address => { - it(`should detect ${address} is a legacy base58Check address`, () => { - const isBase58Check = bchjs.Address.detectAddressFormat(address) - assert.equal(isBase58Check, "legacy") }) }) - CASHADDR_ADDRESSES.forEach(address => { - it(`should detect ${address} is a legacy cashaddr address`, () => { - const isCashaddr = bchjs.Address.detectAddressFormat(address) - assert.equal(isCashaddr, "cashaddr") + describe("#detectAddressFormat", () => { + LEGACY_ADDRESSES.forEach(address => { + it(`should detect ${address} is a legacy base58Check address`, () => { + const isBase58Check = bchjs.Address.detectAddressFormat(address) + assert.equal(isBase58Check, "legacy") + }) + }) + + CASHADDR_ADDRESSES.forEach(address => { + it(`should detect ${address} is a legacy cashaddr address`, () => { + const isCashaddr = bchjs.Address.detectAddressFormat(address) + assert.equal(isCashaddr, "cashaddr") + }) + }) + + REGTEST_ADDRESSES.forEach(address => { + it(`should detect ${address} is a legacy cashaddr address`, () => { + const isCashaddr = bchjs.Address.detectAddressFormat(address) + assert.equal(isCashaddr, "cashaddr") + }) + }) + + describe("errors", () => { + it("should fail when called with an invalid address", () => { + assert.throws(() => { + bchjs.Address.detectAddressFormat() + }, bchjs.BitcoinCash.InvalidAddressError) + assert.throws(() => { + bchjs.Address.detectAddressFormat("some invalid address") + }, bchjs.BitcoinCash.InvalidAddressError) + }) }) }) - REGTEST_ADDRESSES.forEach(address => { - it(`should detect ${address} is a legacy cashaddr address`, () => { - const isCashaddr = bchjs.Address.detectAddressFormat(address) - assert.equal(isCashaddr, "cashaddr") + describe("#detectAddressNetwork", () => { + MAINNET_ADDRESSES.forEach(address => { + it(`should detect ${address} is a mainnet address`, () => { + const isMainnet = bchjs.Address.detectAddressNetwork(address) + assert.equal(isMainnet, "mainnet") + }) + }) + + TESTNET_ADDRESSES.forEach(address => { + it(`should detect ${address} is a testnet address`, () => { + const isTestnet = bchjs.Address.detectAddressNetwork(address) + assert.equal(isTestnet, "testnet") + }) + }) + + REGTEST_ADDRESSES.forEach(address => { + it(`should detect ${address} is a testnet address`, () => { + const isTestnet = bchjs.Address.detectAddressNetwork(address) + assert.equal(isTestnet, "regtest") + }) + }) + + describe("errors", () => { + it("should fail when called with an invalid address", () => { + assert.throws(() => { + bchjs.Address.detectAddressNetwork() + }, bchjs.BitcoinCash.InvalidAddressError) + assert.throws(() => { + bchjs.Address.detectAddressNetwork("some invalid address") + }, bchjs.BitcoinCash.InvalidAddressError) + }) }) }) - describe("errors", () => { - it("should fail when called with an invalid address", () => { - assert.throws(() => { - bchjs.Address.detectAddressFormat() - }, bchjs.BitcoinCash.InvalidAddressError) - assert.throws(() => { - bchjs.Address.detectAddressFormat("some invalid address") - }, bchjs.BitcoinCash.InvalidAddressError) + describe("#detectAddressType", () => { + P2PKH_ADDRESSES.forEach(address => { + it(`should detect ${address} is a P2PKH address`, () => { + const isP2PKH = bchjs.Address.detectAddressType(address) + assert.equal(isP2PKH, "p2pkh") + }) }) - }) -}) -describe("#detectAddressNetwork", () => { - MAINNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is a mainnet address`, () => { - const isMainnet = bchjs.Address.detectAddressNetwork(address) - assert.equal(isMainnet, "mainnet") + P2SH_ADDRESSES.forEach(address => { + it(`should detect ${address} is a P2SH address`, () => { + const isP2SH = bchjs.Address.detectAddressType(address) + assert.equal(isP2SH, "p2sh") + }) + }) + + describe("errors", () => { + it("should fail when called with an invalid address", () => { + assert.throws(() => { + bchjs.Address.detectAddressType() + }, bchjs.BitcoinCash.InvalidAddressError) + assert.throws(() => { + bchjs.Address.detectAddressType("some invalid address") + }, bchjs.BitcoinCash.InvalidAddressError) + }) }) }) - TESTNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is a testnet address`, () => { - const isTestnet = bchjs.Address.detectAddressNetwork(address) - assert.equal(isTestnet, "testnet") + describe("#fromXPub", () => { + XPUBS.forEach((xpub, i) => { + xpub.addresses.forEach((address, j) => { + it(`generate public external change address ${j} for ${xpub.xpub}`, () => { + assert.equal(bchjs.Address.fromXPub(xpub.xpub, `0/${j}`), address) + }) + }) }) }) - REGTEST_ADDRESSES.forEach(address => { - it(`should detect ${address} is a testnet address`, () => { - const isTestnet = bchjs.Address.detectAddressNetwork(address) - assert.equal(isTestnet, "regtest") - }) - }) + describe("#fromOutputScript", () => { + it("generate address from output script", () => { + const script = bchjs.Script.encode([ + Buffer.from("BOX", "ascii"), + bchjs.Script.opcodes.OP_CAT, + Buffer.from("BITBOX", "ascii"), + bchjs.Script.opcodes.OP_EQUAL + ]) - describe("errors", () => { - it("should fail when called with an invalid address", () => { - assert.throws(() => { - bchjs.Address.detectAddressNetwork() - }, bchjs.BitcoinCash.InvalidAddressError) - assert.throws(() => { - bchjs.Address.detectAddressNetwork("some invalid address") - }, bchjs.BitcoinCash.InvalidAddressError) - }) - }) -}) + // hash160 script buffer + const p2sh_hash160 = bchjs.Crypto.hash160(script) -describe("#detectAddressType", () => { - P2PKH_ADDRESSES.forEach(address => { - it(`should detect ${address} is a P2PKH address`, () => { - const isP2PKH = bchjs.Address.detectAddressType(address) - assert.equal(isP2PKH, "p2pkh") - }) - }) + // encode hash160 as P2SH output + const scriptPubKey = bchjs.Script.scriptHash.output.encode(p2sh_hash160) + const p2shAddress = bchjs.Address.fromOutputScript(scriptPubKey) - P2SH_ADDRESSES.forEach(address => { - it(`should detect ${address} is a P2SH address`, () => { - const isP2SH = bchjs.Address.detectAddressType(address) - assert.equal(isP2SH, "p2sh") - }) - }) - - describe("errors", () => { - it("should fail when called with an invalid address", () => { - assert.throws(() => { - bchjs.Address.detectAddressType() - }, bchjs.BitcoinCash.InvalidAddressError) - assert.throws(() => { - bchjs.Address.detectAddressType("some invalid address") - }, bchjs.BitcoinCash.InvalidAddressError) - }) - }) -}) - -describe("#fromXPub", () => { - XPUBS.forEach((xpub, i) => { - xpub.addresses.forEach((address, j) => { - it(`generate public external change address ${j} for ${xpub.xpub}`, () => { - assert.equal(bchjs.Address.fromXPub(xpub.xpub, `0/${j}`), address) + fixtures.p2shMainnet.forEach((address, i) => { + assert.equal(p2shAddress, address) }) }) }) }) - -describe("#fromOutputScript", () => { - const script = bchjs.Script.encode([ - Buffer.from("BOX", "ascii"), - bchjs.Script.opcodes.OP_CAT, - Buffer.from("BITBOX", "ascii"), - bchjs.Script.opcodes.OP_EQUAL - ]) - - // hash160 script buffer - const p2sh_hash160 = bchjs.Crypto.hash160(script) - - // encode hash160 as P2SH output - const scriptPubKey = bchjs.Script.scriptHash.output.encode(p2sh_hash160) - const p2shAddress = bchjs.Address.fromOutputScript(scriptPubKey) - fixtures.p2shMainnet.forEach((address, i) => { - it(`generate address from output script`, () => { - assert.equal(p2shAddress, address) - }) - }) -}) diff --git a/test/unit/bitcoin-cash.js b/test/unit/bitcoin-cash.js deleted file mode 100644 index e64901b..0000000 --- a/test/unit/bitcoin-cash.js +++ /dev/null @@ -1,314 +0,0 @@ -const fixtures = require("./fixtures/bitcoincash.json") -const assert = require("assert") -const BCHJS = require("../../src/bch-js") -const bchjs = new BCHJS() - -// TODO -// 1. generate testnet p2sh -// 2. generate cashaddr mainnet p2sh -// 3. generate cashaddr testnet p2sh -// 4. create bchjs fromBase58 method -// * confirm xpub cannot generate WIF -// * confirm xpriv can generate WIF -// 5. create fromXPriv method w/ tests and docs -// 1. mainnet -// * confirm xpriv generates address -// * confirm xpriv generates WIF -// 2. testnet -// * confirm xpriv generates address -// * confirm xpriv generates WIF -// 6. More error test cases. - -describe("#BitcoinCash", () => { - describe("price conversion", () => { - describe("#toBitcoinCash", () => { - fixtures.conversion.toBCH.satoshis.forEach(satoshi => { - it(`should convert ${satoshi[0]} Satoshis to ${ - satoshi[1] - } $BCH`, () => { - assert.equal(bchjs.BitcoinCash.toBitcoinCash(satoshi[0]), satoshi[1]) - }) - }) - - fixtures.conversion.toBCH.strings.forEach(satoshi => { - it(`should convert "${satoshi[0]}" Satoshis as a string to ${ - satoshi[1] - } $BCH`, () => { - assert.equal(bchjs.BitcoinCash.toBitcoinCash(satoshi[0]), satoshi[1]) - }) - }) - - fixtures.conversion.toBCH.not.forEach(bch => { - it(`converts ${bch[0]} to Bitcoin Cash, not to ${ - bch[1] - } Satoshi`, () => { - assert.notEqual(bchjs.BitcoinCash.toBitcoinCash(bch[0]), bch[1]) - }) - }) - - fixtures.conversion.toBCH.rounding.forEach(satoshi => { - it(`rounding ${satoshi[0]} to ${satoshi[1]} $BCH`, () => { - assert.equal(bchjs.BitcoinCash.toBitcoinCash(satoshi[0]), satoshi[1]) - }) - }) - }) - - describe("#toSatoshi", () => { - fixtures.conversion.toSatoshi.bch.forEach(bch => { - it(`should convert ${bch[0]} $BCH to ${bch[1]} Satoshis`, () => { - assert.equal(bchjs.BitcoinCash.toSatoshi(bch[0]), bch[1]) - }) - }) - - fixtures.conversion.toSatoshi.strings.forEach(bch => { - it(`should convert "${bch[0]}" $BCH as a string to ${ - bch[1] - } Satoshis`, () => { - assert.equal(bchjs.BitcoinCash.toSatoshi(bch[0]), bch[1]) - }) - }) - - fixtures.conversion.toSatoshi.not.forEach(satoshi => { - it(`converts ${satoshi[0]} to Satoshi, not to ${ - satoshi[1] - } Bitcoin Cash`, () => { - assert.notEqual(bchjs.BitcoinCash.toSatoshi(satoshi[0]), satoshi[1]) - }) - }) - - fixtures.conversion.toSatoshi.rounding.forEach(bch => { - it(`rounding ${bch[0]} to ${bch[1]} Satoshi`, () => { - assert.equal(bchjs.BitcoinCash.toSatoshi(bch[0]), bch[1]) - }) - }) - }) - - describe("#satsToBits", () => { - fixtures.conversion.satsToBits.bch.forEach(bch => { - it(`should convert ${bch[0]} BCH to ${bch[1]} bits`, () => { - assert.equal( - bchjs.BitcoinCash.satsToBits(bchjs.BitcoinCash.toSatoshi(bch[0])), - bch[1] - ) - }) - }) - - fixtures.conversion.satsToBits.strings.forEach(bch => { - it(`should convert "${bch[0]}" BCH as a string to ${ - bch[1] - } bits`, () => { - assert.equal( - bchjs.BitcoinCash.satsToBits(bchjs.BitcoinCash.toSatoshi(bch[0])), - bch[1] - ) - }) - }) - }) - // - // describe('#satsFromBits', () => { - // fixtures.conversion.satsFromBits.bch.forEach((bch) => { - // it(`should convert ${bch[1]} bits to ${bch[0]} satoshis`, () => { - // assert.equal(bchjs.BitcoinCash.satsFromBits(bch[1]), bch[0]); - // }); - // }); - // - // fixtures.conversion.satsFromBits.strings.forEach((bch) => { - // it(`should convert "${bch[1]}" bits as a string to ${bch[0]} satoshis`, () => { - // assert.equal(bchjs.BitcoinCash.satsFromBits(bch[1]), bch[0]); - // }); - // }); - // }); - }) - - describe("sign and verify messages", () => { - describe("#signMessageWithPrivKey", () => { - fixtures.signatures.sign.forEach(sign => { - it(`should sign a message w/ ${sign.network} ${sign.privateKeyWIF}`, () => { - const privateKeyWIF = sign.privateKeyWIF - const message = sign.message - const signature = bchjs.BitcoinCash.signMessageWithPrivKey( - privateKeyWIF, - message - ) - assert.equal(signature, sign.signature) - }) - }) - }) - - describe("#verifyMessage", () => { - fixtures.signatures.verify.forEach(sign => { - it(`should verify a valid signed message from ${sign.network} cashaddr address ${sign.address}`, () => { - assert.equal( - bchjs.BitcoinCash.verifyMessage( - sign.address, - sign.signature, - sign.message - ), - true - ) - }) - }) - - fixtures.signatures.verify.forEach(sign => { - const legacyAddress = bchjs.Address.toLegacyAddress(sign.address) - it(`should verify a valid signed message from ${sign.network} legacy address ${legacyAddress}`, () => { - assert.equal( - bchjs.BitcoinCash.verifyMessage( - legacyAddress, - sign.signature, - sign.message - ), - true - ) - }) - }) - - fixtures.signatures.verify.forEach(sign => { - const legacyAddress = bchjs.Address.toLegacyAddress(sign.address) - it(`should not verify an invalid signed message from ${sign.network} cashaddr address ${sign.address}`, () => { - assert.equal( - bchjs.BitcoinCash.verifyMessage( - sign.address, - sign.signature, - "nope" - ), - false - ) - }) - }) - }) - }) - - describe("encode and decode to base58Check", () => { - describe("#encodeBase58Check", () => { - fixtures.encodeBase58Check.forEach((base58Check, i) => { - it(`encode ${base58Check.hex} as base58Check ${base58Check.base58Check}`, () => { - assert.equal( - bchjs.BitcoinCash.encodeBase58Check(base58Check.hex), - base58Check.base58Check - ) - }) - }) - }) - - describe("#decodeBase58Check", () => { - fixtures.encodeBase58Check.forEach((base58Check, i) => { - it(`decode ${base58Check.base58Check} as ${base58Check.hex}`, () => { - assert.equal( - bchjs.BitcoinCash.decodeBase58Check(base58Check.base58Check), - base58Check.hex - ) - }) - }) - }) - }) - - describe("encode and decode BIP21 urls", () => { - describe("#encodeBIP21", () => { - fixtures.bip21.valid.forEach((bip21, i) => { - it(`encode ${bip21.address} as url`, () => { - const url = bchjs.BitcoinCash.encodeBIP21( - bip21.address, - bip21.options - ) - assert.equal(url, bip21.url) - }) - }) - fixtures.bip21.valid_regtest.forEach((bip21, i) => { - it(`encode ${bip21.address} as url`, () => { - const url = bchjs.BitcoinCash.encodeBIP21( - bip21.address, - bip21.options, - true - ) - assert.equal(url, bip21.url) - }) - }) - }) - - describe("#decodeBIP21", () => { - fixtures.bip21.valid.forEach((bip21, i) => { - it(`decodes ${bip21.url}`, () => { - const decoded = bchjs.BitcoinCash.decodeBIP21(bip21.url) - assert.equal(decoded.options.amount, bip21.options.amount) - assert.equal(decoded.options.label, bip21.options.label) - assert.equal( - bchjs.Address.toCashAddress(decoded.address), - bchjs.Address.toCashAddress(bip21.address) - ) - }) - }) - // fixtures.bip21.valid_regtest.forEach((bip21, i) => { - // it(`decodes ${bip21.url}`, () => { - // const decoded = bchjs.BitcoinCash.decodeBIP21(bip21.url) - // assert.equal(decoded.options.amount, bip21.options.amount) - // assert.equal(decoded.options.label, bip21.options.label) - // assert.equal( - // bchjs.Address.toCashAddress(decoded.address, true, true), - // bchjs.Address.toCashAddress(bip21.address, true, true) - // ) - // }) - // }) - }) - }) - - describe("#getByteCount", () => { - fixtures.getByteCount.forEach(fixture => { - it(`get byte count`, () => { - const byteCount = bchjs.BitcoinCash.getByteCount( - fixture.inputs, - fixture.outputs - ) - assert.equal(byteCount, fixture.byteCount) - }) - }) - }) - - describe("#bip38", () => { - describe("#encryptBIP38", () => { - fixtures.bip38.encrypt.mainnet.forEach(fixture => { - it(`BIP 38 encrypt wif ${fixture.wif} with password ${fixture.password} on mainnet`, () => { - const encryptedKey = bchjs.BitcoinCash.encryptBIP38( - fixture.wif, - fixture.password - ) - assert.equal(encryptedKey, fixture.encryptedKey) - }) - }) - - fixtures.bip38.encrypt.testnet.forEach(fixture => { - it(`BIP 38 encrypt wif ${fixture.wif} with password ${fixture.password} on testnet`, () => { - const encryptedKey = bchjs.BitcoinCash.encryptBIP38( - fixture.wif, - fixture.password - ) - assert.equal(encryptedKey, fixture.encryptedKey) - }) - }) - }) - - describe("#decryptBIP38", () => { - fixtures.bip38.decrypt.mainnet.forEach(fixture => { - it(`BIP 38 decrypt encrypted key ${fixture.encryptedKey} on mainnet`, () => { - const wif = bchjs.BitcoinCash.decryptBIP38( - fixture.encryptedKey, - fixture.password, - "mainnet" - ) - assert.equal(wif, fixture.wif) - }) - }) - - fixtures.bip38.decrypt.testnet.forEach(fixture => { - it(`BIP 38 decrypt encrypted key ${fixture.encryptedKey} on testnet`, () => { - const wif = bchjs.BitcoinCash.decryptBIP38( - fixture.encryptedKey, - fixture.password, - "testnet" - ) - assert.equal(wif, fixture.wif) - }) - }) - }) - }) -}) diff --git a/test/unit/blockbook.js b/test/unit/blockbook.js deleted file mode 100644 index 9866c81..0000000 --- a/test/unit/blockbook.js +++ /dev/null @@ -1,275 +0,0 @@ -const chai = require("chai") -const assert = chai.assert -const BCHJS = require("../../src/bch-js") -const bchjs = new BCHJS() -const axios = require("axios") -const sinon = require("sinon") - -const mockData = require("./fixtures/blockbook-mock") - -describe(`#Blockbook`, () => { - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - - describe(`#Balance`, () => { - it(`should GET balance for a single address`, async () => { - // Stub the network call. - sandbox.stub(axios, "get").resolves({ data: mockData.balance }) - - const addr = "bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf" - - const result = await bchjs.Blockbook.balance(addr) - //console.log(`result: ${util.inspect(result)}`) - - assert.hasAnyKeys(result, [ - "page", - "totalPages", - "itemsOnPage", - "address", - "balance", - "totalReceived", - "totalSent", - "unconfirmedBalance", - "unconfirmedTxs", - "txs", - "txids" - ]) - assert.isArray(result.txids) - }) - - it(`should POST request balances for an array of addresses`, async () => { - // Stub the network call. - sandbox - .stub(axios, "post") - .resolves({ data: [mockData.balance, mockData.balance] }) - - const addr = [ - "bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf", - "bitcoincash:qpdh9s677ya8tnx7zdhfrn8qfyvy22wj4qa7nwqa5v" - ] - - const result = await bchjs.Blockbook.balance(addr) - //console.log(`result: ${util.inspect(result)}`) - - assert.isArray(result) - assert.hasAnyKeys(result[0], [ - "page", - "totalPages", - "itemsOnPage", - "address", - "balance", - "totalReceived", - "totalSent", - "unconfirmedBalance", - "unconfirmedTxs", - "txs", - "txids" - ]) - assert.isArray(result[0].txids) - }) - - it(`should throw an error for improper input`, async () => { - try { - // Stub the network call. - sandbox - .stub(axios, "post") - .throws(`Input address must be a string or array of strings`) - - const addr = 12345 - - await bchjs.Blockbook.balance(addr) - assert.equal(true, false, "Unexpected result!") - } catch (err) { - //console.log(`err: `, err) - assert.include( - err.message, - `Input address must be a string or array of strings` - ) - } - }) - /* - it(`should throw error on array size rate limit`, async () => { - try { - // Stub the network call. - sandbox.stub(axios, "post").throws(`Array too large`) - - const addr = [] - for (let i = 0; i < 25; i++) - addr.push("bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf") - - const result = await bchjs.Blockbook.balance(addr) - - console.log(`result: ${util.inspect(result)}`) - assert.equal(true, false, "Unexpected result!") - } catch (err) { - assert.hasAnyKeys(err, ["error"]) - assert.include(err.error, "Array too large") - } - }) - */ - }) - - describe(`#utxo`, () => { - it(`should GET utxos for a single address`, async () => { - // Stub the network call. - sandbox.stub(axios, "get").resolves({ data: mockData.utxo }) - - const addr = "bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf" - - const result = await bchjs.Blockbook.utxo(addr) - //console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.isArray(result) - assert.hasAnyKeys(result[0], [ - "txid", - "vout", - "value", - "height", - "confirmations" - ]) - }) - - it(`should POST utxo details for an array of addresses`, async () => { - // Stub the network call. - sandbox.stub(axios, "post").resolves({ data: mockData.utxos }) - - const addr = [ - "bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf", - "bitcoincash:qpdh9s677ya8tnx7zdhfrn8qfyvy22wj4qa7nwqa5v" - ] - - const result = await bchjs.Blockbook.utxo(addr) - //console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.isArray(result) - assert.isArray(result[0]) - assert.hasAnyKeys(result[0][0], [ - "txid", - "vout", - "value", - "height", - "confirmations" - ]) - }) - - it(`should throw an error for improper input`, async () => { - try { - // Stub the network call. - sandbox - .stub(axios, "post") - .throws(`Input address must be a string or array of strings`) - - const addr = 12345 - - await bchjs.Blockbook.utxo(addr) - assert.equal(true, false, "Unexpected result!") - } catch (err) { - //console.log(`err: `, err) - assert.include( - err.message, - `Input address must be a string or array of strings` - ) - } - }) - /* - it(`should throw error on array size rate limit`, async () => { - try { - const addr = [] - for (let i = 0; i < 25; i++) - addr.push("bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf") - - const result = await bchjs.Blockbook.utxo(addr) - - console.log(`result: ${util.inspect(result)}`) - assert.equal(true, false, "Unexpected result!") - } catch (err) { - assert.hasAnyKeys(err, ["error"]) - assert.include(err.error, "Array too large") - } - }) - */ - }) - - describe(`#tx`, () => { - it(`should GET tx details for a single txid`, async () => { - // Stub the network call. - sandbox.stub(axios, "get").resolves({ data: mockData.utxo }) - - const addr = "bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf" - - const result = await bchjs.Blockbook.utxo(addr) - //console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.isArray(result) - assert.hasAnyKeys(result[0], [ - "txid", - "vout", - "value", - "height", - "confirmations" - ]) - }) - - // it(`should POST utxo details for an array of addresses`, async () => { - // // Stub the network call. - // sandbox.stub(axios, "post").resolves({ data: mockData.utxos }) - // - // const addr = [ - // "bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf", - // "bitcoincash:qpdh9s677ya8tnx7zdhfrn8qfyvy22wj4qa7nwqa5v" - // ] - // - // const result = await bchjs.Blockbook.utxo(addr) - // //console.log(`result: ${JSON.stringify(result, null, 2)}`) - // - // assert.isArray(result) - // assert.isArray(result[0]) - // assert.hasAnyKeys(result[0][0], [ - // "txid", - // "vout", - // "value", - // "height", - // "confirmations" - // ]) - // }) - - // it(`should throw an error for improper input`, async () => { - // try { - // // Stub the network call. - // sandbox - // .stub(axios, "post") - // .throws(`Input address must be a string or array of strings`) - // - // const addr = 12345 - // - // await bchjs.Blockbook.utxo(addr) - // assert.equal(true, false, "Unexpected result!") - // } catch (err) { - // //console.log(`err: `, err) - // assert.include( - // err.message, - // `Input address must be a string or array of strings` - // ) - // } - // }) - - /* - it(`should throw error on array size rate limit`, async () => { - try { - const addr = [] - for (let i = 0; i < 25; i++) - addr.push("bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf") - - const result = await bchjs.Blockbook.utxo(addr) - - console.log(`result: ${util.inspect(result)}`) - assert.equal(true, false, "Unexpected result!") - } catch (err) { - assert.hasAnyKeys(err, ["error"]) - assert.include(err.error, "Array too large") - } - }) - */ - }) -}) diff --git a/test/unit/blockchain.js b/test/unit/blockchain.js deleted file mode 100644 index e088ffe..0000000 --- a/test/unit/blockchain.js +++ /dev/null @@ -1,494 +0,0 @@ -const assert = require("assert") -const assert2 = require("chai").assert -const axios = require("axios") -const BCHJS = require("../../src/bch-js") -const bchjs = new BCHJS() -const sinon = require("sinon") - -const mockData = require("./fixtures/blockchain-mock") - -describe("#Blockchain", () => { - describe("#getBestBlockHash", () => { - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - - it("should get best block hash", done => { - const resolved = new Promise(r => - r({ - data: - "0000000000000000005f1f550d3d8b142b684277016ebd00fa29c668606ae52d" - }) - ) - sandbox.stub(axios, "get").returns(resolved) - - bchjs.Blockchain.getBestBlockHash() - .then(result => { - const hash = - "0000000000000000005f1f550d3d8b142b684277016ebd00fa29c668606ae52d" - assert.equal(hash, result) - }) - .then(done, done) - }) - }) - - describe("#getBlock", () => { - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - const data = { - hash: "00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09", - confirmations: 526807, - size: 216, - height: 1000, - version: 1, - versionHex: "00000001", - merkleroot: - "fe28050b93faea61fa88c4c630f0e1f0a1c24d0082dd0e10d369e13212128f33", - tx: ["fe28050b93faea61fa88c4c630f0e1f0a1c24d0082dd0e10d369e13212128f33"], - time: 1232346882, - mediantime: 1232344831, - nonce: 2595206198, - bits: "1d00ffff", - difficulty: 1, - chainwork: - "000000000000000000000000000000000000000000000000000003e903e903e9", - previousblockhash: - "0000000008e647742775a230787d66fdf92c46a48c896bfbc85cdc8acc67e87d", - nextblockhash: - "00000000a2887344f8db859e372e7e4bc26b23b9de340f725afbf2edb265b4c6" - } - - it("should get block by hash", done => { - const resolved = new Promise(r => r({ data: data })) - sandbox.stub(axios, "get").returns(resolved) - - bchjs.Blockchain.getBlock( - "00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09" - ) - .then(result => { - assert.deepEqual(data, result) - }) - .then(done, done) - }) - }) - - describe("#getBlockchainInfo", () => { - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - const data = { - chain: "main", - blocks: 527810, - headers: 527810, - bestblockhash: - "000000000000000001d127592d091d4c45062504663c9acab27a1b16c028e3c0", - difficulty: 576023394804.6666, - mediantime: 1524878499, - verificationprogress: 0.9999990106793685, - chainwork: - "00000000000000000000000000000000000000000096da5b040913fa09249b4e", - pruned: false, - softforks: [ - { id: "bip34", version: 2, reject: [Object] }, - { id: "bip66", version: 3, reject: [Object] }, - { id: "bip65", version: 4, reject: [Object] } - ], - bip9_softforks: { - csv: { - status: "active", - startTime: 1462060800, - timeout: 1493596800, - since: 419328 - } - } - } - - it("should get blockchain info", done => { - const resolved = new Promise(r => r({ data: data })) - sandbox.stub(axios, "get").returns(resolved) - - bchjs.Blockchain.getBlockchainInfo() - .then(result => { - assert.deepEqual(data, result) - }) - .then(done, done) - }) - }) - - describe("#getBlockCount", () => { - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - const data = 527810 - - it("should get block count", done => { - const resolved = new Promise(r => r({ data: data })) - sandbox.stub(axios, "get").returns(resolved) - - bchjs.Blockchain.getBlockCount() - .then(result => { - assert.deepEqual(data, result) - }) - .then(done, done) - }) - }) - - describe("#getBlockHash", () => { - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - const data = - "000000000000000001d127592d091d4c45062504663c9acab27a1b16c028e3c0" - - it("should get block hash by height", done => { - const resolved = new Promise(r => r({ data: data })) - sandbox.stub(axios, "get").returns(resolved) - - bchjs.Blockchain.getBlockHash(527810) - .then(result => { - assert.deepEqual(data, result) - }) - .then(done, done) - }) - }) - - describe("#getBlockHeader", () => { - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - const data = { - hash: "000000000000000001d127592d091d4c45062504663c9acab27a1b16c028e3c0", - confirmations: 1, - height: 527810, - version: 536870912, - versionHex: "20000000", - merkleroot: - "9298432bbebe4638456aa19cb7ef91639da87668a285d88d0ecd6080424d223b", - time: 1524881438, - mediantime: 1524878499, - nonce: 3326843941, - bits: "1801e8a5", - difficulty: 576023394804.6666, - chainwork: - "00000000000000000000000000000000000000000096da5b040913fa09249b4e", - previousblockhash: - "000000000000000000b33251708bc7a7b4540e61880d8c376e8e2db6a19a4789" - } - - it("should get block header by hash", done => { - const resolved = new Promise(r => r({ data: data })) - sandbox.stub(axios, "get").returns(resolved) - - bchjs.Blockchain.getBlockHeader( - "000000000000000001d127592d091d4c45062504663c9acab27a1b16c028e3c0", - true - ) - .then(result => { - assert.deepEqual(data, result) - }) - .then(done, done) - }) - }) - - describe("#getDifficulty", () => { - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - const data = "577528469277.1339" - - it("should get difficulty", done => { - const resolved = new Promise(r => r({ data: data })) - sandbox.stub(axios, "get").returns(resolved) - - bchjs.Blockchain.getDifficulty() - .then(result => { - assert.deepEqual(data, result) - }) - .then(done, done) - }) - }) - - describe("#getMempoolAncestors", () => { - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - const data = "Transaction not in mempool" - - it("should get mempool ancestors", done => { - const resolved = new Promise(r => r({ data: data })) - sandbox.stub(axios, "get").returns(resolved) - - bchjs.Blockchain.getMempoolAncestors( - "daf58932cb91619304dd4cbd03c7202e89ad7d6cbd6e2209e5f64ce3b6ed7c88", - true - ) - .then(result => { - assert.deepEqual(data, result) - }) - .then(done, done) - }) - }) - - describe("#getMempoolDescendants", () => { - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - const data = { - result: "Transaction not in mempool" - } - - it("should get mempool descendants", done => { - const resolved = new Promise(r => r({ data: data })) - sandbox.stub(axios, "get").returns(resolved) - - bchjs.Blockchain.getMempoolDescendants( - "daf58932cb91619304dd4cbd03c7202e89ad7d6cbd6e2209e5f64ce3b6ed7c88", - true - ) - .then(result => { - assert.deepEqual(data, result) - }) - .then(done, done) - }) - }) - - describe("#getMempoolEntry", () => { - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - const data = { - result: "Transaction not in mempool" - } - - it("should get mempool entry", done => { - const resolved = new Promise(r => r({ data: data })) - sandbox.stub(axios, "get").returns(resolved) - - bchjs.Blockchain.getMempoolEntry( - "daf58932cb91619304dd4cbd03c7202e89ad7d6cbd6e2209e5f64ce3b6ed7c88" - ) - .then(result => { - assert.deepEqual(data, result) - }) - .then(done, done) - }) - }) - - describe("#getMempoolInfo", () => { - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - const data = { - result: { - size: 317, - bytes: 208583, - usage: 554944, - maxmempool: 300000000, - mempoolminfee: 0 - } - } - - it("should get mempool info", done => { - const resolved = new Promise(r => r({ data: data })) - sandbox.stub(axios, "get").returns(resolved) - - bchjs.Blockchain.getMempoolInfo() - .then(result => { - assert.deepEqual(data, result) - }) - .then(done, done) - }) - }) - - describe("#getRawMempool", () => { - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - const data = { - result: { - transactions: [ - { - txid: - "ab36d68dd0a618592fe34e4a898e8beeeb4049133547dbb16f9338384084af96", - size: 191, - fee: 0.00047703, - modifiedfee: 0.00047703, - time: 1524883317, - height: 527811, - startingpriority: 5287822727.272727, - currentpriority: 5287822727.272727, - descendantcount: 1, - descendantsize: 191, - descendantfees: 47703, - ancestorcount: 1, - ancestorsize: 191, - ancestorfees: 47703, - depends: [] - } - ] - } - } - - it("should get mempool info", done => { - const resolved = new Promise(r => r({ data: data })) - sandbox.stub(axios, "get").returns(resolved) - - bchjs.Blockchain.getRawMempool() - .then(result => { - assert.deepEqual(data, result) - }) - .then(done, done) - }) - }) - - describe("#getTxOut", () => { - // TODO finish this test - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - // const data = { - // result: {} - // } - - it("should throw an error for improper txid.", async () => { - try { - await bchjs.Blockchain.getTxOut("badtxid") - } catch (err) { - assert2.include(err.message, "txid needs to be a proper transaction ID") - } - }) - - it("should throw an error if no vout value is provided.", async () => { - try { - await bchjs.Blockchain.getTxOut( - "daf58932cb91619304dd4cbd03c7202e89ad7d6cbd6e2209e5f64ce3b6ed7c88" - ) - } catch (err) { - assert2.include(err.message, "n must be an integer") - } - }) - - it("should throw an error if include_mempool is not a boolean", async () => { - try { - await bchjs.Blockchain.getTxOut( - "daf58932cb91619304dd4cbd03c7202e89ad7d6cbd6e2209e5f64ce3b6ed7c88", - 0, - "bad value" - ) - } catch (err) { - assert2.include( - err.message, - "include_mempool input must be of type boolean" - ) - } - }) - - it("should get information on an unspent tx", async () => { - sandbox.stub(axios, "post").resolves({ data: mockData.txOutUnspent }) - - const result = await bchjs.Blockchain.getTxOut( - "62a3ea958a463a372bc0caf2c374a7f60be9c624be63a0db8db78f05809df6d8", - 0, - true - ) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert2.hasAllKeys(result, [ - "bestblock", - "confirmations", - "value", - "scriptPubKey", - "coinbase" - ]) - }) - - it("should get information on a spent tx", async () => { - sandbox.stub(axios, "post").resolves({ data: null }) - - const result = await bchjs.Blockchain.getTxOut( - "87380e52d151856b23173d6d8a3db01b984c6b50f77ea045a5a1cf4f54497871", - 0, - true - ) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert2.equal(result, null) - }) - }) - - describe("#preciousBlock", () => { - // TODO finish this test - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - const data = { - result: {} - } - - it("should get TODO", done => { - const resolved = new Promise(r => r({ data: data })) - sandbox.stub(axios, "get").returns(resolved) - - bchjs.Blockchain.preciousBlock() - .then(result => { - assert.deepEqual(data, result) - }) - .then(done, done) - }) - }) - - describe("#pruneBlockchain", () => { - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - const data = "Cannot prune blocks because node is not in prune mode." - - it("should prune blockchain", done => { - const resolved = new Promise(r => r({ data: data })) - sandbox.stub(axios, "post").returns(resolved) - - bchjs.Blockchain.pruneBlockchain(507) - .then(result => { - assert.deepEqual(data, result) - }) - .then(done, done) - }) - }) - - describe("#verifyChain", () => { - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - const data = true - - it("should verify blockchain", done => { - const resolved = new Promise(r => r({ data: data })) - sandbox.stub(axios, "get").returns(resolved) - - bchjs.Blockchain.verifyChain(3, 6) - .then(result => { - assert.deepEqual(data, result) - }) - .then(done, done) - }) - }) - - describe("#verifyTxOutProof", () => { - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - const data = "proof must be hexadecimal string (not '')" - - it("should verify utxo proof", done => { - const resolved = new Promise(r => r({ data: data })) - sandbox.stub(axios, "get").returns(resolved) - - bchjs.Blockchain.verifyTxOutProof("3") - .then(result => { - assert.deepEqual(data, result) - }) - .then(done, done) - }) - }) -}) diff --git a/test/unit/control.js b/test/unit/control.js deleted file mode 100644 index 2ec8219..0000000 --- a/test/unit/control.js +++ /dev/null @@ -1,64 +0,0 @@ -const assert = require("assert") -const axios = require("axios") -const BCHJS = require("../../src/bch-js") -const bchjs = new BCHJS() -const sinon = require("sinon") - -describe("#Control", () => { - describe("#getNetworkInfo", () => { - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - - it("should get info", done => { - const data = { - version: 170000, - protocolversion: 70015, - blocks: 527813, - timeoffset: 0, - connections: 21, - proxy: "", - difficulty: 581086703759.5878, - testnet: false, - paytxfee: 0, - relayfee: 0.00001, - errors: "" - } - const resolved = new Promise(r => r({ data: data })) - sandbox.stub(axios, "get").returns(resolved) - - bchjs.Control.getNetworkInfo() - .then(result => { - assert.deepEqual(data, result) - }) - .then(done, done) - }) - }) - - describe("#getMemoryInfo", () => { - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - - it("should get memory info", done => { - const data = { - locked: { - used: 0, - free: 65536, - total: 65536, - locked: 65536, - chunks_used: 0, - chunks_free: 1 - } - } - const resolved = new Promise(r => r({ data: data })) - sandbox.stub(axios, "get").returns(resolved) - - bchjs.Control.getMemoryInfo() - .then(result => { - assert.deepEqual(data, result) - }) - .then(done, done) - }) - }) -}) diff --git a/test/unit/crypto.js b/test/unit/crypto.js deleted file mode 100644 index 73f6d23..0000000 --- a/test/unit/crypto.js +++ /dev/null @@ -1,100 +0,0 @@ -const fixtures = require("./fixtures/crypto.json") -const assert = require("assert") -const BCHJS = require("../../src/bch-js") -const bchjs = new BCHJS() -const Buffer = require("safe-buffer").Buffer - -describe("#Crypto", () => { - describe("#sha256", () => { - fixtures.sha256.forEach(fixture => { - it(`should create SHA256Hash hex encoded ${fixture.hash} from ${fixture.hex}`, () => { - const data = Buffer.from(fixture.hex, "hex") - const sha256Hash = bchjs.Crypto.sha256(data).toString("hex") - assert.equal(sha256Hash, fixture.hash) - }) - - it(`should create 64 character SHA256Hash hex encoded`, () => { - const data = Buffer.from(fixture.hex, "hex") - const sha256Hash = bchjs.Crypto.sha256(data).toString("hex") - assert.equal(sha256Hash.length, 64) - }) - }) - }) - - describe("#ripemd160", () => { - fixtures.ripemd160.forEach(fixture => { - it(`should create RIPEMD160Hash hex encoded ${fixture.hash} from ${fixture.hex}`, () => { - const data = Buffer.from(fixture.hex, "hex") - const ripemd160 = bchjs.Crypto.ripemd160(data).toString("hex") - assert.equal(ripemd160, fixture.hash) - }) - - it(`should create 64 character RIPEMD160Hash hex encoded`, () => { - const data = Buffer.from(fixture.hex, "hex") - const ripemd160 = bchjs.Crypto.ripemd160(data).toString("hex") - assert.equal(ripemd160.length, 40) - }) - }) - }) - - describe("#hash256", () => { - fixtures.hash256.forEach(fixture => { - it(`should create double SHA256 Hash hex encoded ${fixture.hash} from ${fixture.hex}`, () => { - const data = Buffer.from(fixture.hex, "hex") - const hash256 = bchjs.Crypto.hash256(data).toString("hex") - assert.equal(hash256, fixture.hash) - }) - - it(`should create 64 character SHA256 Hash hex encoded`, () => { - const data = Buffer.from(fixture.hex, "hex") - const hash256 = bchjs.Crypto.hash256(data).toString("hex") - assert.equal(hash256.length, 64) - }) - }) - }) - - describe("#hash160", () => { - fixtures.hash160.forEach(fixture => { - it(`should create RIPEMD160(SHA256()) hex encoded ${fixture.hash} from ${fixture.hex}`, () => { - const data = Buffer.from(fixture.hex, "hex") - const hash160 = bchjs.Crypto.hash160(data).toString("hex") - assert.equal(hash160, fixture.hash) - }) - - it(`should create 64 character SHA256Hash hex encoded`, () => { - const data = Buffer.from(fixture.hex, "hex") - const hash160 = bchjs.Crypto.hash160(data).toString("hex") - assert.equal(hash160.length, 40) - }) - }) - }) - - describe("#randomBytes", () => { - for (let i = 0; i < 6; i++) { - it("should return 16 bytes of entropy hex encoded", () => { - const entropy = bchjs.Crypto.randomBytes(16) - assert.equal(Buffer.byteLength(entropy), 16) - }) - - it("should return 20 bytes of entropy hex encoded", () => { - const entropy = bchjs.Crypto.randomBytes(20) - assert.equal(Buffer.byteLength(entropy), 20) - }) - - it("should return 24 bytes of entropy hex encoded", () => { - const entropy = bchjs.Crypto.randomBytes(24) - assert.equal(Buffer.byteLength(entropy), 24) - }) - - it("should return 28 bytes of entropy hex encoded", () => { - const entropy = bchjs.Crypto.randomBytes(28) - assert.equal(Buffer.byteLength(entropy), 28) - }) - - it("should return 32 bytes of entropy hex encoded", () => { - const entropy = bchjs.Crypto.randomBytes(32) - assert.equal(Buffer.byteLength(entropy), 32) - }) - } - }) -}) diff --git a/test/unit/ecpairs.js b/test/unit/ecpairs.js deleted file mode 100644 index d3dbb6f..0000000 --- a/test/unit/ecpairs.js +++ /dev/null @@ -1,146 +0,0 @@ -const assert = require("assert") - -const BCHJS = require("../../src/bch-js") -const bchjs = new BCHJS() - -const Buffer = require("safe-buffer").Buffer - -const fixtures = require("./fixtures/ecpair.json") - -describe("#ECPair", () => { - describe("#fromWIF", () => { - fixtures.fromWIF.forEach(fixture => { - it(`should create ECPair from WIF ${fixture.privateKeyWIF}`, () => { - const ecpair = bchjs.ECPair.fromWIF(fixture.privateKeyWIF) - assert.equal(typeof ecpair, "object") - }) - - it(`should get ${fixture.legacy} legacy address`, () => { - const legacy = bchjs.ECPair.fromWIF(fixture.privateKeyWIF) - assert.equal(bchjs.HDNode.toLegacyAddress(legacy), fixture.legacy) - }) - - it(`should get ${fixture.cashAddr} cash address`, () => { - const cashAddr = bchjs.ECPair.fromWIF(fixture.privateKeyWIF) - assert.equal(bchjs.HDNode.toCashAddress(cashAddr), fixture.cashAddr) - }) - - it(`should get ${fixture.regtestAddr} cash address`, () => { - const cashAddr = bchjs.ECPair.fromWIF(fixture.privateKeyWIF) - assert.equal( - bchjs.HDNode.toCashAddress(cashAddr, true), - fixture.regtestAddr - ) - }) - }) - }) - - describe("#toWIF", () => { - fixtures.toWIF.forEach(fixture => { - it(`should get WIF ${fixture.privateKeyWIF} from ECPair`, () => { - const ecpair = bchjs.ECPair.fromWIF(fixture.privateKeyWIF) - const wif = bchjs.ECPair.toWIF(ecpair) - assert.equal(wif, fixture.privateKeyWIF) - }) - }) - }) - - describe("#fromPublicKey", () => { - fixtures.fromPublicKey.forEach(fixture => { - it(`should create ECPair from public key buffer`, () => { - const ecpair = bchjs.ECPair.fromPublicKey( - Buffer.from(fixture.pubkeyHex, "hex") - ) - assert.equal(typeof ecpair, "object") - }) - - it(`should get ${fixture.legacy} legacy address`, () => { - const ecpair = bchjs.ECPair.fromPublicKey( - Buffer.from(fixture.pubkeyHex, "hex") - ) - assert.equal(bchjs.HDNode.toLegacyAddress(ecpair), fixture.legacy) - }) - - it(`should get ${fixture.cashAddr} cash address`, () => { - const ecpair = bchjs.ECPair.fromPublicKey( - Buffer.from(fixture.pubkeyHex, "hex") - ) - assert.equal(bchjs.HDNode.toCashAddress(ecpair), fixture.cashAddr) - }) - - it(`should get ${fixture.regtestAddr} cash address`, () => { - const ecpair = bchjs.ECPair.fromPublicKey( - Buffer.from(fixture.pubkeyHex, "hex") - ) - assert.equal( - bchjs.HDNode.toCashAddress(ecpair, true), - fixture.regtestAddr - ) - }) - }) - }) - - describe("#toPublicKey", () => { - fixtures.toPublicKey.forEach(fixture => { - it(`should create a public key buffer from an ECPair`, () => { - const ecpair = bchjs.ECPair.fromPublicKey( - Buffer.from(fixture.pubkeyHex, "hex") - ) - const pubkeyBuffer = bchjs.ECPair.toPublicKey(ecpair) - assert.equal(typeof pubkeyBuffer, "object") - }) - }) - }) - - describe("#toLegacyAddress", () => { - fixtures.toLegacyAddress.forEach(fixture => { - it(`should create legacy address ${fixture.legacy} from an ECPair`, () => { - const ecpair = bchjs.ECPair.fromWIF(fixture.privateKeyWIF) - const legacyAddress = bchjs.ECPair.toLegacyAddress(ecpair) - assert.equal(legacyAddress, fixture.legacy) - }) - }) - }) - - describe("#toCashAddress", () => { - fixtures.toCashAddress.forEach(fixture => { - it(`should create cash address ${fixture.cashAddr} from an ECPair`, () => { - const ecpair = bchjs.ECPair.fromWIF(fixture.privateKeyWIF) - const cashAddr = bchjs.ECPair.toCashAddress(ecpair) - assert.equal(cashAddr, fixture.cashAddr) - }) - }) - - fixtures.toCashAddress.forEach(fixture => { - it(`should create regtest cash address ${fixture.regtestAddr} from an ECPair`, () => { - const ecpair = bchjs.ECPair.fromWIF(fixture.privateKeyWIF) - const regtestAddr = bchjs.ECPair.toCashAddress(ecpair, true) - assert.equal(regtestAddr, fixture.regtestAddr) - }) - }) - }) - - describe("#sign", () => { - fixtures.sign.forEach(fixture => { - it(`should sign 32 byte hash buffer`, () => { - const ecpair = bchjs.ECPair.fromWIF(fixture.privateKeyWIF) - const buf = Buffer.from(bchjs.Crypto.sha256(fixture.data), "hex") - const signatureBuf = bchjs.ECPair.sign(ecpair, buf) - assert.equal(typeof signatureBuf, "object") - }) - }) - }) - - describe("#verify", () => { - fixtures.verify.forEach(fixture => { - it(`should verify signed 32 byte hash buffer`, () => { - const ecpair1 = bchjs.ECPair.fromWIF(fixture.privateKeyWIF1) - //const ecpair2 = bchjs.ECPair.fromWIF(fixture.privateKeyWIF2) - const buf = Buffer.from(bchjs.Crypto.sha256(fixture.data), "hex") - const signature = bchjs.ECPair.sign(ecpair1, buf) - const verify = bchjs.ECPair.verify(ecpair1, buf, signature) - assert.equal(verify, true) - }) - }) - }) -}) diff --git a/test/unit/electrumx.js b/test/unit/electrumx.js deleted file mode 100644 index 479d77b..0000000 --- a/test/unit/electrumx.js +++ /dev/null @@ -1,421 +0,0 @@ -const chai = require("chai") -const assert = chai.assert -const axios = require("axios") -const sinon = require("sinon") - -const BCHJS = require("../../src/bch-js") -const bchjs = new BCHJS() - -const mockData = require("./fixtures/electrumx-mock") - -describe(`#ElectrumX`, () => { - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - - describe(`#utxo`, () => { - it(`should throw an error for improper input`, async () => { - try { - const addr = 12345 - - await bchjs.Electrumx.utxo(addr) - assert.equal(true, false, "Unexpected result!") - } catch (err) { - // console.log(`err: `, err) - assert.include( - err.message, - `Input address must be a string or array of strings` - ) - } - }) - - it(`should GET utxos for a single address`, async () => { - // Stub the network call. - sandbox.stub(axios, "get").resolves({ data: mockData.utxo }) - - const addr = "bitcoincash:qqh793x9au6ehvh7r2zflzguanlme760wuzehgzjh9" - - const result = await bchjs.Electrumx.utxo(addr) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.property(result, "success") - assert.equal(result.success, true) - - assert.property(result, "utxos") - assert.isArray(result.utxos) - - 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") - }) - - it(`should POST utxo details for an array of addresses`, async () => { - // Stub the network call. - sandbox.stub(axios, "post").resolves({ data: mockData.utxos }) - - const addr = [ - "bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf", - "bitcoincash:qpdh9s677ya8tnx7zdhfrn8qfyvy22wj4qa7nwqa5v" - ] - - const result = await bchjs.Electrumx.utxo(addr) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.property(result, "success") - assert.equal(result.success, true) - - assert.property(result, "utxos") - assert.isArray(result.utxos) - - assert.property(result.utxos[0], "utxos") - assert.isArray(result.utxos[0].utxos) - assert.property(result.utxos[0], "address") - - 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") - }) - }) - - describe(`#balance`, () => { - it(`should throw an error for improper input`, async () => { - try { - const addr = 12345 - - await bchjs.Electrumx.balance(addr) - assert.equal(true, false, "Unexpected result!") - } catch (err) { - // console.log(`err: `, err) - assert.include( - err.message, - `Input address must be a string or array of strings` - ) - } - }) - - it(`should GET balance for a single address`, async () => { - // Stub the network call. - sandbox.stub(axios, "get").resolves({ data: mockData.balance }) - - const addr = "bitcoincash:qqh793x9au6ehvh7r2zflzguanlme760wuzehgzjh9" - - const result = await bchjs.Electrumx.balance(addr) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.property(result, "success") - assert.equal(result.success, true) - - assert.property(result, "balance") - assert.property(result.balance, "confirmed") - assert.property(result.balance, "unconfirmed") - }) - - it(`should POST balance for an array of addresses`, async () => { - // Stub the network call. - sandbox.stub(axios, "post").resolves({ data: mockData.balances }) - - const addr = [ - "bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf", - "bitcoincash:qpdh9s677ya8tnx7zdhfrn8qfyvy22wj4qa7nwqa5v" - ] - - const result = await bchjs.Electrumx.balance(addr) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.property(result, "success") - assert.equal(result.success, true) - - assert.property(result, "balances") - assert.isArray(result.balances) - - 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") - }) - }) - - describe(`#transactions`, () => { - it(`should throw an error for improper input`, async () => { - try { - const addr = 12345 - - await bchjs.Electrumx.transactions(addr) - assert.equal(true, false, "Unexpected result!") - } catch (err) { - // console.log(`err: `, err) - assert.include( - err.message, - `Input address must be a string or array of strings` - ) - } - }) - - it(`should GET transactions for a single address`, async () => { - // Stub the network call. - sandbox.stub(axios, "get").resolves({ data: mockData.transaction }) - - const addr = "bitcoincash:qqh793x9au6ehvh7r2zflzguanlme760wuzehgzjh9" - - const result = await bchjs.Electrumx.transactions(addr) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.property(result, "success") - assert.equal(result.success, true) - - assert.property(result, "transactions") - assert.isArray(result.transactions) - assert.property(result.transactions[0], "height") - assert.property(result.transactions[0], "tx_hash") - }) - - it(`should POST transaction history for an array of addresses`, async () => { - // Stub the network call. - sandbox.stub(axios, "post").resolves({ data: mockData.transactions }) - - const addr = [ - "bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf", - "bitcoincash:qpdh9s677ya8tnx7zdhfrn8qfyvy22wj4qa7nwqa5v" - ] - - const result = await bchjs.Electrumx.transactions(addr) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.property(result, "success") - assert.equal(result.success, true) - - assert.property(result, "transactions") - assert.isArray(result.transactions) - - assert.property(result.transactions[0], "address") - assert.property(result.transactions[0], "transactions") - assert.isArray(result.transactions[0].transactions) - assert.property(result.transactions[0].transactions[0], "height") - assert.property(result.transactions[0].transactions[0], "tx_hash") - }) - }) - - describe(`#unconfirmed`, () => { - it(`should throw an error for improper input`, async () => { - try { - const addr = 12345 - - await bchjs.Electrumx.unconfirmed(addr) - assert.equal(true, false, "Unexpected result!") - } catch (err) { - // console.log(`err: `, err) - assert.include( - err.message, - `Input address must be a string or array of strings` - ) - } - }) - - it(`should GET unconfirmed utxos for a single address`, async () => { - // Stub the network call. - sandbox.stub(axios, "get").resolves({ data: mockData.unconfirmed }) - - const addr = "bitcoincash:qqh793x9au6ehvh7r2zflzguanlme760wuzehgzjh9" - - const result = await bchjs.Electrumx.unconfirmed(addr) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.property(result, "success") - assert.equal(result.success, true) - - assert.property(result, "utxos") - assert.isArray(result.utxos) - - assert.property(result.utxos[0], "height") - assert.property(result.utxos[0], "tx_hash") - assert.property(result.utxos[0], "fee") - }) - - it(`should POST unconfirmed utxo details for an array of addresses`, async () => { - // Stub the network call. - sandbox.stub(axios, "post").resolves({ data: mockData.unconfirmedArray }) - - const addr = [ - "bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf", - "bitcoincash:qpdh9s677ya8tnx7zdhfrn8qfyvy22wj4qa7nwqa5v" - ] - - const result = await bchjs.Electrumx.unconfirmed(addr) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.property(result, "success") - assert.equal(result.success, true) - - assert.property(result, "utxos") - assert.isArray(result.utxos) - - assert.property(result.utxos[0], "utxos") - assert.isArray(result.utxos[0].utxos) - assert.property(result.utxos[0], "address") - - 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") - }) - }) - - describe(`#blockHeader`, () => { - it(`should throw an error for improper height input`, async () => { - try { - // Mock network calls. - sandbox.stub(axios, "get").rejects({ - response: { - data: { - success: false, - error: "height must be a positive number" - } - } - }) - - const height = -10 - await bchjs.Electrumx.blockHeader(height) - - assert.equal(true, false, "Unexpected result!") - } catch (err) { - // console.log(`err: `, err) - assert.include(err.message, `height must be a positive number`) - } - }) - - it(`should throw an error for improper count input`, async () => { - try { - // Mock network calls. - sandbox.stub(axios, "get").rejects({ - response: { - data: { - success: false, - error: "count must be a positive number" - } - } - }) - - const height = 42 - const count = -10 - - await bchjs.Electrumx.blockHeader(height, count) - assert.equal(true, false, "Unexpected result!") - } catch (err) { - // console.log(`err: `, err) - assert.include(err.message, `count must be a positive number`) - } - }) - - it(`should GET block headers for a given height`, async () => { - // Stub the network call. - 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) - }) - }) - - describe(`#txData`, () => { - it(`should throw an error for improper input`, async () => { - try { - const txid = 12345 - - await bchjs.Electrumx.txData(txid) - assert.equal(true, false, "Unexpected result!") - } catch (err) { - // console.log(`err: `, err) - assert.include( - err.message, - `Input txId must be a string or array of strings` - ) - } - }) - - it(`should GET details data for a single transaction`, async () => { - // Stub the network call. - sandbox.stub(axios, "get").resolves({ data: mockData.details }) - - const txid = - "4db095f34d632a4daf942142c291f1f2abb5ba2e1ccac919d85bdc2f671fb251" - - const result = await bchjs.Electrumx.txData(txid) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.property(result, "success") - assert.equal(result.success, true) - - assert.property(result, "details") - assert.isObject(result.details) - - 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) - }) - - it(`should POST details for an array of transactions`, async () => { - // Stub the network call. - sandbox.stub(axios, "post").resolves({ data: mockData.detailsArray }) - - const txids = [ - "4db095f34d632a4daf942142c291f1f2abb5ba2e1ccac919d85bdc2f671fb251", - "4db095f34d632a4daf942142c291f1f2abb5ba2e1ccac919d85bdc2f671fb251" - ] - - const result = await bchjs.Electrumx.txData(txids) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.property(result, "success") - assert.equal(result.success, true) - - assert.property(result, "transactions") - assert.isArray(result.transactions) - - assert.property(result.transactions[0], "txid") - assert.property(result.transactions[0], "details") - - 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") - - assert.equal(result.transactions.length, 2, "2 outputs for 2 inputs") - }) - }) - describe(`#broadcast`, () => { - it(`should throw an error for improper input`, async () => { - try { - const txHex = 12345 - - await bchjs.Electrumx.broadcast(txHex) - assert.equal(true, false, "Unexpected result!") - } catch (err) { - // console.log(`err: `, err) - assert.include(err.message, `Input txHex must be a string.`) - } - }) - it(`should broadcast a single transaction`, async () => { - // Stub the network call. - sandbox.stub(axios, "post").resolves({ data: mockData.broadcast }) - - 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)}`) - - assert.property(result, "success") - assert.equal(result.success, true) - - assert.property(result, "txid") - assert.equal(result.txid, txid) - }) - }) -}) diff --git a/test/unit/encryption.js b/test/unit/encryption.js deleted file mode 100644 index 9242348..0000000 --- a/test/unit/encryption.js +++ /dev/null @@ -1,68 +0,0 @@ -const assert = require("chai").assert -const sinon = require("sinon") - -const BCHJS = require("../../src/bch-js") -// const bchjs = new BCHJS() -let bchjs - -const mockData = require("./fixtures/encryption-mock") - -describe("#Encryption", () => { - let sandbox - - beforeEach(() => { - bchjs = new BCHJS() - sandbox = sinon.createSandbox() - }) - - afterEach(() => sandbox.restore()) - - describe("#getPubKey", () => { - it("should throw error if BCH address is not provided.", async () => { - try { - await bchjs.encryption.getPubKey() - - assert.equal(true, false, "Unexpected result!") - } catch (err) { - // console.log(`err: `, err) - assert.include( - err.message, - "Input must be a valid Bitcoin Cash address" - ) - } - }) - - it("should report when public key can not be found", async () => { - // Stub the network call. - sandbox - .stub(bchjs.encryption.axios, "get") - .resolves({ data: mockData.failureMock }) - - const addr = "bitcoincash:qpxqr2pmcverj4vukgjqssvk2zju8tp9xsgz2nqagx" - - const result = await bchjs.encryption.getPubKey(addr) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.property(result, "success") - assert.equal(result.success, false) - assert.property(result, "publicKey") - assert.equal(result.publicKey, "not found") - }) - - it("should get a public key", async () => { - // Stub the network call. - sandbox - .stub(bchjs.encryption.axios, "get") - .resolves({ data: mockData.successMock }) - - const addr = "bitcoincash:qpf8jv9hmqcda0502gjp7nm3g24y5h5s4unutghsxq" - - const result = await bchjs.encryption.getPubKey(addr) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.property(result, "success") - assert.equal(result.success, true) - assert.property(result, "publicKey") - }) - }) -}) diff --git a/test/unit/generating.js b/test/unit/generating.js deleted file mode 100644 index 8937467..0000000 --- a/test/unit/generating.js +++ /dev/null @@ -1,28 +0,0 @@ -const assert = require("assert") -const axios = require("axios") -const BCHJS = require("../../src/bch-js") -const bchjs = new BCHJS() -const sinon = require("sinon") - -describe("#Generating", () => { - describe("#generateToAddress", () => { - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - - it("should generate", done => { - const data = [] - const resolved = new Promise(r => r({ data: data })) - sandbox.stub(axios, "post").returns(resolved) - - bchjs.Generating.generateToAddress( - 1, - "bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf" - ) - .then(result => { - assert.deepEqual(data, result) - }) - .then(done, done) - }) - }) -}) diff --git a/test/unit/hdnode.js b/test/unit/hdnode.js deleted file mode 100644 index 44c105f..0000000 --- a/test/unit/hdnode.js +++ /dev/null @@ -1,345 +0,0 @@ -const fixtures = require("./fixtures/hdnode.json") -const slpFixtures = require("./fixtures/slp/address.json") -const assert = require("assert") -const BCHJS = require("../../src/bch-js") -const bchjs = new BCHJS() -const Buffer = require("safe-buffer").Buffer - -describe("#HDNode", () => { - describe("#fromSeed", () => { - fixtures.fromSeed.forEach(mnemonic => { - it(`should create an HDNode from root seed buffer`, async () => { - const rootSeedBuffer = await bchjs.Mnemonic.toSeed(mnemonic) - const hdNode = bchjs.HDNode.fromSeed(rootSeedBuffer) - assert.notEqual(hdNode, null) - }) - }) - }) - - describe("#derive", () => { - fixtures.derive.forEach(derive => { - it(`should derive non hardened child HDNode`, async () => { - const rootSeedBuffer = await bchjs.Mnemonic.toSeed(derive.mnemonic) - const hdNode = bchjs.HDNode.fromSeed(rootSeedBuffer) - const childHDNode = bchjs.HDNode.derive(hdNode, 0) - assert.equal(bchjs.HDNode.toXPub(childHDNode), derive.xpub) - assert.equal(bchjs.HDNode.toXPriv(childHDNode), derive.xpriv) - }) - }) - }) - - describe("#deriveHardened", () => { - fixtures.deriveHardened.forEach(derive => { - it(`should derive hardened child HDNode`, async () => { - const rootSeedBuffer = await bchjs.Mnemonic.toSeed(derive.mnemonic) - const hdNode = bchjs.HDNode.fromSeed(rootSeedBuffer) - const childHDNode = bchjs.HDNode.deriveHardened(hdNode, 0) - assert.equal(bchjs.HDNode.toXPub(childHDNode), derive.xpub) - assert.equal(bchjs.HDNode.toXPriv(childHDNode), derive.xpriv) - }) - }) - - describe("derive BIP44 $BCH account", () => { - fixtures.deriveBIP44.forEach(derive => { - it(`should derive BIP44 $BCH account`, async () => { - const rootSeedBuffer = await bchjs.Mnemonic.toSeed(derive.mnemonic) - const hdNode = bchjs.HDNode.fromSeed(rootSeedBuffer) - const purpose = bchjs.HDNode.deriveHardened(hdNode, 44) - const coin = bchjs.HDNode.deriveHardened(purpose, 145) - const childHDNode = bchjs.HDNode.deriveHardened(coin, 0) - assert.equal(bchjs.HDNode.toXPub(childHDNode), derive.xpub) - assert.equal(bchjs.HDNode.toXPriv(childHDNode), derive.xpriv) - }) - }) - }) - }) - - describe("#derivePath", () => { - describe("derive non hardened Path", () => { - fixtures.derivePath.forEach(derive => { - it(`should derive non hardened child HDNode from path`, async () => { - const rootSeedBuffer = await bchjs.Mnemonic.toSeed(derive.mnemonic) - const hdNode = bchjs.HDNode.fromSeed(rootSeedBuffer) - const childHDNode = bchjs.HDNode.derivePath(hdNode, "0") - assert.equal(bchjs.HDNode.toXPub(childHDNode), derive.xpub) - assert.equal(bchjs.HDNode.toXPriv(childHDNode), derive.xpriv) - }) - }) - }) - - describe("derive hardened Path", () => { - fixtures.deriveHardenedPath.forEach(derive => { - it(`should derive hardened child HDNode from path`, async () => { - const rootSeedBuffer = await bchjs.Mnemonic.toSeed(derive.mnemonic) - const hdNode = bchjs.HDNode.fromSeed(rootSeedBuffer) - const childHDNode = bchjs.HDNode.derivePath(hdNode, "0'") - assert.equal(bchjs.HDNode.toXPub(childHDNode), derive.xpub) - assert.equal(bchjs.HDNode.toXPriv(childHDNode), derive.xpriv) - }) - }) - }) - - describe("derive BIP44 $BCH account", () => { - fixtures.deriveBIP44.forEach(derive => { - it(`should derive BIP44 $BCH account`, async () => { - const rootSeedBuffer = await bchjs.Mnemonic.toSeed(derive.mnemonic) - const hdNode = bchjs.HDNode.fromSeed(rootSeedBuffer) - const childHDNode = bchjs.HDNode.derivePath(hdNode, "44'/145'/0'") - assert.equal(bchjs.HDNode.toXPub(childHDNode), derive.xpub) - assert.equal(bchjs.HDNode.toXPriv(childHDNode), derive.xpriv) - }) - }) - }) - }) - - describe("#toLegacyAddress", () => { - fixtures.toLegacyAddress.forEach(fixture => { - it(`should get address ${fixture.address} from HDNode`, async () => { - const rootSeedBuffer = await bchjs.Mnemonic.toSeed(fixture.mnemonic) - const hdNode = bchjs.HDNode.fromSeed(rootSeedBuffer) - const childHDNode = bchjs.HDNode.derivePath(hdNode, "0") - const addy = bchjs.HDNode.toLegacyAddress(childHDNode) - assert.equal(addy, fixture.address) - }) - }) - }) - - describe("#toCashAddress", () => { - fixtures.toCashAddress.forEach(fixture => { - it(`should get address ${fixture.address} from HDNode`, async () => { - const rootSeedBuffer = await bchjs.Mnemonic.toSeed(fixture.mnemonic) - const hdNode = bchjs.HDNode.fromSeed(rootSeedBuffer) - const childHDNode = bchjs.HDNode.derivePath(hdNode, "0") - const addy = bchjs.HDNode.toCashAddress(childHDNode) - assert.equal(addy, fixture.address) - }) - - it(`should get address ${fixture.regtestAddress} from HDNode`, async () => { - const rootSeedBuffer = await bchjs.Mnemonic.toSeed(fixture.mnemonic) - const hdNode = bchjs.HDNode.fromSeed(rootSeedBuffer) - const childHDNode = bchjs.HDNode.derivePath(hdNode, "0") - const addr = bchjs.HDNode.toCashAddress(childHDNode, true) - assert.equal(addr, fixture.regtestAddress) - }) - }) - }) - - describe("#toWIF", () => { - fixtures.toWIF.forEach(fixture => { - it(`should get privateKeyWIF ${fixture.privateKeyWIF} from HDNode`, () => { - const hdNode = bchjs.HDNode.fromXPriv(fixture.xpriv) - assert.equal(bchjs.HDNode.toWIF(hdNode), fixture.privateKeyWIF) - }) - }) - }) - - describe("#toXPub", () => { - fixtures.toXPub.forEach(fixture => { - it(`should create xpub ${fixture.xpub} from an HDNode`, async () => { - const rootSeedBuffer = await bchjs.Mnemonic.toSeed(fixture.mnemonic) - const hdNode = bchjs.HDNode.fromSeed(rootSeedBuffer) - const xpub = bchjs.HDNode.toXPub(hdNode) - assert.equal(xpub, fixture.xpub) - }) - }) - }) - - describe("#toXPriv", () => { - fixtures.toXPriv.forEach(fixture => { - it(`should create xpriv ${fixture.xpriv} from an HDNode`, async () => { - const rootSeedBuffer = await bchjs.Mnemonic.toSeed(fixture.mnemonic) - const hdNode = bchjs.HDNode.fromSeed(rootSeedBuffer) - const xpriv = bchjs.HDNode.toXPriv(hdNode) - assert.equal(xpriv, fixture.xpriv) - }) - }) - }) - - describe("#toKeyPair", () => { - fixtures.toKeyPair.forEach(fixture => { - it(`should get ECPair from an HDNode`, async () => { - const rootSeedBuffer = await bchjs.Mnemonic.toSeed(fixture.mnemonic) - const hdNode = bchjs.HDNode.fromSeed(rootSeedBuffer) - const keyPair = bchjs.HDNode.toKeyPair(hdNode) - assert.equal(typeof keyPair, "object") - }) - }) - }) - - describe("#toPublicKey", () => { - fixtures.toPublicKey.forEach(fixture => { - it(`should create public key buffer from an HDNode`, async () => { - const rootSeedBuffer = await bchjs.Mnemonic.toSeed(fixture.mnemonic) - const hdNode = bchjs.HDNode.fromSeed(rootSeedBuffer) - const publicKeyBuffer = bchjs.HDNode.toPublicKey(hdNode) - assert.equal(typeof publicKeyBuffer, "object") - }) - }) - }) - - describe("#fromXPriv", () => { - fixtures.fromXPriv.forEach(fixture => { - const hdNode = bchjs.HDNode.fromXPriv(fixture.xpriv) - it(`should create HDNode from xpriv ${fixture.xpriv}`, () => { - assert.notEqual(hdNode, null) - }) - - it(`should export xpriv ${fixture.xpriv}`, () => { - assert.equal(bchjs.HDNode.toXPriv(hdNode), fixture.xpriv) - }) - - it(`should export xpub ${fixture.xpub}`, () => { - assert.equal(bchjs.HDNode.toXPub(hdNode), fixture.xpub) - }) - - it(`should export legacy address ${fixture.legacy}`, () => { - assert.equal(bchjs.HDNode.toLegacyAddress(hdNode), fixture.legacy) - }) - - it(`should export cashaddress ${fixture.cashaddress}`, () => { - assert.equal(bchjs.HDNode.toCashAddress(hdNode), fixture.cashaddress) - }) - - it(`should export regtest cashaddress ${fixture.regtestaddress}`, () => { - assert.equal( - bchjs.HDNode.toCashAddress(hdNode, true), - fixture.regtestaddress - ) - }) - - it(`should export privateKeyWIF ${fixture.privateKeyWIF}`, () => { - assert.equal(bchjs.HDNode.toWIF(hdNode), fixture.privateKeyWIF) - }) - }) - }) - - describe("#fromXPub", () => { - fixtures.fromXPub.forEach(fixture => { - const hdNode = bchjs.HDNode.fromXPub(fixture.xpub) - it(`should create HDNode from xpub ${fixture.xpub}`, () => { - assert.notEqual(hdNode, null) - }) - - it(`should export xpub ${fixture.xpub}`, () => { - assert.equal(bchjs.HDNode.toXPub(hdNode), fixture.xpub) - }) - - it(`should export legacy address ${fixture.legacy}`, () => { - assert.equal(bchjs.HDNode.toLegacyAddress(hdNode), fixture.legacy) - }) - - it(`should export cashaddress ${fixture.cashaddress}`, () => { - assert.equal(bchjs.HDNode.toCashAddress(hdNode), fixture.cashaddress) - }) - - it(`should export regtest cashaddress ${fixture.regtestaddress}`, () => { - assert.equal( - bchjs.HDNode.toCashAddress(hdNode, true), - fixture.regtestaddress - ) - }) - }) - }) - - describe("#bip32", () => { - describe("create accounts and addresses", () => { - fixtures.accounts.forEach(async fixture => { - const seedBuffer = await bchjs.Mnemonic.toSeed(fixture.mnemonic) - console.log(`seedBuffer: ${seedBuffer.toString()}`) - const hdNode = bchjs.HDNode.fromSeed(seedBuffer) - const a = bchjs.HDNode.derivePath(hdNode, "0'") - const external = bchjs.HDNode.derivePath(a, "0") - const account = bchjs.HDNode.createAccount([external]) - - it(`#createAccount`, () => { - assert.notEqual(account, null) - }) - - describe("#getChainAddress", () => { - const external1 = bchjs.Address.toCashAddress( - account.getChainAddress(0) - ) - it(`should create external change address ${external1}`, () => { - assert.equal(external1, fixture.externals[0]) - }) - }) - - describe("#nextChainAddress", () => { - for (let i = 0; i < 4; i++) { - const ex = bchjs.Address.toCashAddress(account.nextChainAddress(0)) - it(`should create external change address ${ex}`, () => { - assert.equal(ex, fixture.externals[i + 1]) - }) - } - }) - }) - }) - }) - - describe("#sign", () => { - fixtures.sign.forEach(fixture => { - it(`should sign 32 byte hash buffer`, () => { - const hdnode = bchjs.HDNode.fromXPriv(fixture.privateKeyWIF) - const buf = Buffer.from(bchjs.Crypto.sha256(fixture.data), "hex") - const signatureBuf = bchjs.HDNode.sign(hdnode, buf) - assert.equal(typeof signatureBuf, "object") - }) - }) - }) - - describe("#verify", () => { - fixtures.verify.forEach(fixture => { - it(`should verify signed 32 byte hash buffer`, () => { - const hdnode1 = bchjs.HDNode.fromXPriv(fixture.privateKeyWIF1) - const buf = Buffer.from(bchjs.Crypto.sha256(fixture.data), "hex") - const signature = bchjs.HDNode.sign(hdnode1, buf) - const verify = bchjs.HDNode.verify(hdnode1, buf, signature) - assert.equal(verify, true) - }) - }) - }) - - describe("#isPublic", () => { - fixtures.isPublic.forEach(fixture => { - it(`should verify hdnode is public`, () => { - const node = bchjs.HDNode.fromXPub(fixture.xpub) - assert.equal(bchjs.HDNode.isPublic(node), true) - }) - }) - - fixtures.isPublic.forEach(fixture => { - it(`should verify hdnode is not public`, () => { - const node = bchjs.HDNode.fromXPriv(fixture.xpriv) - assert.equal(bchjs.HDNode.isPublic(node), false) - }) - }) - }) - - describe("#isPrivate", () => { - fixtures.isPrivate.forEach(fixture => { - it(`should verify hdnode is not private`, () => { - const node = bchjs.HDNode.fromXPub(fixture.xpub) - assert.equal(bchjs.HDNode.isPrivate(node), false) - }) - }) - - fixtures.isPrivate.forEach(fixture => { - it(`should verify hdnode is private`, () => { - const node = bchjs.HDNode.fromXPriv(fixture.xpriv) - assert.equal(bchjs.HDNode.isPrivate(node), true) - }) - }) - }) - - describe("#toIdentifier", () => { - fixtures.toIdentifier.forEach(fixture => { - it(`should get identifier of hdnode`, () => { - const node = bchjs.HDNode.fromXPriv(fixture.xpriv) - const publicKeyBuffer = bchjs.HDNode.toPublicKey(node) - const hash160 = bchjs.Crypto.hash160(publicKeyBuffer) - const identifier = bchjs.HDNode.toIdentifier(node) - assert.equal(identifier.toString("hex"), hash160.toString("hex")) - }) - }) - }) -}) diff --git a/test/unit/ipfs.js b/test/unit/ipfs.js deleted file mode 100644 index 3c6ea3d..0000000 --- a/test/unit/ipfs.js +++ /dev/null @@ -1,443 +0,0 @@ -/* - Unit tests for the IPFS Class. -*/ - -const assert = require("chai").assert -const sinon = require("sinon") -const BCHJS = require("../../src/bch-js") -let bchjs - -const mockData = require("./fixtures/ipfs-mock") - -describe(`#IPFS`, () => { - let sandbox - - beforeEach(() => { - sandbox = sinon.createSandbox() - - bchjs = new BCHJS() - }) - - afterEach(() => sandbox.restore()) - - describe("#initUppy", () => { - it("should initialize uppy", () => { - bchjs.IPFS.initUppy() - }) - }) - - describe("#createFileModelServer", () => { - it("should throw an error if file does not exist", async () => { - try { - const path = "/non-existant-file" - - await bchjs.IPFS.createFileModelServer(path) - - assert.equal(true, false, "Unexpected result") - } catch (err) { - //console.log(`err.message: ${err.message}`) - assert.include(err.message, `Could not find this file`) - } - }) - - it("should create a new file model", async () => { - const path = `${__dirname}/ipfs.js` - - sandbox - .stub(bchjs.IPFS.axios, "post") - .resolves({ data: mockData.mockNewFileModel }) - - const result = await bchjs.IPFS.createFileModelServer(path) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.property(result, "success") - assert.equal(result.success, true) - - assert.property(result, "hostingCostBCH") - assert.property(result, "hostingCostUSD") - assert.property(result, "file") - - assert.property(result.file, "payloadLink") - assert.property(result.file, "hasBeenPaid") - assert.property(result.file, "_id") - assert.property(result.file, "schemaVersion") - assert.property(result.file, "size") - assert.property(result.file, "fileName") - assert.property(result.file, "fileExtension") - assert.property(result.file, "createdTimestamp") - assert.property(result.file, "hostingCost") - assert.property(result.file, "walletIndex") - assert.property(result.file, "bchAddr") - }) - }) - - describe("#uploadFileServer", () => { - it("should throw an error if file does not exist", async () => { - try { - const path = "/non-existant-file" - - await bchjs.IPFS.uploadFileServer(path) - - assert.equal(true, false, "Unexpected result") - } catch (err) { - //console.log(`err.message: ${err.message}`) - assert.include(err.message, `Could not find this file`) - } - }) - - it("should throw an error if modelId is not included", async () => { - try { - const path = `${__dirname}/ipfs.js` - - await bchjs.IPFS.uploadFileServer(path) - - assert.equal(true, false, "Unexpected result") - } catch (err) { - //console.log(`err.message: ${err.message}`) - assert.include(err.message, `Must include a file model ID`) - } - }) - - it("Should throw error if the file was not uploaded", async () => { - try { - const mock = { - successful: [], - failed: [ - { - id: "file id" - } - ] - } - sandbox.stub(bchjs.IPFS.uppy, "upload").resolves(mock) - - const path = `${__dirname}/ipfs.js` - await bchjs.IPFS.uploadFileServer(path, "5ec562319bfacc745e8d8a52") - - assert.equal(true, false, "Unexpected result") - } catch (err) { - //console.log(err) - assert.include(err.message, `The file could not be uploaded`) - } - }) - - it("should return file object if the file is uploaded", async () => { - try { - sandbox.stub(bchjs.IPFS.uppy, "upload").resolves(mockData.uploadData) - - const path = `${__dirname}/ipfs.js` - const result = await bchjs.IPFS.uploadFileServer( - path, - "5ec562319bfacc745e8d8a52" - ) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.property(result, "schemaVersion") - assert.property(result, "size") - assert.property(result, "fileId") - assert.property(result, "fileName") - assert.property(result, "fileExtension") - } catch (err) { - //console.log(err) - assert.equal(true, false, "Unexpected result") - } - }) - }) - - describe("#getStatus", () => { - it("should throw an error if modelId is not included", async () => { - try { - await bchjs.IPFS.getStatus() - - assert.equal(true, false, "Unexpected result") - } catch (err) { - //console.log(`err.message: ${err.message}`) - assert.include(err.message, `Must include a file model ID`) - } - }) - - it("should get data on an unpaid file", async () => { - const modelId = "5ec7392c2acfe57aa62e945a" - - sandbox - .stub(bchjs.IPFS.axios, "get") - .resolves({ data: mockData.unpaidFileData }) - - const result = await bchjs.IPFS.getStatus(modelId) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.property(result, "hasBeenPaid") - assert.property(result, "satCost") - assert.property(result, "bchAddr") - assert.property(result, "ipfsHash") - assert.property(result, "fileId") - assert.property(result, "fileName") - }) - - it("should get data on an unpaid file", async () => { - const modelId = "5ec7392c2acfe57aa62e945a" - - sandbox - .stub(bchjs.IPFS.axios, "get") - .resolves({ data: mockData.paidFileData }) - - const result = await bchjs.IPFS.getStatus(modelId) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.property(result, "hasBeenPaid") - assert.property(result, "satCost") - assert.property(result, "bchAddr") - assert.property(result, "ipfsHash") - assert.property(result, "fileId") - assert.property(result, "fileName") - }) - }) - - describe("#createFileModelWeb", () => { - it("should throw an error if file is undefined", async () => { - try { - let file - - await bchjs.IPFS.createFileModelWeb(file) - - assert.equal(true, false, "Unexpected result") - } catch (err) { - //console.log(`err.message: ${err.message}`) - assert.include(err.message, `File is required`) - } - }) - it("should throw an error if file is empty", async () => { - try { - const file = {} - - await bchjs.IPFS.createFileModelWeb(file) - - assert.equal(true, false, "Unexpected result") - } catch (err) { - //console.log(`err.message: ${err.message}`) - assert.include( - err.message, - `File should have the property 'name' of string type` - ) - } - }) - it("should throw an error if 'name' property is not included", async () => { - try { - const file = { - size: 5000 - } - - await bchjs.IPFS.createFileModelWeb(file) - - assert.equal(true, false, "Unexpected result") - } catch (err) { - //console.log(`err.message: ${err.message}`) - assert.include( - err.message, - `File should have the property 'name' of string type` - ) - } - }) - - it("should throw an error if 'size' property is not included", async () => { - try { - const file = { - name: "ipfs.js" - } - - await bchjs.IPFS.createFileModelWeb(file) - - assert.equal(true, false, "Unexpected result") - } catch (err) { - //console.log(`err.message: ${err.message}`) - assert.include( - err.message, - `File should have the property 'size' of number type` - ) - } - }) - - it("should create a new file model", async () => { - const file = { - name: "ipfs.js", - size: 5000, - type: "text/plain" - } - sandbox - .stub(bchjs.IPFS.axios, "post") - .resolves({ data: mockData.mockNewFileModel }) - - const result = await bchjs.IPFS.createFileModelWeb(file) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.property(result, "success") - assert.equal(result.success, true) - - assert.property(result, "hostingCostBCH") - assert.property(result, "hostingCostUSD") - assert.property(result, "file") - - assert.property(result.file, "payloadLink") - assert.property(result.file, "hasBeenPaid") - assert.property(result.file, "_id") - assert.property(result.file, "schemaVersion") - assert.property(result.file, "size") - assert.property(result.file, "fileName") - assert.property(result.file, "fileExtension") - assert.property(result.file, "createdTimestamp") - assert.property(result.file, "hostingCost") - assert.property(result.file, "walletIndex") - assert.property(result.file, "bchAddr") - }) - }) - - describe("#uploadFileWeb", () => { - it("should throw an error if file is undefined", async () => { - try { - let file - - await bchjs.IPFS.uploadFileWeb(file) - - assert.equal(true, false, "Unexpected result") - } catch (err) { - //console.log(`err.message: ${err.message}`) - assert.include(err.message, `File is required`) - } - }) - it("should throw an error if file is empty", async () => { - try { - const file = {} - - await bchjs.IPFS.uploadFileWeb(file) - - assert.equal(true, false, "Unexpected result") - } catch (err) { - //console.log(`err.message: ${err.message}`) - assert.include( - err.message, - `File should have the property 'name' of string type` - ) - } - }) - it("should throw an error if 'name' property is not included", async () => { - try { - const file = { - size: 5000, - type: "text/plain" - } - - await bchjs.IPFS.uploadFileWeb(file) - - assert.equal(true, false, "Unexpected result") - } catch (err) { - //console.log(`err.message: ${err.message}`) - assert.include( - err.message, - `File should have the property 'name' of string type` - ) - } - }) - it("should throw an error if 'size' property is not included", async () => { - try { - const file = { - name: "ipfs.js", - type: "text/plain" - } - - await bchjs.IPFS.uploadFileWeb(file) - - assert.equal(true, false, "Unexpected result") - } catch (err) { - //console.log(`err.message: ${err.message}`) - assert.include( - err.message, - `File should have the property 'size' of number type` - ) - } - }) - it("should throw an error if 'type' property is not included", async () => { - try { - const file = { - name: "ipfs.js", - size: 5000 - } - - await bchjs.IPFS.uploadFileWeb(file) - - assert.equal(true, false, "Unexpected result") - } catch (err) { - //console.log(`err.message: ${err.message}`) - assert.include( - err.message, - `File should have the property 'type' of string type` - ) - } - }) - it("should throw an error if modelId is not included", async () => { - try { - const file = { - name: "ipfs.js", - size: 5000, - type: "text/plain" - } - await bchjs.IPFS.uploadFileWeb(file) - - assert.equal(true, false, "Unexpected result") - } catch (err) { - //console.log(`err.message: ${err.message}`) - assert.include(err.message, `Must include a file model ID`) - } - }) - - it("Should throw error if the file was not uploaded", async () => { - try { - const mock = { - successful: [], - failed: [ - { - id: "file id" - } - ] - } - sandbox.stub(bchjs.IPFS.uppy, "upload").resolves(mock) - - const file = { - name: "ipfs.js", - size: 5000, - type: "text/plain" - } - await bchjs.IPFS.uploadFileWeb(file, "5ec562319bfacc745e8d8a52") - - assert.equal(true, false, "Unexpected result") - } catch (err) { - //console.log(err) - assert.include(err.message, `The file could not be uploaded`) - } - }) - - it("should return file object if the file is uploaded", async () => { - try { - sandbox.stub(bchjs.IPFS.uppy, "upload").resolves(mockData.uploadData) - - const file = { - name: "ipfs.js", - size: 5000, - type: "text/plain" - } - const result = await bchjs.IPFS.uploadFileWeb( - file, - "5ec562319bfacc745e8d8a52" - ) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.property(result, "schemaVersion") - assert.property(result, "size") - assert.property(result, "fileId") - assert.property(result, "fileName") - assert.property(result, "fileExtension") - } catch (err) { - //console.log(err) - assert.equal(true, false, "Unexpected result") - } - }) - }) -}) diff --git a/test/unit/mining.js b/test/unit/mining.js deleted file mode 100644 index 1586397..0000000 --- a/test/unit/mining.js +++ /dev/null @@ -1,104 +0,0 @@ -const assert = require("assert") -const axios = require("axios") -const BCHJS = require("../../src/bch-js") -const bchjs = new BCHJS() -const sinon = require("sinon") - -describe("#Mining", () => { - describe("#getBlockTemplate", () => { - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - - it("should get block template", done => { - const data = { - data: - "01000000017f6305e3b0b05f5b57a82f4e6d4187e148bbe56a947208390e488bad36472368000000006a47304402203b0079ff5b896187feb02e2679c87ac2fb8d483b60e0721ed33601e2c0eecc700220590f8a0e1a51b53b368294861fd5fc99db3a6607d0f4e543f6217108e208c1834121024c93c841d7f576584ffbf513b7abd8283e6562669905f6554f788fce4cc67a34ffffffff0228100000000000001976a914af78709a76abc8a28e568c9210c8247dd10cff2c88ac22020000000000001976a914f339927678803f451b41400737e7dc83c6a8682188ac00000000", - txid: - "7f462d71c649a0d8cfbaa2d20d8ff86677966b308f0ac9906ee015bf4453f97a", - hash: - "7f462d71c649a0d8cfbaa2d20d8ff86677966b308f0ac9906ee015bf4453f97a", - depends: [], - fee: 226, - sigops: 2 - } - - const resolved = new Promise(r => r({ data: data })) - sandbox.stub(axios, "get").returns(resolved) - - bchjs.Mining.getBlockTemplate("") - .then(result => { - assert.deepEqual(data, result) - }) - .then(done, done) - }) - }) - - describe("#getMiningInfo", () => { - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - - it("should get mining info", done => { - const data = { - blocks: 527816, - currentblocksize: 89408, - currentblocktx: 156, - difficulty: 568757800682.7649, - blockprioritypercentage: 5, - errors: "", - networkhashps: 4347259225696976000, - pooledtx: 184, - chain: "main" - } - - const resolved = new Promise(r => r({ data: data })) - sandbox.stub(axios, "get").returns(resolved) - - bchjs.Mining.getMiningInfo() - .then(result => { - assert.deepEqual(data, result) - }) - .then(done, done) - }) - }) - - describe("#getNetworkHashps", () => { - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - - it("should get network hashps", done => { - const data = 3586365937646890000 - - const resolved = new Promise(r => r({ data: data })) - sandbox.stub(axios, "get").returns(resolved) - - bchjs.Mining.getNetworkHashps() - .then(result => { - assert.equal(data, result) - }) - .then(done, done) - }) - }) - - describe("#submitBlock", () => { - // TODO finish - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - - it("should TODO", done => { - const data = {} - - const resolved = new Promise(r => r({ data: data })) - sandbox.stub(axios, "post").returns(resolved) - - bchjs.Mining.submitBlock() - .then(result => { - assert.deepEqual(data, result) - }) - .then(done, done) - }) - }) -}) diff --git a/test/unit/mnemonic.js b/test/unit/mnemonic.js deleted file mode 100644 index 2028653..0000000 --- a/test/unit/mnemonic.js +++ /dev/null @@ -1,340 +0,0 @@ -const fixtures = require("./fixtures/mnemonic.json") -const assert = require("assert") -const BCHJS = require("../../src/bch-js") -const bchjs = new BCHJS() - -describe("#Mnemonic", () => { - describe("#generate", () => { - it("should generate a 12 word mnemonic", () => { - const mnemonic = bchjs.Mnemonic.generate(128) - assert.equal(mnemonic.split(" ").length, 12) - }) - - it("should generate a 15 word mnemonic", () => { - const mnemonic = bchjs.Mnemonic.generate(160) - assert.equal(mnemonic.split(" ").length, 15) - }) - - it("should generate a 18 word mnemonic", () => { - const mnemonic = bchjs.Mnemonic.generate(192) - assert.equal(mnemonic.split(" ").length, 18) - }) - - it("should generate an 21 word mnemonic", () => { - const mnemonic = bchjs.Mnemonic.generate(224) - assert.equal(mnemonic.split(" ").length, 21) - }) - - it("should generate an 24 word mnemonic", () => { - const mnemonic = bchjs.Mnemonic.generate(256) - assert.equal(mnemonic.split(" ").length, 24) - }) - - it("should generate an 24 word italian mnemonic", () => { - const mnemonic = bchjs.Mnemonic.generate( - 256, - bchjs.Mnemonic.wordLists().italian - ) - assert.equal(mnemonic.split(" ").length, 24) - }) - }) - - describe("#fromEntropy", () => { - it("should generate a 12 word mnemonic from 16 bytes of entropy", () => { - const rand = bchjs.Crypto.randomBytes(16) - const mnemonic = bchjs.Mnemonic.fromEntropy(rand.toString("hex")) - assert.equal(mnemonic.split(" ").length, 12) - }) - - it("should generate a 15 word mnemonic from 20 bytes of entropy", () => { - const rand = bchjs.Crypto.randomBytes(20) - const mnemonic = bchjs.Mnemonic.fromEntropy(rand.toString("hex")) - assert.equal(mnemonic.split(" ").length, 15) - }) - - it("should generate an 18 word mnemonic from 24 bytes of entropy", () => { - const rand = bchjs.Crypto.randomBytes(24) - const mnemonic = bchjs.Mnemonic.fromEntropy(rand.toString("hex")) - assert.equal(mnemonic.split(" ").length, 18) - }) - - it("should generate an 21 word mnemonic from 28 bytes of entropy", () => { - const rand = bchjs.Crypto.randomBytes(28) - const mnemonic = bchjs.Mnemonic.fromEntropy(rand.toString("hex")) - assert.equal(mnemonic.split(" ").length, 21) - }) - - it("should generate an 24 word mnemonic from 32 bytes of entropy", () => { - const rand = bchjs.Crypto.randomBytes(32) - const mnemonic = bchjs.Mnemonic.fromEntropy(rand.toString("hex")) - assert.equal(mnemonic.split(" ").length, 24) - }) - - it("should generate an 24 french word mnemonic 32 bytes of entropy", () => { - const rand = bchjs.Crypto.randomBytes(32) - const mnemonic = bchjs.Mnemonic.fromEntropy( - rand.toString("hex"), - bchjs.Mnemonic.wordLists().french - ) - assert.equal(mnemonic.split(" ").length, 24) - }) - - fixtures.fromEntropy.forEach(entropy => { - const mnemonic = bchjs.Mnemonic.fromEntropy(entropy.entropy) - it(`should convert ${entropy.entropy} to ${entropy.mnemonic}`, () => { - assert.equal(mnemonic, entropy.mnemonic) - }) - }) - }) - - describe("#toEntropy", () => { - it("should turn a 12 word mnemonic to entropy", () => { - const mnemonic = bchjs.Mnemonic.generate(128) - const entropy = bchjs.Mnemonic.toEntropy(mnemonic) - assert.equal(entropy.length, 16) - }) - - it("should turn a 15 word mnemonic to entropy", () => { - const mnemonic = bchjs.Mnemonic.generate(160) - const entropy = bchjs.Mnemonic.toEntropy(mnemonic) - assert.equal(entropy.length, 20) - }) - - it("should turn a 18 word mnemonic to entropy", () => { - const mnemonic = bchjs.Mnemonic.generate(192) - const entropy = bchjs.Mnemonic.toEntropy(mnemonic) - assert.equal(entropy.length, 24) - }) - - it("should turn a 21 word mnemonic to entropy", () => { - const mnemonic = bchjs.Mnemonic.generate(224) - const entropy = bchjs.Mnemonic.toEntropy(mnemonic) - assert.equal(entropy.length, 28) - }) - - it("should turn a 24 word mnemonic to entropy", () => { - const mnemonic = bchjs.Mnemonic.generate(256) - const entropy = bchjs.Mnemonic.toEntropy(mnemonic) - assert.equal(entropy.length, 32) - }) - - it("should turn a 24 word spanish mnemonic to entropy", () => { - const mnemonic = bchjs.Mnemonic.generate( - 256, - bchjs.Mnemonic.wordLists().spanish - ) - const entropy = bchjs.Mnemonic.toEntropy( - mnemonic, - bchjs.Mnemonic.wordLists().spanish - ) - assert.equal(entropy.length, 32) - }) - - fixtures.fromEntropy.forEach(fixture => { - const entropy = bchjs.Mnemonic.toEntropy(fixture.mnemonic) - it(`should convert ${fixture.mnemonic} to ${fixture.entropy}`, () => { - assert.equal(entropy.toString("hex"), fixture.entropy) - }) - }) - }) - - describe("#validate", () => { - it("fails for a mnemonic that is too short", () => { - assert.equal( - bchjs.Mnemonic.validate( - "mixed winner", - bchjs.Mnemonic.wordLists().english - ), - "Invalid mnemonic" - ) - }) - - it("fails for a mnemonic that is too long", () => { - assert.equal( - bchjs.Mnemonic.validate( - "mixed winner decide drift danger together twice planet impose asthma catch require select mask awkward spy relief front work solar pitch economy render cake mixed winner decide drift danger together twice planet impose asthma catch require select mask awkward spy relief front work solar pitch economy render cake mixed winner decide drift danger together twice planet impose asthma catch require select mask awkward spy relief front work solar pitch economy render cake mixed winner decide drift danger together twice planet impose asthma catch require select mask awkward spy relief front work solar pitch economy render cake mixed winner decide drift danger together twice planet impose asthma catch require select mask awkward spy relief front work solar pitch economy render cake mixed winner decide drift danger together twice planet impose asthma catch require select mask awkward spy relief front work solar pitch economy render cake mixed winner decide drift danger together twice planet impose asthma catch require select mask awkward spy relief front work solar pitch economy render cake mixed winner decide drift danger together twice planet impose asthma catch require select mask awkward spy relief front work solar pitch economy render cake", - bchjs.Mnemonic.wordLists().english - ), - "Invalid mnemonic" - ) - }) - - it("fails if mnemonic words are not in the word list", () => { - assert.equal( - bchjs.Mnemonic.validate( - "failsauce one two three four five six seven eight nine ten eleven", - bchjs.Mnemonic.wordLists().english - ), - "failsauce is not in wordlist, did you mean balance?" - ) - }) - - it("validate a 128 bit mnemonic", () => { - const mnemonic = bchjs.Mnemonic.generate(128) - assert.equal( - bchjs.Mnemonic.validate(mnemonic, bchjs.Mnemonic.wordLists().english), - "Valid mnemonic" - ) - }) - - it("validate a 160 bit mnemonic", () => { - const mnemonic = bchjs.Mnemonic.generate(160) - assert.equal( - bchjs.Mnemonic.validate(mnemonic, bchjs.Mnemonic.wordLists().english), - "Valid mnemonic" - ) - }) - - it("validate a 192 bit mnemonic", () => { - const mnemonic = bchjs.Mnemonic.generate(192) - assert.equal( - bchjs.Mnemonic.validate(mnemonic, bchjs.Mnemonic.wordLists().english), - "Valid mnemonic" - ) - }) - - it("validate a 224 bit mnemonic", () => { - const mnemonic = bchjs.Mnemonic.generate(224) - assert.equal( - bchjs.Mnemonic.validate(mnemonic, bchjs.Mnemonic.wordLists().english), - "Valid mnemonic" - ) - }) - - it("validate a 256 bit mnemonic", () => { - const mnemonic = bchjs.Mnemonic.generate(256) - assert.equal( - bchjs.Mnemonic.validate(mnemonic, bchjs.Mnemonic.wordLists().english), - "Valid mnemonic" - ) - }) - - it("validate a 256 bit chinese simplified mnemonic", () => { - const mnemonic = bchjs.Mnemonic.generate( - 256, - bchjs.Mnemonic.wordLists().chinese_simplified - ) - assert.equal( - bchjs.Mnemonic.validate( - mnemonic, - bchjs.Mnemonic.wordLists().chinese_simplified - ), - "Valid mnemonic" - ) - }) - }) - - describe("#toSeed", () => { - it("should create 512 bit / 64 byte HMAC-SHA512 root seed from a 128 bit mnemonic", async () => { - const mnemonic = bchjs.Mnemonic.generate(128) - const rootSeedBuffer = await bchjs.Mnemonic.toSeed(mnemonic, "") - assert.equal(rootSeedBuffer.byteLength, 64) - }) - - it("should create 512 bit / 64 byte HMAC-SHA512 root seed from a 160 bit mnemonic", async () => { - const mnemonic = bchjs.Mnemonic.generate(160) - const rootSeedBuffer = await bchjs.Mnemonic.toSeed(mnemonic, "") - assert.equal(rootSeedBuffer.byteLength, 64) - }) - - it("should create 512 bit / 64 byte HMAC-SHA512 root seed from a 192 bit mnemonic", async () => { - const mnemonic = bchjs.Mnemonic.generate(192) - const rootSeedBuffer = await bchjs.Mnemonic.toSeed(mnemonic, "") - assert.equal(rootSeedBuffer.byteLength, 64) - }) - - it("should create 512 bit / 64 byte HMAC-SHA512 root seed from a 224 bit mnemonic", async () => { - const mnemonic = bchjs.Mnemonic.generate(224) - const rootSeedBuffer = await bchjs.Mnemonic.toSeed(mnemonic, "") - assert.equal(rootSeedBuffer.byteLength, 64) - }) - - it("should create 512 bit / 64 byte HMAC-SHA512 root seed from a 256 bit mnemonic", async () => { - const mnemonic = bchjs.Mnemonic.generate(256) - const rootSeedBuffer = await bchjs.Mnemonic.toSeed(mnemonic, "") - assert.equal(rootSeedBuffer.byteLength, 64) - }) - }) - - describe("#wordLists", () => { - it("return a list of 2048 english words", () => { - assert.equal(bchjs.Mnemonic.wordLists().english.length, 2048) - }) - - it("return a list of 2048 japanese words", () => { - assert.equal(bchjs.Mnemonic.wordLists().japanese.length, 2048) - }) - - it("return a list of 2048 chinese simplified words", () => { - assert.equal(bchjs.Mnemonic.wordLists().chinese_simplified.length, 2048) - }) - - it("return a list of 2048 chinese traditional words", () => { - assert.equal(bchjs.Mnemonic.wordLists().chinese_traditional.length, 2048) - }) - - it("return a list of 2048 french words", () => { - assert.equal(bchjs.Mnemonic.wordLists().french.length, 2048) - }) - - it("return a list of 2048 italian words", () => { - assert.equal(bchjs.Mnemonic.wordLists().italian.length, 2048) - }) - - it("return a list of 2048 korean words", () => { - assert.equal(bchjs.Mnemonic.wordLists().korean.length, 2048) - }) - - it("return a list of 2048 spanish words", () => { - assert.equal(bchjs.Mnemonic.wordLists().spanish.length, 2048) - }) - }) - - describe("#toKeypairs", async () => { - fixtures.toKeypairs.forEach(async (fixture, i) => { - const keypairs = await bchjs.Mnemonic.toKeypairs(fixture.mnemonic, 5) - keypairs.forEach((keypair, j) => { - it(`Generate keypair from mnemonic`, () => { - assert.equal( - keypair.privateKeyWIF, - fixtures.toKeypairs[i].output[j].privateKeyWIF - ) - // assert.equal( - // keypair.address, - // fixtures.toKeypairs[i].output[j].address - // ) - }) - }) - - const regtestKeypairs = await bchjs.Mnemonic.toKeypairs( - fixture.mnemonic, - 5, - true - ) - regtestKeypairs.forEach((keypair, j) => { - it(`Generate keypair from mnemonic`, () => { - assert.equal( - keypair.privateKeyWIF, - fixtures.toKeypairs[i].output[j].privateKeyWIFRegTest - ) - // assert.equal( - // keypair.address, - // fixtures.toKeypairs[i].output[j].regtestAddress - // ) - }) - }) - }) - }) - - describe("#findNearestWord", () => { - fixtures.findNearestWord.forEach((fixture, i) => { - const word = bchjs.Mnemonic.findNearestWord( - fixture.word, - bchjs.Mnemonic.wordLists()[fixture.language] - ) - it(`find word ${fixture.foundWord} near ${fixture.word} in ${fixture.language}`, () => { - assert.equal(word, fixture.foundWord) - }) - }) - }) -}) diff --git a/test/unit/ninsight.js b/test/unit/ninsight.js deleted file mode 100644 index 9670586..0000000 --- a/test/unit/ninsight.js +++ /dev/null @@ -1,255 +0,0 @@ -const chai = require("chai") -const assert = chai.assert -const axios = require("axios") -const sinon = require("sinon") - -const BCHJS = require("../../src/bch-js") -const bchjs = new BCHJS() - -const mockData = require("./fixtures/ninsight-mock") - -describe(`#Ninsight`, () => { - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - - describe(`#utxo`, () => { - it(`should throw an error for improper input`, async () => { - try { - const addr = 12345 - - await bchjs.Ninsight.utxo(addr) - assert.equal(true, false, "Unexpected result!") - } catch (err) { - //console.log(`err: `, err) - assert.include( - err.message, - `Input address must be a string or array of strings.` - ) - } - }) - - it(`should GET utxos for a single address`, async () => { - // Stub the network call. - sandbox.stub(axios, "post").resolves({ data: mockData.utxo }) - - const addr = "bitcoincash:qqh793x9au6ehvh7r2zflzguanlme760wuzehgzjh9" - - const result = await bchjs.Ninsight.utxo(addr) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.property(result, "utxos") - assert.property(result, "legacyAddress") - assert.property(result, "cashAddress") - assert.property(result, "slpAddress") - assert.property(result, "scriptPubKey") - assert.property(result, "asm") - - assert.isArray(result.utxos) - - assert.property(result.utxos[0], "txid") - assert.property(result.utxos[0], "vout") - assert.property(result.utxos[0], "amount") - assert.property(result.utxos[0], "satoshis") - assert.property(result.utxos[0], "height") - assert.property(result.utxos[0], "confirmations") - }) - - it(`should POST utxo details for an array of addresses`, async () => { - // Mock the network call. - sandbox.stub(axios, "post").resolves({ data: mockData.utxoPost }) - - const addr = [ - "bitcoincash:qp3sn6vlwz28ntmf3wmyra7jqttfx7z6zgtkygjhc7", - "bitcoincash:qz0us0z6ucpqt07jgpad0shgh7xmwxyr3ynlcsq0wr" - ] - - const result = await bchjs.Ninsight.utxo(addr) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.isArray(result) - assert.isArray(result[0].utxos) - - assert.property(result[0], "utxos") - assert.property(result[0], "legacyAddress") - assert.property(result[0], "cashAddress") - assert.property(result[0], "slpAddress") - assert.property(result[0], "scriptPubKey") - assert.property(result[0], "asm") - }) - }) - - describe("#unconfirmed", () => { - it("should throw an error for improper input", async () => { - try { - const addr = 12345 - - await bchjs.Ninsight.unconfirmed(addr) - assert.equal(true, false, "Unexpected result!") - } catch (err) { - assert.include( - err.message, - "Input address must be a string or array of strings." - ) - } - }) - - it(`should POST utxos for a single address`, async () => { - // Stub the network call. - sandbox.stub(axios, "post").resolves({ data: mockData.unconfirmed }) - - const addr = "bitcoincash:qpkkjkhe29mqhqmu3evtq3dsnruuzl3rku6usknlh5" - - const result = await bchjs.Ninsight.unconfirmed(addr) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.property(result, "utxos") - assert.property(result, "legacyAddress") - assert.property(result, "cashAddress") - assert.property(result, "slpAddress") - assert.property(result, "scriptPubKey") - - assert.isArray(result.utxos) - - assert.property(result.utxos[0], "txid") - assert.property(result.utxos[0], "vout") - assert.property(result.utxos[0], "amount") - assert.property(result.utxos[0], "satoshis") - assert.property(result.utxos[0], "confirmations") - assert.property(result.utxos[0], "ts") - }) - - it(`should POST utxo details for an array of addresses`, async () => { - // Mock the network call. - sandbox.stub(axios, "post").resolves({ data: mockData.unconfirmedPost }) - - const addr = [ - "bitcoincash:qpkkjkhe29mqhqmu3evtq3dsnruuzl3rku6usknlh5", - "bitcoincash:qz0us0z6ucpqt07jgpad0shgh7xmwxyr3ynlcsq0wr" - ] - - const result = await bchjs.Ninsight.unconfirmed(addr) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.isArray(result) - assert.isArray(result[0].utxos) - - assert.property(result[0], "utxos") - assert.property(result[0], "legacyAddress") - assert.property(result[0], "cashAddress") - assert.property(result[0], "slpAddress") - assert.property(result[0], "scriptPubKey") - }) - }) - - describe(`#transactions`, () => { - it(`should throw an error for improper input`, async () => { - try { - const addr = 12345 - - await bchjs.Ninsight.transactions(addr) - assert.equal(true, false, "Unexpected result!") - } catch (err) { - //console.log(`err: `, err) - assert.include( - err.message, - `Input address must be a string or array of strings.` - ) - } - }) - it(`should POST transaction history for a single address`, async () => { - // Stub the network call. - sandbox.stub(axios, "post").resolves({ data: mockData.transactionsPost }) - - const addr = "bitcoincash:qqh793x9au6ehvh7r2zflzguanlme760wuzehgzjh9" - - const result = await bchjs.Ninsight.transactions(addr) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.isArray(result) - assert.property(result[0], "cashAddress") - assert.property(result[0], "legacyAddress") - assert.property(result[0], "txs") - assert.isArray(result[0].txs) - assert.property(result[0].txs[0], "txid") - assert.property(result[0].txs[0], "vin") - assert.property(result[0].txs[0], "vout") - }) - it(`should POST transaction history for an array of addresses`, async () => { - // Mock the network call. - sandbox.stub(axios, "post").resolves({ data: mockData.transactionsPost }) - - const addr = [ - "bitcoincash:qp3sn6vlwz28ntmf3wmyra7jqttfx7z6zgtkygjhc7", - "bitcoincash:qz0us0z6ucpqt07jgpad0shgh7xmwxyr3ynlcsq0wr" - ] - - const result = await bchjs.Ninsight.transactions(addr) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.isArray(result) - assert.property(result[0], "cashAddress") - assert.property(result[0], "legacyAddress") - assert.property(result[0], "txs") - assert.isArray(result[0].txs) - assert.property(result[0].txs[0], "txid") - }) - }) - describe(`#txDetails`, () => { - it(`should throw an error for improper input`, async () => { - try { - const txid = 12345 - - await bchjs.Ninsight.txDetails(txid) - assert.equal(true, false, "Unexpected result!") - } catch (err) { - //console.log(`err: `, err) - assert.include( - err.message, - `Transaction ID must be a string or array of strings.` - ) - } - }) - it(`should POST transaction details for a single TxID`, async () => { - // Stub the network call. - sandbox.stub(axios, "post").resolves({ data: mockData.detailsPost }) - - const txid = "fe28050b93faea61fa88c4c630f0e1f0a1c24d0082dd0e10d369e13212128f33" - - const result = await bchjs.Ninsight.txDetails(txid) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.isArray(result) - assert.property(result[0], "txid") - assert.property(result[0], "version") - assert.property(result[0], "locktime") - assert.property(result[0], "vin") - assert.property(result[0], "vout") - assert.property(result[0], "blockhash") - assert.property(result[0], "blockheight") - assert.property(result[0], "confirmations") - assert.property(result[0], "time") - assert.property(result[0], "blocktime") - assert.property(result[0], "isCoinBase") - assert.property(result[0], "valueOut") - assert.property(result[0], "size") - }) - it(`should POST transaction details for an array of TxIDs`, async () => { - // Stub the network call. - sandbox.stub(axios, "post").resolves({ data: mockData.detailsPost }) - - const txid = [ - "fe28050b93faea61fa88c4c630f0e1f0a1c24d0082dd0e10d369e13212128f33", - "fe28050b93faea61fa88c4c630f0e1f0a1c24d0082dd0e10d369e13212128f33" - ] - - const result = await bchjs.Ninsight.txDetails(txid) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.isArray(result) - assert.property(result[0], "txid") - assert.property(result[0], "vin") - assert.property(result[0], "vout") - }) - }) -}) diff --git a/test/unit/openbazaar.js b/test/unit/openbazaar.js deleted file mode 100644 index d663fb0..0000000 --- a/test/unit/openbazaar.js +++ /dev/null @@ -1,129 +0,0 @@ -const chai = require("chai") -const assert = chai.assert -const BCHJS = require("../../src/bch-js") -const bchjs = new BCHJS() -const axios = require("axios") -const sinon = require("sinon") - -const mockData = require("./fixtures/openbazaar-mock") - -describe(`#OpenBazaar`, () => { - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - - describe(`#Balance`, () => { - it(`should throw an error for improper input`, async () => { - try { - const addr = 12345 - - await bchjs.OpenBazaar.balance(addr) - assert.equal(true, false, "Unexpected result!") - } catch (err) { - //console.log(`err: `, err) - assert.include(err.message, `Input address must be a string`) - } - }) - - it(`should GET balance for a single address`, async () => { - // Stub the network call. - sandbox.stub(axios, "get").resolves({ data: mockData.balance }) - - const addr = "bitcoincash:qqh793x9au6ehvh7r2zflzguanlme760wuzehgzjh9" - - const result = await bchjs.OpenBazaar.balance(addr) - //console.log(`result: ${util.inspect(result)}`) - - assert.hasAllKeys(result, [ - "page", - "totalPages", - "itemsOnPage", - "addrStr", - "balance", - "totalReceived", - "totalSent", - "unconfirmedBalance", - "unconfirmedTxApperances", - "txApperances", - "transactions" - ]) - assert.isArray(result.transactions) - }) - }) - - describe(`#utxo`, () => { - it(`should throw an error for improper input`, async () => { - try { - const addr = 12345 - - await bchjs.OpenBazaar.utxo(addr) - assert.equal(true, false, "Unexpected result!") - } catch (err) { - //console.log(`err: `, err) - assert.include(err.message, `Input address must be a string`) - } - }) - - it(`should GET utxos for a single address`, async () => { - // Stub the network call. - sandbox.stub(axios, "get").resolves({ data: mockData.utxo }) - - const addr = "bitcoincash:qqh793x9au6ehvh7r2zflzguanlme760wuzehgzjh9" - - const result = await bchjs.OpenBazaar.utxo(addr) - //console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.isArray(result) - assert.hasAllKeys(result[0], [ - "txid", - "vout", - "amount", - "height", - "confirmations", - "satoshis" - ]) - }) - }) - - describe(`#tx`, () => { - it(`should throw an error for improper input`, async () => { - try { - const txid = 12345 - - await bchjs.OpenBazaar.tx(txid) - assert.equal(true, false, "Unexpected result!") - } catch (err) { - //console.log(`err: `, err) - assert.include(err.message, `Input txid must be a string`) - } - }) - - it(`should GET tx details for a single txid`, async () => { - // Stub the network call. - sandbox.stub(axios, "get").resolves({ data: mockData.tx }) - - const txid = - "2b37bdb3b63dd0bca720437754a36671431a950e684b64c44ea910ea9d5297c7" - - const result = await bchjs.OpenBazaar.tx(txid) - //console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.hasAllKeys(result, [ - "txid", - "version", - "vin", - "vout", - "blockhash", - "blockheight", - "confirmations", - "blocktime", - "valueOut", - "valueIn", - "fees", - "hex" - ]) - assert.isArray(result.vin) - assert.isArray(result.vout) - }) - }) -}) diff --git a/test/unit/raw-tranactions.js b/test/unit/raw-tranactions.js deleted file mode 100644 index 0eec0d8..0000000 --- a/test/unit/raw-tranactions.js +++ /dev/null @@ -1,129 +0,0 @@ -/* - TODO: - -Replace old unit tests mocking axios with the more generalized nock library. - See the sendRawTransaction test for an example. - -Create a mocking library of data to compare unit and integration tests. -*/ - -const assert = require("assert") -const axios = require("axios") -const BCHJS = require("../../src/bch-js") -const bchjs = new BCHJS() - -const sinon = require("sinon") -const nock = require("nock") // HTTP mocking - -// Used for debugging -const util = require("util") -util.inspect.defaultOptions = { depth: 1 } - -describe("#RawTransactions", () => { - describe("#decodeRawTransaction", () => { - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - - it("should decode raw transaction", done => { - const data = { - txid: - "4ebd325a4b394cff8c57e8317ccf5a8d0e2bdf1b8526f8aad6c8e43d8240621a", - hash: - "4ebd325a4b394cff8c57e8317ccf5a8d0e2bdf1b8526f8aad6c8e43d8240621a", - size: 10, - version: 2, - locktime: 0, - vin: [], - vout: [] - } - - const resolved = new Promise(r => r({ data: data })) - sandbox.stub(axios, "get").returns(resolved) - - bchjs.RawTransactions.decodeRawTransaction("02000000000000000000") - .then(result => { - assert.equal(data, result) - }) - .then(done, done) - }) - }) - - describe("#decodeScript", () => { - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - - it("should decode script", async () => { - const data = { - asm: "OP_RETURN 5361746f736869204e616b616d6f746f", - type: "nulldata", - p2sh: "bitcoincash:prswx5965nfumux9qng5kj8hw603vcne7q08t8c6jp" - } - - const resolved = new Promise(r => r({ data: data })) - sandbox.stub(axios, "get").returns(resolved) - - const result = await bchjs.RawTransactions.decodeScript( - "6a105361746f736869204e616b616d6f746f" - ) - //console.log(`result: ${util.inspect(result)}`) - - assert.deepEqual(data, result) - }) - }) - - describe("#getRawTransaction", () => { - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - - it("should get raw transaction", done => { - const data = - "020000000160d663961c63c7f0a07f22ec07b8f55b3935bfdbed8b1d8454916e8932fbf109010000006b4830450221008479fab4cfdcb111833d250a43f98ac26d43272b7a29cb1b9a0491eae5c44b3502203448b17253632395c29a7d62058bbfe93efb20fc8636ba6837002d464195aec04121029123258f7cdcd45b864066bcaa9b71f24d5ed1fa1dd36eaf107d8432b5014658ffffffff016d180000000000001976a91479d3297d1823149f4ec61df31d19f2fad5390c0288ac00000000" - - const resolved = new Promise(r => r({ data: data })) - sandbox.stub(axios, "get").returns(resolved) - - bchjs.RawTransactions.getRawTransaction( - "808d617eccaad4f1397fe07a06ec5ed15a0821cf22a3e0931c0c92aef9e572b6" - ) - .then(result => { - assert.equal(data, result) - }) - .then(done, done) - }) - }) - - describe("#sendRawTransaction", () => { - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - - it("should send single raw transaction", async () => { - const data = "Error: transaction already in block chain" - - const resolved = new Promise(r => r({ data: data })) - sandbox.stub(axios, "get").returns(resolved) - - const result = await bchjs.RawTransactions.sendRawTransaction( - "020000000160d663961c63c7f0a07f22ec07b8f55b3935bfdbed8b1d8454916e8932fbf109010000006b4830450221008479fab4cfdcb111833d250a43f98ac26d43272b7a29cb1b9a0491eae5c44b3502203448b17253632395c29a7d62058bbfe93efb20fc8636ba6837002d464195aec04121029123258f7cdcd45b864066bcaa9b71f24d5ed1fa1dd36eaf107d8432b5014658ffffffff016d180000000000001976a91479d3297d1823149f4ec61df31d19f2fad5390c0288ac00000000" - ) - - assert.equal(data, result) - }) - - it("should send an array of raw transactions", async () => { - const data = "Error: transaction already in block chain" - - // Mock the http call to rest.bitcoin.com - nock(`${bchjs.RawTransactions.restURL}`) - .post(uri => uri.includes(`/`)) - .reply(200, { data: data }) - - const result = await bchjs.RawTransactions.sendRawTransaction([ - "020000000160d663961c63c7f0a07f22ec07b8f55b3935bfdbed8b1d8454916e8932fbf109010000006b4830450221008479fab4cfdcb111833d250a43f98ac26d43272b7a29cb1b9a0491eae5c44b3502203448b17253632395c29a7d62058bbfe93efb20fc8636ba6837002d464195aec04121029123258f7cdcd45b864066bcaa9b71f24d5ed1fa1dd36eaf107d8432b5014658ffffffff016d180000000000001976a91479d3297d1823149f4ec61df31d19f2fad5390c0288ac00000000" - ]) - - assert.equal(data, result.data) - }) - }) -}) diff --git a/test/unit/scripts.js b/test/unit/scripts.js deleted file mode 100644 index f327a14..0000000 --- a/test/unit/scripts.js +++ /dev/null @@ -1,476 +0,0 @@ -const fixtures = require("./fixtures/script.json") -const assert = require("assert") -const BCHJS = require("../../src/bch-js") -const bchjs = new BCHJS() -const Buffer = require("safe-buffer").Buffer - -describe("#Script", () => { - describe("#decode", () => { - describe("P2PKH scriptSig", () => { - fixtures.decodeScriptSig.forEach(fixture => { - it(`should decode scriptSig buffer`, () => { - const decodedScriptSig = bchjs.Script.decode( - Buffer.from(fixture.scriptSigHex, "hex") - ) - assert.equal(typeof decodedScriptSig, "object") - }) - - it(`should decode scriptSig buffer to cash address ${fixture.cashAddress}`, () => { - const decodedScriptSig = bchjs.Script.decode( - Buffer.from(fixture.scriptSigHex, "hex") - ) - const address = bchjs.HDNode.toCashAddress( - bchjs.ECPair.fromPublicKey(decodedScriptSig[1]) - ) - assert.equal(address, fixture.cashAddress) - }) - - it(`should decode scriptSig buffer to legacy address ${fixture.legacyAddress}`, () => { - const decodedScriptSig = bchjs.Script.decode( - Buffer.from(fixture.scriptSigHex, "hex") - ) - const address = bchjs.HDNode.toLegacyAddress( - bchjs.ECPair.fromPublicKey(decodedScriptSig[1]) - ) - assert.equal(address, fixture.legacyAddress) - }) - }) - }) - - describe("P2PKH scriptPubKey", () => { - fixtures.decodeScriptPubKey.forEach(fixture => { - it(`should decode scriptSig buffer`, () => { - const decodedScriptPubKey = bchjs.Script.decode( - Buffer.from(fixture.scriptPubKeyHex, "hex") - ) - assert.equal(decodedScriptPubKey.length, 5) - }) - - it(`should match hashed pubKey ${fixture.pubKeyHex}`, () => { - const decodedScriptPubKey = bchjs.Script.decode( - Buffer.from(fixture.scriptPubKeyHex, "hex") - ) - const data = Buffer.from(fixture.pubKeyHex, "hex") - const hash160 = bchjs.Crypto.hash160(data).toString("hex") - assert.equal(decodedScriptPubKey[2].toString("hex"), hash160) - }) - }) - }) - }) - - describe("#encode", () => { - describe("P2PKH scriptSig", () => { - fixtures.encodeScriptSig.forEach(fixture => { - it(`should encode scriptSig chunks to buffer`, () => { - const arr = [ - Buffer.from(fixture.scriptSigChunks[0], "hex"), - Buffer.from(fixture.scriptSigChunks[1], "hex") - ] - const encodedScriptSig = bchjs.Script.encode(arr) - assert.equal(typeof encodedScriptSig, "object") - }) - }) - }) - - describe("P2PKH scriptPubKey", () => { - fixtures.encodeScriptPubKey.forEach(fixture => { - it(`should encode scriptPubKey buffer`, () => { - const decodedScriptPubKey = bchjs.Script.decode( - Buffer.from(fixture.scriptPubKeyHex, "hex") - ) - const compiledScriptPubKey = bchjs.Script.encode(decodedScriptPubKey) - assert.equal( - compiledScriptPubKey.toString("hex"), - fixture.scriptPubKeyHex - ) - }) - }) - }) - - describe("Encode SLP SEND OP_RETURN properly", () => { - it("should correctly compile OP_RETURN SLP SEND transaction", () => { - const scriptArr = [ - bchjs.Script.opcodes.OP_RETURN, - Buffer.from("534c5000", "hex"), - Buffer.from("01", "hex"), - Buffer.from(`SEND`), - Buffer.from( - "73db55368981e4878440637e448d4abe7f661be5c3efdcbcb63bd86a01a76b5a", - "hex" - ), - Buffer.from("00000001", "hex") - ] - - const data = bchjs.Script.encode2(scriptArr) - - // convert data to a hex string - let str = "" - for (let i = 0; i < data.length; i++) { - let hex = Number(data[i]).toString(16) - - // zero pad when its a single digit. - hex = `0${hex}` - hex = hex.slice(-2) - //console.log(`hex: ${hex}`) - - str += hex - } - console.log(`Hex string: ${str}`) - - //console.log(`scriptArr: ${JSON.stringify(data,null,2)}`) - - const correctStr = - "6a04534c500001010453454e442073db55368981e4878440637e448d4abe7f661be5c3efdcbcb63bd86a01a76b5a0400000001" - - assert.equal(str, correctStr) - }) - }) - }) - - describe("#toASM", () => { - describe("P2PKH scriptSig", () => { - fixtures.scriptSigToASM.forEach(fixture => { - it(`should encode scriptSig buffer to ${fixture.asm}`, () => { - const arr = [ - Buffer.from(fixture.scriptSigChunks[0], "hex"), - Buffer.from(fixture.scriptSigChunks[1], "hex") - ] - const compiledScriptSig = bchjs.Script.encode(arr) - const asm = bchjs.Script.toASM(compiledScriptSig) - assert.equal(asm, fixture.asm) - }) - }) - }) - - describe("P2PKH scriptPubKey", () => { - fixtures.scriptPubKeyToASM.forEach(fixture => { - it(`should compile scriptPubKey buffer to ${fixture.asm}`, () => { - const asm = bchjs.Script.toASM( - Buffer.from(fixture.scriptPubKeyHex, "hex") - ) - assert.equal(asm, fixture.asm) - }) - }) - }) - }) - - describe("#fromASM", () => { - describe("P2PKH scriptSig", () => { - fixtures.scriptSigFromASM.forEach(fixture => { - it(`should decode scriptSig asm to buffer`, () => { - const buf = bchjs.Script.fromASM(fixture.asm) - assert.equal(typeof buf, "object") - }) - }) - }) - - describe("P2PKH scriptPubKey", () => { - fixtures.scriptPubKeyFromASM.forEach(fixture => { - it(`should decode scriptPubKey asm to buffer`, () => { - const buf = bchjs.Script.fromASM(fixture.asm) - assert.equal(typeof buf, "object") - }) - }) - }) - }) - - describe("#OPCodes", () => { - for (const opcode in fixtures.opcodes) { - it(`should have OP Code ${opcode}`, () => { - assert.equal(bchjs.Script.opcodes[opcode], fixtures.opcodes[opcode]) - }) - } - }) - - describe("#classifyInput", () => { - fixtures.classifyInput.forEach(fixture => { - it(`should classify input type ${fixture.type}`, () => { - const type = bchjs.Script.classifyInput( - bchjs.Script.fromASM(fixture.script) - ) - assert.equal(type, fixture.type) - }) - }) - }) - - describe("#classifyOutput", () => { - fixtures.classifyOutput.forEach(fixture => { - it(`should classify ouput type ${fixture.type}`, () => { - const type = bchjs.Script.classifyOutput( - bchjs.Script.fromASM(fixture.script) - ) - assert.equal(type, fixture.type) - }) - }) - }) - - describe("#nullDataTemplate", () => { - fixtures.nullDataTemplate.forEach(fixture => { - it(`should encode nulldata output`, () => { - const buf = bchjs.Script.nullData.output.encode( - Buffer.from(`${fixture.data}`, "ascii") - ) - assert.equal(buf.toString("hex"), fixture.hex) - }) - - it(`should decode nulldata output`, () => { - const buf = bchjs.Script.nullData.output.decode( - Buffer.from(`${fixture.hex}`, "hex") - ) - assert.equal(buf.toString("ascii"), fixture.data) - }) - - it(`should confirm correctly formatted nulldata output`, () => { - const buf = bchjs.Script.nullData.output.encode( - Buffer.from(`${fixture.data}`, "ascii") - ) - const valid = bchjs.Script.nullData.output.check(buf) - assert.equal(valid, true) - }) - }) - }) - - describe("#pubKeyTemplate", () => { - describe("#pubKeyInputTemplate", () => { - fixtures.pubKeyInputTemplate.forEach(fixture => { - it(`should encode pubKey input`, () => { - const buf = bchjs.Script.pubKey.input.encode( - Buffer.from(fixture.signature, "hex") - ) - assert.equal(buf.toString("hex"), fixture.hex) - }) - - it(`should decode pubKey input`, () => { - const buf = bchjs.Script.pubKey.input.decode( - Buffer.from(fixture.hex, "hex") - ) - assert.equal(buf.toString("hex"), fixture.signature) - }) - - it(`should confirm correctly formatted pubKeyHash input`, () => { - const buf = bchjs.Script.pubKey.input.encode( - Buffer.from(fixture.signature, "hex") - ) - const valid = bchjs.Script.pubKey.input.check(buf) - assert.equal(valid, true) - }) - }) - }) - - describe("#pubKeyOutputTemplate", () => { - fixtures.pubKeyOutputTemplate.forEach(fixture => { - it(`should encode pubKey output`, () => { - const buf = bchjs.Script.pubKey.output.encode( - Buffer.from(fixture.pubKey, "hex") - ) - assert.equal(buf.toString("hex"), fixture.hex) - }) - - it(`should decode pubKey output`, () => { - const buf = bchjs.Script.pubKey.output.decode( - Buffer.from(`${fixture.hex}`, "hex") - ) - assert.equal(buf.toString("hex"), fixture.pubKey) - }) - - it(`should confirm correctly formatted pubKey output`, () => { - const buf = bchjs.Script.pubKey.output.encode( - Buffer.from(fixture.pubKey, "hex") - ) - const valid = bchjs.Script.pubKey.output.check(buf) - assert.equal(valid, true) - }) - }) - }) - }) - - describe("#pubKeyHashTemplate", () => { - describe("#pubKeyHashInputTemplate", () => { - fixtures.pubKeyHashInputTemplate.forEach(fixture => { - it(`should encode pubKeyHash input`, () => { - const buf = bchjs.Script.pubKeyHash.input.encode( - Buffer.from(fixture.signature, "hex"), - Buffer.from(fixture.pubKey, "hex") - ) - assert.equal(buf.toString("hex"), fixture.hex) - }) - - it(`should decode pubKeyHash input signature`, () => { - const buf = bchjs.Script.pubKeyHash.input.decode( - Buffer.from(fixture.hex, "hex") - ) - assert.equal(buf.signature.toString("hex"), fixture.signature) - }) - - it(`should decode pubKeyHash input pubkey`, () => { - const buf = bchjs.Script.pubKeyHash.input.decode( - Buffer.from(fixture.hex, "hex") - ) - assert.equal(buf.pubKey.toString("hex"), fixture.pubKey) - }) - - it(`should confirm correctly formatted pubKeyHash input`, () => { - const buf = bchjs.Script.pubKeyHash.input.encode( - Buffer.from(fixture.signature, "hex"), - Buffer.from(fixture.pubKey, "hex") - ) - const valid = bchjs.Script.pubKeyHash.input.check(buf) - assert.equal(valid, true) - }) - }) - }) - - describe("#pubKeyHashOutputTemplate", () => { - fixtures.pubKeyHashOutputTemplate.forEach(fixture => { - const node = bchjs.HDNode.fromXPriv(fixture.xpriv) - const identifier = bchjs.HDNode.toIdentifier(node) - it(`should encode pubKeyHash output`, () => { - const buf = bchjs.Script.pubKeyHash.output.encode(identifier) - assert.equal(buf.toString("hex"), fixture.hex) - }) - - it(`should decode pubKeyHash output`, () => { - const buf = bchjs.Script.pubKeyHash.output.decode( - Buffer.from(`${fixture.hex}`, "hex") - ) - assert.equal(buf.toString("hex"), identifier.toString("hex")) - }) - - it(`should confirm correctly formatted pubKeyHash output`, () => { - const buf = bchjs.Script.pubKeyHash.output.encode(identifier) - const valid = bchjs.Script.pubKeyHash.output.check(buf) - assert.equal(valid, true) - }) - }) - }) - }) - - describe("#multisigTemplate", () => { - describe("#multisigInputTemplate", () => { - fixtures.multisigInputTemplate.forEach(fixture => { - it(`should encode multisig input`, () => { - const signatures = fixture.signatures.map(signature => - signature - ? Buffer.from(signature, "hex") - : bchjs.Script.opcodes.OP_0 - ) - - const buf = bchjs.Script.multisig.input.encode(signatures) - assert.equal(buf.toString("hex"), fixture.hex) - }) - - it(`should decode multisig input`, () => { - const buf = bchjs.Script.multisig.input.decode( - Buffer.from(fixture.hex, "hex") - ) - assert.equal(buf[0].toString("hex"), fixture.signatures[0]) - }) - - it(`should confirm correctly formatted multisig input`, () => { - const signatures = fixture.signatures.map(signature => - signature - ? Buffer.from(signature, "hex") - : bchjs.Script.opcodes.OP_0 - ) - - const buf = bchjs.Script.multisig.input.encode(signatures) - const valid = bchjs.Script.multisig.input.check(buf) - assert.equal(valid, true) - }) - }) - }) - - describe("#multisigOutputTemplate", () => { - fixtures.multisigOutputTemplate.forEach(fixture => { - it(`should encode multisig output`, () => { - const pubKeys = fixture.pubKeys.map(p => Buffer.from(p, "hex")) - const m = pubKeys.length - const buf = bchjs.Script.multisig.output.encode(m, pubKeys) - - assert.equal(buf.toString("hex"), fixture.hex) - }) - - it(`should decode multisig output`, () => { - const output = bchjs.Script.multisig.output.decode( - Buffer.from(`${fixture.hex}`, "hex") - ) - assert.equal(output.m, fixture.pubKeys.length) - }) - - it(`should confirm correctly formatted multisig output`, () => { - const pubKeys = fixture.pubKeys.map(p => Buffer.from(p, "hex")) - const m = pubKeys.length - const buf = bchjs.Script.multisig.output.encode(m, pubKeys) - const valid = bchjs.Script.multisig.output.check(buf) - assert.equal(valid, true) - }) - }) - }) - }) - - describe("#scriptHashTemplate", () => { - describe("#scriptHashInputTemplate", () => { - fixtures.scriptHashInputTemplate.forEach(fixture => { - it(`should encode scriptHash input`, () => { - const buf = bchjs.Script.scriptHash.input.encode( - bchjs.Script.fromASM(fixture.redeemScriptSig), - bchjs.Script.fromASM(fixture.redeemScript) - ) - assert.equal(buf.toString("hex"), fixture.hex) - }) - - it(`should decode scriptHash input`, () => { - const redeemScriptSig = bchjs.Script.fromASM(fixture.redeemScriptSig) - const redeemScript = bchjs.Script.fromASM(fixture.redeemScript) - assert.deepEqual( - bchjs.Script.scriptHash.input.decode( - Buffer.from(fixture.hex, "hex") - ), - { - redeemScriptSig: redeemScriptSig, - redeemScript: redeemScript - } - ) - }) - - it(`should confirm correctly formatted scriptHash input`, () => { - const buf = bchjs.Script.scriptHash.input.encode( - bchjs.Script.fromASM(fixture.redeemScriptSig), - bchjs.Script.fromASM(fixture.redeemScript) - ) - const valid = bchjs.Script.scriptHash.input.check(buf) - assert.equal(valid, true) - }) - }) - }) - - describe("#scriptHashOutputTemplate", () => { - fixtures.scriptHashOutputTemplate.forEach(fixture => { - it(`should encode scriptHash output`, () => { - const redeemScript = bchjs.Script.fromASM(fixture.output) - const scriptHash = bchjs.Crypto.hash160(redeemScript) - const buf = bchjs.Script.scriptHash.output.encode(scriptHash) - - assert.equal(buf.toString("hex"), fixture.hex) - }) - - it(`should decode scriptHash output`, () => { - const redeemScript = bchjs.Script.fromASM(fixture.output) - const scriptHash = bchjs.Crypto.hash160(redeemScript) - const buf = bchjs.Script.scriptHash.output.decode( - Buffer.from(`${fixture.hex}`, "hex") - ) - assert.deepEqual(buf, scriptHash) - }) - - it(`should confirm correctly formatted scriptHash output`, () => { - const redeemScript = bchjs.Script.fromASM(fixture.output) - const scriptHash = bchjs.Crypto.hash160(redeemScript) - const buf = bchjs.Script.scriptHash.output.encode(scriptHash) - const valid = bchjs.Script.scriptHash.output.check(buf) - assert.equal(valid, true) - }) - }) - }) - }) -}) diff --git a/test/unit/slp-address.js b/test/unit/slp-address.js deleted file mode 100644 index 6e68bcd..0000000 --- a/test/unit/slp-address.js +++ /dev/null @@ -1,838 +0,0 @@ -const assert = require("assert") - -const slp = require("../../src/slp/slp") -const SLP = new slp({ restURL: "http://fakeurl.com/" }) - -const fixtures = require("./fixtures/slp/address.json") -//const axios = require("axios") -//const sinon = require("sinon") - -function flatten(arrays) { - return [].concat.apply([], arrays) -} - -const LEGACY_MAINNET_ADDRESSES = flatten([ - fixtures.mainnet.legacyP2PKH, - fixtures.mainnet.legacyP2SH -]) - -const CASH_MAINNET_ADDRESSES = flatten([ - fixtures.mainnet.cashAddressP2PKH, - fixtures.mainnet.cashAddressP2SH -]) - -const SLP_MAINNET_ADDRESSES = flatten([ - fixtures.mainnet.slpAddressP2PKH, - fixtures.mainnet.slpAddressP2SH -]) - -const LEGACY_TESTNET_ADDRESSES = flatten([ - fixtures.testnet.legacyP2PKH, - fixtures.testnet.legacyP2SH -]) - -const CASH_TESTNET_ADDRESSES = flatten([ - fixtures.testnet.cashAddressP2PKH, - fixtures.testnet.cashAddressP2SH -]) - -const SLP_TESTNET_ADDRESSES = flatten([ - fixtures.testnet.slpAddressP2PKH, - fixtures.testnet.slpAddressP2SH -]) - -const MAINNET_P2PKH_ADDRESSES = flatten([ - fixtures.mainnet.legacyP2PKH, - fixtures.mainnet.cashAddressP2PKH, - fixtures.mainnet.slpAddressP2PKH -]) - -const TESTNET_P2PKH_ADDRESSES = flatten([ - fixtures.testnet.legacyP2PKH, - fixtures.testnet.cashAddressP2PKH, - fixtures.testnet.slpAddressP2PKH -]) - -const MAINNET_P2SH_ADDRESSES = flatten([ - fixtures.mainnet.legacyP2SH, - fixtures.mainnet.cashAddressP2SH, - fixtures.mainnet.slpAddressP2SH -]) - -const TESTNET_P2SH_ADDRESSES = flatten([ - fixtures.testnet.legacyP2SH, - fixtures.testnet.cashAddressP2SH, - fixtures.testnet.slpAddressP2SH -]) -/* -const CASH_MAINNET_ADDRESSES_NO_PREFIX = CASH_MAINNET_ADDRESSES.map(address => { - const parts = address.split(":") - return parts[1] -}) - -const CASH_TESTNET_ADDRESSES_NO_PREFIX = CASH_TESTNET_ADDRESSES.map(address => { - const parts = address.split(":") - return parts[1] -}) - -const SLP_MAINNET_ADDRESSES_NO_PREFIX = SLP_MAINNET_ADDRESSES.map(address => { - const parts = address.split(":") - return parts[1] -}) - -const SLP_TESTNET_ADDRESSES_NO_PREFIX = SLP_TESTNET_ADDRESSES.map(address => { - const parts = address.split(":") - return parts[1] -}) -*/ -describe("#SLP Address", () => { - describe("#mainnet", () => { - describe("#toLegacyAddress", () => { - it("should convert mainnet legacy address format to itself correctly", () => { - assert.deepEqual( - LEGACY_MAINNET_ADDRESSES.map(address => - SLP.Address.toLegacyAddress(address) - ), - LEGACY_MAINNET_ADDRESSES - ) - }) - - it(`should convert cashAddr to legacyAddr`, async () => { - assert.deepEqual( - CASH_MAINNET_ADDRESSES.map(address => - SLP.Address.toLegacyAddress(address) - ), - LEGACY_MAINNET_ADDRESSES - ) - }) - - it(`should convert slpAddr to legacyAddr`, async () => { - assert.deepEqual( - SLP_MAINNET_ADDRESSES.map(address => - SLP.Address.toLegacyAddress(address) - ), - LEGACY_MAINNET_ADDRESSES - ) - }) - }) - - describe("#toCashAddress", () => { - it("should convert mainnet cash address format to itself correctly", () => { - assert.deepEqual( - CASH_MAINNET_ADDRESSES.map(address => - SLP.Address.toCashAddress(address) - ), - CASH_MAINNET_ADDRESSES - ) - }) - - it(`should convert legacyAddr to cashAddr`, async () => { - assert.deepEqual( - LEGACY_MAINNET_ADDRESSES.map(address => - SLP.Address.toCashAddress(address) - ), - CASH_MAINNET_ADDRESSES - ) - }) - - it(`should convert slpAddr to cashAddr`, async () => { - assert.deepEqual( - SLP_MAINNET_ADDRESSES.map(address => - SLP.Address.toCashAddress(address) - ), - CASH_MAINNET_ADDRESSES - ) - }) - }) - - describe("#toSLPAddress", () => { - it("should convert mainnet slp address format to itself correctly", () => { - assert.deepEqual( - SLP_MAINNET_ADDRESSES.map(address => - SLP.Address.toSLPAddress(address) - ), - SLP_MAINNET_ADDRESSES - ) - }) - - it(`should convert legacyAddr to slpAddr`, async () => { - assert.deepEqual( - LEGACY_MAINNET_ADDRESSES.map(address => - SLP.Address.toSLPAddress(address) - ), - SLP_MAINNET_ADDRESSES - ) - }) - - it(`should convert cashAddr to slpAddr`, async () => { - assert.deepEqual( - CASH_MAINNET_ADDRESSES.map(address => - SLP.Address.toSLPAddress(address) - ), - SLP_MAINNET_ADDRESSES - ) - }) - }) - - describe("#isLegacyAddress", () => { - describe("is legacy addr", () => { - LEGACY_MAINNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is a legacy address`, () => { - const isLegacyaddr = SLP.Address.isLegacyAddress(address) - assert.equal(isLegacyaddr, true) - }) - }) - }) - - describe("cashaddr is not legacy addr", () => { - CASH_MAINNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is not a legacy address`, () => { - const isLegacyaddr = SLP.Address.isLegacyAddress(address) - assert.equal(isLegacyaddr, false) - }) - }) - }) - - describe("slpaddr is not legacy addr", () => { - SLP_MAINNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is not a legacy address`, () => { - const isLegacyaddr = SLP.Address.isLegacyAddress(address) - assert.equal(isLegacyaddr, false) - }) - }) - }) - }) - - describe("#isCashAddress", () => { - describe("is cashaddr", () => { - CASH_MAINNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is a cashaddr address`, () => { - const isCashaddr = SLP.Address.isCashAddress(address) - assert.equal(isCashaddr, true) - }) - }) - }) - - describe("legacy is not cash addr", () => { - LEGACY_MAINNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is not a cash address`, () => { - const isCashaddr = SLP.Address.isCashAddress(address) - assert.equal(isCashaddr, false) - }) - }) - }) - - describe("slpaddr is not cash addr", () => { - SLP_MAINNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is not a cash address`, () => { - const isCashaddr = SLP.Address.isCashAddress(address) - assert.equal(isCashaddr, false) - }) - }) - }) - }) - - describe("#isSLPAddress", () => { - describe("is slpaddr", () => { - SLP_MAINNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is an slp address`, () => { - const isSLPaddr = SLP.Address.isSLPAddress(address) - assert.equal(isSLPaddr, true) - }) - }) - }) - - describe("legacy is not slp addr", () => { - LEGACY_MAINNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is not an slp address`, () => { - const isSLPaddr = SLP.Address.isSLPAddress(address) - assert.equal(isSLPaddr, false) - }) - }) - }) - - describe("cash is not slp addr", () => { - CASH_MAINNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is not an slp address`, () => { - const isSLPaddr = SLP.Address.isSLPAddress(address) - assert.equal(isSLPaddr, false) - }) - }) - }) - }) - - describe("#isMainnetAddress", () => { - describe("mainnet legacy addr", () => { - LEGACY_MAINNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is a mainnet address`, () => { - const isMainnetaddr = SLP.Address.isMainnetAddress(address) - assert.equal(isMainnetaddr, true) - }) - }) - }) - - describe("mainnet cash addr", () => { - CASH_MAINNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is a mainnet address`, () => { - const isMainnetaddr = SLP.Address.isMainnetAddress(address) - assert.equal(isMainnetaddr, true) - }) - }) - }) - - describe("mainnet slp addr", () => { - SLP_MAINNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is a mainnet address`, () => { - const isMainnetaddr = SLP.Address.isMainnetAddress(address) - assert.equal(isMainnetaddr, true) - }) - }) - }) - - describe("testnet legacy addr", () => { - LEGACY_TESTNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is not a mainnet address`, () => { - const isMainnetaddr = SLP.Address.isMainnetAddress(address) - assert.equal(isMainnetaddr, false) - }) - }) - }) - - describe("testnet cash addr", () => { - CASH_TESTNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is not a mainnet address`, () => { - const isMainnetaddr = SLP.Address.isMainnetAddress(address) - assert.equal(isMainnetaddr, false) - }) - }) - }) - - describe("testnet slp addr", () => { - SLP_TESTNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is not a mainnet address`, () => { - const isMainnetaddr = SLP.Address.isMainnetAddress(address) - assert.equal(isMainnetaddr, false) - }) - }) - }) - }) - - describe("#isP2PKHAddress", () => { - describe("mainnet legacy addr", () => { - MAINNET_P2PKH_ADDRESSES.forEach(address => { - it(`should detect ${address} is a P2PKH address`, () => { - const isP2PKHaddr = SLP.Address.isP2PKHAddress(address) - assert.equal(isP2PKHaddr, true) - }) - }) - }) - }) - - describe("#isP2SHAddress", () => { - describe("mainnet legacy addr", () => { - MAINNET_P2SH_ADDRESSES.forEach(address => { - it(`should detect ${address} is a P2SH address`, () => { - const isP2SHaddr = SLP.Address.isP2SHAddress(address) - assert.equal(isP2SHaddr, true) - }) - }) - }) - }) - - describe("#detectAddressFormat", () => { - LEGACY_MAINNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is a legacy address`, () => { - const isLegacy = SLP.Address.detectAddressFormat(address) - assert.equal(isLegacy, "legacy") - }) - }) - - CASH_MAINNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is a cash address`, () => { - const isCashaddr = SLP.Address.detectAddressFormat(address) - assert.equal(isCashaddr, "cashaddr") - }) - }) - - SLP_MAINNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is an slp address`, () => { - const isSlpaddr = SLP.Address.detectAddressFormat(address) - assert.equal(isSlpaddr, "slpaddr") - }) - }) - }) - - describe("#detectAddressNetwork", () => { - LEGACY_MAINNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is a mainnet address`, () => { - const isMainnet = SLP.Address.detectAddressNetwork(address) - assert.equal(isMainnet, "mainnet") - }) - }) - - CASH_MAINNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is a mainnet address`, () => { - const isMainnet = SLP.Address.detectAddressNetwork(address) - assert.equal(isMainnet, "mainnet") - }) - }) - - SLP_MAINNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is a mainnet address`, () => { - const isMainnet = SLP.Address.detectAddressNetwork(address) - assert.equal(isMainnet, "mainnet") - }) - }) - }) - - describe("#detectAddressType", () => { - MAINNET_P2PKH_ADDRESSES.forEach(address => { - it(`should detect ${address} is a p2pkh address`, () => { - const isp2pkh = SLP.Address.detectAddressType(address) - assert.equal(isp2pkh, "p2pkh") - }) - }) - - MAINNET_P2SH_ADDRESSES.forEach(address => { - it(`should detect ${address} is a p2sh address`, () => { - const isp2sh = SLP.Address.detectAddressType(address) - assert.equal(isp2sh, "p2sh") - }) - }) - }) - }) - - describe("#testnet", () => { - describe("#toLegacyAddress", () => { - it("should convert testnet legacy address format to itself correctly", () => { - assert.deepEqual( - LEGACY_TESTNET_ADDRESSES.map(address => - SLP.Address.toLegacyAddress(address) - ), - LEGACY_TESTNET_ADDRESSES - ) - }) - - it(`should convert cashAddr to legacyAddr`, async () => { - assert.deepEqual( - CASH_TESTNET_ADDRESSES.map(address => - SLP.Address.toLegacyAddress(address) - ), - LEGACY_TESTNET_ADDRESSES - ) - }) - - it(`should convert slpAddr to legacyAddr`, async () => { - assert.deepEqual( - SLP_TESTNET_ADDRESSES.map(address => - SLP.Address.toLegacyAddress(address) - ), - LEGACY_TESTNET_ADDRESSES - ) - }) - }) - - describe("#toCashAddress", () => { - it("should convert testnet cash address format to itself correctly", () => { - assert.deepEqual( - CASH_TESTNET_ADDRESSES.map(address => - SLP.Address.toCashAddress(address) - ), - CASH_TESTNET_ADDRESSES - ) - }) - - it(`should convert legacyAddr to cashAddr`, async () => { - assert.deepEqual( - LEGACY_TESTNET_ADDRESSES.map(address => - SLP.Address.toCashAddress(address) - ), - CASH_TESTNET_ADDRESSES - ) - }) - - it(`should convert slpAddr to cashAddr`, async () => { - assert.deepEqual( - SLP_TESTNET_ADDRESSES.map(address => - SLP.Address.toCashAddress(address) - ), - CASH_TESTNET_ADDRESSES - ) - }) - }) - - describe("#toSLPAddress", () => { - it("should convert testnet slp address format to itself correctly", () => { - assert.deepEqual( - SLP_TESTNET_ADDRESSES.map(address => - SLP.Address.toSLPAddress(address) - ), - SLP_TESTNET_ADDRESSES - ) - }) - - it(`should convert legacyAddr to slpAddr`, async () => { - assert.deepEqual( - LEGACY_TESTNET_ADDRESSES.map(address => - SLP.Address.toSLPAddress(address) - ), - SLP_TESTNET_ADDRESSES - ) - }) - - it(`should convert cashAddr to slpAddr`, async () => { - assert.deepEqual( - CASH_TESTNET_ADDRESSES.map(address => - SLP.Address.toSLPAddress(address) - ), - SLP_TESTNET_ADDRESSES - ) - }) - }) - - describe("#isLegacyAddress", () => { - describe("is legacy addr", () => { - LEGACY_TESTNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is a legacy address`, () => { - const isLegacyaddr = SLP.Address.isLegacyAddress(address) - assert.equal(isLegacyaddr, true) - }) - }) - }) - - describe("cashaddr is not legacy addr", () => { - CASH_TESTNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is not a legacy address`, () => { - const isLegacyaddr = SLP.Address.isLegacyAddress(address) - assert.equal(isLegacyaddr, false) - }) - }) - }) - - describe("slpaddr is not legacy addr", () => { - SLP_TESTNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is not a legacy address`, () => { - const isLegacyaddr = SLP.Address.isLegacyAddress(address) - assert.equal(isLegacyaddr, false) - }) - }) - }) - }) - - describe("#isCashAddress", () => { - describe("is cashaddr", () => { - CASH_TESTNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is a cashaddr address`, () => { - const isCashaddr = SLP.Address.isCashAddress(address) - assert.equal(isCashaddr, true) - }) - }) - }) - - describe("legacy is not cash addr", () => { - LEGACY_TESTNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is not a cash address`, () => { - const isCashaddr = SLP.Address.isCashAddress(address) - assert.equal(isCashaddr, false) - }) - }) - }) - - describe("slpaddr is not cash addr", () => { - SLP_TESTNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is not a cash address`, () => { - const isCashaddr = SLP.Address.isCashAddress(address) - assert.equal(isCashaddr, false) - }) - }) - }) - }) - - describe("#isSLPAddress", () => { - describe("is slpaddr", () => { - SLP_TESTNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is an slp address`, () => { - const isSLPaddr = SLP.Address.isSLPAddress(address) - assert.equal(isSLPaddr, true) - }) - }) - }) - - describe("legacy is not slp addr", () => { - LEGACY_TESTNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is not an slp address`, () => { - const isSLPaddr = SLP.Address.isSLPAddress(address) - assert.equal(isSLPaddr, false) - }) - }) - }) - - describe("cash is not slp addr", () => { - CASH_TESTNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is not an slp address`, () => { - const isSLPaddr = SLP.Address.isSLPAddress(address) - assert.equal(isSLPaddr, false) - }) - }) - }) - }) - - describe("#isTestnetAddress", () => { - describe("testnet legacy addr", () => { - LEGACY_TESTNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is a testnet address`, () => { - const isTestnetaddr = SLP.Address.isTestnetAddress(address) - assert.equal(isTestnetaddr, true) - }) - }) - }) - - describe("testnet cash addr", () => { - CASH_TESTNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is a testnet address`, () => { - const isTestnetaddr = SLP.Address.isTestnetAddress(address) - assert.equal(isTestnetaddr, true) - }) - }) - }) - - describe("testnet slp addr", () => { - SLP_TESTNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is a testnet address`, () => { - const isTestnetaddr = SLP.Address.isTestnetAddress(address) - assert.equal(isTestnetaddr, true) - }) - }) - }) - - describe("mainnet legacy addr", () => { - LEGACY_MAINNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is not a testnet address`, () => { - const isTestnetaddr = SLP.Address.isTestnetAddress(address) - assert.equal(isTestnetaddr, false) - }) - }) - }) - - describe("mainnet cash addr", () => { - CASH_MAINNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is not a testnet address`, () => { - const isTestnetaddr = SLP.Address.isTestnetAddress(address) - assert.equal(isTestnetaddr, false) - }) - }) - }) - - describe("mainnet slp addr", () => { - SLP_MAINNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is not a testnet address`, () => { - const isTestnetaddr = SLP.Address.isTestnetAddress(address) - assert.equal(isTestnetaddr, false) - }) - }) - }) - }) - - describe("#isP2PKHAddress", () => { - describe("testnet legacy addr", () => { - TESTNET_P2PKH_ADDRESSES.forEach(address => { - it(`should detect ${address} is a P2PKH address`, () => { - const isP2PKHaddr = SLP.Address.isP2PKHAddress(address) - assert.equal(isP2PKHaddr, true) - }) - }) - }) - }) - - describe("#isP2SHAddress", () => { - describe("testnet legacy addr", () => { - TESTNET_P2SH_ADDRESSES.forEach(address => { - it(`should detect ${address} is a P2SH address`, () => { - const isP2SHaddr = SLP.Address.isP2SHAddress(address) - assert.equal(isP2SHaddr, true) - }) - }) - }) - }) - - describe("#detectAddressFormat", () => { - LEGACY_TESTNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is a legacy address`, () => { - const isLegacy = SLP.Address.detectAddressFormat(address) - assert.equal(isLegacy, "legacy") - }) - }) - - CASH_TESTNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is a cash address`, () => { - const isCashaddr = SLP.Address.detectAddressFormat(address) - assert.equal(isCashaddr, "cashaddr") - }) - }) - - SLP_TESTNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is an slp address`, () => { - const isSlpaddr = SLP.Address.detectAddressFormat(address) - assert.equal(isSlpaddr, "slpaddr") - }) - }) - }) - - describe("#detectAddressNetwork", () => { - LEGACY_TESTNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is a testnet address`, () => { - const isTestnet = SLP.Address.detectAddressNetwork(address) - assert.equal(isTestnet, "testnet") - }) - }) - - CASH_TESTNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is a testnet address`, () => { - const isTestnet = SLP.Address.detectAddressNetwork(address) - assert.equal(isTestnet, "testnet") - }) - }) - - SLP_TESTNET_ADDRESSES.forEach(address => { - it(`should detect ${address} is a testnet address`, () => { - const isTestnet = SLP.Address.detectAddressNetwork(address) - assert.equal(isTestnet, "testnet") - }) - }) - }) - - describe("#detectAddressType", () => { - TESTNET_P2PKH_ADDRESSES.forEach(address => { - it(`should detect ${address} is a p2pkh address`, () => { - const isp2pkh = SLP.Address.detectAddressType(address) - assert.equal(isp2pkh, "p2pkh") - }) - }) - }) - - describe("#detectAddressType", () => { - TESTNET_P2SH_ADDRESSES.forEach(address => { - it(`should detect ${address} is a p2sh address`, () => { - const isp2sh = SLP.Address.detectAddressType(address) - assert.equal(isp2sh, "p2sh") - }) - }) - }) - }) -}) -/* -describe("#details", () => { - let sandbox - beforeEach(() => (sandbox = sinon.sandbox.create())) - afterEach(() => sandbox.restore()) - - it("should get details", done => { - const data = { - balance: 0.00000546, - balanceSat: 546, - totalReceived: 0.00426132, - totalReceivedSat: 426132, - totalSent: 0.00425586, - totalSentSat: 425586, - unconfirmedBalance: 0, - unconfirmedBalanceSat: 0, - unconfirmedTxApperances: 0, - txApperances: 3, - transactions: [ - "902fe6ed7a19570c032b3ba4c4d7af92804662b486a15c8ca2d284166c658dd4", - "467969e067f5612863d0bf2daaa70dede2c6be03abb6fd401c5ef6e1e1f1f5c5", - "c1d9f3490e96a1fe4f77195067f1ab12c787f79b39d107424e0c4c810098e11b" - ], - legacyAddress: "1NM2ozrXVSnMRm66ua6aGeXgMsU7yqwqLS", - cashAddress: "bitcoincash:qr4zg7xth86yzq94gl8jvnf5z4wuupzt3g4hl47n9y", - slpAddress: "simpleledger:qr4zg7xth86yzq94gl8jvnf5z4wuupzt3gev5wtnm6", - currentPage: 0, - pagesTotal: 1 - } - - const resolved = new Promise(r => r({ data: data })) - sandbox.stub(axios, "get").returns(resolved) - - SLP.Address.details( - "simpleledger:qr4zg7xth86yzq94gl8jvnf5z4wuupzt3gev5wtnm6" - ) - .then(result => { - assert.deepEqual(data, result) - }) - .then(done, done) - }) -}) - -describe("#utxo", () => { - let sandbox - beforeEach(() => (sandbox = sinon.sandbox.create())) - afterEach(() => sandbox.restore()) - - it("should get utxo", done => { - const data = { - utxos: [ - { - txid: - "467969e067f5612863d0bf2daaa70dede2c6be03abb6fd401c5ef6e1e1f1f5c5", - vout: 1, - amount: 0.00000546, - satoshis: 546, - height: 568215, - confirmations: 24 - } - ], - legacyAddress: "1NM2ozrXVSnMRm66ua6aGeXgMsU7yqwqLS", - cashAddress: "bitcoincash:qr4zg7xth86yzq94gl8jvnf5z4wuupzt3g4hl47n9y", - scriptPubKey: "76a914ea2478cbb9f44100b547cf264d34155dce044b8a88ac" - } - const resolved = new Promise(r => r({ data: data })) - sandbox.stub(axios, "get").returns(resolved) - - SLP.Address.utxo("simpleledger:qr4zg7xth86yzq94gl8jvnf5z4wuupzt3gev5wtnm6") - .then(result => { - assert.deepEqual( - "467969e067f5612863d0bf2daaa70dede2c6be03abb6fd401c5ef6e1e1f1f5c5", - result.utxos[0].txid - ) - }) - .then(done, done) - }) -}) - -describe("#unconfirmed", () => { - let sandbox - beforeEach(() => (sandbox = sinon.sandbox.create())) - afterEach(() => sandbox.restore()) - - it("should get unconfirmed transactions", done => { - const data = { - utxos: [], - legacyAddress: "1NM2ozrXVSnMRm66ua6aGeXgMsU7yqwqLS", - cashAddress: "bitcoincash:qr4zg7xth86yzq94gl8jvnf5z4wuupzt3g4hl47n9y", - slpAddress: "simpleledger:qr4zg7xth86yzq94gl8jvnf5z4wuupzt3gev5wtnm6", - scriptPubKey: "76a914ea2478cbb9f44100b547cf264d34155dce044b8a88ac" - } - const resolved = new Promise(r => r({ data: data })) - sandbox.stub(axios, "get").returns(resolved) - - SLP.Address.unconfirmed( - "simpleledger:qr4zg7xth86yzq94gl8jvnf5z4wuupzt3gev5wtnm6" - ) - .then(result => { - assert.deepEqual(data, result) - }) - .then(done, done) - }) -}) -*/ - -// (async () => { -// try { -// const details = await SLP.Address.unconfirmed( -// "simpleledger:qr4zg7xth86yzq94gl8jvnf5z4wuupzt3gev5wtnm6" -// ) -// console.log(details) -// } catch (error) { -// console.error(error) -// } -// })() diff --git a/test/unit/slp-ecpair.js b/test/unit/slp-ecpair.js deleted file mode 100644 index 3b77972..0000000 --- a/test/unit/slp-ecpair.js +++ /dev/null @@ -1,17 +0,0 @@ -const fixtures = require("./fixtures/slp/ecpair.json") -const assert = require("assert") - -const SLP = require("../../src/slp/slp") -const slp = new SLP({ restURL: "http://fakeurl.com/" }) - -describe("#SLP ECPair", () => { - describe("#toSLPAddress", () => { - it(`should return slp address for ecpair`, async () => { - fixtures.wif.forEach((wif, index) => { - const ecpair = slp.ECPair.fromWIF(wif) - const slpAddr = slp.ECPair.toSLPAddress(ecpair) - assert.equal(slpAddr, fixtures.address[index]) - }) - }) - }) -}) diff --git a/test/unit/slp-nft1.js b/test/unit/slp-nft1.js deleted file mode 100644 index 9e9640b..0000000 --- a/test/unit/slp-nft1.js +++ /dev/null @@ -1,264 +0,0 @@ -/* - Unit tests for the TokenType1 library. -*/ - -const assert = require("chai").assert -const nock = require("nock") // http call mocking -const sinon = require("sinon") -// const axios = require("axios") - -// Default to unit tests unless some other value for TEST is passed. -if (!process.env.TEST) process.env.TEST = "unit" -// const SERVER = bchjs.restURL - -const BCHJS = require("../../src/bch-js") -const bchjs = new BCHJS() - -// Mock data used for unit tests -// const mockData = require("./fixtures/slp/mock-utils") - -// Default to unit tests unless some other value for TEST is passed. -if (!process.env.TEST) process.env.TEST = "unit" - -describe("#SLP NFT1", () => { - let sandbox - - beforeEach(() => { - // Activate nock if it's inactive. - if (!nock.isActive()) nock.activate() - - sandbox = sinon.createSandbox() - }) - - afterEach(() => { - // Clean up HTTP mocks. - nock.cleanAll() // clear interceptor list. - nock.restore() - - sandbox.restore() - }) - - describe("#newNFTGroupOpReturn", () => { - it("should generate new NFT Group OP_RETURN code", () => { - const configObj = { - name: "SLP Test Token", - ticker: "SLPTEST", - documentUrl: "https://bchjs.cash", - documentHash: "", - initialQty: 5 - } - - const result = bchjs.SLP.NFT1.newNFTGroupOpReturn(configObj) - // console.log(`result: `, result) - - assert.equal(Buffer.isBuffer(result), true) - }) - }) - - describe("#mintNFTGroupOpReturn", () => { - it("should generate NFT Group Mint OP_RETURN code", () => { - const tokenUtxoData = [ - { - txid: - "3de3766b10506c9156533f1639979e49d1884521543c13e4af73647df1ed3f76", - vout: 2, - value: "546", - height: 638207, - confirmations: 63, - satoshis: 546, - utxoType: "minting-baton", - transactionType: "mint", - tokenId: - "680967b3f6fe080dbca8dbd370665bd29742e3490db24e2f28d08b424511807e", - tokenType: 129, - tokenTicker: "NFTP", - tokenName: "NFT Parent", - tokenDocumentUrl: "FullStack.cash", - tokenDocumentHash: "", - decimals: 0, - mintBatonVout: 2, - isValid: true - }, - { - txid: - "3de3766b10506c9156533f1639979e49d1884521543c13e4af73647df1ed3f76", - vout: 1, - value: "546", - height: 638207, - confirmations: 63, - satoshis: 546, - utxoType: "token", - tokenQty: 10, - transactionType: "mint", - tokenId: - "680967b3f6fe080dbca8dbd370665bd29742e3490db24e2f28d08b424511807e", - tokenType: 129, - tokenTicker: "NFTP", - tokenName: "NFT Parent", - tokenDocumentUrl: "FullStack.cash", - tokenDocumentHash: "", - decimals: 0, - mintBatonVout: 2, - isValid: true - } - ] - - const result = bchjs.SLP.NFT1.mintNFTGroupOpReturn(tokenUtxoData, 10) - // console.log(`result: `, result) - - assert.equal(Buffer.isBuffer(result), true) - }) - }) - - describe("#generateNFTChildOpReturn", () => { - it("should generate NFT Genesis OP_RETURN code", () => { - const configObj = { - name: "SLP Test Token", - ticker: "SLPTEST", - documentUrl: "https://bchjs.cash", - documentHash: "" - } - - const result = bchjs.SLP.NFT1.generateNFTChildGenesisOpReturn(configObj) - // console.log(`result: `, result) - - assert.equal(Buffer.isBuffer(result), true) - }) - }) - - describe("#generateNFTChildSendOpReturn", () => { - it("should generate send OP_RETURN code for no change", () => { - // Mock UTXO. - const tokenUtxos = [ - { - txid: - "81955624a8eb7011769ff5faa607f78f84b0f8152b9145e7db8b1e521c895ee3", - vout: 1, - value: "546", - height: 638273, - confirmations: 42, - satoshis: 546, - utxoType: "token", - tokenQty: 1, - tokenId: - "81955624a8eb7011769ff5faa607f78f84b0f8152b9145e7db8b1e521c895ee3", - tokenTicker: "NFTC", - tokenName: "NFT Child", - tokenDocumentUrl: "https://FullStack.cash", - tokenDocumentHash: "", - decimals: 0, - tokenType: 129, - isValid: true - } - ] - - const result = bchjs.SLP.NFT1.generateNFTChildSendOpReturn(tokenUtxos, 1) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.hasAllKeys(result, ["script", "outputs"]) - assert.isNumber(result.outputs) - }) - - it("should generate send OP_RETURN code with change", () => { - // Mock UTXO. - const tokenUtxos = [ - { - txid: - "81955624a8eb7011769ff5faa607f78f84b0f8152b9145e7db8b1e521c895ee3", - vout: 1, - value: "546", - height: 638273, - confirmations: 42, - satoshis: 546, - utxoType: "token", - tokenQty: 4, - tokenId: - "81955624a8eb7011769ff5faa607f78f84b0f8152b9145e7db8b1e521c895ee3", - tokenTicker: "NFTC", - tokenName: "NFT Child", - tokenDocumentUrl: "https://FullStack.cash", - tokenDocumentHash: "", - decimals: 0, - tokenType: 129, - isValid: true - } - ] - - const result = bchjs.SLP.NFT1.generateNFTChildSendOpReturn(tokenUtxos, 1) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.hasAllKeys(result, ["script", "outputs"]) - assert.isNumber(result.outputs) - }) - }) - - describe("#generateNFTGroupSendOpReturn", () => { - it("should generate send OP_RETURN with change", () => { - // Mock UTXO. - const tokenUtxos = [ - { - txid: - "35846676e7514658bbd2fd60b1f0d4d86195908f6b2de5328d54c8e4a2d05919", - vout: 1, - value: "546", - height: 638207, - confirmations: 3, - satoshis: 546, - utxoType: "token", - tokenQty: 10, - transactionType: "mint", - tokenId: - "eee4b82e4bb7113eca433829144363fc45f110693c286494fbf5b5c8043cc981", - tokenType: 129, - tokenTicker: "NFTTT", - tokenName: "NFT Test Token", - tokenDocumentUrl: "https://FullStack.cash", - tokenDocumentHash: "", - decimals: 0, - mintBatonVout: 2, - isValid: true - } - ] - - const result = bchjs.SLP.NFT1.generateNFTGroupSendOpReturn(tokenUtxos, 1) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.hasAllKeys(result, ["script", "outputs"]) - assert.isNumber(result.outputs) - }) - - it("should generate send OP_RETURN with no change", () => { - // Mock UTXO. - const tokenUtxos = [ - { - txid: - "35846676e7514658bbd2fd60b1f0d4d86195908f6b2de5328d54c8e4a2d05919", - vout: 1, - value: "546", - height: 638207, - confirmations: 3, - satoshis: 546, - utxoType: "token", - tokenQty: 10, - transactionType: "mint", - tokenId: - "eee4b82e4bb7113eca433829144363fc45f110693c286494fbf5b5c8043cc981", - tokenType: 129, - tokenTicker: "NFTTT", - tokenName: "NFT Test Token", - tokenDocumentUrl: "https://FullStack.cash", - tokenDocumentHash: "", - decimals: 0, - mintBatonVout: 2, - isValid: true - } - ] - - const result = bchjs.SLP.NFT1.generateNFTGroupSendOpReturn(tokenUtxos, 10) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.hasAllKeys(result, ["script", "outputs"]) - assert.isNumber(result.outputs) - }) - }) -}) diff --git a/test/unit/slp-tokentype1.js b/test/unit/slp-tokentype1.js deleted file mode 100644 index 23fa94f..0000000 --- a/test/unit/slp-tokentype1.js +++ /dev/null @@ -1,319 +0,0 @@ -/* - Unit tests for the TokenType1 library. -*/ - -const assert = require("chai").assert -const nock = require("nock") // http call mocking -const sinon = require("sinon") -// const axios = require("axios") - -// Default to unit tests unless some other value for TEST is passed. -if (!process.env.TEST) process.env.TEST = "unit" -// const SERVER = bchjs.restURL - -const BCHJS = require("../../src/bch-js") -const bchjs = new BCHJS() - -// Mock data used for unit tests -// const mockData = require("./fixtures/slp/mock-utils") - -// Default to unit tests unless some other value for TEST is passed. -if (!process.env.TEST) process.env.TEST = "unit" - -describe("#SLP TokenType1", () => { - let sandbox - - beforeEach(() => { - // Activate nock if it's inactive. - if (!nock.isActive()) nock.activate() - - sandbox = sinon.createSandbox() - }) - - afterEach(() => { - // Clean up HTTP mocks. - nock.cleanAll() // clear interceptor list. - nock.restore() - - sandbox.restore() - }) - - describe("#generateSendOpReturn", () => { - it("should generate send OP_RETURN code", () => { - // Mock UTXO. - const tokenUtxos = [ - { - txid: - "a8eb788b8ddda6faea00e6e2756624b8feb97655363d0400dd66839ea619d36e", - vout: 2, - value: "546", - confirmations: 0, - satoshis: 546, - utxoType: "token", - transactionType: "send", - tokenId: - "497291b8a1dfe69c8daea50677a3d31a5ef0e9484d8bebb610dac64bbc202fb7", - tokenTicker: "TOK-CH", - tokenName: "TokyoCash", - tokenDocumentUrl: "", - tokenDocumentHash: "", - decimals: 8, - tokenQty: 7 - } - ] - - const result = bchjs.SLP.TokenType1.generateSendOpReturn(tokenUtxos, 1) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.hasAllKeys(result, ["script", "outputs"]) - assert.isNumber(result.outputs) - }) - }) - - describe("#generateBurnOpReturn", () => { - it("should generate burn OP_RETURN code", () => { - // Mock UTXO. - const tokenUtxos = [ - { - txid: - "a8eb788b8ddda6faea00e6e2756624b8feb97655363d0400dd66839ea619d36e", - vout: 2, - value: "546", - confirmations: 0, - satoshis: 546, - utxoType: "token", - transactionType: "send", - tokenId: - "497291b8a1dfe69c8daea50677a3d31a5ef0e9484d8bebb610dac64bbc202fb7", - tokenTicker: "TOK-CH", - tokenName: "TokyoCash", - tokenDocumentUrl: "", - tokenDocumentHash: "", - decimals: 8, - tokenQty: 7 - } - ] - - const result = bchjs.SLP.TokenType1.generateBurnOpReturn(tokenUtxos, 1) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - // console.log(`result: `, result) - - assert.equal(Buffer.isBuffer(result), true) - }) - }) - - describe("#generateGenesisOpReturn", () => { - it("should generate genesis OP_RETURN code", () => { - const configObj = { - name: "SLP Test Token", - ticker: "SLPTEST", - documentUrl: "https://bchjs.cash", - documentHash: "", - decimals: 8, - initialQty: 10 - } - - const result = bchjs.SLP.TokenType1.generateGenesisOpReturn(configObj) - // console.log(`result: `, result) - - assert.equal(Buffer.isBuffer(result), true) - }) - - it("should work if user does not specify doc hash", () => { - const configObj = { - name: "SLP Test Token", - ticker: "SLPTEST", - documentUrl: "https://bchjs.cash", - decimals: 8, - initialQty: 10 - } - - const result = bchjs.SLP.TokenType1.generateGenesisOpReturn(configObj) - // console.log(`result: `, result) - - assert.equal(Buffer.isBuffer(result), true) - }) - }) - - describe("#generateMintOpReturn", () => { - it("should throw error if tokenUtxos is not an array.", () => { - try { - bchjs.SLP.TokenType1.generateMintOpReturn({}, 100) - - assert.equal(true, false, "Unexpected result.") - } catch (err) { - assert.include( - err.message, - `tokenUtxos must be an array`, - "Expected error message." - ) - } - }) - - it("should throw error if minting baton is not in UTXOs.", () => { - try { - const utxos = [ - { - txid: - "ccc6d336399e26d98afcd3821b41fb1535cd50f57063ed7593eaed5108659606", - vout: 1, - value: "546", - height: 637618, - confirmations: 239, - satoshis: 546, - utxoType: "token", - tokenQty: 100, - tokenId: - "ccc6d336399e26d98afcd3821b41fb1535cd50f57063ed7593eaed5108659606", - tokenTicker: "SLPTEST", - tokenName: "SLP Test Token", - tokenDocumentUrl: "https://FullStack.cash", - tokenDocumentHash: "", - decimals: 8, - isValid: true - } - ] - - bchjs.SLP.TokenType1.generateMintOpReturn(utxos, 100) - - assert.equal(true, false, "Unexpected result.") - } catch (err) { - assert.include( - err.message, - `Minting baton could not be found in tokenUtxos array`, - "Expected error message." - ) - } - }) - - it("should throw error if tokenId is not included in minting-baton UTXO.", () => { - try { - const utxos = [ - { - txid: - "9d35c1803ed3ab8bd23c198b027f7b3b530586494dc265de6391b74a6b090136", - vout: 2, - value: "546", - height: 637625, - confirmations: 207, - satoshis: 546, - utxoType: "minting-baton", - tokenTicker: "SLPTEST", - tokenName: "SLP Test Token", - tokenDocumentUrl: "https://FullStack.cash", - tokenDocumentHash: "", - decimals: 8, - isValid: true - } - ] - - bchjs.SLP.TokenType1.generateMintOpReturn(utxos, 100) - - assert.equal(true, false, "Unexpected result.") - } catch (err) { - assert.include( - err.message, - `tokenId property not found in mint-baton UTXO`, - "Expected error message." - ) - } - }) - - it("should throw error if decimals is not included in minting-baton UTXO.", () => { - try { - const utxos = [ - { - txid: - "9d35c1803ed3ab8bd23c198b027f7b3b530586494dc265de6391b74a6b090136", - vout: 2, - value: "546", - height: 637625, - confirmations: 207, - satoshis: 546, - utxoType: "minting-baton", - tokenId: - "9d35c1803ed3ab8bd23c198b027f7b3b530586494dc265de6391b74a6b090136", - tokenTicker: "SLPTEST", - tokenName: "SLP Test Token", - tokenDocumentUrl: "https://FullStack.cash", - tokenDocumentHash: "", - isValid: true - } - ] - - bchjs.SLP.TokenType1.generateMintOpReturn(utxos, 100) - - assert.equal(true, false, "Unexpected result.") - } catch (err) { - assert.include( - err.message, - `decimals property not found in mint-baton UTXO`, - "Expected error message." - ) - } - }) - - it("should generate genesis OP_RETURN code", () => { - tokenUtxo = [ - { - txid: - "9d35c1803ed3ab8bd23c198b027f7b3b530586494dc265de6391b74a6b090136", - vout: 2, - value: "546", - height: 637625, - confirmations: 207, - satoshis: 546, - utxoType: "minting-baton", - tokenId: - "9d35c1803ed3ab8bd23c198b027f7b3b530586494dc265de6391b74a6b090136", - tokenTicker: "SLPTEST", - tokenName: "SLP Test Token", - tokenDocumentUrl: "https://FullStack.cash", - tokenDocumentHash: "", - decimals: 8, - isValid: true - } - ] - - const result = bchjs.SLP.TokenType1.generateMintOpReturn(tokenUtxo, 100) - // console.log(`result: `, result) - - assert.equal(Buffer.isBuffer(result), true) - }) - }) - - describe("#getHexOpReturn", () => { - it("should return OP_RETURN object ", async () => { - const tokenUtxos = [ - { - tokenId: - "0a321bff9761f28e06a268b14711274bb77617410a16807bd0437ef234a072b1", - decimals: 0, - tokenQty: 2 - } - ] - - const sendQty = 1.5 - - sandbox.stub(bchjs.SLP.TokenType1.axios, "post").resolves({ - data: { - script: - "6a04534c500001010453454e44200a321bff9761f28e06a268b14711274bb77617410a16807bd0437ef234a072b1080000000000000001080000000000000000", - outputs: 2 - } - }) - - const result = await bchjs.SLP.TokenType1.getHexOpReturn( - tokenUtxos, - sendQty - ) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.property(result, "script") - assert.isString(result.script) - - assert.property(result, "outputs") - assert.isNumber(result.outputs) - }) - }) -}) diff --git a/test/unit/transaction-builder.js b/test/unit/transaction-builder.js deleted file mode 100644 index aa5f29f..0000000 --- a/test/unit/transaction-builder.js +++ /dev/null @@ -1,2039 +0,0 @@ -const fixtures = require("./fixtures/transaction-builder.json") -const assert = require("assert") -const BCHJS = require("../../src/bch-js") -const bchjs = new BCHJS() -const Buffer = require("safe-buffer").Buffer - -describe("#TransactionBuilder", () => { - describe("#hashTypes", () => { - const transactionBuilder = new bchjs.TransactionBuilder("mainnet") - fixtures.hashTypes.forEach(fixture => { - it(`should match hash type`, () => { - assert.equal( - fixture[Object.keys(fixture)[0]], - transactionBuilder.hashTypes[Object.keys(fixture)[0]] - ) - }) - }) - }) - - describe("#P2PK", () => { - describe("#toOne", () => { - describe("#Mainnet", () => { - fixtures.scripts.p2pk.toOne.mainnet.forEach(fixture => { - it(`should create 1-to-1 P2PK transaction on mainnet`, () => { - const node = bchjs.HDNode.fromXPriv(fixture.xpriv) - const transactionBuilder = new bchjs.TransactionBuilder() - const originalAmount = fixture.amount - const txid = fixture.txHash - const pubKey = bchjs.HDNode.toPublicKey(node) - const buf = bchjs.Script.pubKey.output.encode(pubKey) - transactionBuilder.addInput( - txid, - 0, - transactionBuilder.DEFAULT_SEQUENCE, - buf - ) - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 1 }, - { P2PKH: 3 } - ) - const sendAmount = originalAmount - byteCount - transactionBuilder.addOutput(buf, sendAmount) - const keyPair = bchjs.HDNode.toKeyPair(node) - let redeemScript - transactionBuilder.sign( - 0, - keyPair, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - originalAmount - ) - const tx = transactionBuilder.build() - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - - describe("#Testnet", () => { - fixtures.scripts.p2pk.toOne.testnet.forEach(fixture => { - it(`should create 1-to-1 P2PK transaction on testnet`, () => { - const node = bchjs.HDNode.fromXPriv(fixture.xpriv) - const transactionBuilder = new bchjs.TransactionBuilder("testnet") - const originalAmount = fixture.amount - const txid = fixture.txHash - const pubKey = bchjs.HDNode.toPublicKey(node) - const buf = bchjs.Script.pubKey.output.encode(pubKey) - transactionBuilder.addInput( - txid, - 0, - transactionBuilder.DEFAULT_SEQUENCE, - buf - ) - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 3 }, - { P2PKH: 3 } - ) - const sendAmount = originalAmount - byteCount - transactionBuilder.addOutput(buf, sendAmount) - const keyPair = bchjs.HDNode.toKeyPair(node) - let redeemScript - transactionBuilder.sign( - 0, - keyPair, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - originalAmount - ) - const tx = transactionBuilder.build() - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - }) - - describe("#toMany", () => { - describe("#Mainnet", () => { - fixtures.scripts.p2pk.toMany.mainnet.forEach(fixture => { - it(`should create 1-to-many P2PK transaction on mainnet`, () => { - const node1 = bchjs.HDNode.fromXPriv(fixture.xprivs[0]) - const node2 = bchjs.HDNode.fromXPriv(fixture.xprivs[1]) - const node3 = bchjs.HDNode.fromXPriv(fixture.xprivs[2]) - const transactionBuilder = new bchjs.TransactionBuilder() - const originalAmount = fixture.amount - const txid = fixture.txHash - const pubKey1 = bchjs.HDNode.toPublicKey(node1) - const pubKey2 = bchjs.HDNode.toPublicKey(node2) - const pubKey3 = bchjs.HDNode.toPublicKey(node3) - const buf1 = bchjs.Script.pubKey.output.encode(pubKey1) - const buf2 = bchjs.Script.pubKey.output.encode(pubKey2) - const buf3 = bchjs.Script.pubKey.output.encode(pubKey3) - transactionBuilder.addInput( - txid, - 0, - transactionBuilder.DEFAULT_SEQUENCE, - buf1 - ) - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 1 }, - { P2PKH: 3 } - ) - const sendAmount = originalAmount - byteCount - transactionBuilder.addOutput(buf2, Math.floor(sendAmount / 2)) - transactionBuilder.addOutput(buf3, Math.floor(sendAmount / 2)) - const keyPair = bchjs.HDNode.toKeyPair(node1) - let redeemScript - transactionBuilder.sign( - 0, - keyPair, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - originalAmount - ) - const tx = transactionBuilder.build() - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - - describe("#Testnet", () => { - fixtures.scripts.p2pk.toMany.testnet.forEach(fixture => { - it(`should create 1-to-many P2PK transaction on testnet`, () => { - const node1 = bchjs.HDNode.fromXPriv(fixture.xprivs[0]) - const node2 = bchjs.HDNode.fromXPriv(fixture.xprivs[1]) - const node3 = bchjs.HDNode.fromXPriv(fixture.xprivs[2]) - const transactionBuilder = new bchjs.TransactionBuilder("testnet") - const originalAmount = fixture.amount - const txid = fixture.txHash - const pubKey1 = bchjs.HDNode.toPublicKey(node1) - const pubKey2 = bchjs.HDNode.toPublicKey(node2) - const pubKey3 = bchjs.HDNode.toPublicKey(node3) - const buf1 = bchjs.Script.pubKey.output.encode(pubKey1) - const buf2 = bchjs.Script.pubKey.output.encode(pubKey2) - const buf3 = bchjs.Script.pubKey.output.encode(pubKey3) - transactionBuilder.addInput( - txid, - 0, - transactionBuilder.DEFAULT_SEQUENCE, - buf1 - ) - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 3 }, - { P2PKH: 3 } - ) - const sendAmount = originalAmount - byteCount - transactionBuilder.addOutput(buf2, Math.floor(sendAmount / 2)) - transactionBuilder.addOutput(buf3, Math.floor(sendAmount / 2)) - const keyPair = bchjs.HDNode.toKeyPair(node1) - let redeemScript - transactionBuilder.sign( - 0, - keyPair, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - originalAmount - ) - const tx = transactionBuilder.build() - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - }) - - describe("#manyToMany", () => { - describe("#Mainnet", () => { - fixtures.scripts.p2pk.manyToMany.mainnet.forEach(fixture => { - it(`should create many-to-many P2PK transaction on mainnet`, () => { - const node1 = bchjs.HDNode.fromXPriv(fixture.xprivs[0]) - const node2 = bchjs.HDNode.fromXPriv(fixture.xprivs[1]) - const node3 = bchjs.HDNode.fromXPriv(fixture.xprivs[2]) - const node4 = bchjs.HDNode.fromXPriv(fixture.xprivs[3]) - const transactionBuilder = new bchjs.TransactionBuilder() - const originalAmount = fixture.amount - const txid = fixture.txHash - const pubKey1 = bchjs.HDNode.toPublicKey(node1) - const pubKey2 = bchjs.HDNode.toPublicKey(node2) - const pubKey3 = bchjs.HDNode.toPublicKey(node3) - const pubKey4 = bchjs.HDNode.toPublicKey(node4) - const buf1 = bchjs.Script.pubKey.output.encode(pubKey1) - const buf2 = bchjs.Script.pubKey.output.encode(pubKey2) - const buf3 = bchjs.Script.pubKey.output.encode(pubKey3) - const buf4 = bchjs.Script.pubKey.output.encode(pubKey4) - transactionBuilder.addInput( - txid, - 0, - transactionBuilder.DEFAULT_SEQUENCE, - buf1 - ) - transactionBuilder.addInput( - txid, - 1, - transactionBuilder.DEFAULT_SEQUENCE, - buf2 - ) - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 3 }, - { P2PKH: 3 } - ) - const sendAmount = originalAmount - byteCount - transactionBuilder.addOutput(buf3, Math.floor(sendAmount / 2)) - transactionBuilder.addOutput(buf4, Math.floor(sendAmount / 2)) - const keyPair1 = bchjs.HDNode.toKeyPair(node1) - const keyPair2 = bchjs.HDNode.toKeyPair(node2) - let redeemScript - transactionBuilder.sign( - 0, - keyPair1, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - originalAmount / 2 - ) - transactionBuilder.sign( - 1, - keyPair2, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - originalAmount / 2 - ) - const tx = transactionBuilder.build() - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - - describe("#Testnet", () => { - fixtures.scripts.p2pk.manyToMany.testnet.forEach(fixture => { - it(`should create many-to-many P2PK transaction on testnet`, () => { - const node1 = bchjs.HDNode.fromXPriv(fixture.xprivs[0]) - const node2 = bchjs.HDNode.fromXPriv(fixture.xprivs[1]) - const node3 = bchjs.HDNode.fromXPriv(fixture.xprivs[2]) - const node4 = bchjs.HDNode.fromXPriv(fixture.xprivs[3]) - const transactionBuilder = new bchjs.TransactionBuilder("testnet") - const originalAmount = fixture.amount - const txid = fixture.txHash - const pubKey1 = bchjs.HDNode.toPublicKey(node1) - const pubKey2 = bchjs.HDNode.toPublicKey(node2) - const pubKey3 = bchjs.HDNode.toPublicKey(node3) - const pubKey4 = bchjs.HDNode.toPublicKey(node4) - const buf1 = bchjs.Script.pubKey.output.encode(pubKey1) - const buf2 = bchjs.Script.pubKey.output.encode(pubKey2) - const buf3 = bchjs.Script.pubKey.output.encode(pubKey3) - const buf4 = bchjs.Script.pubKey.output.encode(pubKey4) - transactionBuilder.addInput( - txid, - 0, - transactionBuilder.DEFAULT_SEQUENCE, - buf1 - ) - transactionBuilder.addInput( - txid, - 1, - transactionBuilder.DEFAULT_SEQUENCE, - buf2 - ) - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 3 }, - { P2PKH: 3 } - ) - const sendAmount = originalAmount - byteCount - transactionBuilder.addOutput(buf3, Math.floor(sendAmount / 2)) - transactionBuilder.addOutput(buf4, Math.floor(sendAmount / 2)) - const keyPair1 = bchjs.HDNode.toKeyPair(node1) - const keyPair2 = bchjs.HDNode.toKeyPair(node2) - let redeemScript - transactionBuilder.sign( - 0, - keyPair1, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - originalAmount / 2 - ) - transactionBuilder.sign( - 1, - keyPair2, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - originalAmount / 2 - ) - const tx = transactionBuilder.build() - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - }) - - describe("#fromMany", () => { - describe("#Mainnet", () => { - fixtures.scripts.p2pk.fromMany.mainnet.forEach(fixture => { - it(`should create many-to-1 P2PK transaction on mainnet`, () => { - const node1 = bchjs.HDNode.fromXPriv(fixture.xprivs[0]) - const node2 = bchjs.HDNode.fromXPriv(fixture.xprivs[1]) - const node3 = bchjs.HDNode.fromXPriv(fixture.xprivs[2]) - const transactionBuilder = new bchjs.TransactionBuilder() - const originalAmount = fixture.amount - const txid = fixture.txHash - const pubKey1 = bchjs.HDNode.toPublicKey(node1) - const pubKey2 = bchjs.HDNode.toPublicKey(node2) - const pubKey3 = bchjs.HDNode.toPublicKey(node3) - const buf1 = bchjs.Script.pubKey.output.encode(pubKey1) - const buf2 = bchjs.Script.pubKey.output.encode(pubKey2) - const buf3 = bchjs.Script.pubKey.output.encode(pubKey3) - transactionBuilder.addInput( - txid, - 0, - transactionBuilder.DEFAULT_SEQUENCE, - buf1 - ) - transactionBuilder.addInput( - txid, - 1, - transactionBuilder.DEFAULT_SEQUENCE, - buf2 - ) - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 3 }, - { P2PKH: 3 } - ) - const sendAmount = originalAmount - byteCount - transactionBuilder.addOutput(buf3, sendAmount) - const keyPair1 = bchjs.HDNode.toKeyPair(node1) - const keyPair2 = bchjs.HDNode.toKeyPair(node2) - let redeemScript - transactionBuilder.sign( - 0, - keyPair1, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - originalAmount / 2 - ) - transactionBuilder.sign( - 1, - keyPair2, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - originalAmount / 2 - ) - const tx = transactionBuilder.build() - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - - describe("#Testnet", () => { - fixtures.scripts.p2pk.fromMany.testnet.forEach(fixture => { - it(`should create many-to-1 P2PK transaction on testnet`, () => { - const node1 = bchjs.HDNode.fromXPriv(fixture.xprivs[0]) - const node2 = bchjs.HDNode.fromXPriv(fixture.xprivs[1]) - const node3 = bchjs.HDNode.fromXPriv(fixture.xprivs[2]) - const transactionBuilder = new bchjs.TransactionBuilder("testnet") - const originalAmount = fixture.amount - const txid = fixture.txHash - const pubKey1 = bchjs.HDNode.toPublicKey(node1) - const pubKey2 = bchjs.HDNode.toPublicKey(node2) - const pubKey3 = bchjs.HDNode.toPublicKey(node3) - const buf1 = bchjs.Script.pubKey.output.encode(pubKey1) - const buf2 = bchjs.Script.pubKey.output.encode(pubKey2) - const buf3 = bchjs.Script.pubKey.output.encode(pubKey3) - transactionBuilder.addInput( - txid, - 0, - transactionBuilder.DEFAULT_SEQUENCE, - buf1 - ) - transactionBuilder.addInput( - txid, - 1, - transactionBuilder.DEFAULT_SEQUENCE, - buf2 - ) - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 3 }, - { P2PKH: 3 } - ) - const sendAmount = originalAmount - byteCount - transactionBuilder.addOutput(buf3, sendAmount) - const keyPair1 = bchjs.HDNode.toKeyPair(node1) - const keyPair2 = bchjs.HDNode.toKeyPair(node2) - let redeemScript - transactionBuilder.sign( - 0, - keyPair1, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - originalAmount / 2 - ) - transactionBuilder.sign( - 1, - keyPair2, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - originalAmount / 2 - ) - const tx = transactionBuilder.build() - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - }) - }) - - describe("#P2PKH", () => { - describe("#toOne", () => { - describe("#Mainnet", () => { - fixtures.scripts.p2pkh.toOne.mainnet.forEach(fixture => { - it(`should create 1-to-1 P2PKH transaction on mainnet`, () => { - const hdnode = bchjs.HDNode.fromXPriv(fixture.xpriv) - const transactionBuilder = new bchjs.TransactionBuilder() - const keyPair = bchjs.HDNode.toKeyPair(hdnode) - const txHash = fixture.txHash - // original amount of satoshis in vin - const originalAmount = fixture.amount - transactionBuilder.addInput(txHash, fixture.vout) - // get byte count to calculate fee. paying 1 sat/byte - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 1 }, - { P2PKH: 1 } - ) - // amount to send to receiver. It's the original amount - 1 sat/byte for tx size - const sendAmount = originalAmount - byteCount - // add output w/ address and amount to send - let redeemScript - transactionBuilder.addOutput(fixture.outputs[0], sendAmount) - transactionBuilder.sign( - 0, - keyPair, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - originalAmount - ) - - // build tx - const tx = transactionBuilder.build() - // output rawhex - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - - describe("#Testnet", () => { - fixtures.scripts.p2pkh.toOne.testnet.forEach(fixture => { - it(`should create 1-to-1 P2PKH transaction on testnet`, () => { - const hdnode = bchjs.HDNode.fromXPriv(fixture.xpriv, "testnet") - const transactionBuilder = new bchjs.TransactionBuilder("testnet") - const keyPair = bchjs.HDNode.toKeyPair(hdnode) - const txHash = fixture.txHash - // original amount of satoshis in vin - const originalAmount = fixture.amount - transactionBuilder.addInput(txHash, fixture.vout) - // get byte count to calculate fee. paying 1 sat/byte - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 1 }, - { P2PKH: 1 } - ) - // amount to send to receiver. It's the original amount - 1 sat/byte for tx size - const sendAmount = originalAmount - byteCount * 15 - // add output w/ address and amount to send - let redeemScript - transactionBuilder.addOutput(fixture.outputs[0], sendAmount) - transactionBuilder.sign( - 0, - keyPair, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - originalAmount - ) - - // build tx - const tx = transactionBuilder.build() - // output rawhex - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - /* - describe("#RegTest", () => { - fixtures.scripts.p2pkh.toOne.regtest.forEach(fixture => { - it(`should create 1-to-1 P2PKH transaction on regtest`, () => { - const hdnode = bchjs.HDNode.fromXPriv(fixture.xpriv) - const transactionBuilder = new bchjs.TransactionBuilder("regtest") - const keyPair = bchjs.HDNode.toKeyPair(hdnode) - const txHash = fixture.txHash - // original amount of satoshis in vin - const originalAmount = fixture.amount - transactionBuilder.addInput(txHash, fixture.vout) - // get byte count to calculate fee. paying 1 sat/byte - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 1 }, - { P2PKH: 1 } - ) - // amount to send to receiver. It's the original amount - 1 sat/byte for tx size - const sendAmount = originalAmount - byteCount * 15 - // add output w/ address and amount to send - let redeemScript - transactionBuilder.addOutput(fixture.outputs[0], sendAmount) - transactionBuilder.sign( - 0, - keyPair, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - originalAmount - ) - - // build tx - const tx = transactionBuilder.build() - // output rawhex - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - */ - }) - - describe("#toMany", () => { - describe("#Mainnet", () => { - fixtures.scripts.p2pkh.toMany.mainnet.forEach(fixture => { - it(`should create 1-to-2 P2PKH transaction on mainnet`, () => { - const hdnode = bchjs.HDNode.fromXPriv(fixture.xpriv) - const transactionBuilder = new bchjs.TransactionBuilder() - const keyPair = bchjs.HDNode.toKeyPair(hdnode) - const txHash = fixture.txHash - // original amount of satoshis in vin - const originalAmount = fixture.amount - transactionBuilder.addInput(txHash, fixture.vout) - // get byte count to calculate fee. paying 1 sat/byte - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 1 }, - { P2PKH: 2 } - ) - // amount to send to receiver. It's the original amount - 1 sat/byte for tx size - const sendAmount = originalAmount - byteCount - // add output w/ address and amount to send - transactionBuilder.addOutput( - fixture.outputs[0], - Math.floor(sendAmount / 2) - ) - transactionBuilder.addOutput( - fixture.outputs[1], - Math.floor(sendAmount / 2) - ) - let redeemScript - transactionBuilder.sign( - 0, - keyPair, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - originalAmount - ) - // build tx - const tx = transactionBuilder.build() - // output rawhex - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - - describe("#Testnet", () => { - fixtures.scripts.p2pkh.toMany.testnet.forEach(fixture => { - // TODO pass in tesnet network config - it(`should create 1-to-2 P2PKH transaction on testnet`, () => { - const hdnode = bchjs.HDNode.fromXPriv(fixture.xpriv) - const transactionBuilder = new bchjs.TransactionBuilder("testnet") - const keyPair = bchjs.HDNode.toKeyPair(hdnode) - const txHash = fixture.txHash - // original amount of satoshis in vin - const originalAmount = fixture.amount - transactionBuilder.addInput(txHash, fixture.vout) - // get byte count to calculate fee. paying 1 sat/byte - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 1 }, - { P2PKH: 2 } - ) - // amount to send to receiver. It's the original amount - 1 sat/byte for tx size - const sendAmount = originalAmount - byteCount * 15 - // add output w/ address and amount to send - transactionBuilder.addOutput( - fixture.outputs[0], - Math.floor(sendAmount / 2) - ) - transactionBuilder.addOutput( - fixture.outputs[1], - Math.floor(sendAmount / 2) - ) - let redeemScript - transactionBuilder.sign( - 0, - keyPair, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - originalAmount - ) - // build tx - const tx = transactionBuilder.build() - // output rawhex - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - /* - describe("#RegTest", () => { - fixtures.scripts.p2pkh.toMany.regtest.forEach(fixture => { - // TODO pass in tesnet network config - it(`should create 1-to-2 P2PKH transaction on regtest`, () => { - const hdnode = bchjs.HDNode.fromXPriv(fixture.xpriv) - const transactionBuilder = new bchjs.TransactionBuilder("regtest") - const keyPair = bchjs.HDNode.toKeyPair(hdnode) - const txHash = fixture.txHash - // original amount of satoshis in vin - const originalAmount = fixture.amount - transactionBuilder.addInput(txHash, fixture.vout) - // get byte count to calculate fee. paying 1 sat/byte - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 1 }, - { P2PKH: 2 } - ) - // amount to send to receiver. It's the original amount - 1 sat/byte for tx size - const sendAmount = originalAmount - byteCount * 15 - // add output w/ address and amount to send - transactionBuilder.addOutput( - fixture.outputs[0], - Math.floor(sendAmount / 2) - ) - transactionBuilder.addOutput( - fixture.outputs[1], - Math.floor(sendAmount / 2) - ) - let redeemScript - transactionBuilder.sign( - 0, - keyPair, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - originalAmount - ) - // build tx - const tx = transactionBuilder.build() - // output rawhex - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - })*/ - }) - - describe("#manyToMany", () => { - describe("#Mainnet", () => { - fixtures.scripts.p2pkh.manyToMany.mainnet.forEach(fixture => { - it(`should create 2-to-2 P2PKH transaction on mainnet`, () => { - const node1 = bchjs.HDNode.fromXPriv(fixture.xprivs[0]) - const node2 = bchjs.HDNode.fromXPriv(fixture.xprivs[1]) - const transactionBuilder = new bchjs.TransactionBuilder() - const txHash = fixture.txHash - const originalAmount = fixture.amounts[0] + fixture.amounts[1] - transactionBuilder.addInput(txHash, 0) - transactionBuilder.addInput(txHash, 1) - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 2 }, - { P2PKH: 2 } - ) - const sendAmount = originalAmount - byteCount - transactionBuilder.addOutput( - fixture.outputs[0], - Math.floor(sendAmount / 2) - ) - transactionBuilder.addOutput( - fixture.outputs[1], - Math.floor(sendAmount / 2) - ) - const keyPair1 = bchjs.HDNode.toKeyPair(node1) - const keyPair2 = bchjs.HDNode.toKeyPair(node2) - let redeemScript - transactionBuilder.sign( - 0, - keyPair1, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - fixture.amounts[0] - ) - transactionBuilder.sign( - 1, - keyPair2, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - fixture.amounts[1] - ) - const tx = transactionBuilder.build() - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - - describe("#Testnet", () => { - fixtures.scripts.p2pkh.manyToMany.testnet.forEach(fixture => { - it(`should create 2-to-2 P2PKH transaction on testnet`, () => { - const node1 = bchjs.HDNode.fromXPriv(fixture.xprivs[0]) - const node2 = bchjs.HDNode.fromXPriv(fixture.xprivs[1]) - const transactionBuilder = new bchjs.TransactionBuilder("testnet") - const txHash = fixture.txHash - const originalAmount = fixture.amounts[0] + fixture.amounts[1] - transactionBuilder.addInput(txHash, 0) - transactionBuilder.addInput(txHash, 1) - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 2 }, - { P2PKH: 2 } - ) - const sendAmount = originalAmount - byteCount * 15 - transactionBuilder.addOutput( - fixture.outputs[0], - Math.floor(sendAmount / 2) - ) - transactionBuilder.addOutput( - fixture.outputs[1], - Math.floor(sendAmount / 2) - ) - const keyPair1 = bchjs.HDNode.toKeyPair(node1) - const keyPair2 = bchjs.HDNode.toKeyPair(node2) - let redeemScript - transactionBuilder.sign( - 0, - keyPair1, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - fixture.amounts[0] - ) - transactionBuilder.sign( - 1, - keyPair2, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - fixture.amounts[1] - ) - const tx = transactionBuilder.build() - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - /* - describe("#RegTest", () => { - fixtures.scripts.p2pkh.manyToMany.regtest.forEach(fixture => { - it(`should create 2-to-2 P2PKH transaction on regtest`, () => { - const node1 = bchjs.HDNode.fromXPriv(fixture.xprivs[0]) - const node2 = bchjs.HDNode.fromXPriv(fixture.xprivs[1]) - const transactionBuilder = new bchjs.TransactionBuilder("regtest") - const txHash = fixture.txHash - const originalAmount = fixture.amounts[0] + fixture.amounts[1] - transactionBuilder.addInput(txHash, 0) - transactionBuilder.addInput(txHash, 1) - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 2 }, - { P2PKH: 2 } - ) - const sendAmount = originalAmount - byteCount * 15 - transactionBuilder.addOutput( - fixture.outputs[0], - Math.floor(sendAmount / 2) - ) - transactionBuilder.addOutput( - fixture.outputs[1], - Math.floor(sendAmount / 2) - ) - const keyPair1 = bchjs.HDNode.toKeyPair(node1) - const keyPair2 = bchjs.HDNode.toKeyPair(node2) - let redeemScript - transactionBuilder.sign( - 0, - keyPair1, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - fixture.amounts[0] - ) - transactionBuilder.sign( - 1, - keyPair2, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - fixture.amounts[1] - ) - const tx = transactionBuilder.build() - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - */ - }) - - describe("#fromMany", () => { - describe("#Mainnet", () => { - fixtures.scripts.p2pkh.fromMany.mainnet.forEach(fixture => { - it(`should create 2-to-1 P2PKH transaction on mainnet`, () => { - const node1 = bchjs.HDNode.fromXPriv(fixture.xprivs[0]) - const node2 = bchjs.HDNode.fromXPriv(fixture.xprivs[1]) - const transactionBuilder = new bchjs.TransactionBuilder() - const txHash = fixture.txHash - const originalAmount = fixture.amounts[0] + fixture.amounts[1] - transactionBuilder.addInput(txHash, 0) - transactionBuilder.addInput(txHash, 1) - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 2 }, - { P2PKH: 1 } - ) - const sendAmount = originalAmount - byteCount - transactionBuilder.addOutput(fixture.outputs[0], sendAmount) - const keyPair1 = bchjs.HDNode.toKeyPair(node1) - const keyPair2 = bchjs.HDNode.toKeyPair(node2) - let redeemScript - transactionBuilder.sign( - 0, - keyPair1, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - fixture.amounts[0] - ) - transactionBuilder.sign( - 1, - keyPair2, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - fixture.amounts[1] - ) - const tx = transactionBuilder.build() - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - - describe("#Testnet", () => { - fixtures.scripts.p2pkh.fromMany.testnet.forEach(fixture => { - it(`should create 2-to-1 P2PKH transaction on testnet`, () => { - const node1 = bchjs.HDNode.fromXPriv(fixture.xprivs[0]) - const node2 = bchjs.HDNode.fromXPriv(fixture.xprivs[1]) - const transactionBuilder = new bchjs.TransactionBuilder("testnet") - const txHash = fixture.txHash - const originalAmount = fixture.amounts[0] + fixture.amounts[1] - transactionBuilder.addInput(txHash, 0) - transactionBuilder.addInput(txHash, 1) - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 2 }, - { P2PKH: 1 } - ) - const sendAmount = originalAmount - byteCount * 15 - transactionBuilder.addOutput(fixture.outputs[0], sendAmount) - const keyPair1 = bchjs.HDNode.toKeyPair(node1) - const keyPair2 = bchjs.HDNode.toKeyPair(node2) - let redeemScript - transactionBuilder.sign( - 0, - keyPair1, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - fixture.amounts[0] - ) - transactionBuilder.sign( - 1, - keyPair2, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - fixture.amounts[1] - ) - const tx = transactionBuilder.build() - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - /* - describe("#RegTest", () => { - fixtures.scripts.p2pkh.fromMany.regtest.forEach(fixture => { - it(`should create 2-to-1 P2PKH transaction on regtest`, () => { - const node1 = bchjs.HDNode.fromXPriv(fixture.xprivs[0]) - const node2 = bchjs.HDNode.fromXPriv(fixture.xprivs[1]) - const transactionBuilder = new bchjs.TransactionBuilder("regtest") - const txHash = fixture.txHash - const originalAmount = fixture.amounts[0] + fixture.amounts[1] - transactionBuilder.addInput(txHash, 0) - transactionBuilder.addInput(txHash, 1) - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 2 }, - { P2PKH: 1 } - ) - const sendAmount = originalAmount - byteCount * 15 - transactionBuilder.addOutput(fixture.outputs[0], sendAmount) - const keyPair1 = bchjs.HDNode.toKeyPair(node1) - const keyPair2 = bchjs.HDNode.toKeyPair(node2) - let redeemScript - transactionBuilder.sign( - 0, - keyPair1, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - fixture.amounts[0] - ) - transactionBuilder.sign( - 1, - keyPair2, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - fixture.amounts[1] - ) - const tx = transactionBuilder.build() - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - */ - }) - }) - - describe("#op_return", () => { - describe("#Mainnet", () => { - fixtures.nulldata.mainnet.forEach(fixture => { - it(`should create transaction w/ OP_RETURN output on mainnet`, () => { - const node = bchjs.HDNode.fromXPriv(fixture.xpriv) - const transactionBuilder = new bchjs.TransactionBuilder() - const txHash = fixture.txHash - const originalAmount = fixture.amount - transactionBuilder.addInput(txHash, 0) - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 1 }, - { P2PKH: 5 } - ) - const sendAmount = originalAmount - byteCount - transactionBuilder.addOutput(fixture.output, sendAmount) - const data = fixture.data - const buf = bchjs.Script.nullData.output.encode( - Buffer.from(data, "ascii") - ) - transactionBuilder.addOutput(buf, 0) - const keyPair = bchjs.HDNode.toKeyPair(node) - let redeemScript - transactionBuilder.sign( - 0, - keyPair, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - fixture.amount - ) - const tx = transactionBuilder.build() - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - - describe("#Testnet", () => { - fixtures.nulldata.testnet.forEach(fixture => { - it(`should create transaction w/ OP_RETURN output on testnet`, () => { - const node = bchjs.HDNode.fromXPriv(fixture.xpriv) - const transactionBuilder = new bchjs.TransactionBuilder("testnet") - const txHash = fixture.txHash - const originalAmount = fixture.amount - transactionBuilder.addInput(txHash, 0) - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 1 }, - { P2PKH: 5 } - ) - const sendAmount = originalAmount - byteCount - transactionBuilder.addOutput(fixture.output, sendAmount) - const data = fixture.data - const buf = bchjs.Script.nullData.output.encode( - Buffer.from(data, "ascii") - ) - transactionBuilder.addOutput(buf, 0) - const keyPair = bchjs.HDNode.toKeyPair(node) - let redeemScript - transactionBuilder.sign( - 0, - keyPair, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - fixture.amount - ) - const tx = transactionBuilder.build() - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - /* - describe("#RegTest", () => { - fixtures.nulldata.regtest.forEach(fixture => { - it(`should create transaction w/ OP_RETURN output on regtest`, () => { - const node = bchjs.HDNode.fromXPriv(fixture.xpriv) - const transactionBuilder = new bchjs.TransactionBuilder("regtest") - const txHash = fixture.txHash - const originalAmount = fixture.amount - transactionBuilder.addInput(txHash, 0) - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 1 }, - { P2PKH: 5 } - ) - const sendAmount = originalAmount - byteCount - transactionBuilder.addOutput(fixture.output, sendAmount) - const data = fixture.data - const buf = bchjs.Script.nullData.output.encode( - Buffer.from(data, "ascii") - ) - transactionBuilder.addOutput(buf, 0) - const keyPair = bchjs.HDNode.toKeyPair(node) - let redeemScript - transactionBuilder.sign( - 0, - keyPair, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - fixture.amount - ) - const tx = transactionBuilder.build() - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - */ - }) - - describe("#P2MS", () => { - describe("#toOne", () => { - describe("#Mainnet", () => { - fixtures.scripts.p2ms.toOne.mainnet.forEach(fixture => { - it(`should create 1-to-1 1-of-2 P2MS transaction on mainnet`, () => { - const node1 = bchjs.HDNode.fromXPriv(fixture.xprivs[0]) - const node2 = bchjs.HDNode.fromXPriv(fixture.xprivs[1]) - const node3 = bchjs.HDNode.fromXPriv(fixture.xprivs[2]) - const node4 = bchjs.HDNode.fromXPriv(fixture.xprivs[3]) - const transactionBuilder = new bchjs.TransactionBuilder() - const txid = fixture.txHash - const originalAmount = fixture.amount - const pubKey1 = bchjs.HDNode.toPublicKey(node1) - const pubKey2 = bchjs.HDNode.toPublicKey(node2) - const buf1 = bchjs.Script.multisig.output.encode(1, [ - pubKey1, - pubKey2 - ]) - transactionBuilder.addInput( - txid, - 0, - transactionBuilder.DEFAULT_SEQUENCE, - buf1 - ) - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 3 }, - { P2PKH: 3 } - ) - const pubKey3 = bchjs.HDNode.toPublicKey(node3) - const pubKey4 = bchjs.HDNode.toPublicKey(node4) - const buf2 = bchjs.Script.multisig.output.encode(1, [ - pubKey3, - pubKey4 - ]) - const sendAmount = originalAmount - byteCount - transactionBuilder.addOutput(buf2, sendAmount) - let redeemScript - const keyPair = bchjs.HDNode.toKeyPair(node1) - transactionBuilder.sign( - 0, - keyPair, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - originalAmount - ) - const tx = transactionBuilder.build() - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - - // describe('#Testnet', () => { - // fixtures.scripts.p2ms.toOne.testnet.forEach((fixture) => { - // it(`should create 1-to-1 P2MS transaction on testnet`, () => { - // let hdnode = bchjs.HDNode.fromXPriv(fixture.xpriv, 'testnet'); - // let transactionBuilder = new bchjs.TransactionBuilder('testnet'); - // let keyPair = bchjs.HDNode.toKeyPair(hdnode); - // let txHash = fixture.txHash; - // // original amount of satoshis in vin - // let originalAmount = fixture.amount; - // transactionBuilder.addInput(txHash, fixture.vout); - // // get byte count to calculate fee. paying 1 sat/byte - // let byteCount = bchjs.BitcoinCash.getByteCount({ P2PKH: 1 }, { P2PKH: 1 }); - // // amount to send to receiver. It's the original amount - 1 sat/byte for tx size - // let sendAmount = originalAmount - (byteCount * 15); - // // add output w/ address and amount to send - // let redeemScript - // transactionBuilder.addOutput(fixture.outputs[0], sendAmount); - // transactionBuilder.sign(0, keyPair, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, originalAmount); - // - // // build tx - // let tx = transactionBuilder.build(); - // // output rawhex - // let hex = tx.toHex(); - // assert.equal(hex, fixture.hex); - // }); - // }); - // }); - }) - - describe("#toMany", () => { - describe("#Mainnet", () => { - fixtures.scripts.p2ms.toMany.mainnet.forEach(fixture => { - it(`should create 1-to-2 P2MS transaction on mainnet`, () => { - const node1 = bchjs.HDNode.fromXPriv(fixture.xprivs[0]) - const node2 = bchjs.HDNode.fromXPriv(fixture.xprivs[1]) - const node3 = bchjs.HDNode.fromXPriv(fixture.xprivs[2]) - const node4 = bchjs.HDNode.fromXPriv(fixture.xprivs[3]) - const node5 = bchjs.HDNode.fromXPriv(fixture.xprivs[4]) - const node6 = bchjs.HDNode.fromXPriv(fixture.xprivs[5]) - const transactionBuilder = new bchjs.TransactionBuilder() - const txid = fixture.txHash - const originalAmount = fixture.amount - const pubKey1 = bchjs.HDNode.toPublicKey(node1) - const pubKey2 = bchjs.HDNode.toPublicKey(node2) - const buf1 = bchjs.Script.multisig.output.encode(1, [ - pubKey1, - pubKey2 - ]) - transactionBuilder.addInput( - txid, - 0, - transactionBuilder.DEFAULT_SEQUENCE, - buf1 - ) - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 3 }, - { P2PKH: 3 } - ) - const sendAmount = originalAmount - byteCount - const pubKey3 = bchjs.HDNode.toPublicKey(node3) - const pubKey4 = bchjs.HDNode.toPublicKey(node4) - const buf2 = bchjs.Script.multisig.output.encode(1, [ - pubKey3, - pubKey4 - ]) - transactionBuilder.addOutput(buf2, Math.floor(sendAmount / 2)) - const pubKey5 = bchjs.HDNode.toPublicKey(node5) - const pubKey6 = bchjs.HDNode.toPublicKey(node6) - const buf3 = bchjs.Script.multisig.output.encode(1, [ - pubKey5, - pubKey6 - ]) - transactionBuilder.addOutput(buf3, Math.floor(sendAmount / 2)) - let redeemScript - const keyPair = bchjs.HDNode.toKeyPair(node1) - transactionBuilder.sign( - 0, - keyPair, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - originalAmount - ) - const tx = transactionBuilder.build() - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - - // describe('#Testnet', () => { - // fixtures.scripts.p2ms.toMany.testnet.forEach((fixture) => { - // // TODO pass in tesnet network config - // it(`should create 1-to-2 P2MS transaction on testnet`, () => { - // let hdnode = bchjs.HDNode.fromXPriv(fixture.xpriv); - // let transactionBuilder = new bchjs.TransactionBuilder('testnet'); - // let keyPair = bchjs.HDNode.toKeyPair(hdnode); - // let txHash = fixture.txHash; - // // original amount of satoshis in vin - // let originalAmount = fixture.amount; - // transactionBuilder.addInput(txHash, fixture.vout); - // // get byte count to calculate fee. paying 1 sat/byte - // let byteCount = bchjs.BitcoinCash.getByteCount({ P2PKH: 1 }, { P2PKH: 2 }); - // // amount to send to receiver. It's the original amount - 1 sat/byte for tx size - // let sendAmount = originalAmount - (byteCount * 15); - // // add output w/ address and amount to send - // transactionBuilder.addOutput(fixture.outputs[0], Math.floor(sendAmount / 2)); - // transactionBuilder.addOutput(fixture.outputs[1], Math.floor(sendAmount / 2)); - // let redeemScript - // transactionBuilder.sign(0, keyPair, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, originalAmount); - // // build tx - // let tx = transactionBuilder.build(); - // // output rawhex - // let hex = tx.toHex(); - // assert.equal(hex, fixture.hex); - // }); - // }); - // }); - }) - - describe("#manyToMany", () => { - describe("#Mainnet", () => { - fixtures.scripts.p2ms.manyToMany.mainnet.forEach(fixture => { - it(`should create 2-to-2 P2MS transaction on mainnet`, () => { - const node1 = bchjs.HDNode.fromXPriv(fixture.xprivs[0]) - const node2 = bchjs.HDNode.fromXPriv(fixture.xprivs[1]) - const node3 = bchjs.HDNode.fromXPriv(fixture.xprivs[2]) - const node4 = bchjs.HDNode.fromXPriv(fixture.xprivs[3]) - const node5 = bchjs.HDNode.fromXPriv(fixture.xprivs[4]) - const node6 = bchjs.HDNode.fromXPriv(fixture.xprivs[5]) - const node7 = bchjs.HDNode.fromXPriv(fixture.xprivs[6]) - const node8 = bchjs.HDNode.fromXPriv(fixture.xprivs[7]) - const transactionBuilder = new bchjs.TransactionBuilder() - const txid = fixture.txHash - const originalAmount = fixture.amount - const pubKey1 = bchjs.HDNode.toPublicKey(node1) - const pubKey2 = bchjs.HDNode.toPublicKey(node2) - const buf1 = bchjs.Script.multisig.output.encode(1, [ - pubKey1, - pubKey2 - ]) - transactionBuilder.addInput( - txid, - 0, - transactionBuilder.DEFAULT_SEQUENCE, - buf1 - ) - const pubKey3 = bchjs.HDNode.toPublicKey(node3) - const pubKey4 = bchjs.HDNode.toPublicKey(node4) - const buf2 = bchjs.Script.multisig.output.encode(1, [ - pubKey3, - pubKey4 - ]) - transactionBuilder.addInput( - txid, - 1, - transactionBuilder.DEFAULT_SEQUENCE, - buf2 - ) - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 3 }, - { P2PKH: 3 } - ) - const sendAmount = originalAmount - byteCount - const pubKey5 = bchjs.HDNode.toPublicKey(node5) - const pubKey6 = bchjs.HDNode.toPublicKey(node6) - const buf3 = bchjs.Script.multisig.output.encode(1, [ - pubKey5, - pubKey6 - ]) - transactionBuilder.addOutput(buf3, Math.floor(sendAmount / 2)) - const pubKey7 = bchjs.HDNode.toPublicKey(node7) - const pubKey8 = bchjs.HDNode.toPublicKey(node8) - const buf4 = bchjs.Script.multisig.output.encode(1, [ - pubKey7, - pubKey8 - ]) - transactionBuilder.addOutput(buf4, Math.floor(sendAmount / 2)) - let redeemScript - const keyPair1 = bchjs.HDNode.toKeyPair(node1) - const keyPair2 = bchjs.HDNode.toKeyPair(node3) - transactionBuilder.sign( - 0, - keyPair1, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - originalAmount / 2 - ) - transactionBuilder.sign( - 1, - keyPair2, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - originalAmount / 2 - ) - const tx = transactionBuilder.build() - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - - // describe('#Testnet', () => { - // fixtures.scripts.p2ms.manyToMany.testnet.forEach((fixture) => { - // it(`should create 2-to-2 P2MS transaction on testnet`, () => { - // let node1 = bchjs.HDNode.fromXPriv(fixture.xprivs[0]); - // let node2 = bchjs.HDNode.fromXPriv(fixture.xprivs[1]); - // let transactionBuilder = new bchjs.TransactionBuilder('testnet'); - // let txHash = fixture.txHash; - // let originalAmount = fixture.amounts[0] + fixture.amounts[1]; - // transactionBuilder.addInput(txHash, 0); - // transactionBuilder.addInput(txHash, 1); - // let byteCount = bchjs.BitcoinCash.getByteCount({ P2PKH: 2 }, { P2PKH: 2 }); - // let sendAmount = originalAmount - (byteCount * 15); - // transactionBuilder.addOutput(fixture.outputs[0], Math.floor(sendAmount / 2)); - // transactionBuilder.addOutput(fixture.outputs[1], Math.floor(sendAmount / 2)); - // let keyPair1 = bchjs.HDNode.toKeyPair(node1); - // let keyPair2 = bchjs.HDNode.toKeyPair(node2); - // let redeemScript; - // transactionBuilder.sign(0, keyPair1, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amounts[0]); - // transactionBuilder.sign(1, keyPair2, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amounts[1]); - // let tx = transactionBuilder.build(); - // let hex = tx.toHex(); - // assert.equal(hex, fixture.hex); - // }); - // }); - // }); - }) - - describe("#fromMany", () => { - describe("#Mainnet", () => { - fixtures.scripts.p2ms.fromMany.mainnet.forEach(fixture => { - it(`should create 2-to-1 P2MS transaction on mainnet`, () => { - const node1 = bchjs.HDNode.fromXPriv(fixture.xprivs[0]) - const node2 = bchjs.HDNode.fromXPriv(fixture.xprivs[1]) - const node3 = bchjs.HDNode.fromXPriv(fixture.xprivs[2]) - const node4 = bchjs.HDNode.fromXPriv(fixture.xprivs[3]) - const node5 = bchjs.HDNode.fromXPriv(fixture.xprivs[4]) - const node6 = bchjs.HDNode.fromXPriv(fixture.xprivs[5]) - const transactionBuilder = new bchjs.TransactionBuilder() - const txid = fixture.txHash - const originalAmount = fixture.amount - const pubKey1 = bchjs.HDNode.toPublicKey(node1) - const pubKey2 = bchjs.HDNode.toPublicKey(node2) - const buf1 = bchjs.Script.multisig.output.encode(1, [ - pubKey1, - pubKey2 - ]) - transactionBuilder.addInput( - txid, - 0, - transactionBuilder.DEFAULT_SEQUENCE, - buf1 - ) - const pubKey3 = bchjs.HDNode.toPublicKey(node3) - const pubKey4 = bchjs.HDNode.toPublicKey(node4) - const buf2 = bchjs.Script.multisig.output.encode(1, [ - pubKey3, - pubKey4 - ]) - transactionBuilder.addInput( - txid, - 1, - transactionBuilder.DEFAULT_SEQUENCE, - buf2 - ) - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 3 }, - { P2PKH: 3 } - ) - const sendAmount = originalAmount - byteCount - const pubKey5 = bchjs.HDNode.toPublicKey(node5) - const pubKey6 = bchjs.HDNode.toPublicKey(node6) - const buf3 = bchjs.Script.multisig.output.encode(1, [ - pubKey5, - pubKey6 - ]) - transactionBuilder.addOutput(buf3, sendAmount) - let redeemScript - const keyPair1 = bchjs.HDNode.toKeyPair(node1) - const keyPair2 = bchjs.HDNode.toKeyPair(node3) - transactionBuilder.sign( - 0, - keyPair1, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - originalAmount / 2 - ) - transactionBuilder.sign( - 1, - keyPair2, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - originalAmount / 2 - ) - const tx = transactionBuilder.build() - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - - // describe('#Testnet', () => { - // fixtures.scripts.p2ms.fromMany.testnet.forEach((fixture) => { - // it(`should create 2-to-1 P2MS transaction on testnet`, () => { - // let node1 = bchjs.HDNode.fromXPriv(fixture.xprivs[0]); - // let node2 = bchjs.HDNode.fromXPriv(fixture.xprivs[1]); - // let transactionBuilder = new bchjs.TransactionBuilder('testnet'); - // let txHash = fixture.txHash; - // let originalAmount = fixture.amounts[0] + fixture.amounts[1]; - // transactionBuilder.addInput(txHash, 0); - // transactionBuilder.addInput(txHash, 1); - // let byteCount = bchjs.BitcoinCash.getByteCount({ P2PKH: 2 }, { P2PKH: 1 }); - // let sendAmount = originalAmount - (byteCount * 15); - // transactionBuilder.addOutput(fixture.outputs[0], sendAmount); - // let keyPair1 = bchjs.HDNode.toKeyPair(node1); - // let keyPair2 = bchjs.HDNode.toKeyPair(node2); - // let redeemScript; - // transactionBuilder.sign(0, keyPair1, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amounts[0]); - // transactionBuilder.sign(1, keyPair2, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amounts[1]); - // let tx = transactionBuilder.build(); - // let hex = tx.toHex(); - // assert.equal(hex, fixture.hex); - // }); - // }); - // }); - }) - }) - - describe("#P2SH", () => { - describe("#toOne", () => { - describe("#Mainnet", () => { - fixtures.scripts.p2sh.toOne.mainnet.forEach(fixture => { - it(`should create 1-to-1 P2SH transaction on mainnet`, () => { - const node1 = bchjs.HDNode.fromXPriv(fixture.xprivs[0]) - const node2 = bchjs.HDNode.fromXPriv(fixture.xprivs[1]) - const transactionBuilder = new bchjs.TransactionBuilder() - const txid = fixture.txHash - const originalAmount = fixture.amount - const identifier1 = bchjs.HDNode.toIdentifier(node1) - const buf1 = bchjs.Script.encode([ - bchjs.Script.opcodes.OP_DUP, - bchjs.Script.opcodes.OP_HASH160, - identifier1, - bchjs.Script.opcodes.OP_EQUALVERIFY, - bchjs.Script.opcodes.OP_CHECKSIG - ]) - const scriptHash1 = bchjs.Crypto.hash160(buf1) - const data1 = bchjs.Script.scriptHash.output.encode(scriptHash1) - transactionBuilder.addInput( - txid, - 0, - transactionBuilder.DEFAULT_SEQUENCE, - data1 - ) - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 2 }, - { P2PKH: 1 } - ) - const sendAmount = originalAmount - byteCount - const identifier2 = bchjs.HDNode.toIdentifier(node2) - const buf2 = bchjs.Script.encode([ - bchjs.Script.opcodes.OP_DUP, - bchjs.Script.opcodes.OP_HASH160, - identifier2, - bchjs.Script.opcodes.OP_EQUALVERIFY, - bchjs.Script.opcodes.OP_CHECKSIG - ]) - - const scriptHash2 = bchjs.Crypto.hash160(buf2) - const data2 = bchjs.Script.scriptHash.output.encode(scriptHash2) - transactionBuilder.addOutput(data2, sendAmount) - const keyPair1 = bchjs.HDNode.toKeyPair(node1) - transactionBuilder.sign( - 0, - keyPair1, - buf1, - transactionBuilder.hashTypes.SIGHASH_ALL, - originalAmount - ) - const tx = transactionBuilder.build() - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - - // describe('#Testnet', () => { - // fixtures.scripts.p2sh.toOne.testnet.forEach((fixture) => { - // it(`should create 1-to-1 P2SH transaction on testnet`, () => { - // let hdnode = bchjs.HDNode.fromXPriv(fixture.xpriv, 'testnet'); - // let transactionBuilder = new bchjs.TransactionBuilder('testnet'); - // let keyPair = bchjs.HDNode.toKeyPair(hdnode); - // let txHash = fixture.txHash; - // // original amount of satoshis in vin - // let originalAmount = fixture.amount; - // transactionBuilder.addInput(txHash, fixture.vout); - // // get byte count to calculate fee. paying 1 sat/byte - // let byteCount = bchjs.BitcoinCash.getByteCount({ P2PKH: 1 }, { P2PKH: 1 }); - // // amount to send to receiver. It's the original amount - 1 sat/byte for tx size - // let sendAmount = originalAmount - (byteCount * 15); - // // add output w/ address and amount to send - // let redeemScript - // transactionBuilder.addOutput(fixture.outputs[0], sendAmount); - // transactionBuilder.sign(0, keyPair, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, originalAmount); - // - // // build tx - // let tx = transactionBuilder.build(); - // // output rawhex - // let hex = tx.toHex(); - // assert.equal(hex, fixture.hex); - // }); - // }); - // }); - }) - - describe("#toMany", () => { - describe("#Mainnet", () => { - fixtures.scripts.p2sh.toMany.mainnet.forEach(fixture => { - it(`should create 1-to-2 P2SH transaction on mainnet`, () => { - const node1 = bchjs.HDNode.fromXPriv(fixture.xprivs[0]) - const node2 = bchjs.HDNode.fromXPriv(fixture.xprivs[1]) - const node3 = bchjs.HDNode.fromXPriv(fixture.xprivs[2]) - const transactionBuilder = new bchjs.TransactionBuilder() - const txid = fixture.txHash - const originalAmount = fixture.amount - const identifier1 = bchjs.HDNode.toIdentifier(node1) - const buf1 = bchjs.Script.encode([ - bchjs.Script.opcodes.OP_DUP, - bchjs.Script.opcodes.OP_HASH160, - identifier1, - bchjs.Script.opcodes.OP_EQUALVERIFY, - bchjs.Script.opcodes.OP_CHECKSIG - ]) - const scriptHash1 = bchjs.Crypto.hash160(buf1) - const data1 = bchjs.Script.scriptHash.output.encode(scriptHash1) - transactionBuilder.addInput( - txid, - 0, - transactionBuilder.DEFAULT_SEQUENCE, - data1 - ) - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 3 }, - { P2PKH: 2 } - ) - const sendAmount = originalAmount - byteCount - const identifier2 = bchjs.HDNode.toIdentifier(node2) - const buf2 = bchjs.Script.encode([ - bchjs.Script.opcodes.OP_DUP, - bchjs.Script.opcodes.OP_HASH160, - identifier2, - bchjs.Script.opcodes.OP_EQUALVERIFY, - bchjs.Script.opcodes.OP_CHECKSIG - ]) - const scriptHash2 = bchjs.Crypto.hash160(buf2) - const data2 = bchjs.Script.scriptHash.output.encode(scriptHash2) - transactionBuilder.addOutput(data2, Math.floor(sendAmount / 2)) - const identifier3 = bchjs.HDNode.toIdentifier(node3) - const buf3 = bchjs.Script.encode([ - bchjs.Script.opcodes.OP_DUP, - bchjs.Script.opcodes.OP_HASH160, - identifier3, - bchjs.Script.opcodes.OP_EQUALVERIFY, - bchjs.Script.opcodes.OP_CHECKSIG - ]) - const scriptHash3 = bchjs.Crypto.hash160(buf3) - const data3 = bchjs.Script.scriptHash.output.encode(scriptHash3) - transactionBuilder.addOutput(data3, Math.floor(sendAmount / 2)) - const keyPair1 = bchjs.HDNode.toKeyPair(node1) - transactionBuilder.sign( - 0, - keyPair1, - buf1, - transactionBuilder.hashTypes.SIGHASH_ALL, - originalAmount - ) - const tx = transactionBuilder.build() - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - - // describe('#Testnet', () => { - // fixtures.scripts.p2sh.toMany.testnet.forEach((fixture) => { - // // TODO pass in tesnet network config - // it(`should create 1-to-2 P2SH transaction on testnet`, () => { - // let hdnode = bchjs.HDNode.fromXPriv(fixture.xpriv); - // let transactionBuilder = new bchjs.TransactionBuilder('testnet'); - // let keyPair = bchjs.HDNode.toKeyPair(hdnode); - // let txHash = fixture.txHash; - // // original amount of satoshis in vin - // let originalAmount = fixture.amount; - // transactionBuilder.addInput(txHash, fixture.vout); - // // get byte count to calculate fee. paying 1 sat/byte - // let byteCount = bchjs.BitcoinCash.getByteCount({ P2PKH: 1 }, { P2PKH: 2 }); - // // amount to send to receiver. It's the original amount - 1 sat/byte for tx size - // let sendAmount = originalAmount - (byteCount * 15); - // // add output w/ address and amount to send - // transactionBuilder.addOutput(fixture.outputs[0], Math.floor(sendAmount / 2)); - // transactionBuilder.addOutput(fixture.outputs[1], Math.floor(sendAmount / 2)); - // let redeemScript - // transactionBuilder.sign(0, keyPair, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, originalAmount); - // // build tx - // let tx = transactionBuilder.build(); - // // output rawhex - // let hex = tx.toHex(); - // assert.equal(hex, fixture.hex); - // }); - // }); - // }); - }) - - describe("#manyToMany", () => { - describe("#Mainnet", () => { - fixtures.scripts.p2sh.manyToMany.mainnet.forEach(fixture => { - it(`should create 2-to-2 P2SH transaction on mainnet`, () => { - const node1 = bchjs.HDNode.fromXPriv(fixture.xprivs[0]) - const node2 = bchjs.HDNode.fromXPriv(fixture.xprivs[1]) - const node3 = bchjs.HDNode.fromXPriv(fixture.xprivs[2]) - const node4 = bchjs.HDNode.fromXPriv(fixture.xprivs[3]) - const transactionBuilder = new bchjs.TransactionBuilder() - const txid = fixture.txHash - const originalAmount = fixture.amount - const identifier1 = bchjs.HDNode.toIdentifier(node1) - const buf1 = bchjs.Script.encode([ - bchjs.Script.opcodes.OP_DUP, - bchjs.Script.opcodes.OP_HASH160, - identifier1, - bchjs.Script.opcodes.OP_EQUALVERIFY, - bchjs.Script.opcodes.OP_CHECKSIG - ]) - const scriptHash1 = bchjs.Crypto.hash160(buf1) - const data1 = bchjs.Script.scriptHash.output.encode(scriptHash1) - transactionBuilder.addInput( - txid, - 0, - transactionBuilder.DEFAULT_SEQUENCE, - data1 - ) - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 5 }, - { P2PKH: 5 } - ) - const sendAmount = originalAmount - byteCount - const identifier2 = bchjs.HDNode.toIdentifier(node2) - const buf2 = bchjs.Script.encode([ - bchjs.Script.opcodes.OP_DUP, - bchjs.Script.opcodes.OP_HASH160, - identifier2, - bchjs.Script.opcodes.OP_EQUALVERIFY, - bchjs.Script.opcodes.OP_CHECKSIG - ]) - const scriptHash2 = bchjs.Crypto.hash160(buf2) - const data2 = bchjs.Script.scriptHash.output.encode(scriptHash2) - transactionBuilder.addInput( - txid, - 1, - transactionBuilder.DEFAULT_SEQUENCE, - data2 - ) - const identifier3 = bchjs.HDNode.toIdentifier(node3) - const buf3 = bchjs.Script.encode([ - bchjs.Script.opcodes.OP_DUP, - bchjs.Script.opcodes.OP_HASH160, - identifier3, - bchjs.Script.opcodes.OP_EQUALVERIFY, - bchjs.Script.opcodes.OP_CHECKSIG - ]) - const scriptHash3 = bchjs.Crypto.hash160(buf3) - const data3 = bchjs.Script.scriptHash.output.encode(scriptHash3) - transactionBuilder.addOutput(data3, Math.floor(sendAmount / 2)) - const identifier4 = bchjs.HDNode.toIdentifier(node4) - const buf4 = bchjs.Script.encode([ - bchjs.Script.opcodes.OP_DUP, - bchjs.Script.opcodes.OP_HASH160, - identifier4, - bchjs.Script.opcodes.OP_EQUALVERIFY, - bchjs.Script.opcodes.OP_CHECKSIG - ]) - const scriptHash4 = bchjs.Crypto.hash160(buf4) - const data4 = bchjs.Script.scriptHash.output.encode(scriptHash4) - transactionBuilder.addOutput(data4, Math.floor(sendAmount / 2)) - const keyPair1 = bchjs.HDNode.toKeyPair(node1) - const keyPair2 = bchjs.HDNode.toKeyPair(node2) - transactionBuilder.sign( - 0, - keyPair1, - buf1, - transactionBuilder.hashTypes.SIGHASH_ALL, - originalAmount / 2 - ) - transactionBuilder.sign( - 1, - keyPair2, - buf2, - transactionBuilder.hashTypes.SIGHASH_ALL, - originalAmount / 2 - ) - const tx = transactionBuilder.build() - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - - // describe('#Testnet', () => { - // fixtures.scripts.p2sh.manyToMany.testnet.forEach((fixture) => { - // it(`should create 2-to-2 P2SH transaction on testnet`, () => { - // let node1 = bchjs.HDNode.fromXPriv(fixture.xprivs[0]); - // let node2 = bchjs.HDNode.fromXPriv(fixture.xprivs[1]); - // let transactionBuilder = new bchjs.TransactionBuilder('testnet'); - // let txHash = fixture.txHash; - // let originalAmount = fixture.amounts[0] + fixture.amounts[1]; - // transactionBuilder.addInput(txHash, 0); - // transactionBuilder.addInput(txHash, 1); - // let byteCount = bchjs.BitcoinCash.getByteCount({ P2PKH: 2 }, { P2PKH: 2 }); - // let sendAmount = originalAmount - (byteCount * 15); - // transactionBuilder.addOutput(fixture.outputs[0], Math.floor(sendAmount / 2)); - // transactionBuilder.addOutput(fixture.outputs[1], Math.floor(sendAmount / 2)); - // let keyPair1 = bchjs.HDNode.toKeyPair(node1); - // let keyPair2 = bchjs.HDNode.toKeyPair(node2); - // let redeemScript; - // transactionBuilder.sign(0, keyPair1, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amounts[0]); - // transactionBuilder.sign(1, keyPair2, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amounts[1]); - // let tx = transactionBuilder.build(); - // let hex = tx.toHex(); - // assert.equal(hex, fixture.hex); - // }); - // }); - // }); - }) - - describe("#fromMany", () => { - describe("#Mainnet", () => { - fixtures.scripts.p2sh.fromMany.mainnet.forEach(fixture => { - it(`should create 2-to-1 P2SH transaction on mainnet`, () => { - const node1 = bchjs.HDNode.fromXPriv(fixture.xprivs[0]) - const node2 = bchjs.HDNode.fromXPriv(fixture.xprivs[1]) - const node3 = bchjs.HDNode.fromXPriv(fixture.xprivs[2]) - const transactionBuilder = new bchjs.TransactionBuilder() - const txid = fixture.txHash - const originalAmount = fixture.amount - const identifier1 = bchjs.HDNode.toIdentifier(node1) - const buf1 = bchjs.Script.encode([ - bchjs.Script.opcodes.OP_DUP, - bchjs.Script.opcodes.OP_HASH160, - identifier1, - bchjs.Script.opcodes.OP_EQUALVERIFY, - bchjs.Script.opcodes.OP_CHECKSIG - ]) - const scriptHash1 = bchjs.Crypto.hash160(buf1) - const data1 = bchjs.Script.scriptHash.output.encode(scriptHash1) - transactionBuilder.addInput( - txid, - 0, - transactionBuilder.DEFAULT_SEQUENCE, - data1 - ) - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 3 }, - { P2PKH: 2 } - ) - const sendAmount = originalAmount - byteCount - const identifier2 = bchjs.HDNode.toIdentifier(node2) - const buf2 = bchjs.Script.encode([ - bchjs.Script.opcodes.OP_DUP, - bchjs.Script.opcodes.OP_HASH160, - identifier2, - bchjs.Script.opcodes.OP_EQUALVERIFY, - bchjs.Script.opcodes.OP_CHECKSIG - ]) - const scriptHash2 = bchjs.Crypto.hash160(buf2) - const data2 = bchjs.Script.scriptHash.output.encode(scriptHash2) - transactionBuilder.addInput( - txid, - 1, - transactionBuilder.DEFAULT_SEQUENCE, - data2 - ) - const identifier3 = bchjs.HDNode.toIdentifier(node3) - const buf3 = bchjs.Script.encode([ - bchjs.Script.opcodes.OP_DUP, - bchjs.Script.opcodes.OP_HASH160, - identifier3, - bchjs.Script.opcodes.OP_EQUALVERIFY, - bchjs.Script.opcodes.OP_CHECKSIG - ]) - const scriptHash3 = bchjs.Crypto.hash160(buf3) - const data3 = bchjs.Script.scriptHash.output.encode(scriptHash3) - transactionBuilder.addOutput(data3, sendAmount) - const keyPair1 = bchjs.HDNode.toKeyPair(node1) - const keyPair2 = bchjs.HDNode.toKeyPair(node2) - transactionBuilder.sign( - 0, - keyPair1, - buf1, - transactionBuilder.hashTypes.SIGHASH_ALL, - originalAmount / 2 - ) - transactionBuilder.sign( - 1, - keyPair2, - buf2, - transactionBuilder.hashTypes.SIGHASH_ALL, - originalAmount / 2 - ) - const tx = transactionBuilder.build() - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - - // describe('#Testnet', () => { - // fixtures.scripts.p2sh.fromMany.testnet.forEach((fixture) => { - // it(`should create 2-to-1 P2SH transaction on testnet`, () => { - // let node1 = bchjs.HDNode.fromXPriv(fixture.xprivs[0]); - // let node2 = bchjs.HDNode.fromXPriv(fixture.xprivs[1]); - // let transactionBuilder = new bchjs.TransactionBuilder('testnet'); - // let txHash = fixture.txHash; - // let originalAmount = fixture.amounts[0] + fixture.amounts[1]; - // transactionBuilder.addInput(txHash, 0); - // transactionBuilder.addInput(txHash, 1); - // let byteCount = bchjs.BitcoinCash.getByteCount({ P2PKH: 2 }, { P2PKH: 1 }); - // let sendAmount = originalAmount - (byteCount * 15); - // transactionBuilder.addOutput(fixture.outputs[0], sendAmount); - // let keyPair1 = bchjs.HDNode.toKeyPair(node1); - // let keyPair2 = bchjs.HDNode.toKeyPair(node2); - // let redeemScript; - // transactionBuilder.sign(0, keyPair1, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amounts[0]); - // transactionBuilder.sign(1, keyPair2, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, fixture.amounts[1]); - // let tx = transactionBuilder.build(); - // let hex = tx.toHex(); - // assert.equal(hex, fixture.hex); - // }); - // }); - // }); - }) - }) - - describe("#op_return", () => { - describe("#Mainnet", () => { - fixtures.nulldata.mainnet.forEach(fixture => { - it(`should create transaction w/ OP_RETURN output on mainnet`, () => { - const node = bchjs.HDNode.fromXPriv(fixture.xpriv) - const transactionBuilder = new bchjs.TransactionBuilder() - const txHash = fixture.txHash - const originalAmount = fixture.amount - transactionBuilder.addInput(txHash, 0) - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 1 }, - { P2PKH: 5 } - ) - const sendAmount = originalAmount - byteCount - transactionBuilder.addOutput(fixture.output, sendAmount) - const data = fixture.data - const buf = bchjs.Script.nullData.output.encode( - Buffer.from(data, "ascii") - ) - transactionBuilder.addOutput(buf, 0) - const keyPair = bchjs.HDNode.toKeyPair(node) - let redeemScript - transactionBuilder.sign( - 0, - keyPair, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - fixture.amount - ) - const tx = transactionBuilder.build() - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - - describe("#Testnet", () => { - fixtures.nulldata.testnet.forEach(fixture => { - it(`should create transaction w/ OP_RETURN output on testnet`, () => { - const node = bchjs.HDNode.fromXPriv(fixture.xpriv) - const transactionBuilder = new bchjs.TransactionBuilder("testnet") - const txHash = fixture.txHash - const originalAmount = fixture.amount - transactionBuilder.addInput(txHash, 0) - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 1 }, - { P2PKH: 5 } - ) - const sendAmount = originalAmount - byteCount - transactionBuilder.addOutput(fixture.output, sendAmount) - const data = fixture.data - const buf = bchjs.Script.nullData.output.encode( - Buffer.from(data, "ascii") - ) - transactionBuilder.addOutput(buf, 0) - const keyPair = bchjs.HDNode.toKeyPair(node) - let redeemScript - transactionBuilder.sign( - 0, - keyPair, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - fixture.amount - ) - const tx = transactionBuilder.build() - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - /* - describe("#RegTest", () => { - fixtures.nulldata.regtest.forEach(fixture => { - it(`should create transaction w/ OP_RETURN output on regtest`, () => { - const node = bchjs.HDNode.fromXPriv(fixture.xpriv) - const transactionBuilder = new bchjs.TransactionBuilder("regtest") - const txHash = fixture.txHash - const originalAmount = fixture.amount - transactionBuilder.addInput(txHash, 0) - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 1 }, - { P2PKH: 5 } - ) - const sendAmount = originalAmount - byteCount - transactionBuilder.addOutput(fixture.output, sendAmount) - const data = fixture.data - const buf = bchjs.Script.nullData.output.encode( - Buffer.from(data, "ascii") - ) - transactionBuilder.addOutput(buf, 0) - const keyPair = bchjs.HDNode.toKeyPair(node) - let redeemScript - transactionBuilder.sign( - 0, - keyPair, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - fixture.amount - ) - const tx = transactionBuilder.build() - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) -*/ - }) - - describe("#bip66", () => { - fixtures.bip66.forEach(fixture => { - it(`should bip66 encode as ${fixture.DER}`, () => { - const transactionBuilder = new bchjs.TransactionBuilder() - const r = Buffer.from(fixture.r, "hex") - const s = Buffer.from(fixture.s, "hex") - const DER = transactionBuilder.bip66.encode(r, s) - assert.equal(DER.toString("hex"), fixture.DER) - }) - }) - - fixtures.bip66.forEach(fixture => { - it(`should bip66 decode ${fixture.DER}`, () => { - const transactionBuilder = new bchjs.TransactionBuilder() - const buffer = Buffer.from(fixture.DER, "hex") - const signature = transactionBuilder.bip66.decode(buffer) - assert.equal(signature.r.toString("hex"), fixture.r) - assert.equal(signature.s.toString("hex"), fixture.s) - }) - }) - - fixtures.bip66.forEach(fixture => { - it(`should bip66 check ${fixture.DER}`, () => { - const transactionBuilder = new bchjs.TransactionBuilder() - const buffer = Buffer.from(fixture.DER, "hex") - assert.equal(transactionBuilder.bip66.check(buffer), true) - }) - }) - }) - - describe("#bip68", () => { - fixtures.bip68.encode.forEach(fixture => { - it(`should bip68 encode as ${fixture.result}`, () => { - const transactionBuilder = new bchjs.TransactionBuilder() - const obj = {} - obj[fixture.type] = fixture.value - const encode = transactionBuilder.bip68.encode(obj) - assert.equal(encode, fixture.result) - }) - }) - - fixtures.bip68.decode.forEach(fixture => { - it(`should bip68 decode ${fixture.result}`, () => { - const transactionBuilder = new bchjs.TransactionBuilder() - const obj = {} - const decode = transactionBuilder.bip68.decode(fixture.result) - assert.equal(Object.keys(decode)[0], fixture.type) - assert.deepEqual(decode[Object.keys(decode)[0]], fixture.value) - }) - }) - }) - - describe("#LockTime", () => { - describe("#Mainnet", () => { - fixtures.locktime.mainnet.forEach(fixture => { - it(`should create transaction with nLockTime on mainnet`, () => { - const node = bchjs.HDNode.fromXPriv(fixture.xpriv) - const transactionBuilder = new bchjs.TransactionBuilder() - - const txHash = fixture.txHash - const originalAmount = fixture.amount - transactionBuilder.addInput(txHash, 0, 1) - const byteCount = bchjs.BitcoinCash.getByteCount( - { P2PKH: 1 }, - { P2PKH: 1 } - ) - const sendAmount = originalAmount - byteCount - transactionBuilder.addOutput(fixture.output, sendAmount) - const lockTime = fixture.lockTime - transactionBuilder.setLockTime(lockTime) - const keyPair = bchjs.HDNode.toKeyPair(node) - let redeemScript - transactionBuilder.sign( - 0, - keyPair, - redeemScript, - transactionBuilder.hashTypes.SIGHASH_ALL, - fixture.amount - ) - const tx = transactionBuilder.build() - const hex = tx.toHex() - assert.equal(hex, fixture.hex) - }) - }) - }) - }) -}) diff --git a/test/unit/util.js b/test/unit/util.js deleted file mode 100644 index 7a17955..0000000 --- a/test/unit/util.js +++ /dev/null @@ -1,35 +0,0 @@ -const assert = require("assert") -const axios = require("axios") -const BCHJS = require("../../src/bch-js") -const bchjs = new BCHJS() -const sinon = require("sinon") - -describe("#Util", () => { - describe("#validateAddress", () => { - let sandbox - beforeEach(() => (sandbox = sinon.createSandbox())) - afterEach(() => sandbox.restore()) - - it("should validate address", done => { - const data = { - isvalid: true, - address: "bitcoincash:qpz7qtkuyhrsz4qmnnrvf8gz9zd0u9v7eqsewyk4w5", - scriptPubKey: "76a91445e02edc25c701541b9cc6c49d02289afe159ec888ac", - ismine: false, - iswatchonly: false, - isscript: false - } - - const resolved = new Promise(r => r({ data: data })) - sandbox.stub(axios, "get").returns(resolved) - - bchjs.Util.validateAddress( - "bitcoincash:qpz7qtkuyhrsz4qmnnrvf8gz9zd0u9v7eqsewyk4w5" - ) - .then(result => { - assert.deepEqual(data, result) - }) - .then(done, done) - }) - }) -})