import { StreamReader } from "@node-lightning/bufio" ; import { ICloneable } from "./ICloneable" ; import { TimeLockMode } from "./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.
 */ export class Sequence implements ICloneable < Sequence > { param reader public static parse ( reader ) { return new Sequence ( reader . readUInt32LE ( ) ) ; } /**
     * Creates an nSequence value of 0xffff_fffe which is used to enable
     * nLockTime.
     */ public static locktime ( ) { return new Sequence ( 4294967294 ) ; } /**
     * Creates an nSequence value of 0xffff_fffd which is used to
     * enable opt-in full replace-by-fee.
     */ public static rbf ( ) { return new Sequence ( 4294967293 ) ; } /**
     * Creates an nSequence value of 0xffff_ffff
     */ public static default ( ) { return new Sequence ( ) ; } /**
     * Creates an nSequence value of 0
     */ public static zero ( ) { return new Sequence ( 0 ) ; } param blocks public static blockDelay ( blocks ) { const sut = new Sequence ( ) ; sut . blockDelay = blocks ; return sut ; } param seconds public static timeDelay ( seconds ) { const sut = new Sequence ( ) ; sut . timeDelay = seconds ; return sut ; } /**
     * Gets or sets the raw nSequence value.
     */ public get value ( ) : number { return this . _value ; } public set value ( val ) { if ( val < 0 || val > MAX_SEQUENCE ) throw new Error ( "Invalid nSequence" ) ; this . _value = val ; } private _value : number ; constructor ( val = DEFAULT_SEQUENCE ) { this . value = val ; } /**
     * Returns true when the nSequence is the default value 0xffff_ffff
     */ public 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.
     */ public get enabled ( ) : boolean { return BigInt ( this . value ) >> 31n === 0n ; } /**
     * 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.
     */ public get isLockTimeSignaled ( ) : boolean { 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.
     */ public get isRBFSignaled ( ) : boolean { 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.
     */ public get mode ( ) : TimeLockMode { if ( this . value >> 22 === 1 ) return TimeLockMode . Time ; else return 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.
     */ public get timeDelay ( ) : number { return ( this . value & 0xffff ) * 512 ; } public set timeDelay ( seconds ) { let value = Math . ceil ( seconds / 512 ) ; if ( value < 0 || value > 0xffff ) throw new Error ( "Invalid nSequence value" ) ; value |= 1 << 22 ; this . value = value ; } /**
     * Gets or set a relative timelock in blocks.
     */ public get blockDelay ( ) : number { return this . value & 0xffff ; } public set blockDelay ( blocks ) { if ( blocks < 0 || blocks > 0xffff ) throw new Error ( "Invalid nSequence value" ) ; this . value = blocks ; } /**
     * Serializes the value to a buffer
     */ public serialize ( ) { const buf = Buffer . alloc ( 4 ) ; buf . writeUInt32LE ( this . value , 0 ) ; return buf ; } /**
     * Returns the raw value as a hex encoded string, eg: 0xfffffffe
     */ public toString ( ) { return "0x" + this . value . toString ( 16 ) . padStart ( 8 , "0" ) ; } /**
     * Returns the raw value as a hex encoded string, eg: 0xfffffffe
     */ public toJSON ( ) { return this . toString ( ) ; } /**
     * Clone via deep copy
     */ public clone ( ) { return new Sequence ( this . _value ) ; } }