@dartess/multicoin-address-validator
Version:
Multicoin address validator for Bitcoin and other Altcoins ported to TypeScript.
111 lines • 3.63 kB
JavaScript
;
/* eslint-disable no-restricted-syntax,@typescript-eslint/no-explicit-any */
Object.defineProperty(exports, "__esModule", { value: true });
exports.segwit = void 0;
const bech32_1 = require("./bech32");
function convertbits(data, frombits, tobits, pad) {
let acc = 0;
let bits = 0;
const ret = [];
const maxv = (1 << tobits) - 1;
for (let p = 0; p < data.length; ++p) {
const value = data[p];
if (value < 0 || (value >> frombits) !== 0) {
return null;
}
acc = (acc << frombits) | value;
bits += frombits;
while (bits >= tobits) {
bits -= tobits;
ret.push((acc >> bits) & maxv);
}
}
if (pad) {
if (bits > 0) {
ret.push((acc << (tobits - bits)) & maxv);
}
}
else if (bits >= frombits || ((acc << (tobits - bits)) & maxv)) {
return null;
}
return ret;
}
function decode(hrp, addr) {
let bech32m = false;
let dec = bech32_1.bech32.decode(addr, bech32_1.bech32.encodings.BECH32);
if (dec === null) {
dec = bech32_1.bech32.decode(addr, bech32_1.bech32.encodings.BECH32M);
bech32m = true;
}
if (dec === null || dec.hrp !== hrp || dec.data.length < 1 || dec.data[0] > 16) {
return null;
}
const res = convertbits(dec.data.slice(1), 5, 8, false);
if (res === null || res.length < 2 || res.length > 40) {
return null;
}
if (dec.data[0] === 0 && res.length !== 20 && res.length !== 32) {
return null;
}
if (dec.data[0] === 0 && bech32m) {
return null;
}
if (dec.data[0] !== 0 && !bech32m) {
return null;
}
return { version: dec.data[0], program: res };
}
function encode(hrp, version, program) {
let enc = bech32_1.bech32.encodings.BECH32;
if (version > 0) {
enc = bech32_1.bech32.encodings.BECH32M;
}
const convertedBits = convertbits(program, 8, 5, true);
if (convertedBits === null) {
return null;
}
const ret = bech32_1.bech32.encode(hrp, [version].concat(convertedBits), enc);
if (decode(hrp, ret) === null) {
return null;
}
return ret;
}
/// //////////////////////////////////////////////////
const DEFAULT_NETWORK_TYPE = 'prod';
function isCurrencyWithBech32Hrp(currency) {
if (!currency.bech32Hrp || !Array.isArray(currency.bech32Hrp.prod) || !Array.isArray(currency.bech32Hrp.testnet)) {
return false;
}
return currency.bech32Hrp.prod.every((value) => typeof value === 'string')
&& currency.bech32Hrp.testnet.every((value) => typeof value === 'string');
}
function isValidAddress(address, currency, opts = {}) {
if (!isCurrencyWithBech32Hrp(currency)) {
return false;
}
const { networkType = DEFAULT_NETWORK_TYPE } = opts;
let correctBech32Hrps;
if (networkType === 'prod' || networkType === 'testnet') {
correctBech32Hrps = currency.bech32Hrp[networkType];
}
else if (currency.bech32Hrp) {
correctBech32Hrps = currency.bech32Hrp.prod.concat(currency.bech32Hrp.testnet);
}
else {
return false;
}
for (const chrp of correctBech32Hrps) {
const ret = decode(chrp, address);
if (ret) {
return encode(chrp, ret.version, ret.program) === address.toLowerCase();
}
}
return false;
}
const segwit = {
encode,
decode,
isValidAddress,
};
exports.segwit = segwit;
//# sourceMappingURL=segwit_addr.js.map