All files OutPoint.ts

89.66% Statements 26/29
70% Branches 7/10
100% Functions 8/8
89.29% Lines 25/28

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 1111x 1x 1x             1x           14x 14x 14x                 46x 46x     46x 46x 46x     46x                                     111x 111x       111x               8x               1x                     99x 99x 99x 99x             43x                   4x 3x      
import { BufferWriter, StreamReader } from "@node-lightning/bufio";
import { HashByteOrder } from "./HashByteOrder";
import { HashValue } from "./HashValue";
import { ICloneable } from "./ICloneable";
 
/**
 * A tuple defining a transaction output which contains the transaction
 * identifier and the output index.
 */
export class OutPoint implements ICloneable<OutPoint> {
    /**
     * Creates an OutPoint from a byte stream.
     * @param reader
     */
    public static parse(reader: StreamReader): OutPoint {
        const txid = HashValue.parse(reader);
        const outputIndex = reader.readUInt32LE();
        return new OutPoint(txid, outputIndex);
    }
 
    /**
     * Creates an OutPoint instance from an Outpoint serialized
     * to the standard string of "txid:vout" where the txid is in RPC
     * (reversed) byte order
     */
    public static fromString(text: string): OutPoint {
        const parts = /^([0-9a-f]{64,64}):(\d+)$/i.exec(text);
        Iif (!parts) {
            throw new Error("invalid argument");
        }
        const txid = HashValue.fromRpc(parts[1]);
        const voutIdx = parseInt(parts[2]);
        Iif (voutIdx < 0) {
            throw new Error("invalid argument");
        }
        return new OutPoint(txid, voutIdx);
    }
 
    /**
     * Transaction identifier
     */
    public txid: HashValue;
 
    /**
     * Index of output in transaction
     */
    public outputIndex: number;
 
    /**
     * Constructs a new OutPoint
     * @param txid TxId as a HashValue or an RPC (big-endian) string
     * @param outputIndex
     */
    constructor(txid: HashValue | string, outputIndex: number) {
        Eif (txid instanceof HashValue) {
            this.txid = txid;
        } else {
            this.txid = HashValue.fromRpc(txid);
        }
        this.outputIndex = outputIndex;
    }
 
    /**
     * Converts the outpoint to a human readable string in the format
     * [txid]:[voutidx]
     */
    public toString() {
        return `${this.txid.toString(HashByteOrder.RPC)}:${this.outputIndex}`;
    }
 
    /**
     * Converts the outpoint to a JSON object with the txid and index
     * tuple
     */
    public toJSON() {
        return {
            txid: this.txid.toString(HashByteOrder.RPC),
            index: this.outputIndex,
        };
    }
 
    /**
     * Serializes the OutPoint to a buffer where the txid is serialized
     * in internal byte order, and the output index is uint32LE
     */
    public serialize(): Buffer {
        const writer = new BufferWriter(Buffer.alloc(36));
        writer.writeBytes(this.txid.serialize());
        writer.writeUInt32LE(this.outputIndex);
        return writer.toBuffer();
    }
 
    /**
     * Clones by performing deep copy
     */
    public clone(): OutPoint {
        return new OutPoint(this.txid.clone(), this.outputIndex);
    }
 
    /**
     * Returns true when both the transaction identifier and the output
     * index are equal.
     * @param other
     * @returns
     */
    public eq(other: OutPoint): boolean {
        if (other === undefined) return false;
        return this.txid.eq(other.txid) && this.outputIndex === other.outputIndex;
    }
}