@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.
Files changed (51) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/docs/client.md +1 -1
  3. package/docs/services.md +1 -1
  4. package/docs/wallet.md +1 -1
  5. package/mobile/out/src/services/chaintracker/BHServiceClient.d.ts +34 -0
  6. package/mobile/out/src/services/chaintracker/BHServiceClient.d.ts.map +1 -0
  7. package/mobile/out/src/services/chaintracker/BHServiceClient.js +163 -0
  8. package/mobile/out/src/services/chaintracker/BHServiceClient.js.map +1 -0
  9. package/mobile/out/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.d.ts +144 -0
  10. package/mobile/out/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.d.ts.map +1 -0
  11. package/mobile/out/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.js +463 -0
  12. package/mobile/out/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.js.map +1 -0
  13. package/mobile/out/src/services/chaintracker/chaintracks/util/dirtyHashes.d.ts +20 -0
  14. package/mobile/out/src/services/chaintracker/chaintracks/util/dirtyHashes.d.ts.map +1 -0
  15. package/mobile/out/src/services/chaintracker/chaintracks/util/dirtyHashes.js +31 -0
  16. package/mobile/out/src/services/chaintracker/chaintracks/util/dirtyHashes.js.map +1 -0
  17. package/mobile/out/src/services/chaintracker/index.d.ts +1 -0
  18. package/mobile/out/src/services/chaintracker/index.d.ts.map +1 -1
  19. package/mobile/out/src/services/chaintracker/index.js +1 -0
  20. package/mobile/out/src/services/chaintracker/index.js.map +1 -1
  21. package/mobile/out/src/services/createDefaultWalletServicesOptions.d.ts +1 -1
  22. package/mobile/out/src/services/createDefaultWalletServicesOptions.d.ts.map +1 -1
  23. package/mobile/out/src/services/createDefaultWalletServicesOptions.js +10 -7
  24. package/mobile/out/src/services/createDefaultWalletServicesOptions.js.map +1 -1
  25. package/mobile/out/src/utility/utilityHelpers.buffer.d.ts +18 -0
  26. package/mobile/out/src/utility/utilityHelpers.buffer.d.ts.map +1 -0
  27. package/mobile/out/src/utility/utilityHelpers.buffer.js +45 -0
  28. package/mobile/out/src/utility/utilityHelpers.buffer.js.map +1 -0
  29. package/out/src/Setup.d.ts.map +1 -1
  30. package/out/src/Setup.js +4 -0
  31. package/out/src/Setup.js.map +1 -1
  32. package/out/src/services/__tests/ArcGorillaPool.man.test.js.map +1 -1
  33. package/out/src/services/chaintracker/BHServiceClient.d.ts +34 -0
  34. package/out/src/services/chaintracker/BHServiceClient.d.ts.map +1 -0
  35. package/out/src/services/chaintracker/BHServiceClient.js +163 -0
  36. package/out/src/services/chaintracker/BHServiceClient.js.map +1 -0
  37. package/out/src/services/chaintracker/index.d.ts +1 -0
  38. package/out/src/services/chaintracker/index.d.ts.map +1 -1
  39. package/out/src/services/chaintracker/index.js +1 -0
  40. package/out/src/services/chaintracker/index.js.map +1 -1
  41. package/out/src/services/createDefaultWalletServicesOptions.d.ts +1 -1
  42. package/out/src/services/createDefaultWalletServicesOptions.d.ts.map +1 -1
  43. package/out/src/services/createDefaultWalletServicesOptions.js +10 -7
  44. package/out/src/services/createDefaultWalletServicesOptions.js.map +1 -1
  45. package/out/tsconfig.all.tsbuildinfo +1 -1
  46. package/package.json +2 -2
  47. package/src/Setup.ts +6 -0
  48. package/src/services/__tests/ArcGorillaPool.man.test.ts +1 -1
  49. package/src/services/chaintracker/BHServiceClient.ts +199 -0
  50. package/src/services/chaintracker/index.ts +1 -0
  51. 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.6",
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.0",
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 { arcDefaultUrl, arcGorillaPoolUrl } from '../createDefaultWalletServicesOptions'
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,2 +1,3 @@
1
1
  export * from './chaintracks'
2
2
  export * from './ChaintracksChainTracker'
3
+ export * from './BHServiceClient'
@@ -1,13 +1,17 @@
1
1
  import { randomBytesHex, sdk } from '../index.client'
2
2
  import { ChaintracksServiceClient } from './chaintracker'
3
3
 
4
- export function createDefaultWalletServicesOptions(chain: sdk.Chain): sdk.WalletServicesOptions {
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: taalApiKey,
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: gorillaPoolApiKey,
46
- deploymentId
51
+ apiKey: arcApiKey ?? undefined,
52
+ deploymentId,
53
+ callbackUrl: arcCallbackUrl ?? undefined,
54
+ callbackToken: arcCallbackToken ?? undefined
47
55
  }
48
56
  }
49
57
  return o