UNPKG

@vbyte/btc-dev

Version:

Batteries-included toolset for plebian bitcoin development

66 lines (65 loc) 2.35 kB
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; }