@bsv/sdk 1.3.36 → 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 (153) 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 +50 -20
  15. package/dist/cjs/src/auth/clients/AuthFetch.js.map +1 -1
  16. package/dist/cjs/src/auth/transports/SimplifiedFetchTransport.js +40 -17
  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 +5 -1
  59. package/dist/esm/src/auth/clients/AuthFetch.js.map +1 -1
  60. package/dist/esm/src/auth/transports/SimplifiedFetchTransport.js +1 -1
  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 +1 -1
  103. package/dist/types/src/auth/clients/AuthFetch.d.ts.map +1 -1
  104. package/dist/types/src/auth/utils/createNonce.d.ts +1 -1
  105. package/dist/types/src/auth/utils/createNonce.d.ts.map +1 -1
  106. package/dist/types/src/auth/utils/getVerifiableCertificates.d.ts +1 -1
  107. package/dist/types/src/auth/utils/getVerifiableCertificates.d.ts.map +1 -1
  108. package/dist/types/src/auth/utils/verifyNonce.d.ts +1 -1
  109. package/dist/types/src/auth/utils/verifyNonce.d.ts.map +1 -1
  110. package/dist/types/src/primitives/utils.d.ts +4 -1
  111. package/dist/types/src/primitives/utils.d.ts.map +1 -1
  112. package/dist/types/src/storage/StorageUploader.d.ts +40 -0
  113. package/dist/types/src/storage/StorageUploader.d.ts.map +1 -0
  114. package/dist/types/src/storage/StorageUtils.d.ts +31 -0
  115. package/dist/types/src/storage/StorageUtils.d.ts.map +1 -0
  116. package/dist/types/src/storage/__test/StorageUploader.test.d.ts +2 -0
  117. package/dist/types/src/storage/__test/StorageUploader.test.d.ts.map +1 -0
  118. package/dist/types/src/storage/__test/StorageUtils.test.d.ts +2 -0
  119. package/dist/types/src/storage/__test/StorageUtils.test.d.ts.map +1 -0
  120. package/dist/types/src/storage/index.d.ts +3 -0
  121. package/dist/types/src/storage/index.d.ts.map +1 -0
  122. package/dist/types/src/wallet/substrates/XDM.d.ts +1 -1
  123. package/dist/types/src/wallet/substrates/XDM.d.ts.map +1 -1
  124. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  125. package/dist/umd/bundle.js +1 -1
  126. package/docs/primitives.md +4 -1
  127. package/docs/storage.md +210 -0
  128. package/docs/wallet-substrates.md +0 -225
  129. package/mod.ts +1 -0
  130. package/package.json +12 -2
  131. package/src/auth/Peer.ts +8 -5
  132. package/src/auth/__tests/Peer.test.ts +31 -31
  133. package/src/auth/certificates/Certificate.ts +5 -5
  134. package/src/auth/certificates/MasterCertificate.ts +5 -5
  135. package/src/auth/certificates/VerifiableCertificate.ts +6 -6
  136. package/src/auth/certificates/__tests/CompletedProtoWallet.ts +1 -15
  137. package/src/auth/clients/AuthFetch.ts +6 -1
  138. package/src/auth/transports/SimplifiedFetchTransport.ts +1 -1
  139. package/src/auth/utils/createNonce.ts +3 -3
  140. package/src/auth/utils/getVerifiableCertificates.ts +1 -1
  141. package/src/auth/utils/verifyNonce.ts +2 -1
  142. package/src/overlay-tools/LookupResolver.ts +2 -2
  143. package/src/primitives/utils.ts +1 -1
  144. package/src/storage/StorageUploader.ts +108 -0
  145. package/src/storage/StorageUtils.ts +66 -0
  146. package/src/storage/__test/StorageUploader.test.ts +80 -0
  147. package/src/storage/__test/StorageUtils.test.ts +86 -0
  148. package/src/storage/index.ts +2 -0
  149. package/src/wallet/WalletClient.ts +4 -4
  150. package/src/wallet/substrates/HTTPWalletWire.ts +1 -1
  151. package/src/wallet/substrates/WalletWireProcessor.ts +1 -1
  152. package/src/wallet/substrates/WalletWireTransceiver.ts +2 -2
  153. package/src/wallet/substrates/XDM.ts +3 -2
@@ -6,7 +6,7 @@ import { Utils, PrivateKey } from '../../primitives/index.js'
6
6
  import { VerifiableCertificate } from '../../auth/certificates/VerifiableCertificate.js'
7
7
  import { MasterCertificate } from '../../auth/certificates/MasterCertificate.js'
8
8
  import { getVerifiableCertificates } from '../../auth/utils/getVerifiableCertificates.js'
9
- import { CompletedProtoWallet } from '../../../mod.js'
9
+ import { CompletedProtoWallet } from '../certificates/__tests/CompletedProtoWallet.js'
10
10
 
11
11
  jest.mock('../../auth/utils/getVerifiableCertificates')
12
12
 
@@ -337,7 +337,7 @@ describe('Peer class mutual authentication and certificate exchange', () => {
337
337
  }
338
338
  resolve()
339
339
  })().catch((e) => {
340
- console.error(e)
340
+ // console.error(e)
341
341
  })
342
342
  })
343
343
  })
@@ -396,9 +396,9 @@ describe('Peer class mutual authentication and certificate exchange', () => {
396
396
  Object.keys(decryptedFields).length !== 0 &&
397
397
  typeof decryptedFields.libraryCardNumber !== 'undefined'
398
398
  ) {
399
- console.log(
400
- `Alice received Bob's library card number: ${decryptedFields.libraryCardNumber}`
401
- )
399
+ // console.log(
400
+ // `Alice received Bob's library card number: ${decryptedFields.libraryCardNumber}`
401
+ // )
402
402
  aliceAcceptedLibraryCard()
403
403
  }
404
404
  }
@@ -407,7 +407,7 @@ describe('Peer class mutual authentication and certificate exchange', () => {
407
407
 
408
408
  const bobReceivedGeneralMessage = new Promise<void>((resolve) => {
409
409
  bob.listenForGeneralMessages((senderPublicKey, payload) => {
410
- console.log('Bob received message from Alice:', Utils.toUTF8(payload))
410
+ // console.log('Bob received message from Alice:', Utils.toUTF8(payload))
411
411
  resolve()
412
412
  })
413
413
  })
@@ -452,7 +452,7 @@ describe('Peer class mutual authentication and certificate exchange', () => {
452
452
  bob.listenForGeneralMessages((senderPublicKey, payload) => {
453
453
  (async () => {
454
454
  await bobReceivedCertificates
455
- console.log('Bob received message:', Utils.toUTF8(payload))
455
+ // console.log('Bob received message:', Utils.toUTF8(payload))
456
456
 
457
457
  // Bob requests additional certificates after initial communication
458
458
  await bob.requestCertificates(certificatesToRequest, senderPublicKey)
@@ -473,11 +473,11 @@ describe('Peer class mutual authentication and certificate exchange', () => {
473
473
  // Decrypt to confirm
474
474
  for (const cert of certificates) {
475
475
  const decrypted = await cert.decryptFields(walletB)
476
- console.log(
477
- 'Bob received additional certificates from Alice:',
478
- cert
479
- )
480
- console.log('Decrypted fields:', decrypted)
476
+ // console.log(
477
+ // 'Bob received additional certificates from Alice:',
478
+ // cert
479
+ // )
480
+ // console.log('Decrypted fields:', decrypted)
481
481
  }
482
482
  resolve()
483
483
  }
@@ -535,9 +535,9 @@ describe('Peer class mutual authentication and certificate exchange', () => {
535
535
  // Decrypt Alice's certificate fields
536
536
  const decryptedFields = await cert.decryptFields(walletB)
537
537
  if (typeof decryptedFields.membershipStatus !== 'undefined') {
538
- console.log(
539
- `Bob received Alice's membership status: ${decryptedFields.membershipStatus}`
540
- )
538
+ // console.log(
539
+ // `Bob received Alice's membership status: ${decryptedFields.membershipStatus}`
540
+ // )
541
541
  bobAcceptedMembershipStatus()
542
542
  resolve()
543
543
  }
@@ -551,7 +551,7 @@ describe('Peer class mutual authentication and certificate exchange', () => {
551
551
 
552
552
  const bobReceivedGeneralMessage = new Promise<void>((resolve) => {
553
553
  bob.listenForGeneralMessages((senderPublicKey, payload) => {
554
- console.log('Bob received message from Alice:', Utils.toUTF8(payload))
554
+ // console.log('Bob received message from Alice:', Utils.toUTF8(payload))
555
555
  resolve()
556
556
  })
557
557
  })
@@ -628,9 +628,9 @@ describe('Peer class mutual authentication and certificate exchange', () => {
628
628
  for (const cert of certificates) {
629
629
  const decryptedFields = await cert.decryptFields(walletA)
630
630
  if (decryptedFields.driversLicenseNumber !== undefined) {
631
- console.log(
632
- `Alice received Bob's driver's license number: ${decryptedFields.driversLicenseNumber}`
633
- )
631
+ // console.log(
632
+ // `Alice received Bob's driver's license number: ${decryptedFields.driversLicenseNumber}`
633
+ // )
634
634
  aliceAcceptedBobDL()
635
635
  resolve()
636
636
  }
@@ -646,9 +646,9 @@ describe('Peer class mutual authentication and certificate exchange', () => {
646
646
  for (const cert of certificates) {
647
647
  const decryptedFields = await cert.decryptFields(walletB)
648
648
  if (decryptedFields.driversLicenseNumber !== undefined) {
649
- console.log(
650
- `Bob received Alice's driver's license number: ${decryptedFields.driversLicenseNumber}`
651
- )
649
+ // console.log(
650
+ // `Bob received Alice's driver's license number: ${decryptedFields.driversLicenseNumber}`
651
+ // )
652
652
  bobAcceptedAliceDL()
653
653
  resolve()
654
654
  }
@@ -661,7 +661,7 @@ describe('Peer class mutual authentication and certificate exchange', () => {
661
661
  const bobReceivedGeneralMessage = new Promise<void>((resolve) => {
662
662
  bob.listenForGeneralMessages((senderPublicKey, payload) => {
663
663
  (async () => {
664
- console.log('Bob received message from Alice:', Utils.toUTF8(payload))
664
+ // console.log('Bob received message from Alice:', Utils.toUTF8(payload))
665
665
  await bob.toPeer(
666
666
  Utils.toArray('Looking forward to carpooling!'),
667
667
  senderPublicKey
@@ -673,7 +673,7 @@ describe('Peer class mutual authentication and certificate exchange', () => {
673
673
 
674
674
  const aliceReceivedGeneralMessage = new Promise<void>((resolve) => {
675
675
  alice.listenForGeneralMessages((senderPublicKey, payload) => {
676
- console.log('Alice received message from Bob:', Utils.toUTF8(payload))
676
+ // console.log('Alice received message from Bob:', Utils.toUTF8(payload))
677
677
  resolve()
678
678
  })
679
679
  })
@@ -754,9 +754,9 @@ describe('Peer class mutual authentication and certificate exchange', () => {
754
754
  for (const cert of certificates) {
755
755
  const decryptedFields = await cert.decryptFields(walletA)
756
756
  if (decryptedFields.email !== undefined || decryptedFields.name !== undefined) {
757
- console.log(
758
- `Alice received Bob's certificate with fields: ${Object.keys(decryptedFields).join(', ')}`
759
- )
757
+ // console.log(
758
+ // `Alice received Bob's certificate with fields: ${Object.keys(decryptedFields).join(', ')}`
759
+ // )
760
760
  aliceAcceptedPartialCert()
761
761
  resolve()
762
762
  }
@@ -771,9 +771,9 @@ describe('Peer class mutual authentication and certificate exchange', () => {
771
771
  for (const cert of certificates) {
772
772
  const decryptedFields = await cert.decryptFields(walletB)
773
773
  if (decryptedFields.email !== undefined || decryptedFields.name !== undefined) {
774
- console.log(
775
- `Bob received Alice's certificate with fields: ${Object.keys(decryptedFields).join(', ')}`
776
- )
774
+ // console.log(
775
+ // `Bob received Alice's certificate with fields: ${Object.keys(decryptedFields).join(', ')}`
776
+ // )
777
777
  bobAcceptedPartialCert()
778
778
  resolve()
779
779
  }
@@ -784,7 +784,7 @@ describe('Peer class mutual authentication and certificate exchange', () => {
784
784
 
785
785
  const bobReceivedGeneralMessage = new Promise<void>((resolve) => {
786
786
  bob.listenForGeneralMessages((senderPublicKey, payload) => {
787
- console.log('Bob received message:', Utils.toUTF8(payload))
787
+ // console.log('Bob received message:', Utils.toUTF8(payload))
788
788
  resolve()
789
789
  })
790
790
  })
@@ -1,14 +1,14 @@
1
1
  import {
2
- Utils,
3
2
  Base64String,
4
3
  PubKeyHex,
5
4
  HexString,
6
5
  OutpointString,
7
6
  CertificateFieldNameUnder50Bytes,
8
- Signature,
9
- WalletProtocol,
10
- ProtoWallet
11
- } from '../../../mod.js'
7
+ WalletProtocol
8
+ } from '../../wallet/Wallet.interfaces.js'
9
+ import * as Utils from '../../primitives/utils.js'
10
+ import ProtoWallet from '../../wallet/ProtoWallet.js'
11
+ import Signature from '../../primitives/Signature.js'
12
12
 
13
13
  /**
14
14
  * Represents an Identity Certificate as per the Wallet interface specifications.
@@ -1,16 +1,16 @@
1
1
  import {
2
- SymmetricKey,
3
- Utils,
4
2
  Base64String,
5
3
  CertificateFieldNameUnder50Bytes,
6
4
  HexString,
7
5
  OutpointString,
8
6
  PubKeyHex,
9
- Random,
10
7
  WalletCounterparty,
11
- ProtoWallet
12
- } from '../../../mod.js'
8
+ } from '../../wallet/Wallet.interfaces.js'
13
9
  import Certificate from './Certificate.js'
10
+ import * as Utils from '../../primitives/utils.js'
11
+ import SymmetricKey from '../../primitives/SymmetricKey.js'
12
+ import Random from '../../primitives/Random.js'
13
+ import ProtoWallet from '../../wallet/ProtoWallet.js'
14
14
 
15
15
  interface CreateCertificateFieldsResult {
16
16
  certificateFields: Record<CertificateFieldNameUnder50Bytes, Base64String>
@@ -1,13 +1,13 @@
1
- import {
2
- SymmetricKey,
3
- Utils,
1
+ import type {
2
+ PubKeyHex,
4
3
  Base64String,
5
4
  CertificateFieldNameUnder50Bytes,
6
5
  HexString,
7
6
  OutpointString,
8
- PubKeyHex,
9
- ProtoWallet
10
- } from '../../../mod.js'
7
+ } from '../../wallet/Wallet.interfaces.js'
8
+ import SymmetricKey from '../../primitives/SymmetricKey.js'
9
+ import * as Utils from '../../primitives/utils.js'
10
+ import ProtoWallet from '../../wallet/ProtoWallet.js'
11
11
  import Certificate from './Certificate.js'
12
12
 
13
13
  /**
@@ -1,35 +1,21 @@
1
1
  //@ts-nocheck
2
- import { PrivateKey } from '../../../../mod.js'
2
+ import PrivateKey from '../../../primitives/PrivateKey.js'
3
3
  import {
4
4
  ProtoWallet,
5
5
  WalletInterface,
6
-
7
6
  CreateActionResult,
8
-
9
7
  SignActionResult,
10
-
11
8
  AbortActionResult,
12
-
13
9
  ListActionsResult,
14
-
15
10
  InternalizeActionResult,
16
-
17
11
  ListOutputsResult,
18
-
19
12
  RelinquishOutputResult,
20
-
21
13
  AcquireCertificateResult,
22
-
23
14
  ListCertificatesResult,
24
-
25
15
  ProveCertificateResult,
26
-
27
16
  RelinquishCertificateResult,
28
-
29
17
  DiscoverCertificatesResult,
30
-
31
18
  GetHeightResult,
32
-
33
19
  GetHeaderResult,
34
20
  KeyDeriverApi,
35
21
  KeyDeriver,
@@ -1,5 +1,10 @@
1
1
  // @ts-nocheck
2
- import { Utils, Random, P2PKH, PublicKey, WalletInterface, createNonce } from '../../../mod.js'
2
+ import * as Utils from '../../primitives/utils.js'
3
+ import Random from '../../primitives/Random.js'
4
+ import P2PKH from '../../script/templates/P2PKH.js'
5
+ import PublicKey from '../../primitives/PublicKey.js'
6
+ import { WalletInterface } from '../../wallet/Wallet.interfaces.js'
7
+ import { createNonce } from '../utils/createNonce.js'
3
8
  import { Peer } from '../Peer.js'
4
9
  import { SimplifiedFetchTransport } from '../transports/SimplifiedFetchTransport.js'
5
10
  import { SessionManager } from '../SessionManager.js'
@@ -1,7 +1,7 @@
1
1
  // @ts-nocheck
2
2
  // @ts-ignore
3
3
  import { AuthMessage, RequestedCertificateSet, Transport } from "../types.js"
4
- import { Utils } from '../../../mod.js'
4
+ import * as Utils from '../../primitives/utils.js'
5
5
 
6
6
  const SUCCESS_STATUS_CODES = [200, 402]
7
7
 
@@ -1,10 +1,10 @@
1
1
  import {
2
- Utils,
3
- Random,
4
2
  WalletInterface,
5
3
  WalletCounterparty,
6
4
  Base64String
7
- } from '../../../mod.js'
5
+ } from '../../wallet/Wallet.interfaces.js'
6
+ import * as Utils from '../../primitives/utils.js'
7
+ import Random from '../../primitives/Random.js'
8
8
 
9
9
  /**
10
10
  * Creates a nonce derived from a wallet
@@ -1,5 +1,5 @@
1
1
  import { VerifiableCertificate } from '../certificates/VerifiableCertificate.js'
2
- import { WalletInterface } from '../../../mod.js'
2
+ import { WalletInterface } from '../../wallet/Wallet.interfaces.js'
3
3
  import { RequestedCertificateSet } from '../types.js'
4
4
 
5
5
  /**
@@ -1,4 +1,5 @@
1
- import { Utils, WalletInterface, WalletCounterparty, Base64String } from '../../../mod.js'
1
+ import * as Utils from '../../primitives/utils.js'
2
+ import { WalletInterface, WalletCounterparty, Base64String } from '../../wallet/Wallet.interfaces.js'
2
3
 
3
4
  /**
4
5
  * Verifies a nonce derived from a wallet
@@ -227,8 +227,8 @@ export default class LookupResolver {
227
227
  continue
228
228
  }
229
229
  }
230
- } catch (error) {
231
- console.error('Error processing response outputs:', error)
230
+ } catch (_) {
231
+ // Error processing output, proceed.
232
232
  }
233
233
  }
234
234
  return {
@@ -359,7 +359,7 @@ export const fromBase58Check = (
359
359
  str: string,
360
360
  enc?: 'hex',
361
361
  prefixLength: number = 1
362
- ): any => {
362
+ ): { data: number[] | string, prefix: number[] | string } => {
363
363
  const bin = fromBase58(str)
364
364
  let prefix: string | number[] = bin.slice(0, prefixLength)
365
365
  let data: string | number[] = bin.slice(prefixLength, -4)
@@ -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
+ })