@vbyte/btc-dev
Version:
Batteries-included toolset for plebian bitcoin development
66 lines (65 loc) • 2.35 kB
JavaScript
const TIMELOCK_DISABLE = 0x80000000;
const TIMELOCK_TYPE = 0x00400000;
const TIMELOCK_VALUE_MASK = 0x0000FFFF;
const TIMELOCK_VALUE_MAX = 0xFFFF;
const TIMELOCK_GRANULARITY = 512;
export var SequenceField;
(function (SequenceField) {
SequenceField.encode = encode_sequence;
SequenceField.decode = decode_sequence;
})(SequenceField || (SequenceField = {}));
export function encode_sequence(data) {
if (data.mode === 'height') {
const height = parse_height(data.height);
return (height & TIMELOCK_VALUE_MASK) >>> 0;
}
if (data.mode === 'stamp') {
const stamp = parse_stamp(data.stamp);
return (TIMELOCK_TYPE | (stamp & TIMELOCK_VALUE_MASK)) >>> 0;
}
throw new Error('invalid timelock mode: ' + data.mode);
}
export function decode_sequence(sequence) {
const seq = parse_sequence(sequence);
if (seq & TIMELOCK_DISABLE)
return null;
const value = seq & TIMELOCK_VALUE_MASK;
if (seq & TIMELOCK_TYPE) {
const stamp = value * TIMELOCK_GRANULARITY;
if (stamp > 0xFFFFFFFF) {
throw new Error('Decoded timestamp exceeds 32-bit limit');
}
return { mode: 'stamp', stamp };
}
else {
if (value > TIMELOCK_VALUE_MAX) {
throw new Error('Decoded height exceeds maximum');
}
return { mode: 'height', height: value };
}
}
function parse_sequence(sequence) {
const seq = (typeof sequence === 'string')
? parseInt(sequence, 16)
: sequence;
if (!Number.isInteger(seq) || seq < 0 || seq > 0xFFFFFFFF) {
throw new Error(`invalid sequence value: ${seq}`);
}
return seq;
}
function parse_stamp(stamp) {
if (stamp === undefined || !Number.isInteger(stamp)) {
throw new Error(`timestamp must be a number`);
}
const ts = Math.floor(stamp / TIMELOCK_GRANULARITY);
if (!Number.isInteger(ts) || ts < 0 || ts > TIMELOCK_VALUE_MAX) {
throw new Error(`timelock value must be an integer between 0 and ${TIMELOCK_VALUE_MAX} (in 512-second increments)`);
}
return ts;
}
function parse_height(height) {
if (height === undefined || !Number.isInteger(height) || height < 0 || height > TIMELOCK_VALUE_MAX) {
throw new Error(`Heightlock value must be an integer between 0 and ${TIMELOCK_VALUE_MAX}`);
}
return height;
}