@bsv/sdk 1.3.35 → 1.4.0

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 (156) hide show
  1. package/dist/cjs/mod.js +1 -0
  2. package/dist/cjs/mod.js.map +1 -1
  3. package/dist/cjs/package.json +1 -1
  4. package/dist/cjs/src/auth/Peer.js +42 -14
  5. package/dist/cjs/src/auth/Peer.js.map +1 -1
  6. package/dist/cjs/src/auth/certificates/Certificate.js +50 -22
  7. package/dist/cjs/src/auth/certificates/Certificate.js.map +1 -1
  8. package/dist/cjs/src/auth/certificates/MasterCertificate.js +35 -10
  9. package/dist/cjs/src/auth/certificates/MasterCertificate.js.map +1 -1
  10. package/dist/cjs/src/auth/certificates/VerifiableCertificate.js +28 -4
  11. package/dist/cjs/src/auth/certificates/VerifiableCertificate.js.map +1 -1
  12. package/dist/cjs/src/auth/certificates/__tests/CompletedProtoWallet.js +5 -2
  13. package/dist/cjs/src/auth/certificates/__tests/CompletedProtoWallet.js.map +1 -1
  14. package/dist/cjs/src/auth/clients/AuthFetch.js +83 -27
  15. package/dist/cjs/src/auth/clients/AuthFetch.js.map +1 -1
  16. package/dist/cjs/src/auth/transports/SimplifiedFetchTransport.js +70 -34
  17. package/dist/cjs/src/auth/transports/SimplifiedFetchTransport.js.map +1 -1
  18. package/dist/cjs/src/auth/utils/createNonce.js +31 -4
  19. package/dist/cjs/src/auth/utils/createNonce.js.map +1 -1
  20. package/dist/cjs/src/auth/utils/verifyNonce.js +26 -3
  21. package/dist/cjs/src/auth/utils/verifyNonce.js.map +1 -1
  22. package/dist/cjs/src/overlay-tools/LookupResolver.js +2 -2
  23. package/dist/cjs/src/overlay-tools/LookupResolver.js.map +1 -1
  24. package/dist/cjs/src/primitives/utils.js.map +1 -1
  25. package/dist/cjs/src/storage/StorageUploader.js +93 -0
  26. package/dist/cjs/src/storage/StorageUploader.js.map +1 -0
  27. package/dist/cjs/src/storage/StorageUtils.js +73 -0
  28. package/dist/cjs/src/storage/StorageUtils.js.map +1 -0
  29. package/dist/cjs/src/storage/__test/StorageUploader.test.js +92 -0
  30. package/dist/cjs/src/storage/__test/StorageUploader.test.js.map +1 -0
  31. package/dist/cjs/src/storage/__test/StorageUtils.test.js +97 -0
  32. package/dist/cjs/src/storage/__test/StorageUtils.test.js.map +1 -0
  33. package/dist/cjs/src/storage/index.js +30 -0
  34. package/dist/cjs/src/storage/index.js.map +1 -0
  35. package/dist/cjs/src/wallet/WalletClient.js +4 -4
  36. package/dist/cjs/src/wallet/WalletClient.js.map +1 -1
  37. package/dist/cjs/src/wallet/substrates/HTTPWalletWire.js +26 -3
  38. package/dist/cjs/src/wallet/substrates/HTTPWalletWire.js.map +1 -1
  39. package/dist/cjs/src/wallet/substrates/WalletWireProcessor.js +178 -155
  40. package/dist/cjs/src/wallet/substrates/WalletWireProcessor.js.map +1 -1
  41. package/dist/cjs/src/wallet/substrates/WalletWireTransceiver.js +171 -148
  42. package/dist/cjs/src/wallet/substrates/WalletWireTransceiver.js.map +1 -1
  43. package/dist/cjs/src/wallet/substrates/XDM.js +29 -2
  44. package/dist/cjs/src/wallet/substrates/XDM.js.map +1 -1
  45. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  46. package/dist/esm/mod.js +1 -0
  47. package/dist/esm/mod.js.map +1 -1
  48. package/dist/esm/src/auth/Peer.js +7 -5
  49. package/dist/esm/src/auth/Peer.js.map +1 -1
  50. package/dist/esm/src/auth/certificates/Certificate.js +3 -1
  51. package/dist/esm/src/auth/certificates/Certificate.js.map +1 -1
  52. package/dist/esm/src/auth/certificates/MasterCertificate.js +3 -1
  53. package/dist/esm/src/auth/certificates/MasterCertificate.js.map +1 -1
  54. package/dist/esm/src/auth/certificates/VerifiableCertificate.js +2 -1
  55. package/dist/esm/src/auth/certificates/VerifiableCertificate.js.map +1 -1
  56. package/dist/esm/src/auth/certificates/__tests/CompletedProtoWallet.js +1 -1
  57. package/dist/esm/src/auth/certificates/__tests/CompletedProtoWallet.js.map +1 -1
  58. package/dist/esm/src/auth/clients/AuthFetch.js +38 -8
  59. package/dist/esm/src/auth/clients/AuthFetch.js.map +1 -1
  60. package/dist/esm/src/auth/transports/SimplifiedFetchTransport.js +31 -18
  61. package/dist/esm/src/auth/transports/SimplifiedFetchTransport.js.map +1 -1
  62. package/dist/esm/src/auth/utils/createNonce.js +2 -1
  63. package/dist/esm/src/auth/utils/createNonce.js.map +1 -1
  64. package/dist/esm/src/auth/utils/verifyNonce.js +1 -1
  65. package/dist/esm/src/auth/utils/verifyNonce.js.map +1 -1
  66. package/dist/esm/src/overlay-tools/LookupResolver.js +2 -2
  67. package/dist/esm/src/overlay-tools/LookupResolver.js.map +1 -1
  68. package/dist/esm/src/primitives/utils.js.map +1 -1
  69. package/dist/esm/src/storage/StorageUploader.js +68 -0
  70. package/dist/esm/src/storage/StorageUploader.js.map +1 -0
  71. package/dist/esm/src/storage/StorageUtils.js +65 -0
  72. package/dist/esm/src/storage/StorageUtils.js.map +1 -0
  73. package/dist/esm/src/storage/__test/StorageUploader.test.js +64 -0
  74. package/dist/esm/src/storage/__test/StorageUploader.test.js.map +1 -0
  75. package/dist/esm/src/storage/__test/StorageUtils.test.js +72 -0
  76. package/dist/esm/src/storage/__test/StorageUtils.test.js.map +1 -0
  77. package/dist/esm/src/storage/index.js +3 -0
  78. package/dist/esm/src/storage/index.js.map +1 -0
  79. package/dist/esm/src/wallet/WalletClient.js +4 -4
  80. package/dist/esm/src/wallet/WalletClient.js.map +1 -1
  81. package/dist/esm/src/wallet/substrates/HTTPWalletWire.js +1 -1
  82. package/dist/esm/src/wallet/substrates/HTTPWalletWire.js.map +1 -1
  83. package/dist/esm/src/wallet/substrates/WalletWireProcessor.js +1 -1
  84. package/dist/esm/src/wallet/substrates/WalletWireProcessor.js.map +1 -1
  85. package/dist/esm/src/wallet/substrates/WalletWireTransceiver.js +2 -2
  86. package/dist/esm/src/wallet/substrates/WalletWireTransceiver.js.map +1 -1
  87. package/dist/esm/src/wallet/substrates/XDM.js +2 -1
  88. package/dist/esm/src/wallet/substrates/XDM.js.map +1 -1
  89. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  90. package/dist/types/mod.d.ts +1 -0
  91. package/dist/types/mod.d.ts.map +1 -1
  92. package/dist/types/src/auth/Peer.d.ts +1 -1
  93. package/dist/types/src/auth/Peer.d.ts.map +1 -1
  94. package/dist/types/src/auth/certificates/Certificate.d.ts +2 -1
  95. package/dist/types/src/auth/certificates/Certificate.d.ts.map +1 -1
  96. package/dist/types/src/auth/certificates/MasterCertificate.d.ts +2 -1
  97. package/dist/types/src/auth/certificates/MasterCertificate.d.ts.map +1 -1
  98. package/dist/types/src/auth/certificates/VerifiableCertificate.d.ts +2 -1
  99. package/dist/types/src/auth/certificates/VerifiableCertificate.d.ts.map +1 -1
  100. package/dist/types/src/auth/certificates/__tests/CompletedProtoWallet.d.ts +1 -1
  101. package/dist/types/src/auth/certificates/__tests/CompletedProtoWallet.d.ts.map +1 -1
  102. package/dist/types/src/auth/clients/AuthFetch.d.ts +10 -9
  103. package/dist/types/src/auth/clients/AuthFetch.d.ts.map +1 -1
  104. package/dist/types/src/auth/transports/SimplifiedFetchTransport.d.ts.map +1 -1
  105. package/dist/types/src/auth/utils/createNonce.d.ts +1 -1
  106. package/dist/types/src/auth/utils/createNonce.d.ts.map +1 -1
  107. package/dist/types/src/auth/utils/getVerifiableCertificates.d.ts +1 -1
  108. package/dist/types/src/auth/utils/getVerifiableCertificates.d.ts.map +1 -1
  109. package/dist/types/src/auth/utils/verifyNonce.d.ts +1 -1
  110. package/dist/types/src/auth/utils/verifyNonce.d.ts.map +1 -1
  111. package/dist/types/src/primitives/utils.d.ts +4 -1
  112. package/dist/types/src/primitives/utils.d.ts.map +1 -1
  113. package/dist/types/src/storage/StorageUploader.d.ts +40 -0
  114. package/dist/types/src/storage/StorageUploader.d.ts.map +1 -0
  115. package/dist/types/src/storage/StorageUtils.d.ts +31 -0
  116. package/dist/types/src/storage/StorageUtils.d.ts.map +1 -0
  117. package/dist/types/src/storage/__test/StorageUploader.test.d.ts +2 -0
  118. package/dist/types/src/storage/__test/StorageUploader.test.d.ts.map +1 -0
  119. package/dist/types/src/storage/__test/StorageUtils.test.d.ts +2 -0
  120. package/dist/types/src/storage/__test/StorageUtils.test.d.ts.map +1 -0
  121. package/dist/types/src/storage/index.d.ts +3 -0
  122. package/dist/types/src/storage/index.d.ts.map +1 -0
  123. package/dist/types/src/wallet/substrates/XDM.d.ts +1 -1
  124. package/dist/types/src/wallet/substrates/XDM.d.ts.map +1 -1
  125. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  126. package/dist/umd/bundle.js +1 -1
  127. package/docs/primitives.md +4 -1
  128. package/docs/storage.md +210 -0
  129. package/docs/wallet-substrates.md +0 -225
  130. package/mod.ts +1 -0
  131. package/package.json +12 -2
  132. package/src/auth/Peer.ts +8 -5
  133. package/src/auth/__tests/Peer.test.ts +43 -48
  134. package/src/auth/certificates/Certificate.ts +5 -5
  135. package/src/auth/certificates/MasterCertificate.ts +5 -5
  136. package/src/auth/certificates/VerifiableCertificate.ts +6 -6
  137. package/src/auth/certificates/__tests/CompletedProtoWallet.ts +1 -15
  138. package/src/auth/clients/AuthFetch.ts +59 -18
  139. package/src/auth/transports/SimplifiedFetchTransport.ts +31 -19
  140. package/src/auth/utils/__tests/cryptononce.test.ts +0 -2
  141. package/src/auth/utils/createNonce.ts +3 -3
  142. package/src/auth/utils/getVerifiableCertificates.ts +1 -1
  143. package/src/auth/utils/verifyNonce.ts +2 -1
  144. package/src/overlay-tools/LookupResolver.ts +2 -2
  145. package/src/primitives/utils.ts +1 -1
  146. package/src/storage/StorageUploader.ts +108 -0
  147. package/src/storage/StorageUtils.ts +66 -0
  148. package/src/storage/__test/StorageUploader.test.ts +80 -0
  149. package/src/storage/__test/StorageUtils.test.ts +86 -0
  150. package/src/storage/index.ts +2 -0
  151. package/src/transaction/__tests/Transaction.benchmarks.test.ts +1 -16
  152. package/src/wallet/WalletClient.ts +4 -4
  153. package/src/wallet/substrates/HTTPWalletWire.ts +1 -1
  154. package/src/wallet/substrates/WalletWireProcessor.ts +1 -1
  155. package/src/wallet/substrates/WalletWireTransceiver.ts +2 -2
  156. package/src/wallet/substrates/XDM.ts +3 -2
@@ -0,0 +1,108 @@
1
+ import { AuthFetch } from '../auth/clients/AuthFetch.js'
2
+ import { WalletInterface } from '../wallet/Wallet.interfaces.js'
3
+ import * as StorageUtils from './StorageUtils.js'
4
+
5
+ export interface UploaderConfig {
6
+ storageURL: string
7
+ wallet: WalletInterface
8
+ }
9
+
10
+ export interface UploadableFile {
11
+ data: number[]
12
+ type: string
13
+ }
14
+
15
+ export interface UploadFileResult {
16
+ published: boolean
17
+ uhrpURL: string
18
+ }
19
+
20
+ export class StorageUploader {
21
+ private readonly authFetch: AuthFetch
22
+ private readonly baseURL: string
23
+
24
+ constructor (config: UploaderConfig) {
25
+ this.baseURL = config.storageURL
26
+ this.authFetch = new AuthFetch(config.wallet)
27
+ }
28
+
29
+ private async getUploadInfo (
30
+ fileSize: number,
31
+ retentionPeriod: number
32
+ ): Promise<{
33
+ uploadURL: string
34
+ amount?: number
35
+ }> {
36
+ const url = `${this.baseURL}/upload`
37
+ const body = { fileSize, retentionPeriod }
38
+
39
+ const response = await this.authFetch.fetch(url, {
40
+ method: 'POST',
41
+ headers: { 'Content-Type': 'application/json' },
42
+ body: JSON.stringify(body)
43
+ })
44
+ if (!response.ok) {
45
+ throw new Error(`Upload info request failed: HTTP ${response.status}`)
46
+ }
47
+ const data = await response.json() as {
48
+ status: string
49
+ uploadURL: string
50
+ amount?: number
51
+ }
52
+ if (data.status === 'error') {
53
+ throw new Error('Upload route returned an error.')
54
+ }
55
+ return {
56
+ uploadURL: data.uploadURL,
57
+ amount: data.amount
58
+ }
59
+ }
60
+
61
+ private async uploadFile (
62
+ uploadURL: string,
63
+ file: UploadableFile
64
+ ): Promise<UploadFileResult> {
65
+ const body = Uint8Array.from(file.data)
66
+
67
+ const response = await fetch(uploadURL, {
68
+ method: 'PUT',
69
+ body,
70
+ headers: { 'Content-Type': file.type }
71
+ })
72
+ if (!response.ok) {
73
+ throw new Error(`File upload failed: HTTP ${response.status}`)
74
+ }
75
+
76
+ const uhrpURL = await StorageUtils.getURLForFile(file.data)
77
+ return {
78
+ published: true,
79
+ uhrpURL
80
+ }
81
+ }
82
+
83
+ /**
84
+ * Publishes a file to the storage server with the specified retention period.
85
+ *
86
+ * This will:
87
+ * 1. Request an upload URL from the server.
88
+ * 2. Perform an HTTP PUT to upload the file’s raw bytes.
89
+ * 3. Return a UHRP URL referencing the file once published.
90
+ *
91
+ * @param params.file - An object describing the file’s data (number[] array of bytes) and mime type.
92
+ * @param params.retentionPeriod - Number of minutes to keep the file hosted.
93
+ *
94
+ * @returns An object indicating whether the file was published successfully and the resulting UHRP URL.
95
+ *
96
+ * @throws If either the upload info request or the subsequent file upload request fails (non-OK HTTP status).
97
+ */
98
+ public async publishFile (params: {
99
+ file: UploadableFile
100
+ retentionPeriod: number
101
+ }): Promise<UploadFileResult> {
102
+ const { file, retentionPeriod } = params
103
+ const fileSize = file.data.length
104
+
105
+ const { uploadURL } = await this.getUploadInfo(fileSize, retentionPeriod)
106
+ return await this.uploadFile(uploadURL, file)
107
+ }
108
+ }
@@ -0,0 +1,66 @@
1
+ import { sha256 } from '../primitives/Hash.js'
2
+ import { toHex, fromBase58Check, toBase58Check, toArray } from '../primitives/utils.js'
3
+
4
+ /**
5
+ * Takes a UHRP URL and removes any prefixes.
6
+ * @param {string} URL - The UHRP URL.
7
+ * @returns {string} - Normalized URL.
8
+ */
9
+ export const normalizeURL = (URL: string): string => {
10
+ if (URL.toLowerCase().startsWith('uhrp:')) URL = URL.slice(5)
11
+ if (URL.startsWith('//')) URL = URL.slice(2)
12
+ return URL
13
+ }
14
+
15
+ /**
16
+ * Generates a UHRP URL from a given SHA-256 hash.
17
+ * @param {number[]} hash - 32-byte SHA-256 hash.
18
+ * @returns {string} - Base58Check encoded URL.
19
+ */
20
+ export const getURLForHash = (hash: number[]): string => {
21
+ if (hash.length !== 32) {
22
+ throw new Error('Hash length must be 32 bytes (sha256)')
23
+ }
24
+ return toBase58Check(hash, toArray('ce00', 'hex'))
25
+ }
26
+
27
+ /**
28
+ * Generates a UHRP URL for a given file.
29
+ * @param {number[] | string} file - File content as number array or string.
30
+ * @returns {string} - Base58Check encoded URL.
31
+ */
32
+ export const getURLForFile = (file: number[]): string => {
33
+ const hash = sha256(file)
34
+ return getURLForHash(hash)
35
+ }
36
+
37
+ /**
38
+ * Extracts the hash from a UHRP URL.
39
+ * @param {string} URL - UHRP URL.
40
+ * @returns {number[]} - Extracted SHA-256 hash.
41
+ */
42
+ export const getHashFromURL = (URL: string): number[] => {
43
+ URL = normalizeURL(URL)
44
+ const { data, prefix } = fromBase58Check(URL, undefined, 2)
45
+ if (data.length !== 32) {
46
+ throw new Error('Invalid length!')
47
+ }
48
+ if (toHex(prefix as number[]) !== 'ce00') {
49
+ throw new Error('Bad prefix')
50
+ }
51
+ return data as number[]
52
+ }
53
+
54
+ /**
55
+ * Checks if a URL is a valid UHRP URL.
56
+ * @param {string} URL - The URL to validate.
57
+ * @returns {boolean} - True if valid, false otherwise.
58
+ */
59
+ export const isValidURL = (URL: string): boolean => {
60
+ try {
61
+ getHashFromURL(URL)
62
+ return true
63
+ } catch (e) {
64
+ return false
65
+ }
66
+ }
@@ -0,0 +1,80 @@
1
+ import { StorageUploader } from '../StorageUploader.js'
2
+ import * as StorageUtils from '../StorageUtils.js'
3
+ import WalletClient from '../../wallet/WalletClient.js'
4
+
5
+ // A helper for converting a string to a number[] of UTF-8 bytes
6
+ function stringToUtf8Array(str: string): number[] {
7
+ return Array.from(new TextEncoder().encode(str))
8
+ }
9
+
10
+ describe('StorageUploader Tests', () => {
11
+ let uploader: StorageUploader
12
+ let walletClient: WalletClient
13
+ let globalFetchSpy: jest.SpiedFunction<typeof global.fetch>
14
+
15
+ beforeEach(() => {
16
+ walletClient = new WalletClient('json-api', 'non-admin.com')
17
+
18
+ uploader = new StorageUploader({
19
+ storageURL: 'https://example.test.system',
20
+ wallet: walletClient
21
+ })
22
+
23
+ globalFetchSpy = jest
24
+ .spyOn(global, 'fetch')
25
+ .mockResolvedValue(new Response(null, { status: 200 }))
26
+ })
27
+
28
+ afterEach(() => {
29
+ jest.restoreAllMocks()
30
+ })
31
+
32
+ it('should upload a file, produce a valid UHRP URL, and decode it to the known SHA-256', async () => {
33
+ const data = stringToUtf8Array('Hello, world!')
34
+
35
+ // Mock out getUploadInfo so we can control the returned upload/public URLs
36
+ jest.spyOn(uploader as any, 'getUploadInfo').mockResolvedValue({
37
+ uploadURL: 'https://example-upload.com/put',
38
+ })
39
+
40
+ const result = await uploader.publishFile({
41
+ file: {
42
+ data,
43
+ type: 'text/plain'
44
+ },
45
+ retentionPeriod: 7
46
+ })
47
+
48
+ // We expect exactly one PUT request
49
+ expect(globalFetchSpy).toHaveBeenCalledTimes(1)
50
+ // Check the result
51
+ expect(StorageUtils.isValidURL(result.uhrpURL)).toBe(true)
52
+ expect(result.published).toBe(true)
53
+
54
+ const url = StorageUtils.getHashFromURL(result.uhrpURL)
55
+ const firstFour = url.slice(0, 4).map(b => b.toString(16).padStart(2, '0')).join('')
56
+ expect(firstFour).toHaveLength(8)
57
+ })
58
+
59
+ it('should throw if the upload fails with HTTP 500', async () => {
60
+ // Force the fetch to fail
61
+ globalFetchSpy.mockResolvedValueOnce(new Response(null, { status: 500 }))
62
+
63
+ // Also mock getUploadInfo
64
+ jest.spyOn(uploader as any, 'getUploadInfo').mockResolvedValue({
65
+ uploadURL: 'https://example-upload.com/put',
66
+ })
67
+
68
+ const failingData = stringToUtf8Array('failing data')
69
+
70
+ await expect(
71
+ uploader.publishFile({
72
+ file: {
73
+ data: failingData,
74
+ type: 'text/plain'
75
+ },
76
+ retentionPeriod: 30
77
+ })
78
+ ).rejects.toThrow('File upload failed: HTTP 500')
79
+ })
80
+ })
@@ -0,0 +1,86 @@
1
+ import { StorageUtils } from '../index.js'
2
+ import * as Utils from '../../primitives/utils.js'
3
+ import * as Hash from '../..//primitives/Hash.js'
4
+
5
+ // Example data
6
+ const exampleHashHex = '1a5ec49a3f32cd56d19732e89bde5d81755ddc0fd8515dc8b226d47654139dca'
7
+ const exampleHash = Utils.toArray(exampleHashHex, 'hex')
8
+ const exampleFileHex = '687da27f04a112aa48f1cab2e7949f1eea4f7ba28319c1e999910cd561a634a05a3516e6db'
9
+ const exampleFile = Utils.toArray(exampleFileHex, 'hex')
10
+ const exampleURL = 'XUT6PqWb3GP3LR7dmBMCJwZ3oo5g1iGCF3CrpzyuJCemkGu1WGoq'
11
+
12
+ describe('StorageUtils', () => {
13
+ describe('getURLForHash', () => {
14
+ it('Creates the correct URL for the hash', () => {
15
+ const url = StorageUtils.getURLForHash(exampleHash)
16
+ expect(url).toBe(exampleURL)
17
+ })
18
+
19
+ it('Throws an error if hash length is invalid', () => {
20
+ // Get the length of a FILE (not a hash — wrong length!)
21
+ expect(() => StorageUtils.getURLForHash(exampleFile)).toThrow(
22
+ new Error('Hash length must be 32 bytes (sha256)')
23
+ )
24
+ })
25
+ })
26
+
27
+ describe('getURLForFile', () => {
28
+ it('Creates the correct URL for the file', () => {
29
+ const url = StorageUtils.getURLForFile(exampleFile)
30
+ expect(url).toEqual(exampleURL)
31
+ })
32
+ })
33
+
34
+ describe('getHashFromURL', () => {
35
+ it('Decodes the URL to the correct hash', () => {
36
+ const hash = StorageUtils.getHashFromURL(exampleURL)
37
+ expect(Utils.toHex(hash)).toEqual(exampleHashHex)
38
+ })
39
+
40
+ it('Gets the same hash as getting one directly from the file', () => {
41
+ const hashA = StorageUtils.getHashFromURL(exampleURL)
42
+ const hashB = Hash.sha256(exampleFile)
43
+ expect(hashA).toEqual(hashB)
44
+ })
45
+
46
+ it('Throws an error if checksum is invalid', () => {
47
+ const badURL = 'XUU7cTfy6fA6q2neLDmzPqJnGB6o18PXKoGaWLPrH1SeWLKgdCKq'
48
+ expect(() => StorageUtils.getHashFromURL(badURL)).toThrow(new Error('Invalid checksum'))
49
+ })
50
+
51
+ it('Throws an error if URL length is invalid', () => {
52
+ const badURL = 'SomeBase58CheckTooShortOrTooLong'
53
+ expect(() => StorageUtils.getHashFromURL(badURL)).toThrow()
54
+ })
55
+
56
+ it('Throws an error if prefix is invalid', () => {
57
+ const invalidPrefixURL1 = 'AInvalidPrefixTestString1'
58
+ const invalidPrefixURL2 = 'AInvalidPrefixTestString2'
59
+ expect(() => StorageUtils.getHashFromURL(invalidPrefixURL1)).toThrow()
60
+ expect(() => StorageUtils.getHashFromURL(invalidPrefixURL2)).toThrow()
61
+ })
62
+ })
63
+
64
+ describe('isValidURL', () => {
65
+ it('Returns true when URL is valid', () => {
66
+ expect(StorageUtils.isValidURL(exampleURL)).toBe(true)
67
+ })
68
+
69
+ it('Returns false if checksum is invalid', () => {
70
+ const badURL = 'XUU7cTfy6fA6q2neLDmzPqJnGB6o18PXKoGaWLPrH1SeWLKgdCKq'
71
+ expect(StorageUtils.isValidURL(badURL)).toBe(false)
72
+ })
73
+
74
+ it('Returns false if URL length is invalid', () => {
75
+ const badURL = 'SomeBase58CheckTooShortOrTooLong'
76
+ expect(StorageUtils.isValidURL(badURL)).toBe(false)
77
+ })
78
+
79
+ it('Returns false if prefix is invalid', () => {
80
+ const badURL1 = 'AnotherInvalidPrefixTestString'
81
+ const badURL2 = 'YetAnotherInvalidPrefixTestString'
82
+ expect(StorageUtils.isValidURL(badURL1)).toBe(false)
83
+ expect(StorageUtils.isValidURL(badURL2)).toBe(false)
84
+ })
85
+ })
86
+ })
@@ -0,0 +1,2 @@
1
+ export * as StorageUtils from './StorageUtils.js'
2
+ export { StorageUploader } from './StorageUploader.js'
@@ -9,7 +9,7 @@ import MerklePath from '../MerklePath'
9
9
  jest.setTimeout(60000) // Increase timeout for benchmarking tests if necessary
10
10
 
11
11
  // Helper function to measure execution time
12
- async function measureTime (fn: () => Promise<void>): Promise<number> {
12
+ async function measureTime(fn: () => Promise<void>): Promise<number> {
13
13
  const start = process.hrtime()
14
14
  await fn()
15
15
  const diff = process.hrtime(start)
@@ -113,11 +113,6 @@ describe('Transaction Verification Benchmark', () => {
113
113
  const verified = await tx.verify('scripts only')
114
114
  expect(verified).toBe(true)
115
115
  })
116
- console.log(
117
- `Verification time for wide transaction with ${inputCount} inputs: ${timeTaken.toFixed(
118
- 2
119
- )} ms`
120
- )
121
116
  })
122
117
 
123
118
  it('verifies a large transaction with many inputs and outputs', async () => {
@@ -172,11 +167,6 @@ describe('Transaction Verification Benchmark', () => {
172
167
  const verified = await tx.verify('scripts only')
173
168
  expect(verified).toBe(true)
174
169
  })
175
- console.log(
176
- `Verification time for large transaction with ${inputCount} inputs and ${outputCount} outputs: ${timeTaken.toFixed(
177
- 2
178
- )} ms`
179
- )
180
170
  })
181
171
 
182
172
  it('verifies a transaction with nested inputs (complex graph)', async () => {
@@ -243,10 +233,5 @@ describe('Transaction Verification Benchmark', () => {
243
233
  const verified = await finalTx.verify('scripts only')
244
234
  expect(verified).toBe(true)
245
235
  })
246
- console.log(
247
- `Verification time for nested inputs with depth ${depth} and fan-out ${fanOut}: ${timeTaken.toFixed(
248
- 2
249
- )} ms`
250
- )
251
236
  })
252
237
  })
@@ -95,25 +95,25 @@ export default class WalletClient implements WalletInterface {
95
95
  await checkSub()
96
96
  this.substrate = sub
97
97
  } catch (e) {
98
- console.error('XDMSubstrate initialization failed:', e) // Log the error
98
+ // XDM failed, try the next one...
99
99
  try {
100
100
  sub = new XDMSubstrate()
101
101
  await checkSub(MAX_XDM_RESPONSE_WAIT)
102
102
  this.substrate = sub
103
103
  } catch (e) {
104
- console.error('WalletWireTransceiver initialization failed:', e)
104
+ // HTTP wire failed, move on...
105
105
  try {
106
106
  sub = new WalletWireTransceiver(new HTTPWalletWire(this.originator))
107
107
  await checkSub()
108
108
  this.substrate = sub
109
109
  } catch (e) {
110
- console.error('HTTPWalletJSON initialization failed:', e)
110
+ // HTTP JSON failed, attempt the next...
111
111
  try {
112
112
  sub = new HTTPWalletJSON(this.originator)
113
113
  await checkSub()
114
114
  this.substrate = sub
115
115
  } catch (e) {
116
- console.error('No wallet available:', e)
116
+ // No comms. Tell the user to install a BSV wallet.
117
117
  throw new Error(
118
118
  'No wallet available over any communication substrate. Install a BSV wallet today!'
119
119
  )
@@ -1,6 +1,6 @@
1
1
  import WalletWire from './WalletWire.js'
2
2
  import WalletWireCalls from './WalletWireCalls.js'
3
- import { Utils } from '../../primitives/index.js'
3
+ import * as Utils from '../../primitives/utils.js'
4
4
 
5
5
  export default class HTTPWalletWire implements WalletWire {
6
6
  baseUrl: string
@@ -1,6 +1,6 @@
1
1
  import { WalletInterface, SecurityLevel } from '../Wallet.interfaces.js'
2
2
  import WalletWire from './WalletWire.js'
3
- import { Utils } from '../../primitives/index.js'
3
+ import * as Utils from '../../primitives/utils.js'
4
4
  import calls from './WalletWireCalls.js'
5
5
  import Certificate from '../../auth/certificates/Certificate.js'
6
6
 
@@ -46,8 +46,8 @@ import {
46
46
  WalletInterface
47
47
  } from '../Wallet.interfaces.js'
48
48
  import WalletWire from './WalletWire.js'
49
- import { Certificate } from '../../auth/index.js'
50
- import { Utils } from '../../primitives/index.js'
49
+ import Certificate from '../../auth/certificates/Certificate.js'
50
+ import * as Utils from '../../primitives/utils.js'
51
51
  import calls, { CallType } from './WalletWireCalls.js'
52
52
  import { WalletError } from '../WalletError.js'
53
53
 
@@ -27,9 +27,10 @@ import {
27
27
  VersionString7To30Bytes,
28
28
  WalletInterface
29
29
  } from '../Wallet.interfaces.js'
30
- import { Utils, Random } from '../../primitives/index.js'
30
+ import Random from '../../primitives/Random.js'
31
+ import * as Utils from '../../primitives/utils.js'
31
32
  import { WalletError } from '../WalletError.js'
32
- import { CallType } from '../../../mod.js'
33
+ import { CallType } from './WalletWireCalls.js'
33
34
 
34
35
  /**
35
36
  * Facilitates wallet operations over cross-document messaging.