Files
bch-js/src/address.js
T

758 lines
23 KiB
JavaScript

// const axios = require("axios")
const Bitcoin = require('@psf/bitcoincashjs-lib')
const cashaddr = require('cashaddrjs')
const coininfo = require('@psf/coininfo')
class Address {
constructor (config) {
const tmp = {}
if (!config || !config.restURL) tmp.restURL = 'https://api.bchjs.cash/v4/'
else tmp.restURL = config.restURL
this.restURL = tmp.restURL
this.apiToken = tmp.apiToken
this.authToken = config.authToken
if (this.authToken) {
// Add Basic Authentication token to the authorization header.
this.axiosOptions = {
headers: {
authorization: this.authToken
}
}
} else {
// Add JWT token to the authorization header.
this.axiosOptions = {
headers: {
authorization: `Token ${this.apiToken}`
}
}
}
}
/**
* @api Address.toLegacyAddress() toLegacyAddress()
* @apiName toLegacyAddress
* @apiGroup Address
* @apiDescription Convert cashaddr to legacy address format
*
* @apiExample Example usage:
* // mainnet w/ prefix
* bchjs.Address.toLegacyAddress('bitcoincash:qzm47qz5ue99y9yl4aca7jnz7dwgdenl85jkfx3znl')
* // 1HiaTupadqQN66Tvgt7QSE5Wg13BUy25eN
*
* // mainnet w/ no prefix
* bchjs.Address.toLegacyAddress('qzm47qz5ue99y9yl4aca7jnz7dwgdenl85jkfx3znl')
* // 1HiaTupadqQN66Tvgt7QSE5Wg13BUy25eN
*
* // testnet w/ prefix
* bchjs.Address.toLegacyAddress('bchtest:qph2v4mkxjgdqgmlyjx6njmey0ftrxlnggt9t0a6zy')
* // mqc1tmwY2368LLGktnePzEyPAsgADxbksi
*
* // testnet w/ no prefix
* bchjs.Address.toLegacyAddress('qph2v4mkxjgdqgmlyjx6njmey0ftrxlnggt9t0a6zy')
* // mqc1tmwY2368LLGktnePzEyPAsgADxbksi
*/
// Translate address from any address format into a specific format.
toLegacyAddress (address) {
const { prefix, type, hash } = this._decode(address)
let bitcoincash
switch (prefix) {
case 'bitcoincash':
bitcoincash = coininfo.bitcoincash.main
break
case 'bchtest':
bitcoincash = coininfo.bitcoincash.test
break
case 'bchreg':
bitcoincash = coininfo.bitcoincash.regtest
break
default:
throw new Error(`unsupported prefix : ${prefix}`)
}
let version
switch (type) {
case 'P2PKH':
version = bitcoincash.versions.public
break
case 'P2SH':
version = bitcoincash.versions.scripthash
break
default:
throw new Error(`unsupported address type : ${type}`)
}
const hashBuf = Buffer.from(hash)
return Bitcoin.address.toBase58Check(hashBuf, version)
}
/**
* @api Address.toCashAddress() toCashAddress()
* @apiName toCashAddress
* @apiGroup Address
* @apiDescription Convert legacy to cashAddress format
*
* @apiExample Example usage:
* // mainnet
* bchjs.Address.toCashAddress('1HiaTupadqQN66Tvgt7QSE5Wg13BUy25eN')
* // bitcoincash:qzm47qz5ue99y9yl4aca7jnz7dwgdenl85jkfx3znl
*
* // mainnet no prefix
* bchjs.Address.toCashAddress('1HiaTupadqQN66Tvgt7QSE5Wg13BUy25eN', false)
* // qzm47qz5ue99y9yl4aca7jnz7dwgdenl85jkfx3znl
*
* // tesnet
* bchjs.Address.toCashAddress('msDbtTj7kWXPpYaR7PQmMK84i66fJqQMLx')
* // bchtest:qzq9je6pntpva3wf6scr7mlnycr54sjgeqxgrr9ku3
*
* // testnet no prefix
* bchjs.Address.toCashAddress('msDbtTj7kWXPpYaR7PQmMK84i66fJqQMLx', false)
* // qzq9je6pntpva3wf6scr7mlnycr54sjgeqxgrr9ku3
*/
toCashAddress (address, prefix = true, regtest = false) {
const decoded = this._decode(address)
let prefixString
if (regtest) prefixString = 'bchreg'
else prefixString = decoded.prefix
const cashAddress = cashaddr.encode(
prefixString,
decoded.type,
decoded.hash
)
if (prefix) return cashAddress
return cashAddress.split(':')[1]
}
// Converts any address format to hash160
toHash160 (address) {
const legacyAddress = this.toLegacyAddress(address)
const bytes = Bitcoin.address.fromBase58Check(legacyAddress)
return bytes.hash.toString('hex')
}
/**
* @api Address.hash160ToLegacy() hash160ToLegacy()
* @apiName hash160ToLegacy
* @apiGroup Address
* @apiDescription Convert hash160 to legacy address.
*
* @apiExample Example usage:
* // legacy mainnet p2pkh
* bchjs.Address.hash160ToLegacy("573d93b475be4f1925f3b74ed951201b0147eac1")
* // 18xHZ8g2feo4ceejGpvzHkvXT79fi2ZdTG
*
* // legacy mainnet p2sh
* bchjs.Address.hash160ToLegacy("7dc85da64d1d93ef01ef62e0221c02f512e3942f", 0x05)
* // 3DA6RBcFgLwLTpnF6BRAee8w6a9H6JQLCm
*
* // legacy testnet p2pkh
* bchjs.Address.hash160ToLegacy("155187a3283b08b30519db50bc23bbba9f4b6657", 0x6f)
* // mhTg9sgNgvAGfmJs192oUzQWqAXHH5nqLE
*/
// Converts hash160 to Legacy Address
hash160ToLegacy (hash160, network = Bitcoin.networks.bitcoin.pubKeyHash) {
const buffer = Buffer.from(hash160, 'hex')
const legacyAddress = Bitcoin.address.toBase58Check(buffer, network)
return legacyAddress
}
/**
* @api Address.hash160ToCash() hash160ToCash()
* @apiName hash160ToCash
* @apiGroup Address
* @apiDescription Convert hash160 to cash address.
*
* @apiExample Example usage:
* bchjs.Address.hash160ToCash("573d93b475be4f1925f3b74ed951201b0147eac1")
* 'bitcoincash:qptnmya5wkly7xf97wm5ak23yqdsz3l2cyj7k9vyyh'
* bchjs.Address.hash160ToCash("7dc85da64d1d93ef01ef62e0221c02f512e3942f", 0x05)
* 'bitcoincash:pp7ushdxf5we8mcpaa3wqgsuqt639cu59ur5xu5fug'
* bchjs.Address.hash160ToCash("155187a3283b08b30519db50bc23bbba9f4b6657", 0x6f)
* 'bchtest:qq24rpar9qas3vc9r8d4p0prhwaf7jmx2u22nzt946'
*/
// Converts hash160 to Cash Address
hash160ToCash (
hash160,
network = Bitcoin.networks.bitcoin.pubKeyHash,
regtest = false
) {
const legacyAddress = this.hash160ToLegacy(hash160, network)
return this.toCashAddress(legacyAddress, true, regtest)
}
_decode (address) {
try {
return this._decodeLegacyAddress(address)
} catch (error) {}
try {
return this._decodeCashAddress(address)
} catch (error) {}
try {
return this._encodeAddressFromHash160(address)
} catch (error) {}
throw new Error(`Unsupported address format : ${address}`)
}
_decodeLegacyAddress (address) {
const { version, hash } = Bitcoin.address.fromBase58Check(address)
const info = coininfo.bitcoincash
switch (version) {
case info.main.versions.public:
return {
prefix: 'bitcoincash',
type: 'P2PKH',
hash: hash,
format: 'legacy'
}
case info.main.versions.scripthash:
return {
prefix: 'bitcoincash',
type: 'P2SH',
hash: hash,
format: 'legacy'
}
case info.test.versions.public:
return {
prefix: 'bchtest',
type: 'P2PKH',
hash: hash,
format: 'legacy'
}
case info.test.versions.scripthash:
return {
prefix: 'bchtest',
type: 'P2SH',
hash: hash,
format: 'legacy'
}
default:
throw new Error(`Invalid format : ${address}`)
}
}
_decodeCashAddress (address) {
if (address.indexOf(':') !== -1) {
const decoded = cashaddr.decode(address)
decoded.format = 'cashaddr'
return decoded
}
const prefixes = ['bitcoincash', 'bchtest', 'bchreg']
for (let i = 0; i < prefixes.length; ++i) {
try {
const decoded = cashaddr.decode(`${prefixes[i]}:${address}`)
decoded.format = 'cashaddr'
return decoded
} catch (error) {}
}
throw new Error(`Invalid format : ${address}`)
}
_encodeAddressFromHash160 (address) {
try {
return {
legacyAddress: this.hash160ToLegacy(address),
cashAddress: this.hash160ToCash(address),
format: 'hash160'
}
} catch (error) {}
throw new Error(`Invalid format : ${address}`)
}
/**
* @api Address.isLegacyAddress() isLegacyAddress()
* @apiName isLegacyAddress
* @apiGroup Address
* @apiDescription Detect if legacy base58check encoded address.
*
* @apiExample Example usage:
* // cashaddr
* bchjs.Address.isLegacyAddress('bitcoincash:qqfx3wcg8ts09mt5l3zey06wenapyfqq2qrcyj5x0s')
* // false
*
* // w/ no cashaddr prefix
* bchjs.Address.isLegacyAddress('qzm47qz5ue99y9yl4aca7jnz7dwgdenl85jkfx3znl')
* // false
*
* // legacy
* bchjs.Address.isLegacyAddress('1HiaTupadqQN66Tvgt7QSE5Wg13BUy25eN')
* // true
*
* // testnet w/ cashaddr prefix
* bchjs.Address.isLegacyAddress('bchtest:qph2v4mkxjgdqgmlyjx6njmey0ftrxlnggt9t0a6zy')
* // false
*
* // testnet w/ no cashaddr prefix
* bchjs.Address.isLegacyAddress('qph2v4mkxjgdqgmlyjx6njmey0ftrxlnggt9t0a6zy')
* // false
*
* // legacy testnet
* bchjs.Address.isLegacyAddress('mqc1tmwY2368LLGktnePzEyPAsgADxbksi')
* // true
*/
// Test for address format.
isLegacyAddress (address) {
return this.detectAddressFormat(address) === 'legacy'
}
/**
* @api Address.isCashAddress() isCashAddress()
* @apiName isCashAddress
* @apiGroup Address
* @apiDescription Detect if cashAddr encoded address.
*
* @apiExample Example usage:
* // mainnet cashaddr
* bchjs.Address.isCashAddress('bitcoincash:qqfx3wcg8ts09mt5l3zey06wenapyfqq2qrcyj5x0s')
* // true
*
* // mainnet w/ no cashaddr prefix
* bchjs.Address.isCashAddress('qqfx3wcg8ts09mt5l3zey06wenapyfqq2qrcyj5x0s')
* // true
*
* // mainnet legacy
* bchjs.Address.isCashAddress('18HEMuar5ZhXDFep1gEiY1eoPPcBLxfDxj')
* // false
*
* // testnet w/ cashaddr prefix
* bchjs.Address.isCashAddress('bchtest:qph2v4mkxjgdqgmlyjx6njmey0ftrxlnggt9t0a6zy')
* // true
*
* // testnet w/ no cashaddr prefix
* bchjs.Address.isCashAddress('qph2v4mkxjgdqgmlyjx6njmey0ftrxlnggt9t0a6zy')
* // true
*
* // testnet legacy
* bchjs.Address.isCashAddress('mqc1tmwY2368LLGktnePzEyPAsgADxbksi')
* // false
*/
isCashAddress (address) {
return this.detectAddressFormat(address) === 'cashaddr'
}
/**
* @api Address.isHash160() isHash160()
* @apiName isHash160
* @apiGroup Address
* @apiDescription Detect if an addess is a hash160.
*
* @apiExample Example usage:
* let hash160Address = '428df38e23fc879a25819427995c3e6355b12d33';
* bchjs.Address.isHash160(hash160Address);
* // true
*
* let notHash160Address = 'bitcoincash:pz8a837lttkvjksg0jjmmulqvfkgpqrcdgufy8ns5s';
* bchjs.Address.isHash160(notHash160Address);
* // false
*/
isHash160 (address) {
return this.detectAddressFormat(address) === 'hash160'
}
/**
* @api Address.isMainnetAddress() isMainnetAddress()
* @apiName isMainnetAddress
* @apiGroup Address
* @apiDescription Detect if mainnet address .
*
* @apiExample Example usage:
* // mainnet cashaddr
* bchjs.Address.isMainnetAddress('bitcoincash:qqfx3wcg8ts09mt5l3zey06wenapyfqq2qrcyj5x0s')
* // true
*
* // mainnet cashaddr w/ no prefix
* bchjs.Address.isMainnetAddress('qqfx3wcg8ts09mt5l3zey06wenapyfqq2qrcyj5x0s')
* // true
*
* // mainnet legacy
* bchjs.Address.isMainnetAddress('14krEkSaKoTkbFT9iUCfUYARo4EXA8co6M')
* // true
*
* // testnet cashaddr
* bchjs.Address.isMainnetAddress('bchtest:qph2v4mkxjgdqgmlyjx6njmey0ftrxlnggt9t0a6zy')
* // false
*
* // testnet w/ no cashaddr prefix
* bchjs.Address.isMainnetAddress('qph2v4mkxjgdqgmlyjx6njmey0ftrxlnggt9t0a6zy')
* // false
*
* // testnet legacy
* bchjs.Address.isMainnetAddress('mqc1tmwY2368LLGktnePzEyPAsgADxbksi')
* // false
*/
// Test for address network.
isMainnetAddress (address) {
if (address[0] === 'x') return true
else if (address[0] === 't') return false
return this.detectAddressNetwork(address) === 'mainnet'
}
/**
* @api Address.isTestnetAddress() isTestnetAddress()
* @apiName isTestnetAddress
* @apiGroup Address
* @apiDescription Detect if testnet address.
*
* @apiExample Example usage:
* // cashaddr mainnet
* bchjs.Address.isTestnetAddress('bitcoincash:qqfx3wcg8ts09mt5l3zey06wenapyfqq2qrcyj5x0s')
* //false
*
* // w/ no cashaddr prefix
* bchjs.Address.isTestnetAddress('qqfx3wcg8ts09mt5l3zey06wenapyfqq2qrcyj5x0s')
* // false
*
* // legacy mainnet
* bchjs.Address.isTestnetAddress('14krEkSaKoTkbFT9iUCfUYARo4EXA8co6M')
* // false
*
* // cashaddr testnet
* bchjs.Address.isTestnetAddress('bchtest:qph2v4mkxjgdqgmlyjx6njmey0ftrxlnggt9t0a6zy')
* // true
*
* // testnet w/ no cashaddr prefix
* bchjs.Address.isTestnetAddress('qph2v4mkxjgdqgmlyjx6njmey0ftrxlnggt9t0a6zy')
* // true
*
* // testnet legacy
* bchjs.Address.isTestnetAddress('mqc1tmwY2368LLGktnePzEyPAsgADxbksi')
* // true
*/
isTestnetAddress (address) {
if (address[0] === 'x') return false
else if (address[0] === 't') return true
return this.detectAddressNetwork(address) === 'testnet'
}
/**
* @api Address.isRegTestAddress() isRegTestAddress()
* @apiName isRegTestAddress
* @apiGroup Address
* @apiDescription Detect if regtest address.
*
* @apiExample Example usage:
* // regtest
* bchjs.Address.isRegTestAddress('bchreg:qzq9je6pntpva3wf6scr7mlnycr54sjgequ54zx9lh')
* // true
*
* // regtest w/ no prefix
* bchjs.Address.isRegTestAddress('qzq9je6pntpva3wf6scr7mlnycr54sjgequ54zx9lh')
* // true
*
* // cashaddr mainnet
* bchjs.Address.isRegTestAddress('bitcoincash:qqfx3wcg8ts09mt5l3zey06wenapyfqq2qrcyj5x0s')
* //false
*
* // w/ no cashaddr prefix
* bchjs.Address.isRegTestAddress('qqfx3wcg8ts09mt5l3zey06wenapyfqq2qrcyj5x0s')
* // false
*
* // legacy mainnet
* bchjs.Address.isRegTestAddress('14krEkSaKoTkbFT9iUCfUYARo4EXA8co6M')
* // false
*
* // cashaddr testnet
* bchjs.Address.isRegTestAddress('bchtest:qph2v4mkxjgdqgmlyjx6njmey0ftrxlnggt9t0a6zy')
* // false
*
* // testnet w/ no cashaddr prefix
* bchjs.Address.isRegTestAddress('qph2v4mkxjgdqgmlyjx6njmey0ftrxlnggt9t0a6zy')
* // false
*/
isRegTestAddress (address) {
return this.detectAddressNetwork(address) === 'regtest'
}
/**
* @api Address.isP2PKHAddress() isP2PKHAddress()
* @apiName isP2PKHAddress
* @apiGroup Address
* @apiDescription Detect if p2pkh address.
*
* @apiExample Example usage:
* // cashaddr
* bchjs.Address.isP2PKHAddress('bitcoincash:qqfx3wcg8ts09mt5l3zey06wenapyfqq2qrcyj5x0s')
* // true
*
* // w/ no cashaddr prefix
* bchjs.Address.isP2PKHAddress('qqfx3wcg8ts09mt5l3zey06wenapyfqq2qrcyj5x0s')
* // true
*
* // legacy
* bchjs.Address.isP2PKHAddress('14krEkSaKoTkbFT9iUCfUYARo4EXA8co6M')
* // true
*
* // legacy testnet
* bchjs.Address.isP2PKHAddress('mqc1tmwY2368LLGktnePzEyPAsgADxbksi')
* // true
*
* // testnet w/ no cashaddr prefix
* bchjs.Address.isP2PKHAddress('qph2v4mkxjgdqgmlyjx6njmey0ftrxlnggt9t0a6zy')
* // true
*
* // legacy testnet
* bchjs.Address.isP2PKHAddress('mqc1tmwY2368LLGktnePzEyPAsgADxbksi')
* // true
*/
// Test for address type.
isP2PKHAddress (address) {
return this.detectAddressType(address) === 'p2pkh'
}
/**
* @api Address.isP2SHAddress() isP2SHAddress()
* @apiName isP2SHAddress
* @apiGroup Address
* @apiDescription Detect if p2sh address.
*
* @apiExample Example usage:
* // cashaddr
* bchjs.Address.isP2SHAddress('bitcoincash:qqfx3wcg8ts09mt5l3zey06wenapyfqq2qrcyj5x0s')
* // false
*
* // cashaddr w/ no prefix
* bchjs.Address.isP2SHAddress('qqfx3wcg8ts09mt5l3zey06wenapyfqq2qrcyj5x0s')
* // false
*
* // legacy
* bchjs.Address.isP2SHAddress('1NoYQso5UF6XqC4NbjKAp2EnjJ59yLNn74')
* // false
*
* // cashaddr testnet
* bchjs.Address.isP2SHAddress('bchtest:qph2v4mkxjgdqgmlyjx6njmey0ftrxlnggt9t0a6zy')
* // false
*
* // cashaddr testnet w/ no prefix
* bchjs.Address.isP2SHAddress('qph2v4mkxjgdqgmlyjx6njmey0ftrxlnggt9t0a6zy')
* // false
*
* // legacy testnet
* bchjs.Address.isP2SHAddress('mqc1tmwY2368LLGktnePzEyPAsgADxbksi')
* // false
*/
isP2SHAddress (address) {
return this.detectAddressType(address) === 'p2sh'
}
/**
* @api Address.detectAddressFormat() detectAddressFormat()
* @apiName detectAddressFormat
* @apiGroup Address
* @apiDescription Detect address format.
*
* @apiExample Example usage:
* // cashaddr
* bchjs.Address.detectAddressFormat('bitcoincash:qqfx3wcg8ts09mt5l3zey06wenapyfqq2qrcyj5x0s')
* // cashaddr
*
* // cashaddr w/ no prefix
* bchjs.Address.detectAddressFormat('qqfx3wcg8ts09mt5l3zey06wenapyfqq2qrcyj5x0s')
* // cashaddr
*
* // legacy
* bchjs.Address.detectAddressFormat('1NoYQso5UF6XqC4NbjKAp2EnjJ59yLNn74')
* // legacy
*
* // cashaddr testnet
* bchjs.Address.detectAddressFormat('bchtest:qph2v4mkxjgdqgmlyjx6njmey0ftrxlnggt9t0a6zy')
* // cashaddr
*
* // cashaddr testnet w/ no prefix
* bchjs.Address.detectAddressFormat('qph2v4mkxjgdqgmlyjx6njmey0ftrxlnggt9t0a6zy')
* // cashaddr
*
* // legacy testnet
* bchjs.Address.detectAddressFormat('mqc1tmwY2368LLGktnePzEyPAsgADxbksi')
* // legacy
*/
// Detect address format.
detectAddressFormat (address) {
const decoded = this._decode(address)
return decoded.format
}
/**
* @api Address.detectAddressNetwork() detectAddressNetwork()
* @apiName detectAddressNetwork
* @apiGroup Address
* @apiDescription Detect address network.
*
* @apiExample Example usage:
* // cashaddr
* bchjs.Address.detectAddressNetwork('bitcoincash:qqfx3wcg8ts09mt5l3zey06wenapyfqq2qrcyj5x0s')
* // mainnet
*
* // cashaddr w/ no prefix
* bchjs.Address.detectAddressNetwork('qqfx3wcg8ts09mt5l3zey06wenapyfqq2qrcyj5x0s')
* // mainnet
*
* // legacy
* bchjs.Address.detectAddressNetwork('1NoYQso5UF6XqC4NbjKAp2EnjJ59yLNn74')
* // mainnet
*
* // cashaddr testnet
* bchjs.Address.detectAddressNetwork('bchtest:qph2v4mkxjgdqgmlyjx6njmey0ftrxlnggt9t0a6zy')
* // testnet
*
* // cashaddr testnet w/ no prefix
* bchjs.Address.detectAddressNetwork('qph2v4mkxjgdqgmlyjx6njmey0ftrxlnggt9t0a6zy')
* // testnet
*
* // legacy testnet
* bchjs.Address.detectAddressNetwork('mqc1tmwY2368LLGktnePzEyPAsgADxbksi')
* // testnet
*/
// Detect address network.
detectAddressNetwork (address) {
if (address[0] === 'x') return 'mainnet'
else if (address[0] === 't') return 'testnet'
const decoded = this._decode(address)
switch (decoded.prefix) {
case 'bitcoincash':
return 'mainnet'
case 'bchtest':
return 'testnet'
case 'bchreg':
return 'regtest'
default:
throw new Error(`Invalid prefix : ${decoded.prefix}`)
}
}
/**
* @api Address.detectAddressType() detectAddressType()
* @apiName detectAddressType
* @apiGroup Address
* @apiDescription Detect address type.
*
* @apiExample Example usage:
* // cashaddr
* bchjs.Address.detectAddressType('bitcoincash:qqfx3wcg8ts09mt5l3zey06wenapyfqq2qrcyj5x0s');
* // p2pkh
*
* // cashaddr w/ no prefix
* bchjs.Address.detectAddressType('qqfx3wcg8ts09mt5l3zey06wenapyfqq2qrcyj5x0s');
* // p2pkh
*
* // legacy
* bchjs.Address.detectAddressType('1NoYQso5UF6XqC4NbjKAp2EnjJ59yLNn74');
* // p2pkh
*
* // cashaddr testnet
* bchjs.Address.detectAddressType('bchtest:qph2v4mkxjgdqgmlyjx6njmey0ftrxlnggt9t0a6zy');
* // p2pkh
*
* // cashaddr testnet w/ no prefix
* bchjs.Address.detectAddressType('qph2v4mkxjgdqgmlyjx6njmey0ftrxlnggt9t0a6zy');
* // p2pkh
*
* // legacy testnet
* bchjs.Address.detectAddressType('mqc1tmwY2368LLGktnePzEyPAsgADxbksi');
* // p2pkh
*/
// Detect address type.
detectAddressType (address) {
const decoded = this._decode(address)
return decoded.type.toLowerCase()
}
/**
* @api Address.fromXPub() fromXPub()
* @apiName fromXPub
* @apiGroup Address
* @apiDescription Generates an address for an extended public key (xpub).
*
* @apiExample Example usage:
* // generate 5 mainnet external change addresses for xpub6DTNmB7gWa8RtQAfmy8wSDikM5mky4fhsnqQd9AqoCaLcekqNgRZW5JCSXwXkLDkABHTD1qx7kqrbGzT6xBGfAvCJSj2rwvKWP8eZBR2EVA
* let xpub = 'xpub6DTNmB7gWa8RtQAfmy8wSDikM5mky4fhsnqQd9AqoCaLcekqNgRZW5JCSXwXkLDkABHTD1qx7kqrbGzT6xBGfAvCJSj2rwvKWP8eZBR2EVA';
* for(let i = 0; i <= 4; i++) {
* console.log(bchjs.Address.fromXPub(xpub, "0/" + i))
* }
* // bitcoincash:qptnmya5wkly7xf97wm5ak23yqdsz3l2cyj7k9vyyh
* // bitcoincash:qrr2suh9yjsrkl2qp3p967uhfg6u0r6xxsn9h5vuvr
* // bitcoincash:qpkfg4kck99wksyss6nvaqtafeahfnyrpsj0ed372t
* // bitcoincash:qppgmuuwy07g0x39sx2z0x2u8e34tvfdxvy0c2jvx7
* // bitcoincash:qryj8x4s7vfsc864jm0xaak9qfe8qgk245y9ska57l
*
* // generate 5 testnet external change addresses for tpubDCrnMSKwDMAbxg82yqDt97peMvftCXk3EfBb9WgZh27mPbHGkysU3TW7qX5AwydmnVQfaGeNhUR6okQ3dS5AJTP9gEP7jk2Wcj6Xntc6gNh
* let xpub = 'tpubDCrnMSKwDMAbxg82yqDt97peMvftCXk3EfBb9WgZh27mPbHGkysU3TW7qX5AwydmnVQfaGeNhUR6okQ3dS5AJTP9gEP7jk2Wcj6Xntc6gNh';
* for(let i = 0; i <= 4; i++) {
* console.log(bchjs.Address.fromXPub(xpub, "0/" + i))
* }
* // bchtest:qrth8470sc9scek9u0jj2d0349t62gxzdstw2jukl8
* // bchtest:qpm56zc5re0nhms96r7p985aajthp0vxvg6e4ux3kc
* // bchtest:qqtu3tf6yyd73ejhk3a2ylqynpl3mzzhwuzt299jfd
* // bchtest:qzd7dvlnfukggjqsf5ju0qqwwltakfumjsck33js6m
* // bchtest:qq322ataqeas4n0pdn4gz2sdereh5ae43ylk4qdvus
*/
fromXPub (xpub, path = '0/0') {
const HDNode = Bitcoin.HDNode.fromBase58(
xpub,
Bitcoin.networks[this.detectAddressNetwork(xpub)]
)
const address = HDNode.derivePath(path)
return this.toCashAddress(address.getAddress())
}
/**
* @api Address.fromOutputScript() fromOutputScript()
* @apiName fromOutputScript
* @apiGroup Address
* @apiDescription Detect an addess from an OutputScript..
*
* @apiExample Example usage:
* const script = bchjs.Script.encode([
* Buffer.from("BOX", "ascii"),
* bchjs.Script.opcodes.OP_CAT,
* Buffer.from("BITBOX", "ascii"),
* bchjs.Script.opcodes.OP_EQUAL
* ]);
* const p2sh_hash160 = bchjs.Crypto.hash160(script);
* const scriptPubKey = bchjs.Script.scriptHash.output.encode(p2sh_hash160);
*
* // mainnet address from output script
* bchjs.Address.fromOutputScript(scriptPubKey);
* // bitcoincash:pz0qcslrqn7hr44hsszwl4lw5r6udkg6zqncnufkrl
*
* // testnet address from output script
* bchjs.Address.fromOutputScript(scriptPubKey, 'testnet');
* // bchtest:pz0qcslrqn7hr44hsszwl4lw5r6udkg6zqh2hmtpyr
*/
fromOutputScript (scriptPubKey, network = 'mainnet') {
let netParam
if (network !== 'bitcoincash' && network !== 'mainnet') {
netParam = Bitcoin.networks.testnet
}
const regtest = network === 'bchreg'
return this.toCashAddress(
Bitcoin.address.fromOutputScript(scriptPubKey, netParam),
true,
regtest
)
}
}
module.exports = Address