All files / src/services/chaintracker ChaintracksChainTracker.ts

80% Statements 24/30
76.47% Branches 13/17
100% Functions 3/3
79.31% Lines 23/29

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 6957x     57x           57x             23x 23x 23x 23x       4x       25x 25x           25x   25x   25x   25x 25x   25x 1x     24x                   24x     24x   24x 1x     23x    
import { sdk, wait } from '../../index.client'
import { ChainTracker } from "@bsv/sdk";
import { BlockHeader } from "./chaintracks";
import { ChaintracksServiceClient } from "./chaintracks/ChaintracksServiceClient";
 
export interface ChaintracksChainTrackerOptions {
    maxRetries?: number
}
 
export class ChaintracksChainTracker implements ChainTracker {
    chaintracks: ChaintracksServiceClient
    cache: Record<number, string>
    options: ChaintracksChainTrackerOptions
 
    constructor(chain?: sdk.Chain, chaintracks?: ChaintracksServiceClient, options?: ChaintracksChainTrackerOptions) {
 
        chain ||= 'main'
        this.chaintracks = chaintracks ?? new ChaintracksServiceClient(chain, `https://npm-registry.babbage.systems:808${chain === 'main' ? '4' : '3'}`)
        this.cache = {}
        this.options = options || {}
    }
 
    async currentHeight() : Promise<number> {
        return await this.chaintracks.getPresentHeight()
    }
 
    async isValidRootForHeight(root: string, height: number) : Promise<boolean> {
        const cachedRoot = this.cache[height]
        Iif (cachedRoot) {
            return cachedRoot === root
        }
 
        let header: BlockHeader | undefined
 
        const retries = this.options.maxRetries || 3
 
        let error: sdk.WalletError | undefined = undefined
 
        for (let tryCount = 1; tryCount <= retries; tryCount++) {
 
            try {
                header = await this.chaintracks.findHeaderForHeight(height)
 
                if (!header) {
                    return false
                }
 
                break
            } catch (eu: unknown) {
                error = sdk.WalletError.fromUnknown(eu)
                Iif (tryCount > retries) {
                    throw error
                }
                await wait(1000)
            }
        }
 
        Iif (!header)
            throw new sdk.WERR_INTERNAL('no header should have returned false or thrown an error.')
 
        this.cache[height] = header.merkleRoot
 
        if (header.merkleRoot !== root) {
            return false
        }
 
        return true
    }
}