@bsv/sdk 1.3.36 → 1.4.1

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 (198) hide show
  1. package/dist/cjs/mod.js +3 -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/identity/IdentityClient.js +258 -0
  23. package/dist/cjs/src/identity/IdentityClient.js.map +1 -0
  24. package/dist/cjs/src/identity/index.js +19 -0
  25. package/dist/cjs/src/identity/index.js.map +1 -0
  26. package/dist/cjs/src/identity/types/index.js +30 -0
  27. package/dist/cjs/src/identity/types/index.js.map +1 -0
  28. package/dist/cjs/src/overlay-tools/LookupResolver.js +2 -2
  29. package/dist/cjs/src/overlay-tools/LookupResolver.js.map +1 -1
  30. package/dist/cjs/src/primitives/utils.js.map +1 -1
  31. package/dist/cjs/src/registry/RegistryClient.js +392 -0
  32. package/dist/cjs/src/registry/RegistryClient.js.map +1 -0
  33. package/dist/cjs/src/registry/index.js +19 -0
  34. package/dist/cjs/src/registry/index.js.map +1 -0
  35. package/dist/cjs/src/registry/types/index.js +3 -0
  36. package/dist/cjs/src/registry/types/index.js.map +1 -0
  37. package/dist/cjs/src/storage/StorageUploader.js +93 -0
  38. package/dist/cjs/src/storage/StorageUploader.js.map +1 -0
  39. package/dist/cjs/src/storage/StorageUtils.js +73 -0
  40. package/dist/cjs/src/storage/StorageUtils.js.map +1 -0
  41. package/dist/cjs/src/storage/__test/StorageUploader.test.js +92 -0
  42. package/dist/cjs/src/storage/__test/StorageUploader.test.js.map +1 -0
  43. package/dist/cjs/src/storage/__test/StorageUtils.test.js +97 -0
  44. package/dist/cjs/src/storage/__test/StorageUtils.test.js.map +1 -0
  45. package/dist/cjs/src/storage/index.js +30 -0
  46. package/dist/cjs/src/storage/index.js.map +1 -0
  47. package/dist/cjs/src/wallet/WalletClient.js +4 -4
  48. package/dist/cjs/src/wallet/WalletClient.js.map +1 -1
  49. package/dist/cjs/src/wallet/substrates/HTTPWalletWire.js +26 -3
  50. package/dist/cjs/src/wallet/substrates/HTTPWalletWire.js.map +1 -1
  51. package/dist/cjs/src/wallet/substrates/WalletWireProcessor.js +178 -155
  52. package/dist/cjs/src/wallet/substrates/WalletWireProcessor.js.map +1 -1
  53. package/dist/cjs/src/wallet/substrates/WalletWireTransceiver.js +171 -148
  54. package/dist/cjs/src/wallet/substrates/WalletWireTransceiver.js.map +1 -1
  55. package/dist/cjs/src/wallet/substrates/XDM.js +29 -2
  56. package/dist/cjs/src/wallet/substrates/XDM.js.map +1 -1
  57. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  58. package/dist/esm/mod.js +3 -0
  59. package/dist/esm/mod.js.map +1 -1
  60. package/dist/esm/src/auth/Peer.js +7 -5
  61. package/dist/esm/src/auth/Peer.js.map +1 -1
  62. package/dist/esm/src/auth/certificates/Certificate.js +3 -1
  63. package/dist/esm/src/auth/certificates/Certificate.js.map +1 -1
  64. package/dist/esm/src/auth/certificates/MasterCertificate.js +3 -1
  65. package/dist/esm/src/auth/certificates/MasterCertificate.js.map +1 -1
  66. package/dist/esm/src/auth/certificates/VerifiableCertificate.js +2 -1
  67. package/dist/esm/src/auth/certificates/VerifiableCertificate.js.map +1 -1
  68. package/dist/esm/src/auth/certificates/__tests/CompletedProtoWallet.js +1 -1
  69. package/dist/esm/src/auth/certificates/__tests/CompletedProtoWallet.js.map +1 -1
  70. package/dist/esm/src/auth/clients/AuthFetch.js +5 -1
  71. package/dist/esm/src/auth/clients/AuthFetch.js.map +1 -1
  72. package/dist/esm/src/auth/transports/SimplifiedFetchTransport.js +1 -1
  73. package/dist/esm/src/auth/transports/SimplifiedFetchTransport.js.map +1 -1
  74. package/dist/esm/src/auth/utils/createNonce.js +2 -1
  75. package/dist/esm/src/auth/utils/createNonce.js.map +1 -1
  76. package/dist/esm/src/auth/utils/verifyNonce.js +1 -1
  77. package/dist/esm/src/auth/utils/verifyNonce.js.map +1 -1
  78. package/dist/esm/src/identity/IdentityClient.js +255 -0
  79. package/dist/esm/src/identity/IdentityClient.js.map +1 -0
  80. package/dist/esm/src/identity/index.js +3 -0
  81. package/dist/esm/src/identity/index.js.map +1 -0
  82. package/dist/esm/src/identity/types/index.js +27 -0
  83. package/dist/esm/src/identity/types/index.js.map +1 -0
  84. package/dist/esm/src/overlay-tools/LookupResolver.js +2 -2
  85. package/dist/esm/src/overlay-tools/LookupResolver.js.map +1 -1
  86. package/dist/esm/src/primitives/utils.js.map +1 -1
  87. package/dist/esm/src/registry/RegistryClient.js +388 -0
  88. package/dist/esm/src/registry/RegistryClient.js.map +1 -0
  89. package/dist/esm/src/registry/index.js +3 -0
  90. package/dist/esm/src/registry/index.js.map +1 -0
  91. package/dist/esm/src/registry/types/index.js +2 -0
  92. package/dist/esm/src/registry/types/index.js.map +1 -0
  93. package/dist/esm/src/storage/StorageUploader.js +68 -0
  94. package/dist/esm/src/storage/StorageUploader.js.map +1 -0
  95. package/dist/esm/src/storage/StorageUtils.js +65 -0
  96. package/dist/esm/src/storage/StorageUtils.js.map +1 -0
  97. package/dist/esm/src/storage/__test/StorageUploader.test.js +64 -0
  98. package/dist/esm/src/storage/__test/StorageUploader.test.js.map +1 -0
  99. package/dist/esm/src/storage/__test/StorageUtils.test.js +72 -0
  100. package/dist/esm/src/storage/__test/StorageUtils.test.js.map +1 -0
  101. package/dist/esm/src/storage/index.js +3 -0
  102. package/dist/esm/src/storage/index.js.map +1 -0
  103. package/dist/esm/src/wallet/WalletClient.js +4 -4
  104. package/dist/esm/src/wallet/WalletClient.js.map +1 -1
  105. package/dist/esm/src/wallet/substrates/HTTPWalletWire.js +1 -1
  106. package/dist/esm/src/wallet/substrates/HTTPWalletWire.js.map +1 -1
  107. package/dist/esm/src/wallet/substrates/WalletWireProcessor.js +1 -1
  108. package/dist/esm/src/wallet/substrates/WalletWireProcessor.js.map +1 -1
  109. package/dist/esm/src/wallet/substrates/WalletWireTransceiver.js +2 -2
  110. package/dist/esm/src/wallet/substrates/WalletWireTransceiver.js.map +1 -1
  111. package/dist/esm/src/wallet/substrates/XDM.js +2 -1
  112. package/dist/esm/src/wallet/substrates/XDM.js.map +1 -1
  113. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  114. package/dist/types/mod.d.ts +3 -0
  115. package/dist/types/mod.d.ts.map +1 -1
  116. package/dist/types/src/auth/Peer.d.ts +1 -1
  117. package/dist/types/src/auth/Peer.d.ts.map +1 -1
  118. package/dist/types/src/auth/certificates/Certificate.d.ts +2 -1
  119. package/dist/types/src/auth/certificates/Certificate.d.ts.map +1 -1
  120. package/dist/types/src/auth/certificates/MasterCertificate.d.ts +2 -1
  121. package/dist/types/src/auth/certificates/MasterCertificate.d.ts.map +1 -1
  122. package/dist/types/src/auth/certificates/VerifiableCertificate.d.ts +2 -1
  123. package/dist/types/src/auth/certificates/VerifiableCertificate.d.ts.map +1 -1
  124. package/dist/types/src/auth/certificates/__tests/CompletedProtoWallet.d.ts +1 -1
  125. package/dist/types/src/auth/certificates/__tests/CompletedProtoWallet.d.ts.map +1 -1
  126. package/dist/types/src/auth/clients/AuthFetch.d.ts +1 -1
  127. package/dist/types/src/auth/clients/AuthFetch.d.ts.map +1 -1
  128. package/dist/types/src/auth/utils/createNonce.d.ts +1 -1
  129. package/dist/types/src/auth/utils/createNonce.d.ts.map +1 -1
  130. package/dist/types/src/auth/utils/getVerifiableCertificates.d.ts +1 -1
  131. package/dist/types/src/auth/utils/getVerifiableCertificates.d.ts.map +1 -1
  132. package/dist/types/src/auth/utils/verifyNonce.d.ts +1 -1
  133. package/dist/types/src/auth/utils/verifyNonce.d.ts.map +1 -1
  134. package/dist/types/src/identity/IdentityClient.d.ts +50 -0
  135. package/dist/types/src/identity/IdentityClient.d.ts.map +1 -0
  136. package/dist/types/src/identity/index.d.ts +3 -0
  137. package/dist/types/src/identity/index.d.ts.map +1 -0
  138. package/dist/types/src/identity/types/index.d.ts +30 -0
  139. package/dist/types/src/identity/types/index.d.ts.map +1 -0
  140. package/dist/types/src/primitives/utils.d.ts +4 -1
  141. package/dist/types/src/primitives/utils.d.ts.map +1 -1
  142. package/dist/types/src/registry/RegistryClient.d.ts +94 -0
  143. package/dist/types/src/registry/RegistryClient.d.ts.map +1 -0
  144. package/dist/types/src/registry/index.d.ts +3 -0
  145. package/dist/types/src/registry/index.d.ts.map +1 -0
  146. package/dist/types/src/registry/types/index.d.ts +86 -0
  147. package/dist/types/src/registry/types/index.d.ts.map +1 -0
  148. package/dist/types/src/storage/StorageUploader.d.ts +40 -0
  149. package/dist/types/src/storage/StorageUploader.d.ts.map +1 -0
  150. package/dist/types/src/storage/StorageUtils.d.ts +31 -0
  151. package/dist/types/src/storage/StorageUtils.d.ts.map +1 -0
  152. package/dist/types/src/storage/__test/StorageUploader.test.d.ts +2 -0
  153. package/dist/types/src/storage/__test/StorageUploader.test.d.ts.map +1 -0
  154. package/dist/types/src/storage/__test/StorageUtils.test.d.ts +2 -0
  155. package/dist/types/src/storage/__test/StorageUtils.test.d.ts.map +1 -0
  156. package/dist/types/src/storage/index.d.ts +3 -0
  157. package/dist/types/src/storage/index.d.ts.map +1 -0
  158. package/dist/types/src/wallet/substrates/XDM.d.ts +1 -1
  159. package/dist/types/src/wallet/substrates/XDM.d.ts.map +1 -1
  160. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  161. package/dist/umd/bundle.js +1 -1
  162. package/docs/primitives.md +4 -1
  163. package/docs/storage.md +210 -0
  164. package/docs/wallet-substrates.md +0 -225
  165. package/mod.ts +3 -0
  166. package/package.json +11 -1
  167. package/src/auth/Peer.ts +8 -5
  168. package/src/auth/__tests/Peer.test.ts +31 -31
  169. package/src/auth/certificates/Certificate.ts +5 -5
  170. package/src/auth/certificates/MasterCertificate.ts +5 -5
  171. package/src/auth/certificates/VerifiableCertificate.ts +6 -6
  172. package/src/auth/certificates/__tests/CompletedProtoWallet.ts +1 -15
  173. package/src/auth/clients/AuthFetch.ts +6 -1
  174. package/src/auth/transports/SimplifiedFetchTransport.ts +1 -1
  175. package/src/auth/utils/createNonce.ts +3 -3
  176. package/src/auth/utils/getVerifiableCertificates.ts +1 -1
  177. package/src/auth/utils/verifyNonce.ts +2 -1
  178. package/src/identity/IdentityClient.ts +305 -0
  179. package/src/identity/README.md +93 -0
  180. package/src/identity/__tests/IdentityClient.test.ts +278 -0
  181. package/src/identity/index.ts +2 -0
  182. package/src/identity/types/index.ts +46 -0
  183. package/src/overlay-tools/LookupResolver.ts +2 -2
  184. package/src/primitives/utils.ts +1 -1
  185. package/src/registry/RegistryClient.ts +493 -0
  186. package/src/registry/__tests/RegistryClient.test.ts +444 -0
  187. package/src/registry/index.ts +2 -0
  188. package/src/registry/types/index.ts +101 -0
  189. package/src/storage/StorageUploader.ts +108 -0
  190. package/src/storage/StorageUtils.ts +66 -0
  191. package/src/storage/__test/StorageUploader.test.ts +80 -0
  192. package/src/storage/__test/StorageUtils.test.ts +86 -0
  193. package/src/storage/index.ts +2 -0
  194. package/src/wallet/WalletClient.ts +4 -4
  195. package/src/wallet/substrates/HTTPWalletWire.ts +1 -1
  196. package/src/wallet/substrates/WalletWireProcessor.ts +1 -1
  197. package/src/wallet/substrates/WalletWireTransceiver.ts +2 -2
  198. package/src/wallet/substrates/XDM.ts +3 -2
@@ -0,0 +1,93 @@
1
+ # IdentityClient
2
+
3
+ **Resolve who others are and let the world know who you are.**
4
+
5
+ ## Overview
6
+
7
+ `IdentityClient` provides a straightforward interface for resolving and revealing identity certificates. It allows applications to verify user identities through certificates issued by trusted certifiers, reveal identity attributes publicly on the blockchain, and resolving identities associated with given attributes or identity keys.
8
+
9
+ ## Features
10
+
11
+ - **Selective Attribute Revelation**: Create identity tokens which publicly reveal selective identity attributes and are tracked by overlay services.
12
+ - **Identity Resolution**: Easily resolve identity certificates based on identity keys or specific attributes.
13
+ - **Displayable Identities**: Parse identity certificates into user-friendly, displayable identities.
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install @bsv/sdk
19
+ ```
20
+
21
+ ## Usage
22
+
23
+ ### Initialization
24
+
25
+ ```typescript
26
+ import { IdentityClient } from '@bsv/sdk'
27
+
28
+ const identityClient = new IdentityClient()
29
+ ```
30
+
31
+ ### Publicly Reveal Attributes
32
+
33
+ ```typescript
34
+ const broadcastResult = await identityClient.publiclyRevealAttributes(certificate, ['name', 'email'])
35
+ ```
36
+
37
+ ### Resolve Identity by Key
38
+
39
+ ```typescript
40
+ const identities = await identityClient.resolveByIdentityKey({
41
+ identityKey: '<identity-key-here>'
42
+ })
43
+ ```
44
+
45
+ ### Resolve Identity by Attributes
46
+
47
+ ```typescript
48
+ const identities = await identityClient.resolveByAttributes({
49
+ attributes: { email: 'user@example.com' }
50
+ })
51
+ ```
52
+
53
+ ## React Example
54
+
55
+ ```ts
56
+ import React, { useEffect, useState } from 'react'
57
+ import { IdentityClient } from '@bsv/sdk'
58
+
59
+ const identityClient = new IdentityClient()
60
+
61
+ function IdentityDisplay({ identityKey }) {
62
+ const [identities, setIdentities] = useState([])
63
+
64
+ useEffect(() => {
65
+ async function fetchIdentities() {
66
+ const results = await identityClient.resolveByIdentityKey({ identityKey })
67
+ setIdentities(results)
68
+ }
69
+
70
+ fetchIdentities()
71
+ }, [identityKey])
72
+
73
+ return (
74
+ <div>
75
+ {identities.map((identity, index) => (
76
+ <div key={index} style={{ border: '1px solid #ccc', padding: '10px', marginBottom: '10px', borderRadius: '5px' }}>
77
+ <img src={identity.avatarURL} alt="Avatar" style={{ width: '50px', height: '50px', borderRadius: '25px' }} />
78
+ <h3>{identity.name}</h3>
79
+ <p>{identity.badgeLabel}</p>
80
+ <a href={identity.badgeClickURL}>Learn More</a>
81
+ </div>
82
+ ))}
83
+ </div>
84
+ )
85
+ }
86
+
87
+ export default IdentityDisplay
88
+ ```
89
+
90
+ ## License
91
+
92
+ Open BSV License
93
+
@@ -0,0 +1,278 @@
1
+ import { WalletCertificate, WalletInterface } from '../../wallet/index'
2
+ import { IdentityClient } from '../IdentityClient'
3
+ import { Certificate } from '../../auth/certificates/index.js'
4
+ import { KNOWN_IDENTITY_TYPES, defaultIdentity } from '../types/index.js'
5
+
6
+ // ----- Mocks for external dependencies -----
7
+ jest.mock('../../script', () => {
8
+ return {
9
+ PushDrop: jest.fn().mockImplementation(() => ({
10
+ lock: jest.fn().mockResolvedValue({
11
+ toHex: () => 'lockingScriptHex'
12
+ }),
13
+ unlock: jest.fn()
14
+ }))
15
+ }
16
+ })
17
+
18
+ jest.mock('../../overlay-tools/index.js', () => {
19
+ return {
20
+ TopicBroadcaster: jest.fn().mockImplementation(() => ({
21
+ broadcast: jest.fn().mockResolvedValue('broadcastResult')
22
+ }))
23
+ }
24
+ })
25
+
26
+ jest.mock('../../transaction/index.js', () => {
27
+ return {
28
+ Transaction: {
29
+ fromAtomicBEEF: jest.fn().mockImplementation((tx) => ({
30
+ toHexBEEF: () => 'transactionHex'
31
+ })),
32
+ fromBEEF: jest.fn()
33
+ }
34
+ }
35
+ })
36
+
37
+ // ----- Begin Test Suite -----
38
+ describe('IdentityClient', () => {
39
+ let walletMock: Partial<WalletInterface>
40
+ let identityClient: IdentityClient
41
+
42
+ beforeEach(() => {
43
+ // Create a fake wallet implementing the methods used by IdentityClient.
44
+ walletMock = {
45
+ proveCertificate: jest.fn().mockResolvedValue({ keyringForVerifier: 'fakeKeyring' }),
46
+ createAction: jest.fn().mockResolvedValue({
47
+ tx: [1, 2, 3],
48
+ signableTransaction: { tx: [1, 2, 3], reference: 'ref' }
49
+ }),
50
+ listCertificates: jest.fn().mockResolvedValue({ certificates: [] }),
51
+ acquireCertificate: jest.fn().mockResolvedValue({
52
+ fields: { name: 'Alice' },
53
+ verify: jest.fn().mockResolvedValue(true)
54
+ }),
55
+ signAction: jest.fn().mockResolvedValue({ tx: [4, 5, 6] }),
56
+ getNetwork: jest.fn().mockResolvedValue({ network: 'testnet' }),
57
+ discoverByIdentityKey: jest.fn(),
58
+ discoverByAttributes: jest.fn()
59
+ }
60
+
61
+ identityClient = new IdentityClient(walletMock as WalletInterface)
62
+
63
+ // Clear any previous calls/spies.
64
+ jest.clearAllMocks()
65
+ })
66
+
67
+ describe('publiclyRevealAttributes', () => {
68
+ it('should throw an error if certificate has no fields', async () => {
69
+ const certificate = {
70
+ fields: {},
71
+ verify: jest.fn().mockResolvedValue(true)
72
+ } as any as WalletCertificate
73
+ const fieldsToReveal = ['name']
74
+ await expect(
75
+ identityClient.publiclyRevealAttributes(certificate, fieldsToReveal)
76
+ ).rejects.toThrow('Certificate has no fields to reveal!')
77
+ })
78
+
79
+ it('should throw an error if fieldsToReveal is empty', async () => {
80
+ const certificate = {
81
+ fields: { name: 'Alice' },
82
+ verify: jest.fn().mockResolvedValue(true)
83
+ } as any as WalletCertificate
84
+ const fieldsToReveal: string[] = []
85
+ await expect(
86
+ identityClient.publiclyRevealAttributes(certificate, fieldsToReveal)
87
+ ).rejects.toThrow('You must reveal at least one field!')
88
+ })
89
+
90
+ it('should throw an error if certificate verification fails', async () => {
91
+ const certificate = {
92
+ fields: { name: 'Alice' },
93
+ verify: jest.fn().mockRejectedValue(new Error('Verification error')),
94
+ type: 'dummyType',
95
+ serialNumber: 'dummySerial',
96
+ subject: 'dummySubject',
97
+ certifier: 'dummyCertifier',
98
+ revocationOutpoint: 'dummyRevocation',
99
+ signature: 'dummySignature'
100
+ } as any as WalletCertificate
101
+ const fieldsToReveal = ['name']
102
+ await expect(
103
+ identityClient.publiclyRevealAttributes(certificate, fieldsToReveal)
104
+ ).rejects.toThrow('Certificate verification failed!')
105
+ })
106
+
107
+ it('should publicly reveal attributes successfully', async () => {
108
+ // Prepare a dummy certificate with all required properties.
109
+ const certificate = {
110
+ fields: { name: 'Alice' },
111
+ verify: jest.fn().mockResolvedValue(true), // this property is not used since the Certificate is re-instantiated
112
+ type: 'xCert',
113
+ serialNumber: '12345',
114
+ subject: 'abcdef1234567890',
115
+ certifier: 'CertifierX',
116
+ revocationOutpoint: 'outpoint1',
117
+ signature: 'signature1'
118
+ } as any as WalletCertificate
119
+
120
+ // Ensure that Certificate.verify (called on the re-instantiated Certificate)
121
+ // resolves successfully.
122
+ jest.spyOn(Certificate.prototype, 'verify').mockResolvedValue(false)
123
+
124
+ const fieldsToReveal = ['name']
125
+ const result = await identityClient.publiclyRevealAttributes(certificate, fieldsToReveal)
126
+ expect(result).toEqual('broadcastResult')
127
+
128
+ // Validate that proveCertificate was called with the proper arguments.
129
+ expect(walletMock.proveCertificate).toHaveBeenCalledWith({
130
+ certificate,
131
+ fieldsToReveal,
132
+ verifier: expect.any(String)
133
+ })
134
+
135
+ // Validate that createAction was called.
136
+ expect(walletMock.createAction).toHaveBeenCalled()
137
+ })
138
+ })
139
+
140
+ describe('resolveByIdentityKey', () => {
141
+ it('should return parsed identities from discovered certificates', async () => {
142
+ const dummyCertificate = {
143
+ type: KNOWN_IDENTITY_TYPES.xCert,
144
+ subject: 'abcdef1234567890',
145
+ decryptedFields: {
146
+ userName: 'Alice',
147
+ profilePhoto: 'alicePhotoUrl'
148
+ },
149
+ certifierInfo: {
150
+ name: 'CertifierX',
151
+ iconUrl: 'certifierIconUrl'
152
+ }
153
+ }
154
+ // Mock discoverByIdentityKey to return a certificate list.
155
+ walletMock.discoverByIdentityKey = jest.fn().mockResolvedValue({ certificates: [dummyCertificate] })
156
+
157
+ const identities = await identityClient.resolveByIdentityKey({ identityKey: 'dummyKey' })
158
+ expect(walletMock.discoverByIdentityKey).toHaveBeenCalledWith({ identityKey: 'dummyKey' }, undefined)
159
+ expect(identities).toHaveLength(1)
160
+ expect(identities[0]).toEqual({
161
+ name: 'Alice',
162
+ avatarURL: 'alicePhotoUrl',
163
+ abbreviatedKey: 'abcdef1234...',
164
+ identityKey: 'abcdef1234567890',
165
+ badgeLabel: 'X account certified by CertifierX',
166
+ badgeIconURL: 'certifierIconUrl',
167
+ badgeClickURL: 'https://socialcert.net'
168
+ })
169
+ })
170
+ })
171
+
172
+ it('should throw if createAction returns no tx', async () => {
173
+ const certificate = {
174
+ fields: { name: 'Alice' },
175
+ verify: jest.fn().mockResolvedValue(true),
176
+ type: 'xCert',
177
+ serialNumber: '12345',
178
+ subject: 'abcdef1234567890',
179
+ certifier: 'CertifierX',
180
+ revocationOutpoint: 'outpoint1',
181
+ signature: 'signature1'
182
+ } as any as WalletCertificate
183
+
184
+ jest.spyOn(Certificate.prototype, 'verify').mockResolvedValue(false)
185
+
186
+ // Simulate createAction returning an object with tx = undefined
187
+ walletMock.createAction = jest.fn().mockResolvedValue({
188
+ tx: undefined,
189
+ signableTransaction: { tx: undefined, reference: 'ref' }
190
+ })
191
+
192
+ const fieldsToReveal = ['name']
193
+
194
+ await expect(
195
+ identityClient.publiclyRevealAttributes(certificate, fieldsToReveal)
196
+ ).rejects.toThrow('Public reveal failed: failed to create action!')
197
+ })
198
+
199
+ describe('resolveByAttributes', () => {
200
+ it('should return parsed identities from discovered certificates', async () => {
201
+ const dummyCertificate = {
202
+ type: KNOWN_IDENTITY_TYPES.emailCert,
203
+ subject: 'emailSubject1234',
204
+ decryptedFields: {
205
+ email: 'alice@example.com',
206
+ profilePhoto: 'ignored' // not used for email type
207
+ },
208
+ certifierInfo: {
209
+ name: 'EmailCertifier',
210
+ iconUrl: 'emailIconUrl'
211
+ }
212
+ }
213
+ // Mock discoverByAttributes to return a certificate list.
214
+ walletMock.discoverByAttributes = jest.fn().mockResolvedValue({ certificates: [dummyCertificate] })
215
+
216
+ const identities = await identityClient.resolveByAttributes({ attributes: { email: 'alice@example.com' } })
217
+ expect(walletMock.discoverByAttributes).toHaveBeenCalledWith({ attributes: { email: 'alice@example.com' } }, undefined)
218
+ expect(identities).toHaveLength(1)
219
+ expect(identities[0]).toEqual({
220
+ name: 'alice@example.com',
221
+ avatarURL: 'XUTZxep7BBghAJbSBwTjNfmcsDdRFs5EaGEgkESGSgjJVYgMEizu',
222
+ abbreviatedKey: 'emailSubje...',
223
+ identityKey: 'emailSubject1234',
224
+ badgeLabel: 'Email certified by EmailCertifier',
225
+ badgeIconURL: 'emailIconUrl',
226
+ badgeClickURL: 'https://socialcert.net'
227
+ })
228
+ })
229
+ })
230
+
231
+ describe('parseIdentity', () => {
232
+ it('should correctly parse an xCert identity', () => {
233
+ const dummyCertificate = {
234
+ type: KNOWN_IDENTITY_TYPES.xCert,
235
+ subject: 'abcdef1234567890',
236
+ decryptedFields: {
237
+ userName: 'Alice',
238
+ profilePhoto: 'alicePhotoUrl'
239
+ },
240
+ certifierInfo: {
241
+ name: 'CertifierX',
242
+ iconUrl: 'certifierIconUrl'
243
+ }
244
+ }
245
+ const identity = IdentityClient.parseIdentity(dummyCertificate as unknown as any)
246
+ expect(identity).toEqual({
247
+ name: 'Alice',
248
+ avatarURL: 'alicePhotoUrl',
249
+ abbreviatedKey: 'abcdef1234...',
250
+ identityKey: 'abcdef1234567890',
251
+ badgeLabel: 'X account certified by CertifierX',
252
+ badgeIconURL: 'certifierIconUrl',
253
+ badgeClickURL: 'https://socialcert.net'
254
+ })
255
+ })
256
+
257
+ it('should return default identity for unknown type', () => {
258
+ const dummyCertificate = {
259
+ type: 'unknownType',
260
+ subject: '',
261
+ decryptedFields: {
262
+ profilePhoto: 'defaultPhoto'
263
+ },
264
+ certifierInfo: {}
265
+ }
266
+ const identity = IdentityClient.parseIdentity(dummyCertificate as any)
267
+ expect(identity).toEqual({
268
+ name: defaultIdentity.name,
269
+ avatarURL: 'defaultPhoto',
270
+ abbreviatedKey: '',
271
+ identityKey: '',
272
+ badgeLabel: defaultIdentity.badgeLabel,
273
+ badgeIconURL: defaultIdentity.badgeIconURL,
274
+ badgeClickURL: defaultIdentity.badgeClickURL
275
+ })
276
+ })
277
+ })
278
+ })
@@ -0,0 +1,2 @@
1
+ export * from './IdentityClient.js'
2
+ export * from './types/index.js'
@@ -0,0 +1,46 @@
1
+ import { WalletProtocol } from "../../wallet/index.js"
2
+
3
+ export const defaultIdentity: DisplayableIdentity = {
4
+ name: 'Unknown Identity',
5
+ avatarURL: 'XUUB8bbn9fEthk15Ge3zTQXypUShfC94vFjp65v7u5CQ8qkpxzst',
6
+ identityKey: '',
7
+ abbreviatedKey: '',
8
+ badgeIconURL: 'XUUV39HVPkpmMzYNTx7rpKzJvXfeiVyQWg2vfSpjBAuhunTCA9uG',
9
+ badgeLabel: 'Not verified by anyone you trust.',
10
+ badgeClickURL: 'https://projectbabbage.com/docs/unknown-identity'
11
+ }
12
+
13
+ export interface IdentityClientOptions {
14
+ protocolID: WalletProtocol
15
+ keyID: string
16
+ tokenAmount: number
17
+ outputIndex: number
18
+ }
19
+ export const DEFAULT_IDENTITY_CLIENT_OPTIONS: IdentityClientOptions = {
20
+ protocolID: [1, 'identity'],
21
+ keyID: '1',
22
+ tokenAmount: 1,
23
+ outputIndex: 0
24
+ }
25
+
26
+ export interface DisplayableIdentity {
27
+ name: string
28
+ avatarURL: string
29
+ abbreviatedKey: string
30
+ identityKey: string
31
+ badgeIconURL: string
32
+ badgeLabel: string
33
+ badgeClickURL: string
34
+ }
35
+
36
+ export const KNOWN_IDENTITY_TYPES = {
37
+ identiCert: 'z40BOInXkI8m7f/wBrv4MJ09bZfzZbTj2fJqCtONqCY=',
38
+ discordCert: '2TgqRC35B1zehGmB21xveZNc7i5iqHc0uxMb+1NMPW4=',
39
+ phoneCert: 'mffUklUzxbHr65xLohn0hRL0Tq2GjW1GYF/OPfzqJ6A=',
40
+ xCert: 'vdDWvftf1H+5+ZprUw123kjHlywH+v20aPQTuXgMpNc=',
41
+ registrant: 'YoPsbfR6YQczjzPdHCoGC7nJsOdPQR50+SYqcWpJ0y0=',
42
+ emailCert: 'exOl3KM0dIJ04EW5pZgbZmPag6MdJXd3/a1enmUU/BA=',
43
+ anyone: 'mfkOMfLDQmrr3SBxBQ5WeE+6Hy3VJRFq6w4A5Ljtlis=',
44
+ self: 'Hkge6X5JRxt1cWXtHLCrSTg6dCVTxjQJJ48iOYd7n3g=',
45
+ coolCert: 'AGfk/WrT1eBDXpz3mcw386Zww2HmqcIn3uY6x4Af1eo='
46
+ }
@@ -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)