@dartess/multicoin-address-validator
Version:
Multicoin address validator for Bitcoin and other Altcoins ported to TypeScript.
80 lines • 3.37 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.BTCValidator = void 0;
const buffer_1 = require("buffer");
const segwit_addr_1 = require("../crypto/segwit_addr");
const toHex_1 = require("../utils/toHex");
const sha256Checksum_1 = require("../utils/sha256Checksum");
const blake256Checksum_1 = require("../utils/blake256Checksum");
const blake2b256_1 = require("../utils/blake2b256");
const keccak256Checksum_1 = require("../utils/keccak256Checksum");
const base58Decode_1 = require("../utils/base58Decode");
const DEFAULT_NETWORK_TYPE = 'prod';
function getDecoded(address) {
try {
return (0, base58Decode_1.base58Decode)(address);
}
catch (e) {
// if decoding fails, assume invalid address
return null;
}
}
function getChecksum(hashFunction, payload) {
// Each currency may implement different hashing algorithm
switch (hashFunction) {
// blake then keccak hash chain
case 'blake256keccak256': {
const blake = (0, blake2b256_1.blake2b256)(payload);
return (0, keccak256Checksum_1.keccak256Checksum)(buffer_1.Buffer.from(blake, 'hex'));
}
case 'blake256':
return (0, blake256Checksum_1.blake256Checksum)(payload);
// not used yet. maybe it will be useful later
// case 'keccak256':
// return keccak256Checksum(payload);
case 'sha256':
default:
return (0, sha256Checksum_1.sha256Checksum)(payload);
}
}
function getAddressType(address, currency) {
// should be 25 bytes per btc address spec and 26 decred
const expectedLength = 'expectedLength' in currency ? currency.expectedLength : 25;
const hashFunction = 'hashFunction' in currency ? currency.hashFunction : 'sha256';
const decoded = getDecoded(address);
if (decoded) {
const length = decoded.length;
if (length !== expectedLength) {
return null;
}
if ('regex' in currency) {
if (!currency.regex.test(address)) {
return false;
}
}
const checksum = (0, toHex_1.toHex)(decoded.slice(length - 4, length));
const body = (0, toHex_1.toHex)(decoded.slice(0, length - 4));
const goodChecksum = getChecksum(hashFunction, body);
return checksum === goodChecksum ? (0, toHex_1.toHex)(decoded.slice(0, expectedLength - 24)) : null;
}
return null;
}
function isValidP2PKHandP2SHAddress(address, currency, opts) {
const { networkType = DEFAULT_NETWORK_TYPE } = opts;
let correctAddressTypes;
const addressType = getAddressType(address, currency);
if (addressType) {
correctAddressTypes = networkType === 'prod' || networkType === 'testnet'
? currency.addressTypes[networkType]
: currency.addressTypes.prod.concat(currency.addressTypes.testnet);
return correctAddressTypes.indexOf(addressType) >= 0;
}
return false;
}
const BTCValidator = {
isValidAddress(address, currency, opts = {}) {
return isValidP2PKHandP2SHAddress(address, currency, opts) || segwit_addr_1.segwit.isValidAddress(address, currency, opts);
},
};
exports.BTCValidator = BTCValidator;
//# sourceMappingURL=bitcoin_validator.js.map