"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Value = void 0;
/**
 * Represents bitcoin value that can be converted to or from multiple
 * formats.
 */
class Value {
    /**
     * Creates a value object from value in bitcoin, eg: 1.12345678
     * @param num
     */
    static fromBitcoin(num) {
        return Value.fromSats(Math.round(num * 1e8));
    }
    /**
     * Creates a value instance from value in satoshis where 1 satoshis
     * equates to 0.00000001 bitcoin.
     * @param num
     */
    static fromSats(num) {
        return new Value(BigInt(num) * BigInt(1e12));
    }
    /**
     * Creates a value instance from value in millisatoshis, 1/1000 of a
     * satoshi.
     * eg: 123 millisatoshis equates to 0.123 satoshis
     * eg: 123 millisatoshis equates to 0.00000000123 bitcoin
     * @param num
     */
    static fromMilliSats(num) {
        return new Value(BigInt(num) * BigInt(1e9));
    }
    /**
     * Creates a value instance from value in microsatoshis, 1/1e6 of a
     * satoshi.
     * eg: 123 microsatoshis equates to 0.000123 satoshis
     * eg: 123 microsatoshis equates to 0.00000000000123 bitcoin
     * @param num
     */
    static fromMicroSats(num) {
        return new Value(BigInt(num) * BigInt(1e6));
    }
    /**
     * Creates a value instance from value in picosatoshis, 1/1e12 of a
     * satoshi.
     * eg: 123 picosatoshis equates to 0.000000000123 satoshis
     * eg: 123 picosatoshis equates to 0.00000000000000000123 bitcoin
     * @param num
     */
    static fromPicoSats(num) {
        return new Value(BigInt(num));
    }
    /**
     * Generates a value instance of zero
     */
    static zero() {
        return new Value(BigInt(0));
    }
    /**
     * Gets the value in picosatoshis (1/1e12 satoshis)
     */
    get psats() {
        return this._picoSats;
    }
    /**
     * Gets the value in millionth of satoshis (1/1e6 satoshis)
     */
    get microsats() {
        return this._picoSats / BigInt(1e6);
    }
    /**
     * Gets the value in millisatoshis (1/1000 satoshis)
     */
    get msats() {
        return this._picoSats / BigInt(1e9);
    }
    /**
     * Gets the value in satoshis (1/1e8 bitcoin)
     */
    get sats() {
        return this._picoSats / BigInt(1e12);
    }
    /**
     * Gets the value in bitcoin
     */
    get bitcoin() {
        return Math.max(0, Number(this.sats) / 1e8);
    }
    constructor(picoSats) {
        this._picoSats = picoSats;
    }
    /**
     * Clone via deep copy
     */
    clone() {
        return new Value(this._picoSats);
    }
    /**
     * Adds another value to this instance and returns this instance
     * @param other
     */
    add(other) {
        this._picoSats += other.psats;
        return this;
    }
    /**
     * Adds another value to the current value and returns a new Value instance
     * @param other
     */
    addn(other) {
        return new Value(this._picoSats + other.psats);
    }
    /**
     * Subtracts another value from this instance and returns this instance
     * @param other
     */
    sub(other) {
        if (this._picoSats < other.psats) {
            throw new Error('Value underflow');
        }
        this._picoSats -= other.psats;
        return this;
    }
    /**
     * Subtracts another value from the current value and returns a new Value instance
     * @param other
     */
    subn(other) {
        if (this._picoSats < other.psats) {
            throw new Error('Value underflow');
        }
        return new Value(this._picoSats - other.psats);
    }
    /**
     * Returns true if this value is less than the other value
     * @param other
     */
    lt(other) {
        return this._picoSats < other.psats;
    }
    /**
     * Returns true if this value is equal to the other value
     * @param other
     */
    eq(other) {
        return this._picoSats === other.psats;
    }
    /**
     * Returns true if this value is greater than the other value
     * @param other
     */
    gt(other) {
        return this._picoSats > other.psats;
    }
    /**
     * Returns true if this value is greater than or equal to the other value
     * @param other
     */
    gte(other) {
        return this._picoSats >= other.psats;
    }
    /**
     * Returns true if this value is less than or equal to the other value
     * @param other
     */
    lte(other) {
        return this._picoSats <= other.psats;
    }
    /**
     * Returns a string representation of the value in bitcoin format
     * with 8 decimal places
     */
    toString() {
        const btc = this.bitcoin;
        return btc.toFixed(8);
    }
}
exports.Value = Value;
//# sourceMappingURL=Value.js.map