@bsv/sdk 1.4.22 → 1.4.24

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 (62) hide show
  1. package/dist/cjs/package.json +1 -1
  2. package/dist/cjs/src/auth/certificates/VerifiableCertificate.js +10 -0
  3. package/dist/cjs/src/auth/certificates/VerifiableCertificate.js.map +1 -1
  4. package/dist/cjs/src/auth/clients/AuthFetch.js.map +1 -1
  5. package/dist/cjs/src/transaction/broadcasters/Teranode.js +64 -0
  6. package/dist/cjs/src/transaction/broadcasters/Teranode.js.map +1 -0
  7. package/dist/cjs/src/transaction/broadcasters/index.js +3 -1
  8. package/dist/cjs/src/transaction/broadcasters/index.js.map +1 -1
  9. package/dist/cjs/src/transaction/http/BinaryFetchClient.js +94 -0
  10. package/dist/cjs/src/transaction/http/BinaryFetchClient.js.map +1 -0
  11. package/dist/cjs/src/transaction/http/NodejsHttpClient.js.map +1 -1
  12. package/dist/cjs/src/transaction/http/index.js +3 -1
  13. package/dist/cjs/src/transaction/http/index.js.map +1 -1
  14. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  15. package/dist/esm/src/auth/certificates/VerifiableCertificate.js +10 -0
  16. package/dist/esm/src/auth/certificates/VerifiableCertificate.js.map +1 -1
  17. package/dist/esm/src/auth/clients/AuthFetch.js.map +1 -1
  18. package/dist/esm/src/transaction/broadcasters/Teranode.js +62 -0
  19. package/dist/esm/src/transaction/broadcasters/Teranode.js.map +1 -0
  20. package/dist/esm/src/transaction/broadcasters/index.js +1 -0
  21. package/dist/esm/src/transaction/broadcasters/index.js.map +1 -1
  22. package/dist/esm/src/transaction/http/BinaryFetchClient.js +90 -0
  23. package/dist/esm/src/transaction/http/BinaryFetchClient.js.map +1 -0
  24. package/dist/esm/src/transaction/http/NodejsHttpClient.js.map +1 -1
  25. package/dist/esm/src/transaction/http/index.js +1 -0
  26. package/dist/esm/src/transaction/http/index.js.map +1 -1
  27. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  28. package/dist/types/src/auth/certificates/VerifiableCertificate.d.ts +9 -1
  29. package/dist/types/src/auth/certificates/VerifiableCertificate.d.ts.map +1 -1
  30. package/dist/types/src/auth/clients/AuthFetch.d.ts.map +1 -1
  31. package/dist/types/src/transaction/broadcasters/Teranode.d.ts +25 -0
  32. package/dist/types/src/transaction/broadcasters/Teranode.d.ts.map +1 -0
  33. package/dist/types/src/transaction/broadcasters/index.d.ts +1 -0
  34. package/dist/types/src/transaction/broadcasters/index.d.ts.map +1 -1
  35. package/dist/types/src/transaction/http/BinaryFetchClient.d.ts +50 -0
  36. package/dist/types/src/transaction/http/BinaryFetchClient.d.ts.map +1 -0
  37. package/dist/types/src/transaction/http/index.d.ts +1 -0
  38. package/dist/types/src/transaction/http/index.d.ts.map +1 -1
  39. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  40. package/dist/umd/bundle.js +1 -1
  41. package/docs/auth.md +120 -46
  42. package/docs/compat.md +48 -24
  43. package/docs/identity.md +14 -8
  44. package/docs/kvstore.md +9 -3
  45. package/docs/messages.md +4 -4
  46. package/docs/overlay-tools.md +69 -21
  47. package/docs/primitives.md +379 -235
  48. package/docs/registry.md +20 -14
  49. package/docs/script.md +87 -33
  50. package/docs/storage.md +17 -11
  51. package/docs/totp.md +11 -5
  52. package/docs/transaction.md +145 -67
  53. package/docs/wallet.md +169 -133
  54. package/package.json +1 -1
  55. package/src/auth/certificates/VerifiableCertificate.ts +24 -0
  56. package/src/auth/certificates/__tests/VerifiableCertificate.test.ts +28 -1
  57. package/src/auth/clients/AuthFetch.ts +2 -0
  58. package/src/transaction/broadcasters/Teranode.ts +77 -0
  59. package/src/transaction/broadcasters/index.ts +1 -0
  60. package/src/transaction/http/BinaryFetchClient.ts +141 -0
  61. package/src/transaction/http/NodejsHttpClient.ts +1 -1
  62. package/src/transaction/http/index.ts +1 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bsv/sdk",
3
- "version": "1.4.22",
3
+ "version": "1.4.24",
4
4
  "type": "module",
5
5
  "description": "BSV Blockchain Software Development Kit",
6
6
  "main": "dist/cjs/mod.js",
@@ -4,6 +4,7 @@ import type {
4
4
  CertificateFieldNameUnder50Bytes,
5
5
  HexString,
6
6
  OutpointString,
7
+ WalletCertificate,
7
8
  } from '../../wallet/Wallet.interfaces.js'
8
9
  import SymmetricKey from '../../primitives/SymmetricKey.js'
9
10
  import * as Utils from '../../primitives/utils.js'
@@ -50,6 +51,29 @@ export class VerifiableCertificate extends Certificate {
50
51
  this.decryptedFields = decryptedFields
51
52
  }
52
53
 
54
+ /**
55
+ *
56
+ * @param {WalletCertificate} certificate – The source certificate that was issued and signed by the certifier.
57
+ * @param {Record<CertificateFieldNameUnder50Bytes, string>} keyring – A allows the verifier to decrypt selected certificate fields.
58
+ * @returns {VerifiableCertificate} – A fully-formed instance containing the
59
+ * original certificate data plus the supplied keyring.
60
+ */
61
+ static fromCertificate(
62
+ certificate: WalletCertificate,
63
+ keyring: Record<CertificateFieldNameUnder50Bytes, string>
64
+ ): VerifiableCertificate {
65
+ return new VerifiableCertificate(
66
+ certificate.type,
67
+ certificate.serialNumber,
68
+ certificate.subject,
69
+ certificate.certifier,
70
+ certificate.revocationOutpoint,
71
+ certificate.fields,
72
+ keyring,
73
+ certificate.signature
74
+ )
75
+ }
76
+
53
77
  /**
54
78
  * Decrypts selectively revealed certificate fields using the provided keyring and verifier wallet
55
79
  * @param {ProtoWallet} verifierWallet - The wallet instance of the certificate's verifier, used to decrypt field keys.
@@ -1,8 +1,9 @@
1
1
  import { VerifiableCertificate } from '../../../auth/certificates/VerifiableCertificate'
2
+ import Certificate from '../../../auth/certificates/Certificate'
2
3
  import { PrivateKey, Utils } from '../../../../mod'
3
4
  import { CompletedProtoWallet } from '../../../auth/certificates/__tests/CompletedProtoWallet'
4
5
  import { MasterCertificate } from '../../../auth/certificates/MasterCertificate'
5
- import { ProtoWallet } from '../../../wallet/index'
6
+ import { ProtoWallet, WalletCertificate } from '../../../wallet/index'
6
7
 
7
8
  describe('VerifiableCertificate', () => {
8
9
  const subjectPrivateKey = PrivateKey.fromRandom()
@@ -149,4 +150,30 @@ describe('VerifiableCertificate', () => {
149
150
  expect(decrypted).toEqual(plaintextFields)
150
151
  })
151
152
  })
153
+
154
+ describe('fromCertificate', () => {
155
+ it('should create an equivalent VerifiableCertificate and decrypt correctly', async () => {
156
+ const baseCert = new Certificate(
157
+ verifiableCert.type,
158
+ verifiableCert.serialNumber,
159
+ verifiableCert.subject,
160
+ verifiableCert.certifier,
161
+ verifiableCert.revocationOutpoint,
162
+ verifiableCert.fields,
163
+ verifiableCert.signature
164
+ ) as WalletCertificate
165
+
166
+ const verifiable = VerifiableCertificate.fromCertificate(
167
+ baseCert,
168
+ verifiableCert.keyring
169
+ )
170
+
171
+ expect(verifiable).toBeInstanceOf(VerifiableCertificate)
172
+ expect(verifiable.serialNumber).toEqual(sampleSerialNumber)
173
+ expect(verifiable.keyring).toEqual(verifiableCert.keyring)
174
+
175
+ const decrypted = await verifiable.decryptFields(verifierWallet)
176
+ expect(decrypted).toEqual(plaintextFields)
177
+ })
178
+ })
152
179
  })
@@ -495,6 +495,8 @@ export class AuthFetch {
495
495
  }
496
496
  })
497
497
 
498
+
499
+
498
500
  // Attach the payment to the request headers
499
501
  config.headers = config.headers || {}
500
502
  config.headers['x-bsv-payment'] = JSON.stringify({
@@ -0,0 +1,77 @@
1
+ import {
2
+ BroadcastResponse,
3
+ BroadcastFailure,
4
+ Broadcaster
5
+ } from '../Broadcaster.js'
6
+ import Transaction from '../Transaction.js'
7
+ import { binaryHttpClient, HttpClient } from '../http/index.js'
8
+
9
+ /**
10
+ * Represents an Teranode transaction broadcaster.
11
+ */
12
+ export default class Teranode implements Broadcaster {
13
+ readonly URL: string
14
+ readonly httpClient: HttpClient
15
+
16
+ /**
17
+ * Constructs an instance of the Teranode broadcaster.
18
+ *
19
+ * @param {string} URL - The URL endpoint for the Teranode API.
20
+ * @param {HttpClient} httpClient - The HTTP client used to make requests to the API, binaryHttpClient by default.
21
+ */
22
+ constructor(
23
+ URL: string,
24
+ httpClient: HttpClient = binaryHttpClient()
25
+ ) {
26
+ this.URL = URL
27
+ this.httpClient = httpClient
28
+ }
29
+
30
+ /**
31
+ * Broadcasts a transaction via Teranode.
32
+ *
33
+ * @param {Transaction} tx - The transaction to be broadcasted.
34
+ * @returns {Promise<BroadcastResponse | BroadcastFailure>} A promise that resolves to either a success or failure response.
35
+ */
36
+ async broadcast(
37
+ tx: Transaction
38
+ ): Promise<BroadcastResponse | BroadcastFailure> {
39
+ const rawTx = tx.toEF()
40
+ const requestOptions = {
41
+ method: 'POST',
42
+ headers: {
43
+ 'Content-Type': 'application/octet-stream'
44
+ },
45
+ data: new Blob([new Uint8Array(rawTx)])
46
+ }
47
+ try {
48
+ const response = await this.httpClient.request<string>(
49
+ this.URL,
50
+ requestOptions
51
+ )
52
+ if (response.ok) {
53
+ const txid = tx.id('hex')
54
+ return {
55
+ status: 'success',
56
+ txid,
57
+ message: 'broadcast successful'
58
+ }
59
+ } else {
60
+ return {
61
+ status: 'error',
62
+ code: response.status.toString() ?? 'ERR_UNKNOWN',
63
+ description: response.data ?? 'Unknown error'
64
+ }
65
+ }
66
+ } catch (error) {
67
+ return {
68
+ status: 'error',
69
+ code: '500',
70
+ description:
71
+ typeof error.message === 'string'
72
+ ? error.message
73
+ : 'Internal Server Error'
74
+ }
75
+ }
76
+ }
77
+ }
@@ -1,4 +1,5 @@
1
1
  export { default as ARC } from './ARC.js'
2
2
  export type { ArcConfig } from './ARC.js'
3
3
  export { default as WhatsOnChainBroadcaster } from './WhatsOnChainBroadcaster.js'
4
+ export { default as Teranode } from './Teranode.js'
4
5
  export { defaultBroadcaster } from './DefaultBroadcaster.js'
@@ -0,0 +1,141 @@
1
+ import {
2
+ HttpClient,
3
+ HttpClientRequestOptions,
4
+ HttpClientResponse
5
+ } from './HttpClient.js'
6
+
7
+ /** Node Https module interface limited to options needed by ts-sdk */
8
+ export interface BinaryHttpsNodejs {
9
+ request: (
10
+ url: string,
11
+ options: HttpClientRequestOptions,
12
+ callback: (res: any) => void
13
+ ) => BinaryNodejsHttpClientRequest
14
+ }
15
+
16
+ /** Nodejs result of the Node https.request call limited to options needed by ts-sdk */
17
+ export interface BinaryNodejsHttpClientRequest {
18
+ write: (chunk: Buffer) => void
19
+
20
+ on: (event: string, callback: (data: any) => void) => void
21
+
22
+ end: (() => void) & (() => void)
23
+ }
24
+
25
+ /**
26
+ * Adapter for Node Https module to be used as HttpClient
27
+ */
28
+ export class BinaryNodejsHttpClient implements HttpClient {
29
+ constructor(private readonly https: BinaryHttpsNodejs) { }
30
+
31
+ async request(
32
+ url: string,
33
+ requestOptions: HttpClientRequestOptions
34
+ ): Promise<HttpClientResponse> {
35
+ return await new Promise((resolve, reject) => {
36
+ const req = this.https.request(url, requestOptions, (res) => {
37
+ let body = ''
38
+ res.on('data', (chunk: string) => {
39
+ body += chunk
40
+ })
41
+ res.on('end', () => {
42
+ const ok = res.statusCode >= 200 && res.statusCode <= 299
43
+ const mediaType = res.headers['content-type']
44
+ const data =
45
+ body !== '' && typeof mediaType === 'string' && mediaType.startsWith('application/json')
46
+ ? JSON.parse(body)
47
+ : body
48
+ resolve({
49
+ status: res.statusCode,
50
+ statusText: res.statusMessage,
51
+ ok,
52
+ data
53
+ })
54
+ })
55
+ })
56
+
57
+ req.on('error', (error: Error) => {
58
+ reject(error)
59
+ })
60
+
61
+ if (requestOptions.data !== null && requestOptions.data !== undefined) {
62
+ req.write(Buffer.from(requestOptions.data))
63
+ }
64
+ req.end()
65
+ })
66
+ }
67
+ }
68
+
69
+ /** fetch function interface limited to options needed by ts-sdk */
70
+ /**
71
+ * Makes a request to the server.
72
+ * @param url The URL to make the request to.
73
+ * @param options The request configuration.
74
+ */
75
+ export type Fetch = (url: string, options: FetchOptions) => Promise<Response>
76
+
77
+ /**
78
+ * An interface for configuration of the request to be passed to the fetch method
79
+ * limited to options needed by ts-sdk.
80
+ */
81
+ export interface FetchOptions {
82
+ /** A string to set request's method. */
83
+ method?: string
84
+ /** An object literal set request's headers. */
85
+ headers?: Record<string, string>
86
+ /** An object or null to set request's body. */
87
+ body?: Buffer | Uint8Array | Blob | null
88
+ }
89
+
90
+ /**
91
+ * Adapter for Node Https module to be used as HttpClient
92
+ */
93
+ export class BinaryFetchClient implements HttpClient {
94
+ constructor(private readonly fetch: Fetch) { }
95
+
96
+ async request<D>(
97
+ url: string,
98
+ options: HttpClientRequestOptions
99
+ ): Promise<HttpClientResponse<D>> {
100
+ const fetchOptions: FetchOptions = {
101
+ method: options.method,
102
+ headers: options.headers,
103
+ body: options.data
104
+ }
105
+
106
+ const res = await this.fetch(url, fetchOptions)
107
+ const data = await res.text()
108
+
109
+ return {
110
+ ok: res.ok,
111
+ status: res.status,
112
+ statusText: res.statusText,
113
+ data: data as D
114
+ }
115
+ }
116
+ }
117
+
118
+ export function binaryHttpClient(): HttpClient {
119
+ const noHttpClient: HttpClient = {
120
+ async request(..._): Promise<HttpClientResponse> {
121
+ throw new Error('No method available to perform HTTP request')
122
+ }
123
+ }
124
+
125
+ if (typeof window !== 'undefined' && typeof window.fetch === 'function') {
126
+ // Use fetch in a browser environment
127
+ return new BinaryFetchClient(window.fetch.bind(window))
128
+ } else if (typeof require !== 'undefined') {
129
+ // Use Node https module
130
+ // eslint-disable-next-line
131
+ try {
132
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
133
+ const https = require('https')
134
+ return new BinaryNodejsHttpClient(https)
135
+ } catch (e) {
136
+ return noHttpClient
137
+ }
138
+ } else {
139
+ return noHttpClient
140
+ }
141
+ }
@@ -54,7 +54,7 @@ export class NodejsHttpClient implements HttpClient {
54
54
  })
55
55
  })
56
56
 
57
- req.on('error', (error) => {
57
+ req.on('error', (error: Error) => {
58
58
  reject(error)
59
59
  })
60
60
 
@@ -4,6 +4,7 @@ export type {
4
4
  HttpClientRequestOptions
5
5
  } from './HttpClient.js'
6
6
  export { defaultHttpClient } from './DefaultHttpClient.js'
7
+ export { binaryHttpClient } from './BinaryFetchClient.js'
7
8
  export { NodejsHttpClient } from './NodejsHttpClient.js'
8
9
  export { FetchHttpClient } from './FetchHttpClient.js'
9
10
  export type { Fetch, FetchOptions } from './FetchHttpClient.js'