@bsv/wallet-toolbox 1.4.6 → 1.4.7
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/CHANGELOG.md +6 -0
- package/docs/client.md +1 -1
- package/docs/services.md +1 -1
- package/docs/wallet.md +1 -1
- package/mobile/out/src/services/chaintracker/BHServiceClient.d.ts +34 -0
- package/mobile/out/src/services/chaintracker/BHServiceClient.d.ts.map +1 -0
- package/mobile/out/src/services/chaintracker/BHServiceClient.js +163 -0
- package/mobile/out/src/services/chaintracker/BHServiceClient.js.map +1 -0
- package/mobile/out/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.d.ts +144 -0
- package/mobile/out/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.d.ts.map +1 -0
- package/mobile/out/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.js +463 -0
- package/mobile/out/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.js.map +1 -0
- package/mobile/out/src/services/chaintracker/chaintracks/util/dirtyHashes.d.ts +20 -0
- package/mobile/out/src/services/chaintracker/chaintracks/util/dirtyHashes.d.ts.map +1 -0
- package/mobile/out/src/services/chaintracker/chaintracks/util/dirtyHashes.js +31 -0
- package/mobile/out/src/services/chaintracker/chaintracks/util/dirtyHashes.js.map +1 -0
- package/mobile/out/src/services/chaintracker/index.d.ts +1 -0
- package/mobile/out/src/services/chaintracker/index.d.ts.map +1 -1
- package/mobile/out/src/services/chaintracker/index.js +1 -0
- package/mobile/out/src/services/chaintracker/index.js.map +1 -1
- package/mobile/out/src/services/createDefaultWalletServicesOptions.d.ts +1 -1
- package/mobile/out/src/services/createDefaultWalletServicesOptions.d.ts.map +1 -1
- package/mobile/out/src/services/createDefaultWalletServicesOptions.js +10 -7
- package/mobile/out/src/services/createDefaultWalletServicesOptions.js.map +1 -1
- package/mobile/out/src/utility/utilityHelpers.buffer.d.ts +18 -0
- package/mobile/out/src/utility/utilityHelpers.buffer.d.ts.map +1 -0
- package/mobile/out/src/utility/utilityHelpers.buffer.js +45 -0
- package/mobile/out/src/utility/utilityHelpers.buffer.js.map +1 -0
- package/out/src/Setup.d.ts.map +1 -1
- package/out/src/Setup.js +4 -0
- package/out/src/Setup.js.map +1 -1
- package/out/src/services/__tests/ArcGorillaPool.man.test.js.map +1 -1
- package/out/src/services/chaintracker/BHServiceClient.d.ts +34 -0
- package/out/src/services/chaintracker/BHServiceClient.d.ts.map +1 -0
- package/out/src/services/chaintracker/BHServiceClient.js +163 -0
- package/out/src/services/chaintracker/BHServiceClient.js.map +1 -0
- package/out/src/services/chaintracker/index.d.ts +1 -0
- package/out/src/services/chaintracker/index.d.ts.map +1 -1
- package/out/src/services/chaintracker/index.js +1 -0
- package/out/src/services/chaintracker/index.js.map +1 -1
- package/out/src/services/createDefaultWalletServicesOptions.d.ts +1 -1
- package/out/src/services/createDefaultWalletServicesOptions.d.ts.map +1 -1
- package/out/src/services/createDefaultWalletServicesOptions.js +10 -7
- package/out/src/services/createDefaultWalletServicesOptions.js.map +1 -1
- package/out/tsconfig.all.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/Setup.ts +6 -0
- package/src/services/__tests/ArcGorillaPool.man.test.ts +1 -1
- package/src/services/chaintracker/BHServiceClient.ts +199 -0
- package/src/services/chaintracker/index.ts +1 -0
- package/src/services/createDefaultWalletServicesOptions.ts +15 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bsv/wallet-toolbox",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.7",
|
|
4
4
|
"description": "BRC100 conforming wallet, wallet storage and wallet signer components",
|
|
5
5
|
"main": "./out/src/index.js",
|
|
6
6
|
"types": "./out/src/index.d.ts",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@bsv/auth-express-middleware": "^1.1.2",
|
|
34
34
|
"@bsv/payment-express-middleware": "^1.0.6",
|
|
35
|
-
"@bsv/sdk": "^1.6.
|
|
35
|
+
"@bsv/sdk": "^1.6.5",
|
|
36
36
|
"express": "^4.21.2",
|
|
37
37
|
"idb": "^8.0.2",
|
|
38
38
|
"knex": "^3.1.0",
|
package/src/Setup.ts
CHANGED
|
@@ -26,6 +26,8 @@ import {
|
|
|
26
26
|
import { Knex, knex as makeKnex } from 'knex'
|
|
27
27
|
|
|
28
28
|
import * as dotenv from 'dotenv'
|
|
29
|
+
// To rely on your own headers service, uncomment the following line:
|
|
30
|
+
// import { BHServiceClient } from './services/chaintracker'
|
|
29
31
|
dotenv.config()
|
|
30
32
|
|
|
31
33
|
/**
|
|
@@ -145,6 +147,10 @@ DEV_KEYS = '{
|
|
|
145
147
|
if (storage.canMakeAvailable()) await storage.makeAvailable()
|
|
146
148
|
const serviceOptions = Services.createDefaultOptions(chain)
|
|
147
149
|
serviceOptions.taalApiKey = args.env.taalApiKey
|
|
150
|
+
|
|
151
|
+
// To rely on your own headers service, uncomment the following line, updating the url and apiKey to your own values.
|
|
152
|
+
// serviceOptions.chaintracks = new BHServiceClient('main', 'https://headers.spv.money', 'fC42F069YJs30FaWBAgikfDFEfIW1j4q')
|
|
153
|
+
|
|
148
154
|
const services = new Services(serviceOptions)
|
|
149
155
|
const monopts = Monitor.createDefaultWalletMonitorOptions(chain, storage, services)
|
|
150
156
|
const monitor = new Monitor(monopts)
|
|
@@ -2,7 +2,7 @@ import { _tu, logger } from '../../../test/utils/TestUtilsWalletStorage'
|
|
|
2
2
|
import { sdk, wait } from '../../index.client'
|
|
3
3
|
import { ARC } from '../providers/ARC'
|
|
4
4
|
import { Beef, BeefTx } from '@bsv/sdk'
|
|
5
|
-
import {
|
|
5
|
+
import { arcGorillaPoolUrl } from '../createDefaultWalletServicesOptions'
|
|
6
6
|
import { Setup } from '../../index.all'
|
|
7
7
|
|
|
8
8
|
describe('ArcGorillaPool tests', () => {
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { BlockHeadersService, Utils } from '@bsv/sdk'
|
|
2
|
+
import { ChaintracksServiceClient, ChaintracksServiceClientOptions } from './chaintracks/ChaintracksServiceClient'
|
|
3
|
+
import { sdk } from '../../index.client'
|
|
4
|
+
import { BaseBlockHeader, BlockHeader } from './chaintracks'
|
|
5
|
+
import { serializeBlockHeader } from './chaintracks/util/blockHeaderUtilities'
|
|
6
|
+
|
|
7
|
+
interface BHSHeader {
|
|
8
|
+
hash: string
|
|
9
|
+
version: number
|
|
10
|
+
prevBlockHash: string
|
|
11
|
+
merkleRoot: string
|
|
12
|
+
creationTimestamp: number
|
|
13
|
+
difficultyTarget: number
|
|
14
|
+
nonce: number
|
|
15
|
+
work: string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface BHSHeaderState {
|
|
19
|
+
header: BHSHeader
|
|
20
|
+
state: string
|
|
21
|
+
chainWork: string
|
|
22
|
+
height: number
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export class BHServiceClient implements ChaintracksServiceClient {
|
|
26
|
+
bhs: BlockHeadersService
|
|
27
|
+
cache: Record<number, string>
|
|
28
|
+
chain: sdk.Chain
|
|
29
|
+
serviceUrl: string
|
|
30
|
+
options: ChaintracksServiceClientOptions
|
|
31
|
+
apiKey: string
|
|
32
|
+
|
|
33
|
+
constructor(chain: sdk.Chain, url: string, apiKey: string) {
|
|
34
|
+
this.bhs = new BlockHeadersService(url, { apiKey })
|
|
35
|
+
this.cache = {}
|
|
36
|
+
this.chain = chain
|
|
37
|
+
this.serviceUrl = url
|
|
38
|
+
this.options = ChaintracksServiceClient.createChaintracksServiceClientOptions()
|
|
39
|
+
this.options.useAuthrite = true
|
|
40
|
+
this.apiKey = apiKey
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async currentHeight(): Promise<number> {
|
|
44
|
+
return await this.bhs.currentHeight()
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async isValidRootForHeight(root: string, height: number): Promise<boolean> {
|
|
48
|
+
const cachedRoot = this.cache[height]
|
|
49
|
+
if (cachedRoot) {
|
|
50
|
+
return cachedRoot === root
|
|
51
|
+
}
|
|
52
|
+
const isValid = await this.bhs.isValidRootForHeight(root, height)
|
|
53
|
+
this.cache[height] = root
|
|
54
|
+
return isValid
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async getPresentHeight(): Promise<number> {
|
|
58
|
+
return await this.bhs.currentHeight()
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async findHeaderForHeight(height: number): Promise<BlockHeader | undefined> {
|
|
62
|
+
const response = await this.getJsonOrUndefined<BHSHeader[]>(`/api/v1/chain/header/byHeight?height=${height}`)
|
|
63
|
+
const header = response?.[0]
|
|
64
|
+
if (!header) return undefined
|
|
65
|
+
const formatted: BlockHeader = {
|
|
66
|
+
version: header.version,
|
|
67
|
+
previousHash: header.prevBlockHash,
|
|
68
|
+
merkleRoot: header.merkleRoot,
|
|
69
|
+
time: header.creationTimestamp,
|
|
70
|
+
bits: header.difficultyTarget,
|
|
71
|
+
nonce: header.nonce,
|
|
72
|
+
height,
|
|
73
|
+
hash: header.hash
|
|
74
|
+
}
|
|
75
|
+
return formatted
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async findHeaderForBlockHash(hash: string): Promise<BlockHeader | undefined> {
|
|
79
|
+
const response = await this.getJsonOrUndefined<BHSHeaderState>(`/api/v1/chain/header/state/${hash}`)
|
|
80
|
+
if (!response?.header) return undefined
|
|
81
|
+
const formatted: BlockHeader = {
|
|
82
|
+
version: response.header.version,
|
|
83
|
+
previousHash: response.header.prevBlockHash,
|
|
84
|
+
merkleRoot: response.header.merkleRoot,
|
|
85
|
+
time: response.header.creationTimestamp,
|
|
86
|
+
bits: response.header.difficultyTarget,
|
|
87
|
+
nonce: response.header.nonce,
|
|
88
|
+
height: response.height,
|
|
89
|
+
hash: response.header.hash
|
|
90
|
+
}
|
|
91
|
+
return formatted
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async getHeaders(height: number, count: number): Promise<string> {
|
|
95
|
+
const response = await this.getJsonOrUndefined<BHSHeader[]>(
|
|
96
|
+
`/api/v1/chain/header/byHeight?height=${height}&count=${count}`
|
|
97
|
+
)
|
|
98
|
+
if (!response) return ''
|
|
99
|
+
if (response.length < count) throw new Error('Cannot retrieve enough headers')
|
|
100
|
+
const headers = response.map(response => {
|
|
101
|
+
const header: BaseBlockHeader = {
|
|
102
|
+
version: response.version,
|
|
103
|
+
previousHash: response.prevBlockHash,
|
|
104
|
+
merkleRoot: response.merkleRoot,
|
|
105
|
+
time: response.creationTimestamp,
|
|
106
|
+
bits: response.difficultyTarget,
|
|
107
|
+
nonce: response.nonce
|
|
108
|
+
}
|
|
109
|
+
return serializeBlockHeader(header)
|
|
110
|
+
})
|
|
111
|
+
return headers.reduce((str: string, arr: number[]) => str + Utils.toHex(arr), '')
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async findChainWorkForBlockHash(hash: string): Promise<string | undefined> {
|
|
115
|
+
throw new Error('Not implemented')
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
async findChainTipHeader(): Promise<BlockHeader> {
|
|
119
|
+
const response = await this.getJson<BHSHeaderState>('/api/v1/chain/tip/longest')
|
|
120
|
+
const formatted: BlockHeader = {
|
|
121
|
+
version: response.header.version,
|
|
122
|
+
previousHash: response.header.prevBlockHash,
|
|
123
|
+
merkleRoot: response.header.merkleRoot,
|
|
124
|
+
time: response.header.creationTimestamp,
|
|
125
|
+
bits: response.header.difficultyTarget,
|
|
126
|
+
nonce: response.header.nonce,
|
|
127
|
+
height: response.height,
|
|
128
|
+
hash: response.header.hash
|
|
129
|
+
}
|
|
130
|
+
return formatted
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
async getJsonOrUndefined<T>(path: string): Promise<T | undefined> {
|
|
134
|
+
let e: Error | undefined = undefined
|
|
135
|
+
for (let retry = 0; retry < 3; retry++) {
|
|
136
|
+
try {
|
|
137
|
+
const r = await fetch(`${this.serviceUrl}${path}`, { headers: { Authorization: `Bearer ${this.apiKey}` } })
|
|
138
|
+
if (r.status !== 200) throw new Error(JSON.stringify(r))
|
|
139
|
+
const v = <T>await r.json()
|
|
140
|
+
if (!v) return undefined
|
|
141
|
+
return v
|
|
142
|
+
} catch (eu: unknown) {
|
|
143
|
+
e = eu as Error
|
|
144
|
+
}
|
|
145
|
+
if (e && e.name !== 'ECONNRESET') break
|
|
146
|
+
}
|
|
147
|
+
if (e) throw e
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
async getJson<T>(path: string): Promise<T> {
|
|
151
|
+
const r = await this.getJsonOrUndefined<T>(path)
|
|
152
|
+
if (r === undefined) throw new Error('Value was undefined. Requested object may not exist.')
|
|
153
|
+
return r
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/*
|
|
157
|
+
Please note that all methods hereafter are included only to match the interface of ChaintracksServiceClient.
|
|
158
|
+
*/
|
|
159
|
+
|
|
160
|
+
async postJsonVoid<T>(path: string, params: T): Promise<void> {
|
|
161
|
+
throw new Error('Not implemented')
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
async addHeader(header: any): Promise<void> {
|
|
165
|
+
throw new Error('Not implemented')
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
async findHeaderForMerkleRoot(merkleRoot: string, height?: number): Promise<undefined> {
|
|
169
|
+
throw new Error('Not implemented')
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
async startListening(): Promise<void> {
|
|
173
|
+
throw new Error('Not implemented')
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
async listening(): Promise<void> {
|
|
177
|
+
throw new Error('Not implemented')
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
async isSynchronized(): Promise<boolean> {
|
|
181
|
+
throw new Error('Not implemented')
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
async getChain(): Promise<sdk.Chain> {
|
|
185
|
+
return this.chain
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
async isListening(): Promise<boolean> {
|
|
189
|
+
throw new Error('Not implemented')
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
async getChainTipHeader(): Promise<BlockHeader> {
|
|
193
|
+
throw new Error('Not implemented')
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
async findChainTipHashHex(): Promise<string> {
|
|
197
|
+
throw new Error('Not implemented')
|
|
198
|
+
}
|
|
199
|
+
}
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { randomBytesHex, sdk } from '../index.client'
|
|
2
2
|
import { ChaintracksServiceClient } from './chaintracker'
|
|
3
3
|
|
|
4
|
-
export function createDefaultWalletServicesOptions(
|
|
4
|
+
export function createDefaultWalletServicesOptions(
|
|
5
|
+
chain: sdk.Chain,
|
|
6
|
+
arcCallbackUrl?: string,
|
|
7
|
+
arcCallbackToken?: string,
|
|
8
|
+
arcApiKey?: string
|
|
9
|
+
): sdk.WalletServicesOptions {
|
|
5
10
|
const deploymentId = `wallet-toolbox-${randomBytesHex(16)}`
|
|
6
11
|
const taalApiKey =
|
|
7
|
-
chain === 'main'
|
|
12
|
+
arcApiKey || chain === 'main'
|
|
8
13
|
? 'mainnet_9596de07e92300c6287e4393594ae39c' // no plan
|
|
9
14
|
: 'testnet_0e6cf72133b43ea2d7861da2a38684e3' // personal "starter" key
|
|
10
|
-
const gorillaPoolApiKey = chain === 'main' ? '' : ''
|
|
11
15
|
|
|
12
16
|
const o: sdk.WalletServicesOptions = {
|
|
13
17
|
chain,
|
|
@@ -37,13 +41,17 @@ export function createDefaultWalletServicesOptions(chain: sdk.Chain): sdk.Wallet
|
|
|
37
41
|
),
|
|
38
42
|
arcUrl: arcDefaultUrl(chain),
|
|
39
43
|
arcConfig: {
|
|
40
|
-
apiKey:
|
|
41
|
-
deploymentId
|
|
44
|
+
apiKey: arcApiKey ?? undefined,
|
|
45
|
+
deploymentId,
|
|
46
|
+
callbackUrl: arcCallbackUrl ?? undefined,
|
|
47
|
+
callbackToken: arcCallbackToken ?? undefined
|
|
42
48
|
},
|
|
43
49
|
arcGorillaPoolUrl: arcGorillaPoolUrl(chain),
|
|
44
50
|
arcGorillaPoolConfig: {
|
|
45
|
-
apiKey:
|
|
46
|
-
deploymentId
|
|
51
|
+
apiKey: arcApiKey ?? undefined,
|
|
52
|
+
deploymentId,
|
|
53
|
+
callbackUrl: arcCallbackUrl ?? undefined,
|
|
54
|
+
callbackToken: arcCallbackToken ?? undefined
|
|
47
55
|
}
|
|
48
56
|
}
|
|
49
57
|
return o
|