UNPKG

@dartess/multicoin-address-validator

Version:

Multicoin address validator for Bitcoin and other Altcoins ported to TypeScript.

80 lines 3.37 kB
"use strict"; 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