@tomo-inc/ledger-bitcoin-babylon
Version:
Ledger Hardware Wallet Babylon Application Client
114 lines • 7.74 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.createVarint = exports.parseVarint = exports.sanitizeBigintToNumber = void 0;
function bigintToSmallEndian(value, length, buffer, offset) {
for (let i = 0; i < length; i++) {
if (buffer[i + offset] == undefined) {
throw Error('Buffer too small');
}
buffer[i + offset] = Number(value % BigInt(256));
value = value >> BigInt(8);
}
}
function smallEndianToBigint(buffer, offset, length) {
let result = BigInt(0);
for (let i = 0; i < length; i++) {
if (buffer[i + offset] == undefined) {
throw Error('Buffer too small');
}
result += BigInt(buffer[i + offset]) << BigInt(i * 8);
}
return result;
}
/**
* Converts a `bigint` to a `number` if it non-negative and at most MAX_SAFE_INTEGER; throws `RangeError` otherwise.
* Used when converting a Bitcoin-style varint to a `number`, since varints could be larger than what the `Number`
* class can represent without loss of precision.
*
* @param n the number to convert
* @returns `n` as a `number`
*/
function sanitizeBigintToNumber(n) {
if (n < 0)
throw RangeError('Negative bigint is not a valid varint');
if (n > Number.MAX_SAFE_INTEGER)
throw RangeError('Too large for a Number');
return Number(n);
}
exports.sanitizeBigintToNumber = sanitizeBigintToNumber;
function getVarintSize(value) {
if (typeof value == 'number') {
value = sanitizeBigintToNumber(value);
}
if (value < BigInt(0)) {
throw new RangeError('Negative numbers are not supported');
}
if (value >= BigInt(1) << BigInt(64)) {
throw new RangeError('Too large for a Bitcoin-style varint');
}
if (value < BigInt(0xfd))
return 1;
else if (value <= BigInt(0xffff))
return 3;
else if (value <= BigInt(0xffffffff))
return 5;
else
return 9;
}
/**
* Parses a Bitcoin-style variable length integer from a buffer, starting at the given `offset`. Returns a pair
* containing the parsed `BigInt`, and its length in bytes from the buffer.
*
* @param data the `Buffer` from which the variable-length integer is read
* @param offset a non-negative offset to read from
* @returns a pair where the first element is the parsed BigInt, and the second element is the length in bytes parsed
* from the buffer.
*
* @throws `RangeError` if offset is negative.
* @throws `Error` if the buffer's end is reached withut parsing being completed.
*/
function parseVarint(data, offset) {
if (offset < 0) {
throw RangeError("Negative offset is invalid");
}
if (data[offset] == undefined) {
throw Error('Buffer too small');
}
if (data[offset] < 0xfd) {
return [BigInt(data[offset]), 1];
}
else {
let size;
if (data[offset] === 0xfd)
size = 2;
else if (data[offset] === 0xfe)
size = 4;
else
size = 8;
return [smallEndianToBigint(data, offset + 1, size), size + 1];
}
}
exports.parseVarint = parseVarint;
function createVarint(value) {
if (typeof value == 'number') {
value = sanitizeBigintToNumber(value);
}
const size = getVarintSize(value);
value = BigInt(value);
const buffer = Buffer.alloc(size);
if (size == 1) {
buffer[0] = Number(value);
}
else {
if (size == 3)
buffer[0] = 0xfd;
else if (size === 5)
buffer[0] = 0xfe;
else
buffer[0] = 0xff;
bigintToSmallEndian(value, size - 1, buffer, 1);
}
return buffer;
}
exports.createVarint = createVarint;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFyaW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi92YXJpbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsU0FBUyxtQkFBbUIsQ0FDMUIsS0FBYSxFQUNiLE1BQWMsRUFDZCxNQUFjLEVBQ2QsTUFBYztJQUVkLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFDL0IsSUFBSSxNQUFNLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLFNBQVMsRUFBRTtZQUNuQyxNQUFNLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1NBQ2pDO1FBQ0QsTUFBTSxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsR0FBRyxNQUFNLENBQUMsS0FBSyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ2pELEtBQUssR0FBRyxLQUFLLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0tBQzVCO0FBQ0gsQ0FBQztBQUVELFNBQVMsbUJBQW1CLENBQzFCLE1BQWMsRUFDZCxNQUFjLEVBQ2QsTUFBYztJQUVkLElBQUksTUFBTSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN2QixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1FBQy9CLElBQUksTUFBTSxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxTQUFTLEVBQUU7WUFDbkMsTUFBTSxLQUFLLENBQUMsa0JBQWtCLENBQUMsQ0FBQztTQUNqQztRQUNELE1BQU0sSUFBSSxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7S0FDdkQ7SUFDRCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFD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