@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.
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/src/auth/certificates/VerifiableCertificate.js +10 -0
- package/dist/cjs/src/auth/certificates/VerifiableCertificate.js.map +1 -1
- package/dist/cjs/src/auth/clients/AuthFetch.js.map +1 -1
- package/dist/cjs/src/transaction/broadcasters/Teranode.js +64 -0
- package/dist/cjs/src/transaction/broadcasters/Teranode.js.map +1 -0
- package/dist/cjs/src/transaction/broadcasters/index.js +3 -1
- package/dist/cjs/src/transaction/broadcasters/index.js.map +1 -1
- package/dist/cjs/src/transaction/http/BinaryFetchClient.js +94 -0
- package/dist/cjs/src/transaction/http/BinaryFetchClient.js.map +1 -0
- package/dist/cjs/src/transaction/http/NodejsHttpClient.js.map +1 -1
- package/dist/cjs/src/transaction/http/index.js +3 -1
- package/dist/cjs/src/transaction/http/index.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/auth/certificates/VerifiableCertificate.js +10 -0
- package/dist/esm/src/auth/certificates/VerifiableCertificate.js.map +1 -1
- package/dist/esm/src/auth/clients/AuthFetch.js.map +1 -1
- package/dist/esm/src/transaction/broadcasters/Teranode.js +62 -0
- package/dist/esm/src/transaction/broadcasters/Teranode.js.map +1 -0
- package/dist/esm/src/transaction/broadcasters/index.js +1 -0
- package/dist/esm/src/transaction/broadcasters/index.js.map +1 -1
- package/dist/esm/src/transaction/http/BinaryFetchClient.js +90 -0
- package/dist/esm/src/transaction/http/BinaryFetchClient.js.map +1 -0
- package/dist/esm/src/transaction/http/NodejsHttpClient.js.map +1 -1
- package/dist/esm/src/transaction/http/index.js +1 -0
- package/dist/esm/src/transaction/http/index.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/src/auth/certificates/VerifiableCertificate.d.ts +9 -1
- package/dist/types/src/auth/certificates/VerifiableCertificate.d.ts.map +1 -1
- package/dist/types/src/auth/clients/AuthFetch.d.ts.map +1 -1
- package/dist/types/src/transaction/broadcasters/Teranode.d.ts +25 -0
- package/dist/types/src/transaction/broadcasters/Teranode.d.ts.map +1 -0
- package/dist/types/src/transaction/broadcasters/index.d.ts +1 -0
- package/dist/types/src/transaction/broadcasters/index.d.ts.map +1 -1
- package/dist/types/src/transaction/http/BinaryFetchClient.d.ts +50 -0
- package/dist/types/src/transaction/http/BinaryFetchClient.d.ts.map +1 -0
- package/dist/types/src/transaction/http/index.d.ts +1 -0
- package/dist/types/src/transaction/http/index.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/dist/umd/bundle.js +1 -1
- package/docs/auth.md +120 -46
- package/docs/compat.md +48 -24
- package/docs/identity.md +14 -8
- package/docs/kvstore.md +9 -3
- package/docs/messages.md +4 -4
- package/docs/overlay-tools.md +69 -21
- package/docs/primitives.md +379 -235
- package/docs/registry.md +20 -14
- package/docs/script.md +87 -33
- package/docs/storage.md +17 -11
- package/docs/totp.md +11 -5
- package/docs/transaction.md +145 -67
- package/docs/wallet.md +169 -133
- package/package.json +1 -1
- package/src/auth/certificates/VerifiableCertificate.ts +24 -0
- package/src/auth/certificates/__tests/VerifiableCertificate.test.ts +28 -1
- package/src/auth/clients/AuthFetch.ts +2 -0
- package/src/transaction/broadcasters/Teranode.ts +77 -0
- package/src/transaction/broadcasters/index.ts +1 -0
- package/src/transaction/http/BinaryFetchClient.ts +141 -0
- package/src/transaction/http/NodejsHttpClient.ts +1 -1
- package/src/transaction/http/index.ts +1 -0
package/package.json
CHANGED
|
@@ -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
|
})
|
|
@@ -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
|
+
}
|
|
@@ -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'
|