@idos-network/credentials 1.2.0 → 2.2.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.
- package/README.md +289 -85
- package/assets/idos-credential-subject-edd-v1.json +10 -0
- package/assets/idos-credential-subject-v1.json +1 -1
- package/assets/idos-credential-subject-v2.json +1 -1
- package/assets/idos-credential-subject-v3.json +83 -0
- package/assets/idos-credentials-v1.json +2 -2
- package/assets/idos-credentials-v2.json +10 -0
- package/dist/index-0NqXMjNk.d.mts +395 -0
- package/dist/index-0NqXMjNk.d.mts.map +1 -0
- package/dist/index-WW372Tf5.d.mts +57 -0
- package/dist/index-WW372Tf5.d.mts.map +1 -0
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/loader-Cg6hs1-P.mjs +2 -0
- package/dist/loader-Cg6hs1-P.mjs.map +1 -0
- package/dist/parser/index.d.mts +19 -0
- package/dist/parser/index.d.mts.map +1 -0
- package/dist/parser/index.mjs +2 -0
- package/dist/parser/index.mjs.map +1 -0
- package/dist/schemas/index.d.mts +2 -0
- package/dist/schemas/index.mjs +1 -0
- package/dist/schemas-BVGuUlPe.mjs +2 -0
- package/dist/schemas-BVGuUlPe.mjs.map +1 -0
- package/dist/types/index.d.mts +2 -135
- package/dist/types/index.mjs +1 -63
- package/dist/utils/index.d.mts +38 -22
- package/dist/utils/index.d.mts.map +1 -1
- package/dist/utils/index.mjs +1 -123
- package/dist/utils/index.mjs.map +1 -1
- package/dist/verifier/index.d.mts +8 -0
- package/dist/verifier/index.d.mts.map +1 -0
- package/dist/verifier/index.mjs +2 -0
- package/dist/verifier/index.mjs.map +1 -0
- package/package.json +31 -15
- package/src/parser/index.test.ts +266 -0
- package/src/parser/index.ts +69 -0
- package/src/schemas/EddV1/index.test.ts +40 -0
- package/src/schemas/EddV1/index.ts +53 -0
- package/src/schemas/Envelope.ts +37 -0
- package/src/schemas/FaceIdV1/index.test.ts +26 -0
- package/src/schemas/FaceIdV1/index.ts +33 -0
- package/src/schemas/KycV1/IdDocument.ts +41 -0
- package/src/schemas/KycV1/ResidentialAddress.ts +56 -0
- package/src/schemas/KycV1/Subject.ts +86 -0
- package/src/schemas/KycV1/index.test.ts +156 -0
- package/src/schemas/KycV1/index.ts +40 -0
- package/src/schemas/KycV2/Subject.ts +67 -0
- package/src/schemas/KycV2/index.test.ts +162 -0
- package/src/schemas/KycV2/index.ts +45 -0
- package/src/schemas/KycV3/Biometric.ts +14 -0
- package/src/schemas/KycV3/Contact.ts +13 -0
- package/src/schemas/KycV3/EDD.ts +32 -0
- package/src/schemas/KycV3/IdDocument.ts +92 -0
- package/src/schemas/KycV3/Onboarding.ts +36 -0
- package/src/schemas/KycV3/Person.ts +105 -0
- package/src/schemas/KycV3/ResidentialAddress.ts +73 -0
- package/src/schemas/KycV3/Screening.ts +27 -0
- package/src/schemas/KycV3/SourceOfWealth.ts +44 -0
- package/src/schemas/KycV3/Subject.ts +54 -0
- package/src/schemas/KycV3/index.test.ts +682 -0
- package/src/schemas/KycV3/index.ts +108 -0
- package/src/schemas/VerifiableCredential.ts +232 -0
- package/src/schemas/enums.ts +126 -0
- package/src/schemas/index.ts +14 -0
- package/src/schemas/integration.test.ts +251 -0
- package/src/schemas/types.ts +11 -0
- package/src/schemas/utils.ts +274 -0
- package/src/types/credentials.ts +18 -249
- package/src/utils/{utils.test.ts → index.test.ts} +59 -67
- package/src/utils/index.ts +129 -137
- package/src/utils/issuer.ts +42 -0
- package/src/{builder → utils}/loader.ts +22 -17
- package/src/verifier/index.test.ts +149 -0
- package/src/{builder/verifier.ts → verifier/index.ts} +4 -8
- package/types/internals.d.ts +11 -6
- package/dist/builder/index.d.mts +0 -20
- package/dist/builder/index.d.mts.map +0 -1
- package/dist/builder/index.mjs +0 -619
- package/dist/builder/index.mjs.map +0 -1
- package/dist/types/index.d.mts.map +0 -1
- package/dist/types/index.mjs.map +0 -1
- package/src/builder/builder.test.ts +0 -407
- package/src/builder/index.ts +0 -122
package/README.md
CHANGED
|
@@ -1,145 +1,349 @@
|
|
|
1
1
|
# idOS Credentials JavaScript SDK
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`@idos-network/credentials` provides helpers for creating, verifying, parsing, and
|
|
4
|
+
classifying idOS verifiable credentials. It wraps the W3C Verifiable Credentials
|
|
5
|
+
data model with idOS-specific schemas for KYC, Face ID and EDD credential subjects.
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
Credentials are built and read through versioned classes. Each holds structured
|
|
8
|
+
`envelope` and `subject` data, validates it with `class-validator` decorators, and
|
|
9
|
+
can:
|
|
10
|
+
|
|
11
|
+
- `serializeSubject()` structured subject sections into the flat JSON-LD credential subject
|
|
12
|
+
- `deserialize()` a signed verifiable credential back into structured fields
|
|
13
|
+
- `issue()` a signed W3C verifiable credential from the current state
|
|
14
|
+
|
|
15
|
+
## Generated schemas
|
|
16
|
+
|
|
17
|
+
The classes in `src/schemas` are the source of truth for credential definitions.
|
|
18
|
+
The JSON-LD assets in `assets` are generated from them by reflecting over their
|
|
19
|
+
decorators.
|
|
20
|
+
|
|
21
|
+
Do not edit `assets/*.json` directly. Update the classes and run the generator,
|
|
22
|
+
which builds the package first because it reflects over `dist`:
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
pnpm --filter @idos-network/credentials generate:schemas
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Generated contexts are loaded by URL in issued credentials, for example:
|
|
29
|
+
|
|
30
|
+
```text
|
|
31
|
+
https://idos-network.github.io/idos-sdk-js/credentials/idos-credentials-v2.json
|
|
32
|
+
https://idos-network.github.io/idos-sdk-js/credentials/idos-credential-subject-v3.json
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Naming and versioning
|
|
36
|
+
|
|
37
|
+
Credential data is versioned because the idOS credential format evolves over
|
|
38
|
+
time. The package exports explicit versioned classes from
|
|
39
|
+
`@idos-network/credentials/schemas`:
|
|
40
|
+
|
|
41
|
+
| Class | Subject context |
|
|
42
|
+
| ------------------------------ | ----------------------------------------- |
|
|
43
|
+
| `VerifiableCredentialKycV1` | `idos-credential-subject-v1.json` |
|
|
44
|
+
| `VerifiableCredentialKycV2` | `idos-credential-subject-v2.json` |
|
|
45
|
+
| `VerifiableCredentialKycV3` | `idos-credential-subject-v3.json` |
|
|
46
|
+
| `VerifiableCredentialFaceIdV1` | `idos-credential-subject-face-id-v1.json` |
|
|
47
|
+
| `VerifiableCredentialEddV1` | `idos-credential-subject-edd-v1.json` |
|
|
48
|
+
|
|
49
|
+
Use explicit versioned classes when reading stored credentials with long-lived
|
|
50
|
+
compatibility requirements. Use the latest version when creating new credentials.
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
import { VerifiableCredentialKycV3 } from "@idos-network/credentials/schemas";
|
|
54
|
+
import type { VerifiableCredential } from "@idos-network/credentials/types";
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Verifiable credentials
|
|
58
|
+
|
|
59
|
+
idOS credentials are W3C verifiable credentials with an idOS envelope and a
|
|
60
|
+
versioned credential subject.
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
export interface VerifiableCredential<K> {
|
|
64
|
+
"@context": string[];
|
|
65
|
+
type: string[];
|
|
66
|
+
issuer: string;
|
|
67
|
+
id: string;
|
|
68
|
+
level: string;
|
|
69
|
+
kycLevel: number;
|
|
70
|
+
issued: string;
|
|
71
|
+
approvedAt: string;
|
|
72
|
+
expirationDate?: string;
|
|
73
|
+
credentialSubject: K;
|
|
74
|
+
issuanceDate: string;
|
|
75
|
+
proof: VerifiableCredentialProof;
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
The full credential is what gets encrypted and stored in idOS. Always verify the
|
|
80
|
+
credential proof before trusting or using its contents.
|
|
81
|
+
|
|
82
|
+
Working with credentials means using a versioned class rather than editing the
|
|
83
|
+
flat JSON-LD shape by hand:
|
|
84
|
+
|
|
85
|
+
| Field / method | Role |
|
|
86
|
+
| -------------------------- | ---------------------------------------------------------- |
|
|
87
|
+
| `envelope` | Structured envelope fields (`id`, `level`, dates, …) |
|
|
88
|
+
| `subject` | Structured subject: its own fields plus sections |
|
|
89
|
+
| `setEnvelope(fields)` | Set envelope fields |
|
|
90
|
+
| `setSubject(fields)` | Set the subject's own fields, such as `id` |
|
|
91
|
+
| `addSection(name, fields)` | Add one subject section (`person`, `idDocument`, …) |
|
|
92
|
+
| `checkValidity()` | Derive missing fields, then validate both halves |
|
|
93
|
+
| `serializeSubject()` | Flatten `subject` into the JSON-LD credential subject |
|
|
94
|
+
| `serializeEnvelope()` | The flat envelope fields |
|
|
95
|
+
| `deserialize(vc)` | Rebuild `envelope` and `subject` from an issued credential |
|
|
96
|
+
| `issue(issuer)` | Sign a full verifiable credential |
|
|
97
|
+
| `level()` / `kycLevel()` | Derive level values from structured subject data |
|
|
98
|
+
| `publicNotes()` | The notes stored unencrypted alongside the credential |
|
|
99
|
+
|
|
100
|
+
`setEnvelope`, `setSubject` and `addSection` all return the credential, so calls
|
|
101
|
+
chain. Each rejects fields the target does not declare — a misspelled field would
|
|
102
|
+
otherwise vanish on serialization and produce a credential silently missing data.
|
|
103
|
+
|
|
104
|
+
Serialization converts `Date` values to ISO strings and `Buffer` files to base85;
|
|
105
|
+
deserialization reverses both. Sections are flattened with their name as a prefix
|
|
106
|
+
(`person.firstName` → `personFirstName`), while the subject's own fields travel
|
|
107
|
+
unprefixed.
|
|
108
|
+
|
|
109
|
+
## Create an issuer key
|
|
110
|
+
|
|
111
|
+
Credentials are signed with Ed25519 keys. You can pass either an
|
|
112
|
+
`Ed25519VerificationKey2020` instance or issuer key material that can be converted
|
|
113
|
+
to one.
|
|
6
114
|
|
|
7
115
|
```javascript
|
|
8
116
|
import { Ed25519VerificationKey2020 } from "@digitalbazaar/ed25519-verification-key-2020";
|
|
9
117
|
|
|
10
|
-
const issuer = "https://my-issuer.id
|
|
118
|
+
const issuer = "https://my-issuer.id";
|
|
11
119
|
|
|
12
120
|
const key = await Ed25519VerificationKey2020.generate({
|
|
13
121
|
id: `${issuer}/keys/1`,
|
|
14
122
|
controller: `${issuer}/issuers/1`,
|
|
15
123
|
});
|
|
16
|
-
|
|
17
|
-
/* Ed25519VerificationKey2020 {
|
|
18
|
-
id: "https://my-issuer.id/keys/1",
|
|
19
|
-
controller: "https://my-issuer.id/issuers/1",
|
|
20
|
-
revoked: undefined,
|
|
21
|
-
type: 'Ed25519VerificationKey2020',
|
|
22
|
-
publicKeyMultibase: 'z6MkqozXNX5bbcs17yarKiwiZN1obZ3AR6evoubA2AyRnFnq',
|
|
23
|
-
privateKeyMultibase: 'zrv1yczBBXSupDwutYPAoi1fyZLi1cZTPdXHaJXLiKX68E4u1jRy7Npc4dp65hAbKuwTws79MoiAJFDs4XKscz7Sjh3'
|
|
24
|
-
} */
|
|
25
124
|
```
|
|
26
125
|
|
|
27
|
-
|
|
126
|
+
For verification, the public key is enough:
|
|
28
127
|
|
|
29
128
|
```javascript
|
|
30
|
-
|
|
129
|
+
const trustedIssuer = {
|
|
130
|
+
issuer: "https://my-issuer.id",
|
|
131
|
+
publicKeyMultibase: key.publicKeyMultibase,
|
|
132
|
+
};
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Build a KYC credential
|
|
136
|
+
|
|
137
|
+
Each section is validated as it is added, and `issue()` builds and signs the full
|
|
138
|
+
verifiable credential. For KYC v3, `level` and `kycLevel` can be omitted from the
|
|
139
|
+
envelope: they are derived from the subject data during `serializeSubject()` /
|
|
140
|
+
`issue()`. `expirationDate` is derived only when `subject.idDocument.dateOfExpiry`
|
|
141
|
+
exists; otherwise it remains absent.
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
import { VerifiableCredentialKycV3 } from "@idos-network/credentials/schemas";
|
|
145
|
+
import type { AvailableIssuerType, VerifiableCredential } from "@idos-network/credentials/types";
|
|
31
146
|
|
|
32
147
|
const id = "z6MkszZtxCmA2Ce4vUV132PCuLQmwnaDD5mw2L23fGNnsiX3";
|
|
33
148
|
|
|
34
|
-
const
|
|
35
|
-
{
|
|
149
|
+
const kycCredential = new VerifiableCredentialKycV3()
|
|
150
|
+
.setEnvelope({
|
|
36
151
|
id: `${issuer}/credentials/${id}`,
|
|
37
|
-
level: "human",
|
|
38
152
|
issued: new Date("2022-01-01"),
|
|
39
153
|
approvedAt: new Date("2022-01-01"),
|
|
40
154
|
expirationDate: new Date("2030-01-01"),
|
|
41
|
-
}
|
|
42
|
-
{
|
|
43
|
-
|
|
44
|
-
applicantId: "1234567890",
|
|
45
|
-
inquiryId: "1234567890",
|
|
155
|
+
})
|
|
156
|
+
.setSubject({ id: `uuid:${id}` })
|
|
157
|
+
.addSection("person", {
|
|
46
158
|
firstName: "John",
|
|
47
|
-
familyName: "
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
159
|
+
familyName: "Doe",
|
|
160
|
+
dateOfBirth: new Date("1990-01-01"),
|
|
161
|
+
nationality: "US",
|
|
162
|
+
})
|
|
163
|
+
.addSection("idDocument", {
|
|
164
|
+
type: "PASSPORT",
|
|
165
|
+
country: "US",
|
|
166
|
+
number: "123456789",
|
|
167
|
+
frontFile: Buffer.from("ID document front"),
|
|
168
|
+
})
|
|
169
|
+
.addSection("contact", {
|
|
170
|
+
email: "john@example.com",
|
|
171
|
+
})
|
|
172
|
+
.addSection("biometric", {
|
|
59
173
|
selfieFile: Buffer.from("Selfie"),
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
},
|
|
68
|
-
residentialAddressProofCategory: "Utility Bill",
|
|
69
|
-
residentialAddressProofDateOfIssue: new Date("2022-01-01"),
|
|
70
|
-
residentialAddressProofFile: Buffer.from("Proof of address"),
|
|
71
|
-
},
|
|
72
|
-
key,
|
|
73
|
-
true, // Validation against schema
|
|
74
|
-
);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
// Optional: inspect the flat subject or derived level without issuing
|
|
177
|
+
const flatSubject = kycCredential.serializeSubject();
|
|
178
|
+
const level = kycCredential.level(); // "basic+liveness+email"
|
|
179
|
+
|
|
180
|
+
const issuerKey: AvailableIssuerType = key;
|
|
75
181
|
|
|
76
|
-
|
|
182
|
+
const credential: VerifiableCredential<unknown> = await kycCredential.issue(issuerKey);
|
|
77
183
|
```
|
|
78
184
|
|
|
79
|
-
|
|
185
|
+
Dates and files are accepted in either form: `new Date("2022-01-01")` or its ISO
|
|
186
|
+
string, a `Buffer` or its base85 encoding.
|
|
187
|
+
|
|
188
|
+
## Build a Face ID credential
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
import { VerifiableCredentialFaceIdV1 } from "@idos-network/credentials/schemas";
|
|
192
|
+
|
|
193
|
+
const faceIdCredential = new VerifiableCredentialFaceIdV1()
|
|
194
|
+
.setEnvelope({
|
|
195
|
+
id: `${issuer}/credentials/${id}`,
|
|
196
|
+
approvedAt: new Date("2022-01-01"),
|
|
197
|
+
})
|
|
198
|
+
.setSubject({
|
|
199
|
+
faceSignUserId: "11111111-1111-1111-1111-111111111111",
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
const issuedFaceIdCredential = await faceIdCredential.issue(key);
|
|
203
|
+
// issuedFaceIdCredential.level === "human", derived rather than set
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Serialize and deserialize
|
|
207
|
+
|
|
208
|
+
Use `serializeSubject()` when you need the flat credential subject. Use
|
|
209
|
+
`deserialize()` when you already have a verifiable credential and want structured
|
|
210
|
+
access to its fields.
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
import { VerifiableCredentialKycV3 } from "@idos-network/credentials/schemas";
|
|
214
|
+
|
|
215
|
+
const flatSubject = kycCredential.serializeSubject();
|
|
216
|
+
// Dates -> ISO strings, Buffers -> base85, sections -> prefixed keys
|
|
217
|
+
// e.g. person.firstName -> personFirstName
|
|
218
|
+
|
|
219
|
+
const roundTrip = new VerifiableCredentialKycV3();
|
|
220
|
+
await roundTrip.deserialize(credential);
|
|
221
|
+
|
|
222
|
+
console.log(roundTrip.envelope.id);
|
|
223
|
+
console.log(roundTrip.subject.person?.firstName);
|
|
224
|
+
console.log(roundTrip.subject.idDocument?.frontFile); // Buffer
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
`deserialize()` rejects a credential whose subject carries a field the version does
|
|
228
|
+
not declare: the subject context defines the subject exhaustively, so an unknown
|
|
229
|
+
key means the credential does not match the `@context` it claims. The envelope is
|
|
230
|
+
the lenient half — the credential's own W3C fields (`proof`, `issuanceDate`,
|
|
231
|
+
`type`, `issuer`) are dropped rather than rejected.
|
|
232
|
+
|
|
233
|
+
## Verify a credential
|
|
234
|
+
|
|
235
|
+
`verifyCredential` checks a credential against a list of trusted issuers. It
|
|
236
|
+
returns as soon as one issuer verifies the credential successfully.
|
|
80
237
|
|
|
81
238
|
```javascript
|
|
82
|
-
import { verifyCredential } from "@idos-network/credentials";
|
|
239
|
+
import { verifyCredential } from "@idos-network/credentials/verifier";
|
|
83
240
|
|
|
84
|
-
// We have a list of issuers we trust to
|
|
85
241
|
const allowedIssuers = [
|
|
86
242
|
{
|
|
87
|
-
issuer: "https://
|
|
88
|
-
publicKeyMultibase:
|
|
243
|
+
issuer: "https://my-issuer.id",
|
|
244
|
+
publicKeyMultibase: key.publicKeyMultibase,
|
|
89
245
|
},
|
|
90
|
-
// Ed25519VerificationKey2020 instance, or issuer information are available
|
|
91
|
-
// You don't need a privateKeyMultibase for verification!
|
|
92
246
|
key,
|
|
93
247
|
];
|
|
94
248
|
|
|
95
249
|
const [verified, resultsByIssuer] = await verifyCredential(credential, allowedIssuers);
|
|
96
|
-
|
|
97
|
-
console.log("
|
|
250
|
+
|
|
251
|
+
console.log("Verified:", verified);
|
|
252
|
+
console.log("Results by issuer:", resultsByIssuer);
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Parse a credential
|
|
256
|
+
|
|
257
|
+
`parseCredential` inspects the credential subject `@context`, constructs the
|
|
258
|
+
matching version, then deserializes and validates it. An unknown context throws so
|
|
259
|
+
callers can handle unsupported versions explicitly.
|
|
260
|
+
|
|
261
|
+
Parsing does **not** verify the signature — the result reflects whatever was in the
|
|
262
|
+
input, signed or forged. For untrusted input call `verifyCredential()` first, and
|
|
263
|
+
only parse once it reports verified.
|
|
264
|
+
|
|
265
|
+
```typescript
|
|
266
|
+
import { parseCredential } from "@idos-network/credentials/parser";
|
|
267
|
+
import { VerifiableCredentialKycV3 } from "@idos-network/credentials/schemas";
|
|
268
|
+
|
|
269
|
+
const parsed = await parseCredential(credential);
|
|
270
|
+
|
|
271
|
+
if (parsed instanceof VerifiableCredentialKycV3) {
|
|
272
|
+
console.log(parsed.subject.person?.firstName);
|
|
273
|
+
console.log(parsed.level());
|
|
274
|
+
}
|
|
98
275
|
```
|
|
99
276
|
|
|
100
|
-
## Derive level
|
|
277
|
+
## Derive a level
|
|
278
|
+
|
|
279
|
+
For KYC v3, call `level()` to derive the string level from structured subject data:
|
|
280
|
+
a verified address proof yields `plus`, and optional addons include `liveness`,
|
|
281
|
+
`email`, `phoneNumber`, `edd`, `sow`, `screening`, and `onboarding`. `kycLevel()`
|
|
282
|
+
derives the numeric level (0–3) from the same data.
|
|
101
283
|
|
|
102
284
|
```javascript
|
|
103
|
-
import {
|
|
104
|
-
|
|
105
|
-
const level = deriveLevel({
|
|
106
|
-
id: "uuid:1234",
|
|
107
|
-
firstName: "John",
|
|
108
|
-
familyName: "Doe",
|
|
109
|
-
idDocumentType: "PASSPORT",
|
|
110
|
-
dateOfBirth: new Date("1990-01-01"),
|
|
111
|
-
idDocumentCountry: "US",
|
|
112
|
-
idDocumentNumber: "123456789",
|
|
113
|
-
idDocumentFrontFile: Buffer.from("ID Document Front"),
|
|
114
|
-
});
|
|
285
|
+
import { VerifiableCredentialKycV3 } from "@idos-network/credentials/schemas";
|
|
115
286
|
|
|
116
|
-
|
|
287
|
+
const kycCredential = new VerifiableCredentialKycV3()
|
|
288
|
+
.setSubject({ id: "uuid:1234" })
|
|
289
|
+
.addSection("person", {
|
|
290
|
+
firstName: "John",
|
|
291
|
+
familyName: "Doe",
|
|
292
|
+
dateOfBirth: new Date("1990-01-01"),
|
|
293
|
+
nationality: "US",
|
|
294
|
+
})
|
|
295
|
+
.addSection("idDocument", {
|
|
296
|
+
type: "PASSPORT",
|
|
297
|
+
country: "US",
|
|
298
|
+
number: "123456789",
|
|
299
|
+
frontFile: Buffer.from("ID document front"),
|
|
300
|
+
})
|
|
301
|
+
.addSection("contact", {
|
|
302
|
+
email: "john@example.com",
|
|
303
|
+
})
|
|
304
|
+
.addSection("biometric", {
|
|
305
|
+
selfieFile: Buffer.from("Selfie"),
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
const level = kycCredential.level();
|
|
309
|
+
// level = "basic+liveness+email"
|
|
310
|
+
|
|
311
|
+
const kycLevel = kycCredential.kycLevel();
|
|
312
|
+
// kycLevel = 1
|
|
117
313
|
```
|
|
118
314
|
|
|
119
|
-
##
|
|
315
|
+
## Match levels and credentials
|
|
316
|
+
|
|
317
|
+
Use the matching helpers to check whether a credential level satisfies a required
|
|
318
|
+
base level and set of addons, or to pick the strongest matching credential from a
|
|
319
|
+
list.
|
|
120
320
|
|
|
121
321
|
```javascript
|
|
122
322
|
import {
|
|
123
|
-
pickHighestMatchingLevel,
|
|
124
|
-
matchLevelOrHigher,
|
|
125
323
|
highestMatchingCredential,
|
|
324
|
+
matchLevelOrHigher,
|
|
325
|
+
pickHighestMatchingLevel,
|
|
126
326
|
} from "@idos-network/credentials/utils";
|
|
127
327
|
|
|
128
|
-
const
|
|
129
|
-
//
|
|
328
|
+
const hasBasicLiveness = matchLevelOrHigher("basic", ["liveness"], "basic+liveness");
|
|
329
|
+
// hasBasicLiveness = true
|
|
130
330
|
|
|
131
|
-
const
|
|
132
|
-
|
|
331
|
+
const hasBasicLivenessAndEmail = matchLevelOrHigher(
|
|
332
|
+
"basic",
|
|
333
|
+
["liveness", "email"],
|
|
334
|
+
"basic+liveness",
|
|
335
|
+
);
|
|
336
|
+
// hasBasicLivenessAndEmail = false
|
|
133
337
|
|
|
134
|
-
const
|
|
135
|
-
//
|
|
338
|
+
const hasBasicLivenessFromPlus = matchLevelOrHigher("basic", ["liveness"], "plus+liveness");
|
|
339
|
+
// hasBasicLivenessFromPlus = true
|
|
136
340
|
|
|
137
341
|
const pickedLevel = pickHighestMatchingLevel(
|
|
138
342
|
["basic+liveness", "plus+liveness+email", "plus+liveness+email+phoneNumber"],
|
|
139
343
|
"plus",
|
|
140
344
|
["liveness", "email"],
|
|
141
345
|
);
|
|
142
|
-
// pickedLevel = plus+liveness+email+phoneNumber
|
|
346
|
+
// pickedLevel = "plus+liveness+email+phoneNumber"
|
|
143
347
|
|
|
144
348
|
const pickedCredential = highestMatchingCredential([...idOSCredentials], "basic", {
|
|
145
349
|
addons: ["email", "liveness"],
|
|
@@ -148,6 +352,6 @@ const pickedCredential = highestMatchingCredential([...idOSCredentials], "basic"
|
|
|
148
352
|
type: "kyc",
|
|
149
353
|
},
|
|
150
354
|
});
|
|
151
|
-
// pickedCredential
|
|
152
|
-
//
|
|
355
|
+
// pickedCredential is the highest-scoring credential that matches the level,
|
|
356
|
+
// addons, and public notes constraints.
|
|
153
357
|
```
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"phoneNumber": "xsd:string",
|
|
20
20
|
"dateOfBirth": "aux:date",
|
|
21
21
|
"placeOfBirth": "xsd:string",
|
|
22
|
+
"selfieFile": "xsd:string",
|
|
22
23
|
"idDocumentCountry": "xsd:string",
|
|
23
24
|
"idDocumentNumber": "xsd:string",
|
|
24
25
|
"idDocumentType": "xsd:string",
|
|
@@ -26,7 +27,6 @@
|
|
|
26
27
|
"idDocumentDateOfExpiry": "aux:date",
|
|
27
28
|
"idDocumentFrontFile": "xsd:string",
|
|
28
29
|
"idDocumentBackFile": "xsd:string",
|
|
29
|
-
"selfieFile": "xsd:string",
|
|
30
30
|
"residentialAddressStreet": "xsd:string",
|
|
31
31
|
"residentialAddressHouseNumber": "xsd:string",
|
|
32
32
|
"residentialAddressAdditionalAddressInfo": "xsd:string",
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"ssn": "xsd:string",
|
|
16
16
|
"dateOfBirth": "aux:date",
|
|
17
17
|
"placeOfBirth": "xsd:string",
|
|
18
|
+
"selfieFile": "xsd:string",
|
|
18
19
|
"idDocumentCountry": "xsd:string",
|
|
19
20
|
"idDocumentNumber": "xsd:string",
|
|
20
21
|
"idDocumentType": "xsd:string",
|
|
@@ -22,7 +23,6 @@
|
|
|
22
23
|
"idDocumentDateOfExpiry": "aux:date",
|
|
23
24
|
"idDocumentFrontFile": "xsd:string",
|
|
24
25
|
"idDocumentBackFile": "xsd:string",
|
|
25
|
-
"selfieFile": "xsd:string",
|
|
26
26
|
"residentialAddressStreet": "xsd:string",
|
|
27
27
|
"residentialAddressHouseNumber": "xsd:string",
|
|
28
28
|
"residentialAddressAdditionalAddressInfo": "xsd:string",
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
{
|
|
2
|
+
"@context": {
|
|
3
|
+
"@version": 1.1,
|
|
4
|
+
"@protected": true,
|
|
5
|
+
"xsd": "http://www.w3.org/2001/XMLSchema#",
|
|
6
|
+
"personFirstName": "xsd:string",
|
|
7
|
+
"personFamilyName": "xsd:string",
|
|
8
|
+
"personMiddleName": "xsd:string",
|
|
9
|
+
"personFatherName": "xsd:string",
|
|
10
|
+
"personMaidenName": "xsd:string",
|
|
11
|
+
"personMotherName": "xsd:string",
|
|
12
|
+
"personGender": "xsd:string",
|
|
13
|
+
"personNationality": "xsd:string",
|
|
14
|
+
"personSecondNationality": "xsd:string",
|
|
15
|
+
"personDateOfBirth": "xsd:date",
|
|
16
|
+
"personPlaceOfBirth": "xsd:string",
|
|
17
|
+
"personRegionOfBirth": "xsd:string",
|
|
18
|
+
"personStateless": "xsd:boolean",
|
|
19
|
+
"personRefugeeStatus": "xsd:boolean",
|
|
20
|
+
"personSubsidiaryProtectionStatus": "xsd:boolean",
|
|
21
|
+
"personNationalIdNumber": "xsd:string",
|
|
22
|
+
"personTaxIdNumber": "xsd:string",
|
|
23
|
+
"personTaxIdIssuingCountry": "xsd:string",
|
|
24
|
+
"personTaxResidenceCountry": "xsd:string",
|
|
25
|
+
"personSsn": "xsd:string",
|
|
26
|
+
"idDocumentType": "xsd:string",
|
|
27
|
+
"idDocumentNumber": "xsd:string",
|
|
28
|
+
"idDocumentCountry": "xsd:string",
|
|
29
|
+
"idDocumentDateOfExpiry": "xsd:date",
|
|
30
|
+
"idDocumentDateOfIssue": "xsd:date",
|
|
31
|
+
"idDocumentIssuingAuthority": "xsd:string",
|
|
32
|
+
"idDocumentFrontFile": "xsd:string",
|
|
33
|
+
"idDocumentFrontFileType": "xsd:string",
|
|
34
|
+
"idDocumentFrontFileName": "xsd:string",
|
|
35
|
+
"idDocumentBackFile": "xsd:string",
|
|
36
|
+
"idDocumentBackFileType": "xsd:string",
|
|
37
|
+
"idDocumentBackFileName": "xsd:string",
|
|
38
|
+
"idDocumentMrzLine1": "xsd:string",
|
|
39
|
+
"idDocumentTitle": "xsd:string",
|
|
40
|
+
"idDocumentExtendedValidUntil": "xsd:date",
|
|
41
|
+
"idDocumentAdditionalNumber": "xsd:string",
|
|
42
|
+
"idDocumentEthnicity": "xsd:string",
|
|
43
|
+
"idDocumentIssuingSubdivision": "xsd:string",
|
|
44
|
+
"contactEmail": "xsd:string",
|
|
45
|
+
"contactPhoneNumber": "xsd:string",
|
|
46
|
+
"biometricSelfieFile": "xsd:string",
|
|
47
|
+
"biometricSelfieMatch": "xsd:double",
|
|
48
|
+
"residentialAddressSource": "xsd:string",
|
|
49
|
+
"residentialAddressStreet": "xsd:string",
|
|
50
|
+
"residentialAddressHouseNumber": "xsd:string",
|
|
51
|
+
"residentialAddressAdditionalAddressInfo": "xsd:string",
|
|
52
|
+
"residentialAddressRegion": "xsd:string",
|
|
53
|
+
"residentialAddressCity": "xsd:string",
|
|
54
|
+
"residentialAddressPostalCode": "xsd:string",
|
|
55
|
+
"residentialAddressCountry": "xsd:string",
|
|
56
|
+
"residentialAddressProofCategory": "xsd:string",
|
|
57
|
+
"residentialAddressProofDateOfIssue": "xsd:date",
|
|
58
|
+
"residentialAddressProofFile": "xsd:string",
|
|
59
|
+
"residentialAddressProofFileType": "xsd:string",
|
|
60
|
+
"residentialAddressProofFileName": "xsd:string",
|
|
61
|
+
"residentialAddressIpCountry": "xsd:string",
|
|
62
|
+
"screeningSanctionsCheckResult": "xsd:string",
|
|
63
|
+
"screeningSanctionsConfidenceScore": "xsd:double",
|
|
64
|
+
"screeningPepCheckResult": "xsd:string",
|
|
65
|
+
"screeningPepConfidenceScore": "xsd:double",
|
|
66
|
+
"eddOccupation": "xsd:string",
|
|
67
|
+
"eddSourceOfFundsCategory": "xsd:string",
|
|
68
|
+
"eddSourceOfFundsProofFile": "xsd:string",
|
|
69
|
+
"eddSourceOfFundsProofFileType": "xsd:string",
|
|
70
|
+
"eddSourceOfFundsProofFileName": "xsd:string",
|
|
71
|
+
"sourceOfWealthType": "xsd:string",
|
|
72
|
+
"sourceOfWealthYearlyGrossIncome": "xsd:string",
|
|
73
|
+
"sourceOfWealthYearlyGrossIncomeCurrency": "xsd:string",
|
|
74
|
+
"sourceOfWealthApproximateNetWorth": "xsd:string",
|
|
75
|
+
"sourceOfWealthApproximateNetWorthCurrency": "xsd:string",
|
|
76
|
+
"sourceOfWealthSourceOfWealthProofFile": "xsd:string",
|
|
77
|
+
"onboardingIntendedUse": "xsd:string",
|
|
78
|
+
"onboardingEmploymentStatus": "xsd:string",
|
|
79
|
+
"onboardingExpectedMonthlyTransactionCount": "xsd:string",
|
|
80
|
+
"onboardingExpectedMonthlyTransactionVolume": "xsd:string",
|
|
81
|
+
"onboardingExpectedMonthlyTransactionVolumeCurrency": "xsd:string"
|
|
82
|
+
}
|
|
83
|
+
}
|