@bsv/wallet-toolbox 1.6.11 → 1.6.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/client.md +77 -4
- package/docs/services.md +77 -4
- package/docs/wallet.md +77 -4
- package/mobile/out/src/services/chaintracker/chaintracks/Api/ChaintracksFetchApi.d.ts +10 -0
- package/mobile/out/src/services/chaintracker/chaintracks/Api/ChaintracksFetchApi.d.ts.map +1 -1
- package/mobile/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageIdb.d.ts +1 -0
- package/mobile/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageIdb.d.ts.map +1 -1
- package/mobile/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageIdb.js +14 -0
- package/mobile/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageIdb.js.map +1 -1
- package/mobile/out/src/services/chaintracker/chaintracks/util/BulkFileDataManager.d.ts.map +1 -1
- package/mobile/out/src/services/chaintracker/chaintracks/util/BulkFileDataManager.js +7 -6
- package/mobile/out/src/services/chaintracker/chaintracks/util/BulkFileDataManager.js.map +1 -1
- package/mobile/out/src/services/chaintracker/chaintracks/util/ChaintracksFetch.d.ts +4 -0
- package/mobile/out/src/services/chaintracker/chaintracks/util/ChaintracksFetch.d.ts.map +1 -1
- package/mobile/out/src/services/chaintracker/chaintracks/util/ChaintracksFetch.js +4 -0
- package/mobile/out/src/services/chaintracker/chaintracks/util/ChaintracksFetch.js.map +1 -1
- package/mobile/out/src/services/chaintracker/chaintracks/util/HeightRange.d.ts +20 -2
- package/mobile/out/src/services/chaintracker/chaintracks/util/HeightRange.d.ts.map +1 -1
- package/mobile/out/src/services/chaintracker/chaintracks/util/HeightRange.js +22 -4
- package/mobile/out/src/services/chaintracker/chaintracks/util/HeightRange.js.map +1 -1
- package/mobile/out/src/services/chaintracker/chaintracks/util/validBulkHeaderFilesByFileHash.d.ts +32 -0
- package/mobile/out/src/services/chaintracker/chaintracks/util/validBulkHeaderFilesByFileHash.d.ts.map +1 -1
- package/mobile/out/src/services/chaintracker/chaintracks/util/validBulkHeaderFilesByFileHash.js +32 -0
- package/mobile/out/src/services/chaintracker/chaintracks/util/validBulkHeaderFilesByFileHash.js.map +1 -1
- package/mobile/package-lock.json +2 -2
- package/mobile/package.json +1 -1
- package/out/src/services/chaintracker/chaintracks/Api/ChaintracksFetchApi.d.ts +10 -0
- package/out/src/services/chaintracker/chaintracks/Api/ChaintracksFetchApi.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/ChaintracksService.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/ChaintracksService.js +8 -0
- package/out/src/services/chaintracker/chaintracks/ChaintracksService.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageIdb.d.ts +1 -0
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageIdb.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageIdb.js +14 -0
- package/out/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageIdb.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/__tests/Chaintracks.test.js +11 -0
- package/out/src/services/chaintracker/chaintracks/__tests/Chaintracks.test.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/__tests/createIdbChaintracks.test.js +2 -1
- package/out/src/services/chaintracker/chaintracks/__tests/createIdbChaintracks.test.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/BulkFileDataManager.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/BulkFileDataManager.js +7 -6
- package/out/src/services/chaintracker/chaintracks/util/BulkFileDataManager.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/ChaintracksFetch.d.ts +4 -0
- package/out/src/services/chaintracker/chaintracks/util/ChaintracksFetch.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/ChaintracksFetch.js +4 -0
- package/out/src/services/chaintracker/chaintracks/util/ChaintracksFetch.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/ChaintracksFs.d.ts +4 -0
- package/out/src/services/chaintracker/chaintracks/util/ChaintracksFs.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/ChaintracksFs.js +4 -0
- package/out/src/services/chaintracker/chaintracks/util/ChaintracksFs.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/HeightRange.d.ts +20 -2
- package/out/src/services/chaintracker/chaintracks/util/HeightRange.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/HeightRange.js +22 -4
- package/out/src/services/chaintracker/chaintracks/util/HeightRange.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/validBulkHeaderFilesByFileHash.d.ts +32 -0
- package/out/src/services/chaintracker/chaintracks/util/validBulkHeaderFilesByFileHash.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/validBulkHeaderFilesByFileHash.js +32 -0
- package/out/src/services/chaintracker/chaintracks/util/validBulkHeaderFilesByFileHash.js.map +1 -1
- package/out/src/storage/remoting/StorageServer.js +1 -1
- package/out/src/storage/remoting/StorageServer.js.map +1 -1
- package/out/tsconfig.all.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/services/chaintracker/chaintracks/Api/ChaintracksFetchApi.ts +10 -0
- package/src/services/chaintracker/chaintracks/ChaintracksService.ts +11 -1
- package/src/services/chaintracker/chaintracks/Storage/ChaintracksStorageIdb.ts +14 -0
- package/src/services/chaintracker/chaintracks/__tests/Chaintracks.test.ts +12 -0
- package/src/services/chaintracker/chaintracks/__tests/createIdbChaintracks.test.ts +2 -1
- package/src/services/chaintracker/chaintracks/util/BulkFileDataManager.ts +7 -6
- package/src/services/chaintracker/chaintracks/util/ChaintracksFetch.ts +4 -0
- package/src/services/chaintracker/chaintracks/util/ChaintracksFs.ts +4 -0
- package/src/services/chaintracker/chaintracks/util/HeightRange.ts +23 -5
- package/src/services/chaintracker/chaintracks/util/validBulkHeaderFilesByFileHash.ts +32 -0
- package/src/storage/remoting/StorageServer.ts +1 -1
package/package.json
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import { HttpClient } from '@bsv/sdk'
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Provides a simplified interface based on the @bsv/sdk `HttpClient` class
|
|
5
|
+
* with just the methods necesary for most Chaintracks operations.
|
|
6
|
+
*
|
|
7
|
+
* The primary purpose is to isolate and centralize external package dependency.
|
|
8
|
+
*
|
|
9
|
+
* Specific ingestors are free to use other means for access.
|
|
10
|
+
*
|
|
11
|
+
* The `ChaintracksFetch` class implements this interface.
|
|
12
|
+
*/
|
|
3
13
|
export interface ChaintracksFetchApi {
|
|
4
14
|
httpClient: HttpClient
|
|
5
15
|
download(url: string): Promise<Uint8Array>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Chaintracks } from './Chaintracks'
|
|
2
2
|
|
|
3
3
|
import { IncomingMessage, Server, ServerResponse } from 'http'
|
|
4
|
-
import express from 'express'
|
|
4
|
+
import express, { Request, Response } from 'express'
|
|
5
5
|
import bodyParser from 'body-parser'
|
|
6
6
|
import { Chain } from '../../../sdk/types'
|
|
7
7
|
import { createNoDbChaintracksOptions } from './createDefaultNoDbChaintracksOptions'
|
|
@@ -85,6 +85,16 @@ export class ChaintracksService {
|
|
|
85
85
|
}
|
|
86
86
|
})
|
|
87
87
|
|
|
88
|
+
app.get(`/robots.txt`, (req: Request, res: Response) => {
|
|
89
|
+
res.type('text/plain')
|
|
90
|
+
res.send(`User-agent: *\nDisallow: /`)
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
app.get(`/`, (req: Request, res: Response) => {
|
|
94
|
+
res.type('text/plain')
|
|
95
|
+
res.send(`Chaintracks ${this.chain}Net Block Header Service`)
|
|
96
|
+
})
|
|
97
|
+
|
|
88
98
|
const handleErr = (err: any, res: any) => {
|
|
89
99
|
res.status(500).json({
|
|
90
100
|
status: 'error',
|
|
@@ -39,9 +39,23 @@ export class ChaintracksStorageIdb extends ChaintracksStorageBase implements Cha
|
|
|
39
39
|
this.dbName = `chaintracks-${this.chain}net`
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
override async makeAvailable(): Promise<void> {
|
|
43
|
+
if (this.isAvailable && this.hasMigrated) return
|
|
44
|
+
// Not a base class policy, but we want to ensure migrations are run before getting to business.
|
|
45
|
+
if (!this.hasMigrated) {
|
|
46
|
+
await this.migrateLatest()
|
|
47
|
+
}
|
|
48
|
+
if (!this.isAvailable) {
|
|
49
|
+
await super.makeAvailable()
|
|
50
|
+
// Connect the bulk data file manager to the table provided by this storage class.
|
|
51
|
+
await this.bulkManager.setStorage(this, this.log)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
42
55
|
override async migrateLatest(): Promise<void> {
|
|
43
56
|
if (this.db) return
|
|
44
57
|
this.db = await this.initDB()
|
|
58
|
+
await super.migrateLatest()
|
|
45
59
|
}
|
|
46
60
|
|
|
47
61
|
override async destroy(): Promise<void> {}
|
|
@@ -4,6 +4,7 @@ import { wait } from '../../../../utility/utilityHelpers'
|
|
|
4
4
|
import { Chain } from '../../../../sdk'
|
|
5
5
|
import { createNoDbChaintracksOptions } from '../createDefaultNoDbChaintracksOptions'
|
|
6
6
|
import { ChaintracksFs } from '../util/ChaintracksFs'
|
|
7
|
+
import { LocalCdnServer } from './LocalCdnServer'
|
|
7
8
|
|
|
8
9
|
const rootFolder = './src/services/chaintracker/chaintracks/__tests/data'
|
|
9
10
|
|
|
@@ -39,6 +40,17 @@ describe('Chaintracks tests', () => {
|
|
|
39
40
|
await NoDbBody('test', true)
|
|
40
41
|
})
|
|
41
42
|
|
|
43
|
+
test.skip('5 run local CDN on port 8300', async () => {
|
|
44
|
+
const fs = ChaintracksFs
|
|
45
|
+
const server = new LocalCdnServer(8300, fs.pathJoin(rootFolder, 'export'))
|
|
46
|
+
await server.start()
|
|
47
|
+
let done = false
|
|
48
|
+
for (; !done; ) {
|
|
49
|
+
await wait(10000)
|
|
50
|
+
}
|
|
51
|
+
await server.stop()
|
|
52
|
+
})
|
|
53
|
+
|
|
42
54
|
async function NoDbBody(chain: Chain, exportHeaders?: boolean) {
|
|
43
55
|
const o = createNoDbChaintracksOptions(chain)
|
|
44
56
|
const c = new Chaintracks(o)
|
|
@@ -16,7 +16,8 @@ describe('createIdbChaintracks tests', () => {
|
|
|
16
16
|
const target: Chain = 'main'
|
|
17
17
|
if (_tu.noEnv(target)) return
|
|
18
18
|
const env = _tu.getEnv(target)
|
|
19
|
-
const { chain, chaintracks, storage } = await createIdbChaintracks(env.chain, env.whatsonchainApiKey)
|
|
19
|
+
const { chain, chaintracks, storage, available } = await createIdbChaintracks(env.chain, env.whatsonchainApiKey)
|
|
20
|
+
await available
|
|
20
21
|
const headerListener: HeaderListener = (header: BlockHeader) => {
|
|
21
22
|
console.log(`headerListener: height: ${header.height} hash: ${header.hash} ${new Date().toISOString()}`)
|
|
22
23
|
}
|
|
@@ -192,11 +192,8 @@ export class BulkFileDataManager {
|
|
|
192
192
|
} else if (isBdfIncremental(vbf) && lbf && isBdfIncremental(lbf)) {
|
|
193
193
|
await this.mergeIncremental(lbf, vbf, r)
|
|
194
194
|
} else {
|
|
195
|
-
const added = this.add(vbf)
|
|
195
|
+
const added = await this.add(vbf)
|
|
196
196
|
r.inserted.push(added)
|
|
197
|
-
if (this.storage) {
|
|
198
|
-
vbf.fileId = await this.storage.insertBulkFile(added)
|
|
199
|
-
}
|
|
200
197
|
}
|
|
201
198
|
}
|
|
202
199
|
this.log(`BulkFileDataManager.merge:\n${this.toLogString(r)}\n`)
|
|
@@ -515,13 +512,17 @@ export class BulkFileDataManager {
|
|
|
515
512
|
}
|
|
516
513
|
}
|
|
517
514
|
|
|
518
|
-
private add(bfd: BulkFileData): BulkHeaderFileInfo {
|
|
515
|
+
private async add(bfd: BulkFileData): Promise<BulkHeaderFileInfo> {
|
|
519
516
|
this.validateBfdForAdd(bfd)
|
|
520
517
|
const index = this.bfds.length
|
|
521
518
|
this.bfds.push(bfd)
|
|
522
519
|
this.fileHashToIndex[bfd.fileHash] = index
|
|
523
520
|
this.ensureMaxRetained()
|
|
524
|
-
|
|
521
|
+
const info = bfdToInfo(bfd, true)
|
|
522
|
+
if (this.storage) {
|
|
523
|
+
info.fileId = bfd.fileId = await this.storage.insertBulkFile(info)
|
|
524
|
+
}
|
|
525
|
+
return info
|
|
525
526
|
}
|
|
526
527
|
|
|
527
528
|
private replaceBfdAtIndex(index: number, update: BulkFileData): void {
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { defaultHttpClient, HttpClient } from '@bsv/sdk'
|
|
2
2
|
import { ChaintracksFetchApi } from '../Api/ChaintracksFetchApi'
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* This class implements the ChaintracksFetchApi
|
|
6
|
+
* using the @bsv/sdk `defaultHttpClient`.
|
|
7
|
+
*/
|
|
4
8
|
export class ChaintracksFetch implements ChaintracksFetchApi {
|
|
5
9
|
httpClient: HttpClient = defaultHttpClient()
|
|
6
10
|
|
|
@@ -38,6 +38,10 @@ export abstract class ChaintracksFsStatics {
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
/**
|
|
42
|
+
* This object is an implementation of the `ChaintracksFsApi` interface
|
|
43
|
+
* using the `fs` package which may not be available in all environments.
|
|
44
|
+
*/
|
|
41
45
|
export const ChaintracksFs: ChaintracksFsApi = ChaintracksFsStatics
|
|
42
46
|
|
|
43
47
|
export class ChaintracksReadableFile implements ChaintracksReadableFileApi {
|
|
@@ -10,16 +10,32 @@ export interface HeightRanges {
|
|
|
10
10
|
live: HeightRange
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Represents a range of block heights.
|
|
15
|
+
*
|
|
16
|
+
* Operations support integrating contiguous batches of headers,
|
|
17
|
+
*/
|
|
13
18
|
export class HeightRange implements HeightRangeApi {
|
|
14
19
|
constructor(
|
|
15
20
|
public minHeight: number,
|
|
16
21
|
public maxHeight: number
|
|
17
22
|
) {}
|
|
18
23
|
|
|
24
|
+
/**
|
|
25
|
+
* All ranges where maxHeight is less than minHeight are considered empty.
|
|
26
|
+
* The canonical empty range is (0, -1).
|
|
27
|
+
*/
|
|
19
28
|
static readonly empty = new HeightRange(0, -1)
|
|
20
29
|
|
|
21
30
|
/**
|
|
22
|
-
* @
|
|
31
|
+
* @returns true iff minHeight is greater than maxHeight.
|
|
32
|
+
*/
|
|
33
|
+
get isEmpty() {
|
|
34
|
+
return this.minHeight > this.maxHeight
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @param headers an array of objects with a non-negative integer `height` property.
|
|
23
39
|
* @returns range of height values from the given headers, or the empty range if there are no headers.
|
|
24
40
|
*/
|
|
25
41
|
static from(headers: BlockHeader[]): HeightRange {
|
|
@@ -29,14 +45,16 @@ export class HeightRange implements HeightRangeApi {
|
|
|
29
45
|
return new HeightRange(minHeight, maxHeight)
|
|
30
46
|
}
|
|
31
47
|
|
|
48
|
+
/**
|
|
49
|
+
* @returns the number of heights in the range, or 0 if the range is empty.
|
|
50
|
+
*/
|
|
32
51
|
get length() {
|
|
33
52
|
return Math.max(0, this.maxHeight - this.minHeight + 1)
|
|
34
53
|
}
|
|
35
54
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
55
|
+
/**
|
|
56
|
+
* @returns an easy to read string representation of the height range.
|
|
57
|
+
*/
|
|
40
58
|
toString(): string {
|
|
41
59
|
return this.isEmpty ? '<empty>' : `${this.minHeight}-${this.maxHeight}`
|
|
42
60
|
}
|
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
import { BulkHeaderFileInfo } from './BulkHeaderFile'
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Compares meta data received for a bulk header file `vbf` to known
|
|
5
|
+
* valid bulk header files based on their `fileHash`.
|
|
6
|
+
*
|
|
7
|
+
* Short circuits both the retreival and validation of individual headers,
|
|
8
|
+
* only a single SHA256 hash of the aggregate data needs to be compared.
|
|
9
|
+
*
|
|
10
|
+
* The standard file size for historic block headers is 100,000 per file
|
|
11
|
+
* which results in a many orders of magnitude initialization speedup.
|
|
12
|
+
*
|
|
13
|
+
* The following properties must match:
|
|
14
|
+
* - `firstHeight`
|
|
15
|
+
* - `count`
|
|
16
|
+
* - `prevChainWork`
|
|
17
|
+
* - `prevHash`
|
|
18
|
+
* - `lastChainWork`
|
|
19
|
+
* - `lastHash`
|
|
20
|
+
* - `chain`
|
|
21
|
+
*
|
|
22
|
+
* @param vbf
|
|
23
|
+
* @returns true iff bulk file meta data (excluding its source) matches a known file.
|
|
24
|
+
*
|
|
25
|
+
* @publicbody
|
|
26
|
+
*/
|
|
3
27
|
export function isKnownValidBulkHeaderFile(vbf: BulkHeaderFileInfo): boolean {
|
|
4
28
|
if (!vbf || !vbf.fileHash) return false
|
|
5
29
|
const bf = validBulkHeaderFilesByFileHash()[vbf.fileHash]
|
|
@@ -20,6 +44,10 @@ export function isKnownValidBulkHeaderFile(vbf: BulkHeaderFileInfo): boolean {
|
|
|
20
44
|
|
|
21
45
|
let _validBulkHeaderFilesByFileHash: Record<string, BulkHeaderFileInfo> | undefined
|
|
22
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Hash map of known valid bulk header files by their `fileHash`.
|
|
49
|
+
* @returns object where keys are file hashes of known bulk header files.
|
|
50
|
+
*/
|
|
23
51
|
export function validBulkHeaderFilesByFileHash(): Record<string, BulkHeaderFileInfo> {
|
|
24
52
|
if (!_validBulkHeaderFilesByFileHash) {
|
|
25
53
|
_validBulkHeaderFilesByFileHash = {}
|
|
@@ -32,6 +60,10 @@ export function validBulkHeaderFilesByFileHash(): Record<string, BulkHeaderFileI
|
|
|
32
60
|
return _validBulkHeaderFilesByFileHash
|
|
33
61
|
}
|
|
34
62
|
|
|
63
|
+
/**
|
|
64
|
+
* Static array of known valid bulk header files.
|
|
65
|
+
* `sourceUrl` is included only as a reference to the original certifying authority.
|
|
66
|
+
*/
|
|
35
67
|
export const validBulkHeaderFiles: BulkHeaderFileInfo[] = [
|
|
36
68
|
{
|
|
37
69
|
sourceUrl: 'https://cdn.projectbabbage.com/blockheaders',
|
|
@@ -68,7 +68,7 @@ export class StorageServer {
|
|
|
68
68
|
|
|
69
69
|
this.app.get(`/`, (req: Request, res: Response) => {
|
|
70
70
|
res.type('text/plain')
|
|
71
|
-
res.send(`BRC-100 Storage Provider.`)
|
|
71
|
+
res.send(`BRC-100 ${this.wallet.chain}Net Storage Provider.`)
|
|
72
72
|
})
|
|
73
73
|
|
|
74
74
|
const options: AuthMiddlewareOptions = {
|