@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.
- package/dist/cjs/mod.js +3 -0
- package/dist/cjs/mod.js.map +1 -1
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/src/auth/Peer.js +42 -14
- package/dist/cjs/src/auth/Peer.js.map +1 -1
- package/dist/cjs/src/auth/certificates/Certificate.js +50 -22
- package/dist/cjs/src/auth/certificates/Certificate.js.map +1 -1
- package/dist/cjs/src/auth/certificates/MasterCertificate.js +35 -10
- package/dist/cjs/src/auth/certificates/MasterCertificate.js.map +1 -1
- package/dist/cjs/src/auth/certificates/VerifiableCertificate.js +28 -4
- package/dist/cjs/src/auth/certificates/VerifiableCertificate.js.map +1 -1
- package/dist/cjs/src/auth/certificates/__tests/CompletedProtoWallet.js +5 -2
- package/dist/cjs/src/auth/certificates/__tests/CompletedProtoWallet.js.map +1 -1
- package/dist/cjs/src/auth/clients/AuthFetch.js +50 -20
- package/dist/cjs/src/auth/clients/AuthFetch.js.map +1 -1
- package/dist/cjs/src/auth/transports/SimplifiedFetchTransport.js +40 -17
- package/dist/cjs/src/auth/transports/SimplifiedFetchTransport.js.map +1 -1
- package/dist/cjs/src/auth/utils/createNonce.js +31 -4
- package/dist/cjs/src/auth/utils/createNonce.js.map +1 -1
- package/dist/cjs/src/auth/utils/verifyNonce.js +26 -3
- package/dist/cjs/src/auth/utils/verifyNonce.js.map +1 -1
- package/dist/cjs/src/identity/IdentityClient.js +258 -0
- package/dist/cjs/src/identity/IdentityClient.js.map +1 -0
- package/dist/cjs/src/identity/index.js +19 -0
- package/dist/cjs/src/identity/index.js.map +1 -0
- package/dist/cjs/src/identity/types/index.js +30 -0
- package/dist/cjs/src/identity/types/index.js.map +1 -0
- package/dist/cjs/src/overlay-tools/LookupResolver.js +2 -2
- package/dist/cjs/src/overlay-tools/LookupResolver.js.map +1 -1
- package/dist/cjs/src/primitives/utils.js.map +1 -1
- package/dist/cjs/src/registry/RegistryClient.js +392 -0
- package/dist/cjs/src/registry/RegistryClient.js.map +1 -0
- package/dist/cjs/src/registry/index.js +19 -0
- package/dist/cjs/src/registry/index.js.map +1 -0
- package/dist/cjs/src/registry/types/index.js +3 -0
- package/dist/cjs/src/registry/types/index.js.map +1 -0
- package/dist/cjs/src/storage/StorageUploader.js +93 -0
- package/dist/cjs/src/storage/StorageUploader.js.map +1 -0
- package/dist/cjs/src/storage/StorageUtils.js +73 -0
- package/dist/cjs/src/storage/StorageUtils.js.map +1 -0
- package/dist/cjs/src/storage/__test/StorageUploader.test.js +92 -0
- package/dist/cjs/src/storage/__test/StorageUploader.test.js.map +1 -0
- package/dist/cjs/src/storage/__test/StorageUtils.test.js +97 -0
- package/dist/cjs/src/storage/__test/StorageUtils.test.js.map +1 -0
- package/dist/cjs/src/storage/index.js +30 -0
- package/dist/cjs/src/storage/index.js.map +1 -0
- package/dist/cjs/src/wallet/WalletClient.js +4 -4
- package/dist/cjs/src/wallet/WalletClient.js.map +1 -1
- package/dist/cjs/src/wallet/substrates/HTTPWalletWire.js +26 -3
- package/dist/cjs/src/wallet/substrates/HTTPWalletWire.js.map +1 -1
- package/dist/cjs/src/wallet/substrates/WalletWireProcessor.js +178 -155
- package/dist/cjs/src/wallet/substrates/WalletWireProcessor.js.map +1 -1
- package/dist/cjs/src/wallet/substrates/WalletWireTransceiver.js +171 -148
- package/dist/cjs/src/wallet/substrates/WalletWireTransceiver.js.map +1 -1
- package/dist/cjs/src/wallet/substrates/XDM.js +29 -2
- package/dist/cjs/src/wallet/substrates/XDM.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/mod.js +3 -0
- package/dist/esm/mod.js.map +1 -1
- package/dist/esm/src/auth/Peer.js +7 -5
- package/dist/esm/src/auth/Peer.js.map +1 -1
- package/dist/esm/src/auth/certificates/Certificate.js +3 -1
- package/dist/esm/src/auth/certificates/Certificate.js.map +1 -1
- package/dist/esm/src/auth/certificates/MasterCertificate.js +3 -1
- package/dist/esm/src/auth/certificates/MasterCertificate.js.map +1 -1
- package/dist/esm/src/auth/certificates/VerifiableCertificate.js +2 -1
- package/dist/esm/src/auth/certificates/VerifiableCertificate.js.map +1 -1
- package/dist/esm/src/auth/certificates/__tests/CompletedProtoWallet.js +1 -1
- package/dist/esm/src/auth/certificates/__tests/CompletedProtoWallet.js.map +1 -1
- package/dist/esm/src/auth/clients/AuthFetch.js +5 -1
- package/dist/esm/src/auth/clients/AuthFetch.js.map +1 -1
- package/dist/esm/src/auth/transports/SimplifiedFetchTransport.js +1 -1
- package/dist/esm/src/auth/transports/SimplifiedFetchTransport.js.map +1 -1
- package/dist/esm/src/auth/utils/createNonce.js +2 -1
- package/dist/esm/src/auth/utils/createNonce.js.map +1 -1
- package/dist/esm/src/auth/utils/verifyNonce.js +1 -1
- package/dist/esm/src/auth/utils/verifyNonce.js.map +1 -1
- package/dist/esm/src/identity/IdentityClient.js +255 -0
- package/dist/esm/src/identity/IdentityClient.js.map +1 -0
- package/dist/esm/src/identity/index.js +3 -0
- package/dist/esm/src/identity/index.js.map +1 -0
- package/dist/esm/src/identity/types/index.js +27 -0
- package/dist/esm/src/identity/types/index.js.map +1 -0
- package/dist/esm/src/overlay-tools/LookupResolver.js +2 -2
- package/dist/esm/src/overlay-tools/LookupResolver.js.map +1 -1
- package/dist/esm/src/primitives/utils.js.map +1 -1
- package/dist/esm/src/registry/RegistryClient.js +388 -0
- package/dist/esm/src/registry/RegistryClient.js.map +1 -0
- package/dist/esm/src/registry/index.js +3 -0
- package/dist/esm/src/registry/index.js.map +1 -0
- package/dist/esm/src/registry/types/index.js +2 -0
- package/dist/esm/src/registry/types/index.js.map +1 -0
- package/dist/esm/src/storage/StorageUploader.js +68 -0
- package/dist/esm/src/storage/StorageUploader.js.map +1 -0
- package/dist/esm/src/storage/StorageUtils.js +65 -0
- package/dist/esm/src/storage/StorageUtils.js.map +1 -0
- package/dist/esm/src/storage/__test/StorageUploader.test.js +64 -0
- package/dist/esm/src/storage/__test/StorageUploader.test.js.map +1 -0
- package/dist/esm/src/storage/__test/StorageUtils.test.js +72 -0
- package/dist/esm/src/storage/__test/StorageUtils.test.js.map +1 -0
- package/dist/esm/src/storage/index.js +3 -0
- package/dist/esm/src/storage/index.js.map +1 -0
- package/dist/esm/src/wallet/WalletClient.js +4 -4
- package/dist/esm/src/wallet/WalletClient.js.map +1 -1
- package/dist/esm/src/wallet/substrates/HTTPWalletWire.js +1 -1
- package/dist/esm/src/wallet/substrates/HTTPWalletWire.js.map +1 -1
- package/dist/esm/src/wallet/substrates/WalletWireProcessor.js +1 -1
- package/dist/esm/src/wallet/substrates/WalletWireProcessor.js.map +1 -1
- package/dist/esm/src/wallet/substrates/WalletWireTransceiver.js +2 -2
- package/dist/esm/src/wallet/substrates/WalletWireTransceiver.js.map +1 -1
- package/dist/esm/src/wallet/substrates/XDM.js +2 -1
- package/dist/esm/src/wallet/substrates/XDM.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/mod.d.ts +3 -0
- package/dist/types/mod.d.ts.map +1 -1
- package/dist/types/src/auth/Peer.d.ts +1 -1
- package/dist/types/src/auth/Peer.d.ts.map +1 -1
- package/dist/types/src/auth/certificates/Certificate.d.ts +2 -1
- package/dist/types/src/auth/certificates/Certificate.d.ts.map +1 -1
- package/dist/types/src/auth/certificates/MasterCertificate.d.ts +2 -1
- package/dist/types/src/auth/certificates/MasterCertificate.d.ts.map +1 -1
- package/dist/types/src/auth/certificates/VerifiableCertificate.d.ts +2 -1
- package/dist/types/src/auth/certificates/VerifiableCertificate.d.ts.map +1 -1
- package/dist/types/src/auth/certificates/__tests/CompletedProtoWallet.d.ts +1 -1
- package/dist/types/src/auth/certificates/__tests/CompletedProtoWallet.d.ts.map +1 -1
- package/dist/types/src/auth/clients/AuthFetch.d.ts +1 -1
- package/dist/types/src/auth/clients/AuthFetch.d.ts.map +1 -1
- package/dist/types/src/auth/utils/createNonce.d.ts +1 -1
- package/dist/types/src/auth/utils/createNonce.d.ts.map +1 -1
- package/dist/types/src/auth/utils/getVerifiableCertificates.d.ts +1 -1
- package/dist/types/src/auth/utils/getVerifiableCertificates.d.ts.map +1 -1
- package/dist/types/src/auth/utils/verifyNonce.d.ts +1 -1
- package/dist/types/src/auth/utils/verifyNonce.d.ts.map +1 -1
- package/dist/types/src/identity/IdentityClient.d.ts +50 -0
- package/dist/types/src/identity/IdentityClient.d.ts.map +1 -0
- package/dist/types/src/identity/index.d.ts +3 -0
- package/dist/types/src/identity/index.d.ts.map +1 -0
- package/dist/types/src/identity/types/index.d.ts +30 -0
- package/dist/types/src/identity/types/index.d.ts.map +1 -0
- package/dist/types/src/primitives/utils.d.ts +4 -1
- package/dist/types/src/primitives/utils.d.ts.map +1 -1
- package/dist/types/src/registry/RegistryClient.d.ts +94 -0
- package/dist/types/src/registry/RegistryClient.d.ts.map +1 -0
- package/dist/types/src/registry/index.d.ts +3 -0
- package/dist/types/src/registry/index.d.ts.map +1 -0
- package/dist/types/src/registry/types/index.d.ts +86 -0
- package/dist/types/src/registry/types/index.d.ts.map +1 -0
- package/dist/types/src/storage/StorageUploader.d.ts +40 -0
- package/dist/types/src/storage/StorageUploader.d.ts.map +1 -0
- package/dist/types/src/storage/StorageUtils.d.ts +31 -0
- package/dist/types/src/storage/StorageUtils.d.ts.map +1 -0
- package/dist/types/src/storage/__test/StorageUploader.test.d.ts +2 -0
- package/dist/types/src/storage/__test/StorageUploader.test.d.ts.map +1 -0
- package/dist/types/src/storage/__test/StorageUtils.test.d.ts +2 -0
- package/dist/types/src/storage/__test/StorageUtils.test.d.ts.map +1 -0
- package/dist/types/src/storage/index.d.ts +3 -0
- package/dist/types/src/storage/index.d.ts.map +1 -0
- package/dist/types/src/wallet/substrates/XDM.d.ts +1 -1
- package/dist/types/src/wallet/substrates/XDM.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/dist/umd/bundle.js +1 -1
- package/docs/primitives.md +4 -1
- package/docs/storage.md +210 -0
- package/docs/wallet-substrates.md +0 -225
- package/mod.ts +3 -0
- package/package.json +11 -1
- package/src/auth/Peer.ts +8 -5
- package/src/auth/__tests/Peer.test.ts +31 -31
- package/src/auth/certificates/Certificate.ts +5 -5
- package/src/auth/certificates/MasterCertificate.ts +5 -5
- package/src/auth/certificates/VerifiableCertificate.ts +6 -6
- package/src/auth/certificates/__tests/CompletedProtoWallet.ts +1 -15
- package/src/auth/clients/AuthFetch.ts +6 -1
- package/src/auth/transports/SimplifiedFetchTransport.ts +1 -1
- package/src/auth/utils/createNonce.ts +3 -3
- package/src/auth/utils/getVerifiableCertificates.ts +1 -1
- package/src/auth/utils/verifyNonce.ts +2 -1
- package/src/identity/IdentityClient.ts +305 -0
- package/src/identity/README.md +93 -0
- package/src/identity/__tests/IdentityClient.test.ts +278 -0
- package/src/identity/index.ts +2 -0
- package/src/identity/types/index.ts +46 -0
- package/src/overlay-tools/LookupResolver.ts +2 -2
- package/src/primitives/utils.ts +1 -1
- package/src/registry/RegistryClient.ts +493 -0
- package/src/registry/__tests/RegistryClient.test.ts +444 -0
- package/src/registry/index.ts +2 -0
- package/src/registry/types/index.ts +101 -0
- package/src/storage/StorageUploader.ts +108 -0
- package/src/storage/StorageUtils.ts +66 -0
- package/src/storage/__test/StorageUploader.test.ts +80 -0
- package/src/storage/__test/StorageUtils.test.ts +86 -0
- package/src/storage/index.ts +2 -0
- package/src/wallet/WalletClient.ts +4 -4
- package/src/wallet/substrates/HTTPWalletWire.ts +1 -1
- package/src/wallet/substrates/WalletWireProcessor.ts +1 -1
- package/src/wallet/substrates/WalletWireTransceiver.ts +2 -2
- 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,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
|
+
}
|
package/src/primitives/utils.ts
CHANGED
|
@@ -359,7 +359,7 @@ export const fromBase58Check = (
|
|
|
359
359
|
str: string,
|
|
360
360
|
enc?: 'hex',
|
|
361
361
|
prefixLength: number = 1
|
|
362
|
-
):
|
|
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)
|