mirror of
https://github.com/Permissionless-Software-Foundation/bch-js.git
synced 2026-09-22 00:52:01 -07:00
523 lines
15 KiB
JavaScript
523 lines
15 KiB
JavaScript
const Bitcoin = require('@psf/bitcoincashjs-lib')
|
|
const sb = require('satoshi-bitcoin')
|
|
const bitcoinMessage = require('bitcoinjs-message')
|
|
const bs58 = require('bs58')
|
|
const bip21 = require('@psf/bip21')
|
|
const coininfo = require('@psf/coininfo')
|
|
const bip38 = require('bip38')
|
|
const wif = require('wif')
|
|
|
|
const Buffer = require('safe-buffer').Buffer
|
|
|
|
class BitcoinCash {
|
|
constructor (address) {
|
|
this._address = address
|
|
}
|
|
|
|
/**
|
|
* @api BitcoinCash.toSatoshi() toSatoshi()
|
|
* @apiName toSatoshi
|
|
* @apiGroup BitcoinCash
|
|
* @apiDescription
|
|
* Converting Bitcoin Cash units to satoshi units.
|
|
*
|
|
* @apiExample Example usage:
|
|
* // convert 9 $BCH to satoshis
|
|
* bchjs.BitcoinCash.toSatoshi(9)
|
|
* // 900000000
|
|
*
|
|
* // convert 1 $BCH to satoshis
|
|
* bchjs.BitcoinCash.toSatoshi(1)
|
|
* // 100000000
|
|
*
|
|
* // convert 100 $BCH to satoshis
|
|
* bchjs.BitcoinCash.toSatoshi(100)
|
|
* // 10000000000
|
|
*
|
|
* // convert 42 $BCH to satoshis
|
|
* bchjs.BitcoinCash.toSatoshi(42)
|
|
* // 4200000000
|
|
*
|
|
* // convert 507 $BCH to satoshis
|
|
* bchjs.BitcoinCash.toSatoshi(507)
|
|
* // 50700000000
|
|
*/
|
|
// Translate coins to satoshi value
|
|
toSatoshi (coins) {
|
|
return sb.toSatoshi(coins)
|
|
}
|
|
|
|
/**
|
|
* @api BitcoinCash.toBitcoinCash() toBitcoinCash()
|
|
* @apiName toBitcoinCash
|
|
* @apiGroup BitcoinCash
|
|
* @apiDescription
|
|
* Converting satoshi units to Bitcoin Cash units.
|
|
*
|
|
* @apiExample Example usage:
|
|
* // convert 900000000 satoshis to $BCH
|
|
* bchjs.BitcoinCash.toBitcoinCash(900000000)
|
|
* // 9
|
|
*
|
|
* // convert 100000000 satoshis to $BCH
|
|
* bchjs.BitcoinCash.toBitcoinCash(100000000)
|
|
* // 1
|
|
*
|
|
* // convert 10000000000 satoshis to $BCH
|
|
* bchjs.BitcoinCash.toBitcoinCash(10000000000)
|
|
* // 100
|
|
*
|
|
* // convert 4200000000 satoshis to $BCH
|
|
* bchjs.BitcoinCash.toBitcoinCash(4200000000)
|
|
* // 42
|
|
*
|
|
* // convert 50700000000 satoshis to $BCH
|
|
* bchjs.BitcoinCash.toBitcoinCash(50700000000)
|
|
* // 507
|
|
*/
|
|
// Translate satoshi to coin value
|
|
toBitcoinCash (satoshis) {
|
|
return sb.toBitcoin(satoshis)
|
|
}
|
|
|
|
/**
|
|
* @api BitcoinCash.toBits() toBits()
|
|
* @apiName toBits
|
|
* @apiGroup BitcoinCash
|
|
* @apiDescription
|
|
* Converting satoshi units to Bits denomination.
|
|
*
|
|
* @apiExample Example usage:
|
|
* // convert 4242323400 satoshis to 42423.234 bits
|
|
* bchjs.BitcoinCash.toBits(4242323400)
|
|
* // 42423.234
|
|
* // convert 100000000 satoshis to 1000 bits
|
|
* bchjs.BitcoinCash.toBits(100000000)
|
|
* // 1000
|
|
* // convert 314000000 satoshis to 3140 bits
|
|
* bchjs.BitcoinCash.toBits(314000000)
|
|
* // 3140
|
|
* // convert 987600000000 satoshis to 9876000 bits
|
|
* bchjs.BitcoinCash.toBits(987600000000)
|
|
* // 9876000
|
|
* // convert 12300 satoshis to 0.123 bits
|
|
* bchjs.BitcoinCash.toBits(12300)
|
|
* // 0.123
|
|
*/
|
|
// Translate satoshi to bits denomination
|
|
toBits (satoshis) {
|
|
return parseFloat(satoshis) / 100
|
|
}
|
|
|
|
// Translate satoshi to bits denomination
|
|
// TODO remove in 2.0
|
|
satsToBits (satoshis) {
|
|
return parseFloat(satoshis) / 100
|
|
}
|
|
|
|
// Translate bits to satoshi denomination
|
|
// TODO remove in 2.0
|
|
// fromBits(bits) {
|
|
// return this.toInteger(bits * 100);
|
|
// }
|
|
//
|
|
// // Translate bits to satoshi denomination
|
|
// satsFromBits(bits) {
|
|
// return this.toInteger(bits * 100);
|
|
// }
|
|
//
|
|
// toInteger(number){
|
|
// return Math.round( // round to nearest integer
|
|
// Number(number) // type cast your input
|
|
// );
|
|
// }
|
|
|
|
/**
|
|
* @api BitcoinCash.signMessageWithPrivKey() signMessageWithPrivKey()
|
|
* @apiName signMessageWithPrivKey
|
|
* @apiGroup BitcoinCash
|
|
* @apiDescription
|
|
* Sign message with private key.
|
|
*
|
|
* @apiExample Example usage:
|
|
* bchjs.BitcoinCash.signMessageWithPrivKey(
|
|
* 'KxtpRDUJDiutLaTV8Vuavhb6h7zq9YV9ZKA3dU79PCgYmNVmkkvS',
|
|
* 'EARTH'
|
|
* )
|
|
* // IIYVhlo2Z6TWFjYX1+YM+7vQKz0m+zYdSe4eYpFLuAQDEZXqll7lZC8Au22VI2LLP5x+IerZckVk3QQPsA3e8/8=
|
|
*/
|
|
// sign message
|
|
signMessageWithPrivKey (privateKeyWIF, message) {
|
|
const network = privateKeyWIF.charAt(0) === 'c' ? 'testnet' : 'mainnet'
|
|
let bitcoincash
|
|
if (network === 'mainnet') bitcoincash = coininfo.bitcoincash.main
|
|
else bitcoincash = coininfo.bitcoincash.test
|
|
|
|
const bitcoincashBitcoinJSLib = bitcoincash.toBitcoinJS()
|
|
const keyPair = Bitcoin.ECPair.fromWIF(
|
|
privateKeyWIF,
|
|
bitcoincashBitcoinJSLib
|
|
)
|
|
const privateKey = keyPair.d.toBuffer(32)
|
|
return bitcoinMessage
|
|
.sign(message, privateKey, keyPair.compressed)
|
|
.toString('base64')
|
|
}
|
|
|
|
/**
|
|
* @api BitcoinCash.verifyMessage() verifyMessage()
|
|
* @apiName verifyMessage
|
|
* @apiGroup BitcoinCash
|
|
* @apiDescription
|
|
* Verify message.
|
|
*
|
|
* @apiExample Example usage:
|
|
* bchjs.BitcoinCash.verifyMessage(
|
|
* 'bitcoincash:qp2zvw3zpk5xx43w4tve7mtekd9kaxwj4uenq9eupv',
|
|
* 'IIYVhlo2Z6TWFjYX1+YM+7vQKz0m+zYdSe4eYpFLuAQDEZXqll7lZC8Au22VI2LLP5x+IerZckVk3QQPsA3e8/8=',
|
|
* 'EARTH'
|
|
* )
|
|
* // true
|
|
*/
|
|
// verify message
|
|
verifyMessage (address, signature, message) {
|
|
return bitcoinMessage.verify(
|
|
message,
|
|
this._address.toLegacyAddress(address),
|
|
signature
|
|
)
|
|
}
|
|
|
|
/**
|
|
* @api BitcoinCash.encodeBase58Check() encodeBase58Check()
|
|
* @apiName encodeBase58Check
|
|
* @apiGroup BitcoinCash
|
|
* @apiDescription
|
|
* Encodes hex string as base58Check.
|
|
*
|
|
* @apiExample Example usage:
|
|
* // encode 0079bd35d306f648350818470c9f18903df6e06902a026f2a7 as base58check
|
|
* let hex = '0079bd35d306f648350818470c9f18903df6e06902a026f2a7'
|
|
* bchjs.BitcoinCash.encodeBase58Check(hex)
|
|
* // 1C6hRmfzvWst5WA7bFRCVAqHt5gE2g7Qar
|
|
*
|
|
* // encode 006da742680accf2282df5fade8e9b7a01a517e779289b52cc as base58check
|
|
* let hex = '006da742680accf2282df5fade8e9b7a01a517e779289b52cc'
|
|
* bchjs.BitcoinCash.encodeBase58Check(hex)
|
|
* // 1Azo2JBz2JswboeY9xSMcp14BAfhjnD9SK
|
|
*
|
|
* // encode 00c68a6a07ccdaf1669cfd8d244d80ff36b713551c6208f672 as base58check
|
|
* let hex = '00c68a6a07ccdaf1669cfd8d244d80ff36b713551c6208f672'
|
|
* bchjs.BitcoinCash.encodeBase58Check(hex)
|
|
* // 1K6ncAmMEyQrKUYosZRD9swyZNXECu2aKs
|
|
*
|
|
* // encode 00d0a6b5e3dd43d0fb895b3b3df565bb8266c5ab00a25dbeb5 as base58check
|
|
* let hex = '00d0a6b5e3dd43d0fb895b3b3df565bb8266c5ab00a25dbeb5'
|
|
* bchjs.BitcoinCash.encodeBase58Check(hex)
|
|
* // 1L2FG9hH3bwchhxHaCs5cg1QNbhmbaeAs6
|
|
*
|
|
* // encode 00db04c2e6f104997cb04c956bf25da6078e559d303127f08b as base58check
|
|
* let hex = '00db04c2e6f104997cb04c956bf25da6078e559d303127f08b'
|
|
* bchjs.BitcoinCash.encodeBase58Check(hex)
|
|
* // 1Ly4gqPddveYHMNkfjoXHanVszXpD3duKg
|
|
*/
|
|
// encode base58Check
|
|
encodeBase58Check (hex) {
|
|
return bs58.encode(Buffer.from(hex, 'hex'))
|
|
}
|
|
|
|
/**
|
|
* @api BitcoinCash.decodeBase58Check() decodeBase58Check()
|
|
* @apiName decodeBase58Check
|
|
* @apiGroup BitcoinCash
|
|
* @apiDescription
|
|
* Decodes base58Check encoded string to hex.
|
|
*
|
|
* @apiExample Example usage:
|
|
* // decode 1C6hRmfzvWst5WA7bFRCVAqHt5gE2g7Qar to hex
|
|
* let base58check = '1C6hRmfzvWst5WA7bFRCVAqHt5gE2g7Qar'
|
|
* bchjs.BitcoinCash.decodeBase58Check(base58check)
|
|
* // 0079bd35d306f648350818470c9f18903df6e06902a026f2a7
|
|
*
|
|
* // decode 1Azo2JBz2JswboeY9xSMcp14BAfhjnD9SK to hex
|
|
* let base58check = '1Azo2JBz2JswboeY9xSMcp14BAfhjnD9SK'
|
|
* bchjs.BitcoinCash.decodeBase58Check(base58check)
|
|
* // 006da742680accf2282df5fade8e9b7a01a517e779289b52cc
|
|
*
|
|
* // decode 1K6ncAmMEyQrKUYosZRD9swyZNXECu2aKs to hex
|
|
* let base58check = '1K6ncAmMEyQrKUYosZRD9swyZNXECu2aKs'
|
|
* bchjs.BitcoinCash.decodeBase58Check(base58check)
|
|
* // 00c68a6a07ccdaf1669cfd8d244d80ff36b713551c6208f672
|
|
*
|
|
* // decode 1L2FG9hH3bwchhxHaCs5cg1QNbhmbaeAs6 to hex
|
|
* let base58check = '1L2FG9hH3bwchhxHaCs5cg1QNbhmbaeAs6'
|
|
* bchjs.BitcoinCash.decodeBase58Check(base58check)
|
|
* // 00d0a6b5e3dd43d0fb895b3b3df565bb8266c5ab00a25dbeb5
|
|
*
|
|
* // decode 1Ly4gqPddveYHMNkfjoXHanVszXpD3duKg to hex
|
|
* let base58check = '1Ly4gqPddveYHMNkfjoXHanVszXpD3duKg'
|
|
* bchjs.BitcoinCash.decodeBase58Check(base58check)
|
|
* // 00db04c2e6f104997cb04c956bf25da6078e559d303127f08b
|
|
*/
|
|
// decode base58Check
|
|
decodeBase58Check (address) {
|
|
return bs58.decode(address).toString('hex')
|
|
}
|
|
|
|
/**
|
|
* @api BitcoinCash.encodeBIP21() encodeBIP21()
|
|
* @apiName encodeBIP21
|
|
* @apiGroup BitcoinCash
|
|
* @apiDescription
|
|
* Encodes address and options as BIP21 uri.
|
|
*
|
|
* @apiExample Example usage:
|
|
* let address = 'bitcoincash:qrdsfshx7yzfjl9sfj2khuja5crcu4vaxqrt2qkz5s'
|
|
* let options = {
|
|
* amount: 1,
|
|
* label: '#BCHForEveryone',
|
|
* }
|
|
* bchjs.BitcoinCash.encodeBIP21(address, options)
|
|
* // bitcoincash:qrdsfshx7yzfjl9sfj2khuja5crcu4vaxqrt2qkz5s?amount=1&label=%23BCHForEveryone
|
|
*
|
|
* let address = '1C6hRmfzvWst5WA7bFRCVAqHt5gE2g7Qar'
|
|
* let options = {
|
|
* amount: 12.5,
|
|
* label: 'coinbase donation',
|
|
* message: "and ya don't stop",
|
|
* }
|
|
* bchjs.BitcoinCash.encodeBIP21(address, options)
|
|
* // bitcoincash:qpum6dwnqmmysdggrprse8ccjq7ldcrfqgmmtgcmny?amount=12.5&label=coinbase%20donation&message=and%20ya%20don%27t%20stop
|
|
*
|
|
* let address = 'qzw6tfrh8p0jh834uf9rhg77pjg5rgnt3qw0e54u03'
|
|
* let options = {
|
|
* amount: 42,
|
|
* label: 'no prefix',
|
|
* }
|
|
* bchjs.BitcoinCash.encodeBIP21(address, options)
|
|
* // bitcoincash:qzw6tfrh8p0jh834uf9rhg77pjg5rgnt3qw0e54u03?amount=42&label=no%20prefix
|
|
*/
|
|
// encode bip21 url
|
|
encodeBIP21 (address, options, regtest = false) {
|
|
return bip21.encode(
|
|
this._address.toCashAddress(address, true, regtest),
|
|
options
|
|
)
|
|
}
|
|
|
|
/**
|
|
* @api BitcoinCash.decodeBIP21() decodeBIP21()
|
|
* @apiName decodeBIP21
|
|
* @apiGroup BitcoinCash
|
|
* @apiDescription
|
|
* Decodes BIP21 uri.
|
|
*
|
|
* @apiExample Example usage:
|
|
* let bip21 =
|
|
* 'bitcoincash:qrdsfshx7yzfjl9sfj2khuja5crcu4vaxqrt2qkz5s?amount=1&label=%23BCHForEveryone'
|
|
* bchjs.BitcoinCash.decodeBIP21(bip21)
|
|
* // { address: 'qrdsfshx7yzfjl9sfj2khuja5crcu4vaxqrt2qkz5s', options: { amount: 1, label: '#BCHForEveryone' } }
|
|
*
|
|
* let bip21 =
|
|
* 'bitcoincash:qpum6dwnqmmysdggrprse8ccjq7ldcrfqgmmtgcmny?amount=12.5&label=coinbase%20donation&message=and%20ya%20don%27t%20stop'
|
|
* bchjs.BitcoinCash.decodeBIP21(bip21)
|
|
* // { address: 'qpum6dwnqmmysdggrprse8ccjq7ldcrfqgmmtgcmny',
|
|
* // options:
|
|
* // { amount: 12.5,
|
|
* // label: 'coinbase donation',
|
|
* // message: 'and ya don\'t stop'
|
|
* // }
|
|
* // }
|
|
*
|
|
* let bip21 =
|
|
* 'bitcoincash:qzw6tfrh8p0jh834uf9rhg77pjg5rgnt3qw0e54u03?amount=42&label=no%20prefix'
|
|
* bchjs.BitcoinCash.decodeBIP21(bip21)
|
|
* // { address: 'qzw6tfrh8p0jh834uf9rhg77pjg5rgnt3qw0e54u03', options: { amount: 42, label: 'no prefix' } }
|
|
*/
|
|
// decode bip21 url
|
|
decodeBIP21 (url) {
|
|
return bip21.decode(url)
|
|
}
|
|
|
|
/**
|
|
* @api BitcoinCash.getByteCount() getByteCount()
|
|
* @apiName getByteCount
|
|
* @apiGroup BitcoinCash
|
|
* @apiDescription
|
|
* Get byte count of transaction.
|
|
*
|
|
* @apiExample Example usage:
|
|
* // 1 P2PKH input
|
|
* let inputs = {
|
|
* P2PKH: 1,
|
|
* }
|
|
* // 1 P2SH output
|
|
* let outputs = {
|
|
* P2SH: 1,
|
|
* }
|
|
* bchjs.BitcoinCash.getByteCount(inputs, outputs)
|
|
* // 190
|
|
*
|
|
* // 4 MULTISIG-P2SH 2-of-4 and 10 P2PKH inputs
|
|
* let inputs = {
|
|
* 'MULTISIG-P2SH:2-4': 4,
|
|
* P2PKH: 10,
|
|
* }
|
|
* // 23 P2PKH outputs
|
|
* let outputs = {
|
|
* P2PKH: 23,
|
|
* }
|
|
* bchjs.BitcoinCash.getByteCount(inputs, outputs)
|
|
* // 2750
|
|
*
|
|
* // 2 MULTISIG-P2SH 3-of-5 inputs
|
|
* let inputs = {
|
|
* 'MULTISIG-P2SH:3-5': 2,
|
|
* }
|
|
* // 2 P2PKH outputs
|
|
* let outputs = {
|
|
* P2PKH: 2,
|
|
* }
|
|
* bchjs.BitcoinCash.getByteCount(inputs, outputs)
|
|
* // 565
|
|
*
|
|
* // 111 P2PKH inputs
|
|
* let inputs = {
|
|
* P2PKH: 111,
|
|
* }
|
|
* // 2 P2PKH outputs
|
|
* let outputs = {
|
|
* P2PKH: 2,
|
|
* }
|
|
* bchjs.BitcoinCash.getByteCount(inputs, outputs)
|
|
* // 16506
|
|
*
|
|
* // 10 P2PKH and 1 MULTISIG-P2SH 1-of-2 input
|
|
* let inputs = {
|
|
* P2PKH: 10,
|
|
* 'MULTISIG-P2SH:1-2': 1,
|
|
* }
|
|
* // 2 P2PKH and 1 P2SH outputs
|
|
* let outputs = {
|
|
* P2PKH: 2,
|
|
* P2SH: 1,
|
|
* }
|
|
* bchjs.BitcoinCash.getByteCount(inputs, outputs)
|
|
* // 1780
|
|
*/
|
|
getByteCount (inputs, outputs) {
|
|
// from https://github.com/bitcoinjs/bitcoinjs-lib/issues/921#issuecomment-354394004
|
|
let totalWeight = 0
|
|
let hasWitness = false
|
|
// assumes compressed pubkeys in all cases.
|
|
const types = {
|
|
inputs: {
|
|
'MULTISIG-P2SH': 49 * 4,
|
|
'MULTISIG-P2WSH': 6 + 41 * 4,
|
|
'MULTISIG-P2SH-P2WSH': 6 + 76 * 4,
|
|
P2PKH: 148 * 4,
|
|
P2WPKH: 108 + 41 * 4,
|
|
'P2SH-P2WPKH': 108 + 64 * 4
|
|
},
|
|
outputs: {
|
|
P2SH: 32 * 4,
|
|
P2PKH: 34 * 4,
|
|
P2WPKH: 31 * 4,
|
|
P2WSH: 43 * 4
|
|
}
|
|
}
|
|
|
|
Object.keys(inputs).forEach(function (key) {
|
|
if (key.slice(0, 8) === 'MULTISIG') {
|
|
// ex. "MULTISIG-P2SH:2-3" would mean 2 of 3 P2SH MULTISIG
|
|
const keyParts = key.split(':')
|
|
if (keyParts.length !== 2) throw new Error(`invalid input: ${key}`)
|
|
const newKey = keyParts[0]
|
|
const mAndN = keyParts[1].split('-').map(function (item) {
|
|
return parseInt(item)
|
|
})
|
|
|
|
totalWeight += types.inputs[newKey] * inputs[key]
|
|
const multiplyer = newKey === 'MULTISIG-P2SH' ? 4 : 1
|
|
totalWeight += (73 * mAndN[0] + 34 * mAndN[1]) * multiplyer
|
|
} else {
|
|
totalWeight += types.inputs[key] * inputs[key]
|
|
}
|
|
if (key.indexOf('W') >= 0) hasWitness = true
|
|
})
|
|
|
|
Object.keys(outputs).forEach(function (key) {
|
|
totalWeight += types.outputs[key] * outputs[key]
|
|
})
|
|
|
|
if (hasWitness) totalWeight += 2
|
|
|
|
totalWeight += 10 * 4
|
|
|
|
return Math.ceil(totalWeight / 4)
|
|
}
|
|
|
|
/**
|
|
* @api BitcoinCash.encryptBIP38() encryptBIP38()
|
|
* @apiName encryptBIP38
|
|
* @apiGroup BitcoinCash
|
|
* @apiDescription
|
|
* BIP38 encrypt privkey WIFs.
|
|
*
|
|
* @apiExample Example usage:
|
|
* // mainnet
|
|
* bchjs.BitcoinCash.encryptBIP38(
|
|
* 'L1phBREbhL4vb1uHHHCAse8bdGE5c7ic2PFjRxMawLzQCsiFVbvu',
|
|
* '9GKVkabAHBMyAf'
|
|
* )
|
|
* // 6PYU2fDHRVF2194gKDGkbFbeu4mFgkWtVvg2RPd2Sp6KmZx3RCHFpgBB2G
|
|
*
|
|
* // testnet
|
|
* bchjs.BitcoinCash.encryptBIP38(
|
|
* 'cSx7KzdH9EcvDEireu2WYpGnXdFYpta7sJUNt5kVCJgA7kcAU8Gm',
|
|
* '1EBPIyj55eR8bVUov9'
|
|
* )
|
|
* // 6PYUAPLwLSEjWSAfoe9NTSPkMZXnJA8j8EFJtKaeSnP18RCouutBrS2735
|
|
*/
|
|
encryptBIP38 (privKeyWIF, passphrase) {
|
|
const decoded = wif.decode(privKeyWIF)
|
|
|
|
return bip38.encrypt(decoded.privateKey, decoded.compressed, passphrase)
|
|
}
|
|
|
|
/**
|
|
* @api BitcoinCash.decryptBIP38() decryptBIP38()
|
|
* @apiName decryptBIP38
|
|
* @apiGroup BitcoinCash
|
|
* @apiDescription
|
|
* BIP38 encrypt privkey WIFs.
|
|
*
|
|
* @apiExample Example usage:
|
|
* // mainnet
|
|
* bchjs.BitcoinCash.decryptBIP38(
|
|
* '6PYU2fDHRVF2194gKDGkbFbeu4mFgkWtVvg2RPd2Sp6KmZx3RCHFpgBB2G',
|
|
* '9GKVkabAHBMyAf',
|
|
* 'mainnet'
|
|
* )
|
|
* // L1phBREbhL4vb1uHHHCAse8bdGE5c7ic2PFjRxMawLzQCsiFVbvu
|
|
*
|
|
* // testnet
|
|
* bchjs.BitcoinCash.decryptBIP38(
|
|
* '6PYUAPLwLSEjWSAfoe9NTSPkMZXnJA8j8EFJtKaeSnP18RCouutBrS2735',
|
|
* '1EBPIyj55eR8bVUov9',
|
|
* 'testnet'
|
|
* )
|
|
* // cSx7KzdH9EcvDEireu2WYpGnXdFYpta7sJUNt5kVCJgA7kcAU8Gm
|
|
*/
|
|
decryptBIP38 (encryptedKey, passphrase, network = 'mainnet') {
|
|
const decryptedKey = bip38.decrypt(encryptedKey, passphrase)
|
|
let prefix
|
|
if (network === 'testnet') prefix = 0xef
|
|
else prefix = 0x80
|
|
|
|
return wif.encode(prefix, decryptedKey.privateKey, decryptedKey.compressed)
|
|
}
|
|
}
|
|
|
|
module.exports = BitcoinCash
|