@ordinalsbot/bitcoin-fee-estimator
Version:
A library for calculating Bitcoin transaction fees
94 lines (93 loc) • 2.99 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.bech32Polymod = bech32Polymod;
exports.bech32VerifyChecksum = bech32VerifyChecksum;
exports.bech32Decode = bech32Decode;
exports.bech32ConvertWords = bech32ConvertWords;
const BECH32_ALPHABET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
const BECH32_CONST = 1;
const BECH32M_CONST = 0x2bc830a3;
function bech32Polymod(values) {
const GEN = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];
let chk = 1;
for (const v of values) {
const b = chk >> 25;
chk = ((chk & 0x1ffffff) << 5) ^ v;
for (let i = 0; i < 5; i++) {
if ((b >> i) & 1) {
chk ^= GEN[i];
}
}
}
return chk;
}
function bech32VerifyChecksum(hrp, data, encoding) {
const consts = encoding === "bech32" ? BECH32_CONST : BECH32M_CONST;
return bech32Polymod([...bech32HrpExpand(hrp), ...data]) === consts;
}
function bech32HrpExpand(hrp) {
const result = [];
for (let i = 0; i < hrp.length; i++) {
result.push(hrp.charCodeAt(i) >> 5);
}
result.push(0);
for (let i = 0; i < hrp.length; i++) {
result.push(hrp.charCodeAt(i) & 31);
}
return result;
}
function bech32Decode(bechString) {
let hasLower = false;
let hasUpper = false;
for (let i = 0; i < bechString.length; i++) {
if (bechString[i] < "!" || bechString[i] > "~")
return null;
if (bechString[i] >= "a" && bechString[i] <= "z")
hasLower = true;
if (bechString[i] >= "A" && bechString[i] <= "Z")
hasUpper = true;
}
if (hasLower && hasUpper)
return null;
const bechStringLower = bechString.toLowerCase();
const pos = bechStringLower.lastIndexOf("1");
if (pos < 1 ||
pos + 7 > bechStringLower.length ||
bechStringLower.length > 90)
return null;
const hrp = bechStringLower.substring(0, pos);
const data = [];
for (let i = pos + 1; i < bechStringLower.length; i++) {
const c = bechStringLower[i];
const d = BECH32_ALPHABET.indexOf(c);
if (d === -1)
return null;
data.push(d);
}
if (!bech32VerifyChecksum(hrp, data, "bech32") &&
!bech32VerifyChecksum(hrp, data, "bech32m")) {
return null;
}
const encoding = bech32VerifyChecksum(hrp, data, "bech32")
? "bech32"
: "bech32m";
return { hrp, words: data.slice(0, -6), encoding };
}
function bech32ConvertWords(data, inBits, outBits, pad) {
let value = 0;
let bits = 0;
const maxV = (1 << outBits) - 1;
const result = [];
for (const d of data) {
value = (value << inBits) | d;
bits += inBits;
while (bits >= outBits) {
bits -= outBits;
result.push((value >> bits) & maxV);
}
}
if (pad && bits > 0) {
result.push((value << (outBits - bits)) & maxV);
}
return result;
}