UNPKG

@node-dlc/bitcoin

Version:
187 lines 5.67 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Sequence = void 0; const TimeLockMode_1 = require("./TimeLockMode"); const MAX_SEQUENCE = 4294967295; const DEFAULT_SEQUENCE = 4294967295; /** * A transaction input's nSequence field according to BIP 68 where * rules for relative timelocks are defined. Relative timelocks prevent * mining of a transaction until a certain age of the spent output * in blocks or timespan. * * nSequence defaults to a value of 0xffff_ffff which disables the field. * When using a nLocktime, at least one transaction must be non-default. * In this condition, it is standard to use 0xffff_fffe. */ class Sequence { /** * Parses the value from a byte stream * @param reader */ static parse(reader) { return new Sequence(reader.readUInt32LE()); } /** * Creates an nSequence value of 0xffff_fffe which is used to enable * nLockTime. */ static locktime() { return new Sequence(4294967294); } /** * Creates an nSequence value of 0xffff_fffd which is used to * enable opt-in full replace-by-fee. */ static rbf() { return new Sequence(4294967293); } /** * Creates an nSequence value of 0xffff_ffff */ static default() { return new Sequence(); } /** * Creates an nSequence value of 0 */ static zero() { return new Sequence(0); } /** * Creates an nSequence value with the specified block delay * @param blocks number of blocks sequence must wait */ static blockDelay(blocks) { const sut = new Sequence(); sut.blockDelay = blocks; return sut; } /** * Creates an nSequence value with the specified time delay * @param seconds delay in seconds which will be rounded up to the * nearest 512 second interval */ static timeDelay(seconds) { const sut = new Sequence(); sut.timeDelay = seconds; return sut; } /** * Gets or sets the raw nSequence value. */ get value() { return this._value; } set value(val) { if (val < 0 || val > MAX_SEQUENCE) throw new Error('Invalid nSequence'); this._value = val; } constructor(val = DEFAULT_SEQUENCE) { this.value = val; } /** * Returns true when the nSequence is the default value 0xffff_ffff */ get isDefault() { return this.value === DEFAULT_SEQUENCE; } /** * Returns true when the relative timelock is enabled. Technically * this occurs when the top-most bit is unset. This means that the * default value of 0xffff_ffff is unset. */ get enabled() { return BigInt(this.value) >> BigInt(31) === BigInt(0); } /** * Returns true for a value that would enable nLockTime. To enable * nLockTime, at least one input in the transaction must have a * non-default nSequence value. */ get isLockTimeSignaled() { return this.value < DEFAULT_SEQUENCE; } /** * Returns true for a value that would signal opt-in replace-by-fee * as defined in BIP 125. To signal this, the nSequence must be less * than 0xffffffff-1. */ get isRBFSignaled() { return this.value < DEFAULT_SEQUENCE - 1; } /** * Gets the time lock mode for the nSequence. Technically, the bit * with index 22 controls the mode. When the bit is set, it will use * time-based relative time locks. When it is unset, it will use * block-based relatively time locks. */ get mode() { if (this.value >> 22 === 1) return TimeLockMode_1.TimeLockMode.Time; else return TimeLockMode_1.TimeLockMode.Block; } /** * Gets or sets a relative timelock in seconds. Time-based relative * time locks are encoded in 512 second granularity which is close * to the 600 seconds each block should be generated in. When * setting a value in seconds, it will rounded up to the nearest * 512s granularity. */ get timeDelay() { return (this.value & 0xffff) * 512; } set timeDelay(seconds) { // calculate the delay in 512 second granularity let value = Math.ceil(seconds / 512); // if the value execeeds the max value, throw an error if (value < 0 || value > 0xffff) throw new Error('Invalid nSequence value'); // set the typeto time-based relatively timelock value |= 1 << 22; // set the actual value this.value = value; } /** * Gets or set a relative timelock in blocks. */ get blockDelay() { return this.value & 0xffff; } set blockDelay(blocks) { // if the value exceeds the max value, throw an error if (blocks < 0 || blocks > 0xffff) throw new Error('Invalid nSequence value'); this.value = blocks; } /** * Serializes the value to a buffer */ serialize() { const buf = Buffer.alloc(4); buf.writeUInt32LE(this.value, 0); return buf; } /** * Returns the raw value as a hex encoded string, eg: 0xfffffffe */ toString() { return '0x' + this.value.toString(16).padStart(8, '0'); } /** * Returns the raw value as a hex encoded string, eg: 0xfffffffe */ toJSON() { return this.toString(); } /** * Clone via deep copy */ clone() { return new Sequence(this._value); } } exports.Sequence = Sequence; //# sourceMappingURL=Sequence.js.map