All files / src/storage/schema/entities Output.ts

100% Statements 89/89
93.18% Branches 41/44
100% Functions 58/58
100% Lines 89/89

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 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169    57x 57x   57x   3549x 3549x                                                                 3x 3139x 2x 1x 1975x 2x 2x 1570x 1575x 1570x 2946x 1570x 1909x 1571x 6x 1x 6x 1x 6x 2x 7x 2x 6x 2x   5x 1x 6x 2x 6x 2x 6x 2x 6x 2x 5x 1x 5x 1x 6x 2x 6x 2x 7x 2x 5x 2x 5x 2x   3542x 1x 1x 1x     4x                                           2x   2x         3540x 3540x 3540x 3540x                 1569x 1569x 1569x 1569x 1569x 1569x       1973x 1973x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x   1973x    
/* eslint-disable @typescript-eslint/no-unused-vars */
import { MerklePath } from "@bsv/sdk"
import { arraysEqual, entity, optionalArraysEqual, sdk, table, verifyId, verifyOneOrNone } from "../../../index.client";
import { EntityBase } from ".";
 
export class Output extends EntityBase<table.Output> {
    constructor(api?: table.Output) {
        const now = new Date()
        super(api || {
            outputId: 0,
            created_at: now,
            updated_at: now,
            userId: 0,
            transactionId: 0,
            spendable: false,
            change: false,
            satoshis: 0,
            outputDescription: '',
            vout: 0,
            type: '',
            providedBy: 'you',
            purpose: '',
 
            txid: undefined,
            basketId: undefined,
            spentBy: undefined,
            derivationPrefix: undefined,
            derivationSuffix: undefined,
            senderIdentityKey: undefined,
            customInstructions: undefined,
            spendingDescription: undefined,
            scriptLength: undefined,
            scriptOffset: undefined,
            lockingScript: undefined,
        })
    }
 
    override updateApi(): void {
        /* nothing needed yet... */
    }
 
    get outputId() { return this.api.outputId }
    set outputId(v: number) { this.api.outputId = v }
    get created_at() { return this.api.created_at }
    set created_at(v: Date) { this.api.created_at = v }
    get updated_at() { return this.api.updated_at }
    set updated_at(v: Date) { this.api.updated_at = v }
    get userId() { return this.api.userId }
    set userId(v: number) { this.api.userId = v }
    get transactionId() { return this.api.transactionId }
    set transactionId(v: number) { this.api.transactionId = v }
    get basketId() { return this.api.basketId }
    set basketId(v: number | undefined) { this.api.basketId = v }
    get spentBy() { return this.api.spentBy }
    set spentBy(v: number | undefined) { this.api.spentBy = v }
    get vout() { return this.api.vout }
    set vout(v: number) { this.api.vout = v }
    get satoshis() { return this.api.satoshis }
    set satoshis(v: number) { this.api.satoshis = v }
    get outputDescription() { return this.api.outputDescription }
    set outputDescription(v: string) { this.api.outputDescription = v }
    get spendable() { return this.api.spendable }
    set spendable(v: boolean) { this.api.spendable = v }
    get change() { return this.api.change }
    set change(v: boolean) { this.api.change = v }
 
    get txid() { return this.api.txid }
    set txid(v: string | undefined) { this.api.txid = v }
    get type() { return this.api.type }
    set type(v: string) { this.api.type = v }
    get providedBy() { return this.api.providedBy }
    set providedBy(v: sdk.StorageProvidedBy) { this.api.providedBy = v }
    get purpose() { return this.api.purpose }
    set purpose(v: string) { this.api.purpose = v }
    get spendingDescription() { return this.api.spendingDescription }
    set spendingDescription(v: string | undefined) { this.api.spendingDescription = v }
    get derivationPrefix() { return this.api.derivationPrefix }
    set derivationPrefix(v: string | undefined) { this.api.derivationPrefix = v }
    get derivationSuffix() { return this.api.derivationSuffix }
    set derivationSuffix(v: string | undefined) { this.api.derivationSuffix = v }
    get senderIdentityKey() { return this.api.senderIdentityKey }
    set senderIdentityKey(v: string | undefined) { this.api.senderIdentityKey = v }
    get customInstructions() { return this.api.customInstructions }
    set customInstructions(v: string | undefined) { this.api.customInstructions = v }
    get lockingScript() { return this.api.lockingScript }
    set lockingScript(v: number[] | undefined) { this.api.lockingScript = v }
    get scriptLength() { return this.api.scriptLength }
    set scriptLength(v: number | undefined) { this.api.scriptLength = v }
    get scriptOffset() { return this.api.scriptOffset }
    set scriptOffset(v: number | undefined) { this.api.scriptOffset = v }
 
    override get id(): number { return this.api.outputId }
    override set id(v: number) { this.api.outputId = v }
    override get entityName(): string { return 'Output' }
    override get entityTable(): string { return 'outputs' }
    
    override equals(ei: table.Output, syncMap?: entity.SyncMap | undefined): boolean {
        if (
            this.transactionId !== (syncMap ? syncMap.transaction.idMap[ei.transactionId] : ei.transactionId) ||
            this.basketId !== (syncMap && ei.basketId ? syncMap.outputBasket.idMap[ei.basketId] : ei.basketId) ||
            this.spentBy !== (syncMap && ei.spentBy ? syncMap.transaction.idMap[ei.spentBy] : ei.spentBy) ||
            this.vout !== ei.vout ||
            this.satoshis !== ei.satoshis ||
            this.spendable !== ei.spendable ||
            this.change !== ei.change ||
            this.txid !== ei.txid ||
            this.type !== ei.type ||
            this.providedBy !== ei.providedBy ||
            this.purpose !== ei.purpose ||
            this.outputDescription !== ei.outputDescription ||
            this.spendingDescription !== ei.spendingDescription ||
            this.derivationPrefix !== ei.derivationPrefix ||
            this.derivationSuffix !== ei.derivationSuffix ||
            this.senderIdentityKey !== ei.senderIdentityKey ||
            this.customInstructions !== ei.customInstructions ||
            !optionalArraysEqual(this.lockingScript, ei.lockingScript) ||
            this.scriptLength !== ei.scriptLength ||
            this.scriptOffset !== ei.scriptOffset
        )
            return false
 
        return true
    }
 
    static async mergeFind(storage: entity.EntityStorage, userId: number, ei: table.Output, syncMap: entity.SyncMap, trx?: sdk.TrxToken)
    : Promise<{ found: boolean, eo: entity.Output, eiId: number }> {
        const transactionId = syncMap.transaction.idMap[ei.transactionId]
        const basketId = ei.basketId ? syncMap.outputBasket.idMap[ei.basketId] : null
        const ef = verifyOneOrNone(await storage.findOutputs({ partial: { userId, transactionId, vout: ei.vout, }, trx }))
        return {
            found: !!ef,
            eo: new entity.Output(ef || { ...ei }),
            eiId: verifyId(ei.outputId)
        }
    }
 
 
    override async mergeNew(storage: entity.EntityStorage, userId: number, syncMap: entity.SyncMap, trx?: sdk.TrxToken): Promise<void> {
        this.userId = userId
        this.basketId = this.basketId ? syncMap.outputBasket.idMap[this.basketId] : undefined
        this.transactionId = syncMap.transaction.idMap[this.transactionId]
        this.spentBy = this.spentBy ? syncMap.transaction.idMap[this.spentBy] : undefined
        this.outputId = 0
        this.outputId = await storage.insertOutput(this.toApi(), trx)
    }
 
    override async mergeExisting(storage: entity.EntityStorage, since: Date | undefined, ei: table.Output, syncMap: entity.SyncMap, trx?: sdk.TrxToken): Promise<boolean> {
        let wasMerged = false
        if (ei.updated_at > this.updated_at) {
            this.spentBy = ei.spentBy ? syncMap.transaction.idMap[ei.spentBy] : undefined
            this.spendable = ei.spendable
            this.change = ei.change
            this.type = ei.type
            this.providedBy = ei.providedBy
            this.purpose = ei.purpose
            this.outputDescription = ei.outputDescription
            this.spendingDescription = ei.spendingDescription
            this.senderIdentityKey = ei.senderIdentityKey
            this.customInstructions = ei.customInstructions
            this.scriptLength = ei.scriptLength
            this.scriptOffset = ei.scriptOffset
            this.lockingScript = ei.lockingScript
            this.updated_at = new Date()
            await storage.updateOutput(this.id, this.toApi(), trx)
            wasMerged = true
        }
        return wasMerged
    }
}