/***
* @license
* https://github.com/raven-community/rvnaddr
* Copyright (c) 2018 MSFTserver
* Copyright (c) 2018 Emilio Almansi
* Distributed under the MIT software license, see the accompanying
* file LICENSE or http://www.opensource.org/licenses/mit-license.php.
*/
var bs58check = require('bs58check')
/**
* General purpose Ravencoin address detection and translation.<br />
* Supports all major Ravencoin address formats.<br />
* Currently:
* <ul>
* <li> Legacy format </li>
* <li> Rvn2addr format </li>
* </ul>
* @module rvnaddr
*/
/**
* @static
* Supported Ravencoin address formats.
*/
var Format = {}
Format.Legacy = 'legacy'
//Format.Rvn2addr = 'rvn2addr'
/**
* @static
* Supported networks.
*/
var Network = {}
Network.Mainnet = 'mainnet'
Network.Testnet = 'testnet'
/**
* @static
* Supported address types.
*/
var Type = {}
Type.P2PKH = 'p2pkh'
Type.P2SH = 'p2sh'
/**
* Detects what is the given address' format.
* @static
* @param {string} address - A valid Ravencoin address in any format.
* @return {string}
* @throws {InvalidAddressError}
*/
function detectAddressFormat (address) {
return decodeAddress(address).format
}
/**
* Detects what is the given address' network.
* @static
* @param {string} address - A valid Ravencoin address in any format.
* @return {string}
* @throws {InvalidAddressError}
*/
function detectAddressNetwork (address) {
return decodeAddress(address).network
}
/**
* Detects what is the given address' type.
* @static
* @param {string} address - A valid Ravencoin address in any format.
* @return {string}
* @throws {InvalidAddressError}
*/
function detectAddressType (address) {
return decodeAddress(address).type
}
/**
* Translates the given address into legacy format.
* @static
* @param {string} address - A valid Ravencoin address in any format.
* @return {string}
* @throws {InvalidAddressError}
*/
function toLegacyAddress (address) {
var decoded = decodeAddress(address)
if (decoded.format === Format.Legacy) {
return address
}
return encodeAsLegacy(decoded)
}
/**
* Translates the given address into rvn2addr format.
* @static
* @param {string} address - A valid Ravencoin address in any format.
* @return {string}
* @throws {InvalidAddressError}
*/
//function toRvn2Address (address) {
// var decoded = decodeAddress(address)
// if (decoded.format === Format.Rvn2addr) {
// return address
// }
// return encodeAsRvn2addr(decoded)
//}
/**
* Version byte table for base58 formats.
* @private
*/
var VERSION_BYTE = {}
VERSION_BYTE[Format.Legacy] = {}
VERSION_BYTE[Format.Legacy][Network.Mainnet] = {}
VERSION_BYTE[Format.Legacy][Network.Mainnet][Type.P2PKH] = 0
VERSION_BYTE[Format.Legacy][Network.Mainnet][Type.P2SH] = 5
VERSION_BYTE[Format.Legacy][Network.Testnet] = {}
VERSION_BYTE[Format.Legacy][Network.Testnet][Type.P2PKH] = 111
VERSION_BYTE[Format.Legacy][Network.Testnet][Type.P2SH] = 196
/**
* Decodes the given address into its constituting hash, format, network and type.
* @private
* @param {string} address - A valid Ravencoin address in any format.
* @return {object}
* @throws {InvalidAddressError}
*/
function decodeAddress (address) {
try {
return decodeBase58Address(address)
} catch (error) {
}
//try {
// return decodeRvn2Address(address)
//} catch (error) {
//}
throw new InvalidAddressError()
}
/**
* Attempts to decode the given address assuming it is a base58 address.
* @private
* @param {string} address - A valid Ravencoin address in any format.
* @return {object}
* @throws {InvalidAddressError}
*/
function decodeBase58Address (address) {
try {
var payload = bs58check.decode(address)
var versionByte = payload[0]
var hash = Array.prototype.slice.call(payload, 1)
switch (versionByte) {
case VERSION_BYTE[Format.Legacy][Network.Mainnet][Type.P2PKH]:
return {
hash: hash,
format: Format.Legacy,
network: Network.Mainnet,
type: Type.P2PKH
}
case VERSION_BYTE[Format.Legacy][Network.Mainnet][Type.P2SH]:
return {
hash: hash,
format: Format.Legacy,
network: Network.Mainnet,
type: Type.P2SH
}
case VERSION_BYTE[Format.Legacy][Network.Testnet][Type.P2PKH]:
return {
hash: hash,
format: Format.Legacy,
network: Network.Testnet,
type: Type.P2PKH
}
case VERSION_BYTE[Format.Legacy][Network.Testnet][Type.P2SH]:
return {
hash: hash,
format: Format.Legacy,
network: Network.Testnet,
type: Type.P2SH
}
}
} catch (error) {
}
throw new InvalidAddressError()
}
/**
* Attempts to decode the given address assuming it is a rvn2addr address.
* @private
* @param {string} address - A valid Ravencoin address in any format.
* @return {object}
* @throws {InvalidAddressError}
*/
//function decodeRvn2Address (address) {
// if (address.indexOf(':') !== -1) {
// try {
// return decodeRvn2AddressWithPrefix(address)
// } catch (error) {
// }
// } else {
// var prefixes = ['ravencoin', 'rvntest', 'regtest']
// for (var i = 0; i < prefixes.length; ++i) {
// try {
// var prefix = prefixes[i]
// return decodeRvn2AddressWithPrefix(prefix + ':' + address)
// } catch (error) {
// }
// }
// }
// throw new InvalidAddressError()
//}
/**
* Attempts to decode the given address assuming it is a rvn2addr address with explicit prefix.
* @private
* @param {string} address - A valid Ravencoin address in any format.
* @return {object}
* @throws {InvalidAddressError}
*/
//function decodeRvn2AddressWithPrefix (address) {
// try {
// var decoded = rvn2addr.decode(address)
// var hash = Array.prototype.slice.call(decoded.hash, 0)
// var type = decoded.type === 'P2PKH' ? Type.P2PKH : Type.P2SH
// switch (decoded.prefix) {
// case 'ravencoin':
// return {
// hash: hash,
// format: Format.Rvn2addr,
// network: Network.Mainnet,
// type: type
// }
// case 'rvntest':
// case 'regtest':
// return {
// hash: hash,
// format: Format.Rvn2addr,
// network: Network.Testnet,
// type: type
// }
// }
// } catch (error) {
// }
// throw new InvalidAddressError()
//}
/**//
* Encodes the given decoded address into legacy format.
* @private
* @param {object} decoded
* @returns {string}
*/
function encodeAsLegacy (decoded) {
var versionByte = VERSION_BYTE[Format.Legacy][decoded.network][decoded.type]
var buffer = Buffer.alloc(1 + decoded.hash.length)
buffer[0] = versionByte
buffer.set(decoded.hash, 1)
return bs58check.encode(buffer)
}
/**
* Encodes the given decoded address into rvn2addr format.
* @private
* @param {object} decoded
* @returns {string}
*/
//function encodeAsRvn2addr (decoded) {
// var prefix = decoded.network === Network.Mainnet ? 'ravencoin' : 'rvntest'
// var type = decoded.type === Type.P2PKH ? 'P2PKH' : 'P2SH'
// var hash = Uint8Array.from(decoded.hash)
// return rvn2addr.encode(prefix, type, hash)
//}
/**
* Returns a boolean indicating whether the address is in legacy format.
* @static
* @param {string} address - A valid Ravencoin address in any format.
* @returns {boolean}
* @throws {InvalidAddressError}
*/
function isLegacyAddress (address) {
return detectAddressFormat(address) === Format.Legacy
}
/**
* Returns a boolean indicating whether the address is in rvn2addr format.
* @static
* @param {string} address - A valid Ravencoin address in any format.
* @returns {boolean}
* @throws {InvalidAddressError}
*/
//function isRvn2Address (address) {
// return detectAddressFormat(address) === Format.Rvn2addr
//}
/**
* Returns a boolean indicating whether the address is a mainnet address.
* @static
* @param {string} address - A valid Ravencoin address in any format.
* @returns {boolean}
* @throws {InvalidAddressError}
*/
function isMainnetAddress (address) {
return detectAddressNetwork(address) === Network.Mainnet
}
/**
* Returns a boolean indicating whether the address is a testnet address.
* @static
* @param {string} address - A valid Ravencoin address in any format.
* @returns {boolean}
* @throws {InvalidAddressError}
*/
function isTestnetAddress (address) {
return detectAddressNetwork(address) === Network.Testnet
}
/**
* Returns a boolean indicating whether the address is a p2pkh address.
* @static
* @param {string} address - A valid Ravencoin address in any format.
* @returns {boolean}
* @throws {InvalidAddressError}
*/
function isP2PKHAddress (address) {
return detectAddressType(address) === Type.P2PKH
}
/**
* Returns a boolean indicating whether the address is a p2sh address.
* @static
* @param {string} address - A valid Ravencoin address in any format.
* @returns {boolean}
* @throws {InvalidAddressError}
*/
function isP2SHAddress (address) {
return detectAddressType(address) === Type.P2SH
}
/**
* Error thrown when the address given as input is not a valid Ravencoin address.
* @constructor
* InvalidAddressError
*/
function InvalidAddressError () {
var error = new Error()
this.name = error.name = 'InvalidAddressError'
this.message = error.message = 'Received an invalid Ravencoin address as input.'
this.stack = error.stack
}
InvalidAddressError.prototype = Object.create(Error.prototype)
module.exports = {
Format: Format,
Network: Network,
Type: Type,
detectAddressFormat: detectAddressFormat,
detectAddressNetwork: detectAddressNetwork,
detectAddressType: detectAddressType,
toLegacyAddress: toLegacyAddress,
//toRvn2Address: toRvn2Address,
isLegacyAddress: isLegacyAddress,
//isRvn2Address: isRvn2Address,
isMainnetAddress: isMainnetAddress,
isTestnetAddress: isTestnetAddress,
isP2PKHAddress: isP2PKHAddress,
isP2SHAddress: isP2SHAddress,
InvalidAddressError: InvalidAddressError
}