@idos-network/credentials 1.5.0 → 2.2.2

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 (82) hide show
  1. package/README.md +289 -85
  2. package/assets/idos-credential-subject-edd-v1.json +10 -0
  3. package/assets/idos-credential-subject-v1.json +1 -1
  4. package/assets/idos-credential-subject-v2.json +1 -1
  5. package/assets/idos-credential-subject-v3.json +83 -0
  6. package/assets/idos-credentials-v1.json +2 -2
  7. package/assets/idos-credentials-v2.json +10 -0
  8. package/dist/index-0NqXMjNk.d.mts +395 -0
  9. package/dist/index-0NqXMjNk.d.mts.map +1 -0
  10. package/dist/index-WW372Tf5.d.mts +57 -0
  11. package/dist/index-WW372Tf5.d.mts.map +1 -0
  12. package/dist/index.mjs +1 -1
  13. package/dist/loader-Cg6hs1-P.mjs +2 -0
  14. package/dist/loader-Cg6hs1-P.mjs.map +1 -0
  15. package/dist/parser/index.d.mts +19 -0
  16. package/dist/parser/index.d.mts.map +1 -0
  17. package/dist/parser/index.mjs +2 -0
  18. package/dist/parser/index.mjs.map +1 -0
  19. package/dist/schemas/index.d.mts +2 -0
  20. package/dist/schemas/index.mjs +1 -0
  21. package/dist/schemas-BVGuUlPe.mjs +2 -0
  22. package/dist/schemas-BVGuUlPe.mjs.map +1 -0
  23. package/dist/types/index.d.mts +2 -134
  24. package/dist/types/index.mjs +1 -63
  25. package/dist/utils/index.d.mts +37 -15
  26. package/dist/utils/index.d.mts.map +1 -1
  27. package/dist/utils/index.mjs +1 -116
  28. package/dist/utils/index.mjs.map +1 -1
  29. package/dist/verifier/index.d.mts +8 -0
  30. package/dist/verifier/index.d.mts.map +1 -0
  31. package/dist/verifier/index.mjs +2 -0
  32. package/dist/verifier/index.mjs.map +1 -0
  33. package/package.json +23 -10
  34. package/src/parser/index.test.ts +266 -0
  35. package/src/parser/index.ts +69 -0
  36. package/src/schemas/EddV1/index.test.ts +40 -0
  37. package/src/schemas/EddV1/index.ts +53 -0
  38. package/src/schemas/Envelope.ts +37 -0
  39. package/src/schemas/FaceIdV1/index.test.ts +26 -0
  40. package/src/schemas/FaceIdV1/index.ts +33 -0
  41. package/src/schemas/KycV1/IdDocument.ts +41 -0
  42. package/src/schemas/KycV1/ResidentialAddress.ts +56 -0
  43. package/src/schemas/KycV1/Subject.ts +86 -0
  44. package/src/schemas/KycV1/index.test.ts +156 -0
  45. package/src/schemas/KycV1/index.ts +40 -0
  46. package/src/schemas/KycV2/Subject.ts +67 -0
  47. package/src/schemas/KycV2/index.test.ts +162 -0
  48. package/src/schemas/KycV2/index.ts +45 -0
  49. package/src/schemas/KycV3/Biometric.ts +14 -0
  50. package/src/schemas/KycV3/Contact.ts +13 -0
  51. package/src/schemas/KycV3/EDD.ts +32 -0
  52. package/src/schemas/KycV3/IdDocument.ts +92 -0
  53. package/src/schemas/KycV3/Onboarding.ts +36 -0
  54. package/src/schemas/KycV3/Person.ts +105 -0
  55. package/src/schemas/KycV3/ResidentialAddress.ts +73 -0
  56. package/src/schemas/KycV3/Screening.ts +27 -0
  57. package/src/schemas/KycV3/SourceOfWealth.ts +44 -0
  58. package/src/schemas/KycV3/Subject.ts +54 -0
  59. package/src/schemas/KycV3/index.test.ts +682 -0
  60. package/src/schemas/KycV3/index.ts +108 -0
  61. package/src/schemas/VerifiableCredential.ts +232 -0
  62. package/src/schemas/enums.ts +126 -0
  63. package/src/schemas/index.ts +14 -0
  64. package/src/schemas/integration.test.ts +251 -0
  65. package/src/schemas/types.ts +11 -0
  66. package/src/schemas/utils.ts +274 -0
  67. package/src/types/credentials.ts +18 -249
  68. package/src/utils/{utils.test.ts → index.test.ts} +59 -67
  69. package/src/utils/index.ts +129 -134
  70. package/src/utils/issuer.ts +42 -0
  71. package/src/{builder → utils}/loader.ts +22 -17
  72. package/src/verifier/index.test.ts +149 -0
  73. package/src/{builder/verifier.ts → verifier/index.ts} +4 -8
  74. package/types/internals.d.ts +11 -6
  75. package/dist/builder/index.d.mts +0 -19
  76. package/dist/builder/index.d.mts.map +0 -1
  77. package/dist/builder/index.mjs +0 -619
  78. package/dist/builder/index.mjs.map +0 -1
  79. package/dist/types/index.d.mts.map +0 -1
  80. package/dist/types/index.mjs.map +0 -1
  81. package/src/builder/builder.test.ts +0 -407
  82. package/src/builder/index.ts +0 -122
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas-BVGuUlPe.mjs","names":["EDD","Subject","Subject","IdDocument","ResidentialAddress","Subject","IdDocument","ResidentialAddress","Subject","Subject","IdDocument","ResidentialAddress","Subject"],"sources":["../src/schemas/enums.ts","../src/schemas/utils.ts","../src/schemas/VerifiableCredential.ts","../src/schemas/Envelope.ts","../src/schemas/EddV1/index.ts","../src/schemas/FaceIdV1/index.ts","../src/schemas/KycV1/IdDocument.ts","../src/schemas/KycV1/ResidentialAddress.ts","../src/schemas/KycV1/Subject.ts","../src/schemas/KycV1/index.ts","../src/schemas/KycV2/Subject.ts","../src/schemas/KycV2/index.ts","../src/schemas/KycV3/Biometric.ts","../src/schemas/KycV3/Contact.ts","../src/schemas/KycV3/EDD.ts","../src/schemas/KycV3/IdDocument.ts","../src/schemas/KycV3/Onboarding.ts","../src/schemas/KycV3/Person.ts","../src/schemas/KycV3/ResidentialAddress.ts","../src/schemas/KycV3/Screening.ts","../src/schemas/KycV3/SourceOfWealth.ts","../src/schemas/KycV3/Subject.ts","../src/schemas/KycV3/index.ts"],"sourcesContent":["/*\n * Enum values as `as const` arrays: `@IsIn(...)` validates against the array and the union\n * type is derived from it, so each set of values is written once.\n */\n\nexport const IntendedUses = [\n \"INVESTING\",\n \"PAYMENT_TO_FRIENDS_FAMILY_OR_OTHERS\",\n \"PURCHASE_DIGITAL_ASSETS\",\n \"ONLINE_PURCHASES_OF_GOODS_OR_SERVICES\",\n \"TRADING\",\n] as const;\nexport type IntendedUse = (typeof IntendedUses)[number];\n\nexport const IDDocumentTypes = [\n \"PASSPORT\",\n \"DRIVERS\",\n \"ID_CARD\",\n \"VOTING_CARD\",\n \"PAN_CARD\",\n \"INTERNAL_PASSPORT\",\n \"RESIDENCE_PERMIT\",\n] as const;\nexport type IDDocumentType = (typeof IDDocumentTypes)[number];\n\nexport const ResidentialAddressSources = [\n \"MANUAL\",\n \"GPS\",\n \"EXTERNAL_DB\",\n \"PROOF_OF_ADDRESS\",\n \"PROOF_OF_IDENTITY\",\n \"AUTO_COMPLETE\",\n] as const;\nexport type ResidentialAddressSource = (typeof ResidentialAddressSources)[number];\n\nexport const ScreeningResults = [\"CLEAR\", \"NOT_CHECKED\"] as const;\nexport type ScreeningResult = (typeof ScreeningResults)[number];\n\nexport const Genders = [\"M\", \"F\", \"OTHER\"] as const;\nexport type Gender = (typeof Genders)[number];\n\nexport const EmploymentStatuses = [\n \"EMPLOYED\",\n \"SELF_EMPLOYED\",\n \"UNEMPLOYED\",\n \"RETIRED\",\n \"STUDENT\",\n] as const;\nexport type EmploymentStatus = (typeof EmploymentStatuses)[number];\n\nexport const ExpectedMonthlyTransactionCounts = [\n \"LESS_THAN_5\",\n \"BETWEEN_5_AND_10\",\n \"MORE_THAN_10\",\n] as const;\nexport type ExpectedMonthlyTransactionCount = (typeof ExpectedMonthlyTransactionCounts)[number];\n\nexport const ExpectedMonthlyTransactionVolumes = [\n \"LESS_THAN_500\",\n \"MORE_THAN_500_LESS_THAN_2000\",\n \"MORE_THAN_2000\",\n] as const;\nexport type ExpectedMonthlyTransactionVolume = (typeof ExpectedMonthlyTransactionVolumes)[number];\n\nexport const SourceOfWealthTypes = [\n \"SALARY\",\n \"SAVINGS\",\n \"INVESTMENTS\",\n \"CRYPTO_TRADING\",\n \"OTHER\",\n] as const;\nexport type SourceOfWealthType = (typeof SourceOfWealthTypes)[number];\n\nexport const YearlyGrossIncomes = [\n \"LESS_THAN_20000\",\n \"FROM_20001_TO_30000\",\n \"FROM_30001_TO_40000\",\n \"FROM_40001_TO_50000\",\n \"FROM_50001_TO_60000\",\n \"FROM_60001_TO_70000\",\n \"FROM_70001_TO_80000\",\n \"FROM_80001_TO_90000\",\n \"FROM_90001_TO_100000\",\n \"FROM_100001_TO_110000\",\n \"FROM_110001_TO_120000\",\n \"FROM_120001_TO_130000\",\n \"FROM_130001_TO_140000\",\n \"FROM_140001_TO_150000\",\n \"FROM_150001_TO_200000\",\n \"FROM_200001_TO_500000\",\n \"MORE_THAN_500000\",\n] as const;\nexport type YearlyGrossIncome = (typeof YearlyGrossIncomes)[number];\n\nexport const ApproximateNetWorths = [\n \"UP_TO_25000\",\n \"BETWEEN_25001_AND_50000\",\n \"BETWEEN_50001_AND_100000\",\n \"BETWEEN_100001_AND_300000\",\n \"BETWEEN_300001_AND_500000\",\n \"BETWEEN_500001_AND_1000000\",\n \"OVER_1000001\",\n] as const;\nexport type ApproximateNetWorth = (typeof ApproximateNetWorths)[number];\n\nexport const Occupations = [\n \"AGRICULTURE\",\n \"ARTS_AND_ENTERTAINMENT\",\n \"CONSTRUCTION\",\n \"EDUCATION\",\n \"FINANCIAL_SERVICES\",\n \"INFORMATION_AND_TECHNOLOGY\",\n \"RETAIL\",\n \"REAL_ESTATE\",\n \"OTHER\",\n \"BUSINESS_OWNER\",\n \"HEALTHCARE\",\n \"INDUSTRIAL\",\n \"LEGAL_SERVICES\",\n \"PUBLIC_SECTOR\",\n \"SENIOR_MANAGEMENT\",\n] as const;\nexport type Occupation = (typeof Occupations)[number];\n\nexport const Currencies = [\"EUR\", \"USD\", \"GBP\", \"OTHER\"] as const;\nexport type Currency = (typeof Currencies)[number];\n","import \"reflect-metadata\";\nimport { base85ToFile, fileToBase85 } from \"@idos-network/utils/codecs\";\nimport { Transform, Type, instanceToPlain, plainToInstance } from \"class-transformer\";\nimport {\n IsDate,\n IsInstance,\n ValidateIf,\n ValidateNested,\n type ValidationError,\n getMetadataStorage,\n validateSync,\n} from \"class-validator\";\n\n/*\n * A credential subject travels the wire flat: every section is merged into one object with\n * its own name as a prefix (`person` + `firstName` -> `personFirstName`), while `root`\n * contributes its fields unprefixed. `@Section` records the mapping so both directions are\n * derived from the class instead of being generated or hand-written per version.\n */\n\nconst SECTIONS = Symbol(\"idos:sections\");\n\ntype Ctor<T> = new () => T;\n\ninterface SectionMeta {\n property: string;\n prefix: string;\n type: () => Ctor<object>;\n}\n\nfunction flatKey(prefix: string, field: string): string {\n return prefix ? `${prefix}${field.charAt(0).toUpperCase()}${field.slice(1)}` : field;\n}\n\n/**\n * Declares a property as a flattened section, and wires up the nested class for\n * class-transformer and class-validator. Pass `prefix: \"\"` to keep the section's field\n * names as they are — that is what `root` does.\n *\n * Presence stays the caller's business: pair with `@IsDefined()` for a mandatory section\n * or `@IsOptional()` for an optional one.\n */\nexport function Section(type: () => Ctor<object>, prefix?: string): PropertyDecorator {\n return (target, propertyKey) => {\n const property = String(propertyKey);\n\n /*\n * Read inherited sections but define our own copy, so a subclass extending a subject\n * sees its parent's sections without mutating the parent's array.\n */\n const own = Reflect.getOwnMetadata(SECTIONS, target.constructor) as SectionMeta[] | undefined;\n const sections = own ?? [\n ...((Reflect.getMetadata(SECTIONS, target.constructor) as SectionMeta[] | undefined) ?? []),\n ];\n\n sections.push({ property, prefix: prefix ?? property, type });\n Reflect.defineMetadata(SECTIONS, sections, target.constructor);\n\n Type(type)(target, propertyKey);\n ValidateNested()(target, propertyKey);\n };\n}\n\nexport function sectionsOf(cls: Ctor<object>): SectionMeta[] {\n return (Reflect.getMetadata(SECTIONS, cls) as SectionMeta[] | undefined) ?? [];\n}\n\n/**\n * The field names of a class, taken from its validation metadata — which is why every\n * field needs at least one validation decorator to survive a round trip. Inherited fields\n * are included.\n */\nexport function fieldsOf(cls: Ctor<object>): string[] {\n const metadata = getMetadataStorage().getTargetValidationMetadatas(cls, cls.name, true, false);\n\n return [...new Set(metadata.map((entry) => entry.propertyName))];\n}\n\n/**\n * Flattens an instance to its wire form. Classes declaring `@Section` properties merge\n * those sections in with their prefixes; anything else contributes its own fields.\n * Undefined values are dropped rather than emitted as explicit `undefined` keys.\n */\nexport function toFlat<T extends object>(instance: T): Record<string, unknown> {\n const plain = instanceToPlain(instance) as Record<string, unknown>;\n const sections = new Map(\n sectionsOf(instance.constructor as Ctor<object>).map(({ property, prefix }) => [\n property,\n prefix,\n ]),\n );\n const flat: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(plain)) {\n /*\n * A key the class declares as a section is merged in with its prefix; anything else is a\n * field of the class itself, like the subject's `id`, and travels as it is.\n */\n if (!sections.has(key)) {\n if (value !== undefined) flat[key] = value;\n continue;\n }\n\n if (!value) continue;\n\n const prefix = sections.get(key) as string;\n\n for (const [field, nested] of Object.entries(value as Record<string, unknown>)) {\n if (nested !== undefined) flat[flatKey(prefix, field)] = nested;\n }\n }\n\n return flat;\n}\n\n/** The flat wire keys a class accepts: its own fields, plus each section's prefixed fields. */\nexport function flatFieldsOf(cls: Ctor<object>): Set<string> {\n const sections = sectionsOf(cls);\n const sectionProperties = new Set(sections.map(({ property }) => property));\n const keys = fieldsOf(cls).filter((field) => !sectionProperties.has(field));\n\n for (const { prefix, type } of sections) {\n for (const field of fieldsOf(type())) keys.push(flatKey(prefix, field));\n }\n\n return new Set(keys);\n}\n\n/**\n * Rebuilds an instance from its wire form, the inverse of `toFlat`. Only keys the class\n * declares are read, so extras a credential happens to carry (`proof`, `@context`, an\n * unknown section) are dropped instead of landing on the instance.\n */\nexport function fromFlat<T extends object>(cls: Ctor<T>, flat: Record<string, unknown>): T {\n const sections = sectionsOf(cls);\n const sectionProperties = new Set(sections.map(({ property }) => property));\n const nested: Record<string, unknown> = {};\n\n // The class's own fields — everything it declares that is not a section, like a subject's `id`.\n for (const field of fieldsOf(cls)) {\n if (!sectionProperties.has(field) && Object.hasOwn(flat, field)) nested[field] = flat[field];\n }\n\n for (const { property, prefix, type } of sections) {\n const section: Record<string, unknown> = {};\n\n for (const field of fieldsOf(type())) {\n const key = flatKey(prefix, field);\n\n if (Object.hasOwn(flat, key)) section[field] = flat[key];\n }\n\n // An absent section stays absent — an empty object would validate as a broken section.\n if (Object.keys(section).length > 0) nested[property] = section;\n }\n\n return plainToInstance(cls, nested);\n}\n\n/**\n * Builds an instance from the subset of a class's fields a caller passed, applying the class's\n * `toClassOnly` transforms — so either form of a value is accepted: an ISO string or a `Date`,\n * ascii85 or a `Buffer`.\n *\n * Fields the caller left out stay absent rather than becoming an explicit `undefined`, which\n * would overwrite a section already added.\n */\nexport function toClass<T extends object>(cls: Ctor<T>, fields: object): Partial<T> {\n const instance = plainToInstance(cls, fields) as Record<string, unknown>;\n\n return Object.fromEntries(Object.keys(fields).map((key) => [key, instance[key]])) as Partial<T>;\n}\n\nfunction describe(errors: ValidationError[], path = \"\"): string[] {\n return errors.flatMap((error) => {\n const at = path ? `${path}.${error.property}` : error.property;\n\n return [\n ...Object.values(error.constraints ?? {}).map((message) => `${at}: ${message}`),\n ...describe(error.children ?? [], at),\n ];\n });\n}\n\nexport class CredentialValidationError extends Error {\n override readonly name = \"CredentialValidationError\";\n\n constructor(\n label: string,\n readonly errors: ValidationError[],\n ) {\n super(`Invalid ${label}: ${describe(errors).join(\"; \")}`);\n }\n}\n\n/** Throws `CredentialValidationError` unless `instance` and its sections are valid. */\nexport function assertValid(label: string, instance: object): void {\n const errors = validateSync(instance);\n\n if (errors.length > 0) throw new CredentialValidationError(label, errors);\n}\n\n/**\n * Validates this property when `predicate` holds, and whenever it carries a value — so a\n * conditionally required field is still type-checked when the condition is off.\n *\n * Do not combine with `@IsOptional()`: that skips every validator on an absent value,\n * including this one.\n */\nexport function RequiredWhen(predicate: (object: any) => boolean): PropertyDecorator {\n return (target, propertyKey) =>\n ValidateIf(\n (object: Record<string, unknown>) =>\n predicate(object) || object[String(propertyKey)] !== undefined,\n )(target, propertyKey);\n}\n\n/** `RequiredWhen`, for the common case of a field required by the presence of another. */\nexport function RequiredWith(property: string): PropertyDecorator {\n return RequiredWhen((object: Record<string, unknown>) => object[property] !== undefined);\n}\n\n/*\n * Codecs: the encoded side is what a serialized credential carries, the decoded side is\n * what a subject holds. A field declares its representation once, and neither direction\n * inspects value types at serialization time.\n */\n\nfunction decorate(...decorators: PropertyDecorator[]): PropertyDecorator {\n return (target, propertyKey) => {\n for (const decorator of decorators) decorator(target, propertyKey);\n };\n}\n\n/** A date carried as an ISO 8601 string on the wire, held as a `Date` in a subject. */\nexport function IsoDateField(): PropertyDecorator {\n return decorate(\n Transform(({ value }) => (value instanceof Date ? value.toISOString() : value), {\n toPlainOnly: true,\n }),\n Transform(({ value }) => (typeof value === \"string\" ? new Date(value) : value), {\n toClassOnly: true,\n }),\n // `new Date(\"nonsense\")` yields an Invalid Date, which `IsDate` rejects.\n IsDate(),\n );\n}\n\n/** `fileToBase85` always emits delimited ascii85; `base85.decode` accepts anything. */\nconst ASCII85_FRAMED = /^<~[\\s\\S]*~>$/;\n\n/** A file carried as ascii85 on the wire, held as a `Buffer` in a subject. */\nexport function Base85FileField(): PropertyDecorator {\n return decorate(\n Transform(({ value }) => (Buffer.isBuffer(value) ? fileToBase85(value) : value), {\n toPlainOnly: true,\n }),\n /*\n * Undecodable input is handed on untouched so `IsInstance` reports it, rather than\n * being turned into a `false` that reads like an intentional value.\n */\n Transform(\n ({ value }) => {\n if (typeof value !== \"string\" || !ASCII85_FRAMED.test(value)) return value;\n\n return base85ToFile(value) || value;\n },\n { toClassOnly: true },\n ),\n IsInstance(Buffer, {\n message: ({ property }) => `${property} must be a file encoded as delimited ascii85`,\n }),\n );\n}\n","import { Ed25519Signature2020 } from \"@digitalbazaar/ed25519-signature-2020\";\nimport * as vc from \"@digitalbazaar/vc\";\n\nimport type { AvailableIssuerType, VerifiableCredential } from \"../types\";\nimport type { PublicNotes } from \"./types\";\n\nimport { assertNoExtraFields } from \"../utils\";\nimport { issuerToKey } from \"../utils/issuer\";\nimport {\n CONTEXT_ED25519_SIGNATURE_2020_V1,\n CONTEXT_V1,\n defaultDocumentLoader,\n} from \"../utils/loader\";\nimport {\n assertValid,\n fieldsOf,\n flatFieldsOf,\n fromFlat,\n sectionsOf,\n toClass,\n toFlat,\n} from \"./utils\";\n\ntype Ctor<T> = new () => T;\n\n/** The sections of a subject class, with their optionality dropped. */\nexport type Sections<TSubject> = {\n [K in keyof TSubject]-?: NonNullable<TSubject[K]>;\n};\n\n/**\n * The fields of a class that are not sections: a subject's `id`, an envelope's own fields.\n * Sections are the properties holding another class; everything a credential carries as a\n * value is one of the types below.\n */\nexport type OwnFields<T> = Partial<\n Pick<\n T,\n {\n [K in keyof T]-?: NonNullable<T[K]> extends string | number | boolean | Date | Buffer\n ? K\n : never;\n }[keyof T]\n >\n>;\n\n/**\n * A credential under construction: an envelope and a subject built up section by section,\n * validated as a whole, then flattened for issuance.\n *\n * Both halves stay partial until `checkValidity()` runs — proving them complete is the\n * point of that call.\n */\nexport abstract class VerifiableCredentialBase<TEnvelope extends object, TSubject extends object> {\n /*\n * The JSON-LD contexts, declared here and defined by each subclass. `declare static` stands in\n * for the abstract static TypeScript lacks: a subclass that forgets one is not caught at compile\n * time, but the instance methods below can read them.\n */\n declare static readonly envelopeContext: string;\n declare static readonly subjectContext: string;\n\n readonly envelope: Partial<TEnvelope> = {};\n readonly subject: Partial<TSubject> = {};\n\n protected constructor(\n private readonly envelopeClass: Ctor<TEnvelope>,\n private readonly subjectClass: Ctor<TSubject>,\n ) {}\n\n /**\n * Adds one section of the subject. Fields the section does not declare are rejected: they\n * would silently vanish on serialization, and a caller who misspells one deserves to hear\n * about it rather than issue a credential missing the field.\n *\n * Pass `validate: false` to defer value checks to `checkValidity()`; the extra-field check\n * always runs.\n */\n addSection<K extends keyof TSubject>(\n section: K,\n fields: Sections<TSubject>[K],\n validate = true,\n ): this {\n const meta = sectionsOf(this.subjectClass).find(({ property }) => property === section);\n\n if (!meta) throw new Error(`Unknown section: ${String(section)}`);\n\n const cls = meta.type();\n const known = new Set(fieldsOf(cls));\n const extra = Object.keys(fields).filter((field) => !known.has(field));\n\n if (extra.length > 0) {\n throw new Error(`Unexpected ${String(section)} fields: ${extra.join(\", \")}`);\n }\n\n /*\n * Assigned onto a real instance rather than a bare object, so `validateSync` finds the\n * class's metadata and `instanceToPlain` applies its transforms.\n */\n const instance = Object.assign(new cls(), fields);\n\n if (validate) assertValid(String(section), instance);\n\n this.subject[section] = instance as TSubject[K];\n\n return this;\n }\n\n /**\n * Sets the subject's own fields — the ones that are not a section, such as `id`. Unknown\n * fields are rejected for the same reason `addSection` rejects them.\n *\n * Values are checked by `checkValidity()`, since a field left out here may still be filled\n * in by `setMissingFields()` later.\n */\n setSubject(fields: OwnFields<TSubject>): this {\n Object.assign(this.subject, this.ownFields(\"subject\", this.subjectClass, fields));\n\n return this;\n }\n\n /** `setSubject`, for the envelope: `id`, `issued`, `approvedAt`, `expirationDate`. */\n setEnvelope(fields: OwnFields<TEnvelope>): this {\n Object.assign(this.envelope, this.ownFields(\"envelope\", this.envelopeClass, fields));\n\n return this;\n }\n\n /**\n * Fills in the fields this credential derives from its own contents, then validates both\n * halves. Throws `CredentialValidationError` if either is incomplete or invalid.\n */\n checkValidity(): void {\n this.setMissingFields();\n\n assertValid(\"envelope\", Object.assign(new this.envelopeClass(), this.envelope));\n assertValid(\"subject\", Object.assign(new this.subjectClass(), this.subject));\n }\n\n /** The flat credential subject, with its `@context`. */\n serializeSubject(): Record<string, unknown> {\n this.checkValidity();\n\n return {\n \"@context\": [this.contexts.subjectContext],\n ...toFlat(Object.assign(new this.subjectClass(), this.subject)),\n };\n }\n\n /** The flat envelope fields. */\n serializeEnvelope(): Record<string, unknown> {\n this.checkValidity();\n\n return toFlat(Object.assign(new this.envelopeClass(), this.envelope));\n }\n\n /** Signs the credential with `issuer`, producing a verifiable credential. */\n async issue(issuer: AvailableIssuerType): Promise<VerifiableCredential<unknown>> {\n const key = await issuerToKey(issuer);\n\n const credential = {\n \"@context\": [CONTEXT_V1, this.contexts.envelopeContext, CONTEXT_ED25519_SIGNATURE_2020_V1],\n type: [\"VerifiableCredential\"],\n issuer: key.controller,\n ...this.serializeEnvelope(),\n credentialSubject: this.serializeSubject(),\n };\n\n return vc.issue({\n credential,\n suite: new Ed25519Signature2020({ key }),\n documentLoader: defaultDocumentLoader,\n });\n }\n\n /**\n * Rebuilds envelope and subject from a serialized credential.\n *\n * A subject key the class does not declare is an error: the subject context defines the\n * subject exhaustively, so an unknown key means the credential does not match the\n * `@context` it claims, and reading it anyway would silently discard what it carried.\n *\n * The envelope is the lenient half — a credential carries W3C fields of its own there\n * (`proof`, `issuanceDate`, `type`, `issuer`), which are dropped rather than rejected.\n *\n * SECURITY: this does not verify the signature. See `verifyCredential()`.\n */\n async deserialize(credential: VerifiableCredential<unknown>): Promise<void> {\n const { credentialSubject, ...envelope } = credential;\n\n // The subject's `@context` is the credential's own, not one of its fields.\n const { \"@context\": _context, ...subject } = credentialSubject as Record<string, unknown>;\n\n assertNoExtraFields(\"subject\", flatFieldsOf(this.subjectClass), subject);\n\n Object.assign(this.envelope, fromFlat(this.envelopeClass, envelope as Record<string, unknown>));\n\n Object.assign(\n this.subject,\n fromFlat(this.subjectClass, credentialSubject as Record<string, unknown>),\n );\n }\n\n /** The credential's level, derived from its contents. */\n abstract level(): string;\n\n /** The credential's public notes, stored unencrypted alongside it. */\n abstract publicNotes(): PublicNotes;\n\n /**\n * The class's own fields, transformed onto an instance. Fields the class does not declare, or\n * declares as a section rather than a value, are rejected as they are by `add`.\n */\n private ownFields<T extends object>(label: string, cls: Ctor<T>, fields: object): Partial<T> {\n const sections = new Set(sectionsOf(cls).map(({ property }) => property));\n const own = fieldsOf(cls).filter((field) => !sections.has(field));\n\n assertNoExtraFields(label, new Set(own), fields);\n\n return toClass(cls, fields);\n }\n\n /** The subclass's static contexts, reached through the instance. */\n private get contexts(): typeof VerifiableCredentialBase {\n return this.constructor as typeof VerifiableCredentialBase;\n }\n\n /** Fills in derived envelope fields left unset by the caller. */\n protected setMissingFields(): void {\n (this.envelope as { level?: string }).level ??= this.level();\n }\n}\n","import { IsInt, IsOptional, IsPositive, IsString } from \"class-validator\";\n\nimport { IsoDateField } from \"./utils\";\n\n/** The envelope: the credential's own fields, alongside `credentialSubject`. */\nexport class EnvelopeV1 {\n @IsString()\n id: string;\n\n /* Level of KYC verification performed (e.g. basic, plus+liveness). */\n @IsString()\n level: string;\n\n /* Date the credential was approved. */\n @IsOptional()\n @IsoDateField()\n approvedAt?: Date;\n}\n\n/** `EnvelopeV1` plus a numeric KYC level and the issuance/expiry dates. */\nexport class EnvelopeV2 extends EnvelopeV1 {\n /* Level of KYC verification performed (1, 2 or 3). */\n @IsOptional()\n @IsInt()\n @IsPositive()\n kycLevel?: number;\n\n /* @default new Date() */\n @IsOptional()\n @IsoDateField()\n issued?: Date;\n\n /* Date the credential expires. */\n @IsOptional()\n @IsoDateField()\n expirationDate?: Date;\n}\n","import { IsDefined, IsIn, IsOptional, IsString } from \"class-validator\";\n\nimport type { PublicNotes } from \"../types\";\n\nimport { CONTEXT_IDOS_CREDENTIAL_V1, CONTEXT_IDOS_CREDENTIAL_V1_EDD } from \"../../utils/loader\";\nimport { Occupations, type Occupation } from \"../enums\";\nimport { EnvelopeV1 } from \"../Envelope\";\nimport { Base85FileField, Section } from \"../utils\";\nimport { VerifiableCredentialBase } from \"../VerifiableCredential\";\n\n/** The same fields as KycV3's `edd` section, here as a credential of its own. */\nexport class EDD {\n /* The person's occupation or job title. */\n @IsOptional()\n @IsIn(Occupations)\n occupation?: Occupation;\n\n /* The origin of money used in transactions (e.g. salary, business income, savings). */\n @IsOptional()\n @IsString()\n sourceOfFundsCategory?: string;\n\n /* A file containing proof of the person's source of funds. */\n @IsOptional()\n @Base85FileField()\n sourceOfFundsProofFile?: Buffer;\n}\n\nexport class Subject {\n @IsString()\n id: string;\n\n @Section(() => EDD)\n @IsDefined()\n edd: EDD;\n}\n\nexport class EddV1 extends VerifiableCredentialBase<EnvelopeV1, Subject> {\n static readonly envelopeContext: string = CONTEXT_IDOS_CREDENTIAL_V1;\n static readonly subjectContext: string = CONTEXT_IDOS_CREDENTIAL_V1_EDD;\n\n constructor() {\n super(EnvelopeV1, Subject);\n }\n\n override level(): string {\n return \"edd\";\n }\n\n override publicNotes(): PublicNotes {\n return { type: \"edd\", level: this.level() };\n }\n}\n","import { IsString } from \"class-validator\";\n\nimport type { PublicNotes } from \"../types\";\n\nimport { CONTEXT_IDOS_CREDENTIAL_V1, CONTEXT_IDOS_CREDENTIAL_V1_FACE_ID } from \"../../utils/loader\";\nimport { EnvelopeV1 } from \"../Envelope\";\nimport { VerifiableCredentialBase } from \"../VerifiableCredential\";\n\n/*\n * One field and no sections, so the subject lives here rather than in a file of its own.\n * No `id`: unlike the other versions, this subject has never declared one.\n */\nexport class Subject {\n @IsString()\n faceSignUserId: string;\n}\n\nexport class FaceIdV1 extends VerifiableCredentialBase<EnvelopeV1, Subject> {\n static readonly envelopeContext: string = CONTEXT_IDOS_CREDENTIAL_V1;\n static readonly subjectContext: string = CONTEXT_IDOS_CREDENTIAL_V1_FACE_ID;\n\n constructor() {\n super(EnvelopeV1, Subject);\n }\n\n override level(): string {\n return \"human\";\n }\n\n override publicNotes(): PublicNotes {\n return { type: \"pop\", level: this.level() };\n }\n}\n","import { IsOptional, IsString, IsISO31661Alpha2 } from \"class-validator\";\n\nimport { Base85FileField, IsoDateField } from \"../utils\";\n\n/** The identity document, as v1 and v2 describe it: every field optional and untyped. */\nexport class IdDocument {\n /* The country of issuance of the identity document (ISO 3166-1 alpha-2). */\n @IsOptional()\n @IsISO31661Alpha2()\n country?: string;\n\n /* The unique number on the identity document. */\n @IsOptional()\n @IsString()\n number?: string;\n\n /* The type of identity document (e.g. PASSPORT, ID_CARD, DRIVERS). */\n @IsOptional()\n @IsString()\n type?: string;\n\n /* The date the identity document was issued. */\n @IsOptional()\n @IsoDateField()\n dateOfIssue?: Date;\n\n /* The date the identity document expires. */\n @IsOptional()\n @IsoDateField()\n dateOfExpiry?: Date;\n\n /* The file containing the front of the identity document. */\n @IsOptional()\n @Base85FileField()\n frontFile?: Buffer;\n\n /* The file containing the back of the identity document. */\n @IsOptional()\n @Base85FileField()\n backFile?: Buffer;\n}\n","import { IsOptional, IsString, IsISO31661Alpha2 } from \"class-validator\";\n\nimport { Base85FileField, IsoDateField } from \"../utils\";\n\n/** The residential address, as v1 and v2 describe it: every field optional, no `verified` flag. */\nexport class ResidentialAddress {\n /* Street address. */\n @IsOptional()\n @IsString()\n street?: string;\n\n /* House number. */\n @IsOptional()\n @IsString()\n houseNumber?: string;\n\n /* Additional address information (e.g. apartment number). */\n @IsOptional()\n @IsString()\n additionalAddressInfo?: string;\n\n /* Region (e.g. state, province). */\n @IsOptional()\n @IsString()\n region?: string;\n\n /* Locality (e.g. city, town). */\n @IsOptional()\n @IsString()\n city?: string;\n\n /* Postal code. */\n @IsOptional()\n @IsString()\n postalCode?: string;\n\n /* Country (ISO 3166-1 alpha-2). */\n @IsOptional()\n @IsISO31661Alpha2()\n country?: string;\n\n /* Type of document provided to verify the address (e.g. utility bill, bank statement). */\n @IsOptional()\n @IsString()\n proofCategory?: string;\n\n /* Date the address proof document was issued. */\n @IsOptional()\n @IsoDateField()\n proofDateOfIssue?: Date;\n\n /* The document provided as address proof. */\n @IsOptional()\n @Base85FileField()\n proofFile?: Buffer;\n}\n","import { IsEmail, IsOptional, IsString, IsISO31661Alpha2 } from \"class-validator\";\n\nimport { Base85FileField, IsoDateField, Section } from \"../utils\";\nimport { IdDocument } from \"./IdDocument\";\nimport { ResidentialAddress } from \"./ResidentialAddress\";\n\n/*\n * The credential subject. The fields v1 groups under `root` are declared here directly: they\n * travel unprefixed, which is exactly how a class's own fields are flattened.\n */\nexport class Subject {\n @IsString()\n id: string;\n\n @IsOptional()\n @IsString()\n applicantId?: string;\n\n @IsOptional()\n @IsString()\n inquiryId?: string;\n\n @IsOptional()\n @IsString()\n firstName?: string;\n\n @IsOptional()\n @IsString()\n middleName?: string;\n\n @IsOptional()\n @IsISO31661Alpha2()\n nationality?: string;\n\n @IsOptional()\n @IsString()\n familyName?: string;\n\n @IsOptional()\n @IsString()\n maidenName?: string;\n\n @IsOptional()\n @IsString()\n gender?: string;\n\n @IsOptional()\n @IsString()\n governmentId?: string;\n\n @IsOptional()\n @IsString()\n governmentIdType?: string;\n\n @IsOptional()\n @IsEmail()\n email?: string;\n\n @IsOptional()\n @IsString()\n ssn?: string;\n\n @IsOptional()\n @IsString()\n phoneNumber?: string;\n\n @IsOptional()\n @IsoDateField()\n dateOfBirth?: Date;\n\n @IsOptional()\n @IsString()\n placeOfBirth?: string;\n\n @IsOptional()\n @Base85FileField()\n selfieFile?: Buffer;\n\n @Section(() => IdDocument)\n @IsOptional()\n idDocument?: IdDocument;\n\n @Section(() => ResidentialAddress)\n @IsOptional()\n residentialAddress?: ResidentialAddress;\n}\n","import type { PublicNotes } from \"../types\";\n\nimport { CONTEXT_IDOS_CREDENTIAL_V1, CONTEXT_IDOS_CREDENTIAL_V1_SUBJECT } from \"../../utils/loader\";\nimport { EnvelopeV1 } from \"../Envelope\";\nimport { VerifiableCredentialBase } from \"../VerifiableCredential\";\nimport { Subject } from \"./Subject\";\n\nexport class KycV1 extends VerifiableCredentialBase<EnvelopeV1, Subject> {\n static readonly envelopeContext: string = CONTEXT_IDOS_CREDENTIAL_V1;\n static readonly subjectContext: string = CONTEXT_IDOS_CREDENTIAL_V1_SUBJECT;\n\n constructor() {\n super(EnvelopeV1, Subject);\n }\n\n override level(): string {\n const { residentialAddress, selfieFile, email, phoneNumber } = this.subject;\n\n // A complete address proof is the sign of plus.\n const base =\n residentialAddress?.proofFile &&\n residentialAddress.city &&\n residentialAddress.proofCategory &&\n residentialAddress.country\n ? \"plus\"\n : \"basic\";\n\n const addons = [\n selfieFile && \"liveness\",\n email && \"email\",\n phoneNumber && \"phoneNumber\",\n ].filter(Boolean);\n\n return [base, ...addons].join(\"+\");\n }\n\n override publicNotes(): PublicNotes {\n return { type: \"kyc\", level: this.level() };\n }\n}\n","import { IsEmail, IsOptional, IsString, IsISO31661Alpha2 } from \"class-validator\";\n\nimport { IdDocument } from \"../KycV1/IdDocument\";\nimport { ResidentialAddress } from \"../KycV1/ResidentialAddress\";\nimport { Base85FileField, IsoDateField, Section } from \"../utils\";\n\n/** v1's subject, minus the applicant/inquiry and government-id fields v2 dropped. */\nexport class Subject {\n @IsString()\n id: string;\n\n @IsOptional()\n @IsString()\n firstName?: string;\n\n @IsOptional()\n @IsString()\n middleName?: string;\n\n @IsOptional()\n @IsISO31661Alpha2()\n nationality?: string;\n\n @IsOptional()\n @IsString()\n familyName?: string;\n\n @IsOptional()\n @IsString()\n maidenName?: string;\n\n @IsOptional()\n @IsString()\n gender?: string;\n\n @IsOptional()\n @IsEmail()\n email?: string;\n\n @IsOptional()\n @IsString()\n phoneNumber?: string;\n\n @IsOptional()\n @IsString()\n ssn?: string;\n\n @IsOptional()\n @IsoDateField()\n dateOfBirth?: Date;\n\n @IsOptional()\n @IsString()\n placeOfBirth?: string;\n\n @IsOptional()\n @Base85FileField()\n selfieFile?: Buffer;\n\n @Section(() => IdDocument)\n @IsOptional()\n idDocument?: IdDocument;\n\n @Section(() => ResidentialAddress)\n @IsOptional()\n residentialAddress?: ResidentialAddress;\n}\n","import type { PublicNotes } from \"../types\";\n\nimport { CONTEXT_IDOS_CREDENTIAL_V2, CONTEXT_IDOS_CREDENTIAL_V2_SUBJECT } from \"../../utils/loader\";\nimport { EnvelopeV2 } from \"../Envelope\";\nimport { VerifiableCredentialBase } from \"../VerifiableCredential\";\nimport { Subject } from \"./Subject\";\n\n/*\n * v2 derives its level the same way as v1; what changed is the subject context and the\n * envelope, which gained `kycLevel` and the issuance dates — declared in v2's own,\n * separately protected envelope context.\n */\nexport class KycV2 extends VerifiableCredentialBase<EnvelopeV2, Subject> {\n static readonly envelopeContext: string = CONTEXT_IDOS_CREDENTIAL_V2;\n static readonly subjectContext: string = CONTEXT_IDOS_CREDENTIAL_V2_SUBJECT;\n\n constructor() {\n super(EnvelopeV2, Subject);\n }\n\n override level(): string {\n const { residentialAddress, selfieFile, email, phoneNumber } = this.subject;\n\n // A complete address proof is the sign of plus.\n const base =\n residentialAddress?.proofFile &&\n residentialAddress.city &&\n residentialAddress.proofCategory &&\n residentialAddress.country\n ? \"plus\"\n : \"basic\";\n\n const addons = [\n selfieFile && \"liveness\",\n email && \"email\",\n phoneNumber && \"phoneNumber\",\n ].filter(Boolean);\n\n return [base, ...addons].join(\"+\");\n }\n\n override publicNotes(): PublicNotes {\n return { type: \"kyc\", level: this.level() };\n }\n}\n","import { IsNumber, IsOptional } from \"class-validator\";\n\nimport { Base85FileField } from \"../utils\";\n\nexport class Biometric {\n /* The person's selfie image. */\n @Base85FileField()\n selfieFile: Buffer;\n\n /* A score indicating whether the selfie/liveness photo matches the document photo. */\n @IsOptional()\n @IsNumber()\n selfieMatch?: number;\n}\n","import { IsEmail, IsOptional, IsString } from \"class-validator\";\n\nexport class Contact {\n /* The person's email address. */\n @IsOptional()\n @IsEmail()\n email?: string;\n\n /* The person's phone number. */\n @IsOptional()\n @IsString()\n phoneNumber?: string;\n}\n","import { IsIn, IsMimeType, IsOptional, IsString } from \"class-validator\";\n\nimport { Occupations, type Occupation } from \"../enums\";\nimport { Base85FileField, RequiredWhen } from \"../utils\";\n\nexport class EDD {\n /* The person's occupation or job title. */\n @IsOptional()\n @IsIn(Occupations)\n occupation?: Occupation;\n\n /* The origin of money used in transactions (e.g. salary, business income, savings). */\n @IsOptional()\n @IsString()\n sourceOfFundsCategory?: string;\n\n /* A file containing proof of the person's source of funds. */\n @IsOptional()\n @Base85FileField()\n sourceOfFundsProofFile?: Buffer;\n\n /* Type of the document provided as proof of the person's source of funds. */\n @RequiredWhen((edd: EDD) => !!edd.sourceOfFundsProofFile)\n @IsString()\n @IsMimeType()\n sourceOfFundsProofFileType?: string;\n\n /* Name of the document provided as proof of the person's source of funds. */\n @RequiredWhen((edd: EDD) => !!edd.sourceOfFundsProofFile)\n @IsString()\n sourceOfFundsProofFileName?: string;\n}\n","import { IsIn, IsOptional, IsISO31661Alpha2, Length, IsString, IsMimeType } from \"class-validator\";\n\nimport { IDDocumentTypes, type IDDocumentType } from \"../enums\";\nimport { Base85FileField, IsoDateField, RequiredWhen } from \"../utils\";\n\nexport class IdDocument {\n /* The type of identity document used for verification (e.g. PASSPORT, ID_CARD, DRIVERS). */\n @IsIn(IDDocumentTypes)\n type: IDDocumentType;\n\n /* The unique number on the identity document (e.g. passport number, ID card number). */\n @Length(1, 255)\n number: string;\n\n /* The country of issuance of the identity document. */\n @IsISO31661Alpha2()\n country: string;\n\n /* The date the identity document expires or ceases to be valid. */\n @IsOptional()\n @IsoDateField()\n dateOfExpiry?: Date;\n\n /* The date the identity document was issued. */\n @IsOptional()\n @IsoDateField()\n dateOfIssue?: Date;\n\n /* The authority that issued the document (e.g. DVLA, Bundesdruckerei). */\n @IsOptional()\n @Length(1, 255)\n issuingAuthority?: string;\n\n /* The file containing the front of the identity document. */\n @Base85FileField()\n frontFile: Buffer;\n\n /* Type of the document provided as front of the identity document. */\n @IsString()\n @IsMimeType()\n frontFileType: string;\n\n /* Name of the document provided as front of the identity document. */\n @IsString()\n frontFileName: string;\n\n /* The file containing the back of the identity document. */\n @IsOptional()\n @Base85FileField()\n backFile?: Buffer;\n\n /* Type of the document provided as back of the identity document. */\n @RequiredWhen((idDocument: IdDocument) => !!idDocument.backFile)\n @IsString()\n @IsMimeType()\n backFileType?: string;\n\n /* Name of the document provided as back of the identity document. */\n @RequiredWhen((idDocument: IdDocument) => !!idDocument.backFile)\n @IsString()\n backFileName?: string;\n\n /* The Machine-Readable Zone (MRZ) line from the document. Includes mrzLine2 and mrzLine3. */\n @IsOptional()\n @Length(1, 255)\n mrzLine1?: string;\n\n /* A title or honorific on the identity document (e.g. Dr, Mr, Ms, Prof). */\n @IsOptional()\n @Length(1, 255)\n title?: string;\n\n /* An extended expiry date when the document's validity has been officially extended. */\n @IsOptional()\n @IsoDateField()\n extendedValidUntil?: Date;\n\n /* A secondary personal identification number on the document (e.g. DNI in Spain, CRP in Brazil). */\n @IsOptional()\n @Length(1, 255)\n additionalNumber?: string;\n\n /* The person's ethnicity as indicated on the document — only present on some national documents. */\n @IsOptional()\n @Length(1, 255)\n ethnicity?: string;\n\n /* The state or province that issued the document (e.g. US state driver's licenses). */\n @IsOptional()\n @Length(1, 255)\n issuingSubdivision?: string;\n}\n","import { IsIn } from \"class-validator\";\n\nimport {\n Currencies,\n EmploymentStatuses,\n ExpectedMonthlyTransactionCounts,\n ExpectedMonthlyTransactionVolumes,\n IntendedUses,\n type Currency,\n type EmploymentStatus,\n type ExpectedMonthlyTransactionCount,\n type ExpectedMonthlyTransactionVolume,\n type IntendedUse,\n} from \"../enums\";\n\nexport class Onboarding {\n /* Intended use of the credentials. */\n @IsIn(IntendedUses)\n intendedUse: IntendedUse;\n\n /* The person's employment status (e.g. EMPLOYED, RETIRED). */\n @IsIn(EmploymentStatuses)\n employmentStatus: EmploymentStatus;\n\n /* The person's expected monthly transaction count, as a band. */\n @IsIn(ExpectedMonthlyTransactionCounts)\n expectedMonthlyTransactionCount: ExpectedMonthlyTransactionCount;\n\n /* The person's expected monthly transaction volume, as a band. */\n @IsIn(ExpectedMonthlyTransactionVolumes)\n expectedMonthlyTransactionVolume: ExpectedMonthlyTransactionVolume;\n\n /* The currency of the person's expected monthly transaction volume. */\n @IsIn(Currencies)\n expectedMonthlyTransactionVolumeCurrency: Currency;\n}\n","import { IsBoolean, IsIn, IsOptional, IsString, IsISO31661Alpha2 } from \"class-validator\";\n\nimport { Genders, type Gender } from \"../enums\";\nimport { IsoDateField, RequiredWhen } from \"../utils\";\n\nexport class Person {\n /* The person's first/given name(s) as on their identity document. */\n @RequiredWhen((person: Person) => !person.familyName)\n @IsString()\n firstName?: string;\n\n /* The person's family/last name as on their identity document. */\n @IsOptional()\n @IsString()\n familyName?: string;\n\n /* The person's middle name(s). */\n @IsOptional()\n @IsString()\n middleName?: string;\n\n /* The person's father's name / patronymic — required in some jurisdictions (e.g. Greece). */\n @IsOptional()\n @IsString()\n fatherName?: string;\n\n /* The person's maiden name (family name before marriage). */\n @IsOptional()\n @IsString()\n maidenName?: string;\n\n /* The person's mother's birth name — required in some jurisdictions (e.g. Hungary). */\n @IsOptional()\n @IsString()\n motherName?: string;\n\n /* The person's gender (M, F, or OTHER). */\n @IsOptional()\n @IsIn(Genders)\n gender?: Gender;\n\n /* The person's nationality country code (ISO 3166-1 alpha-2). */\n @RequiredWhen((person: Person) => !person.stateless && !person.secondNationality)\n @IsISO31661Alpha2()\n nationality?: string;\n\n /* A second nationality held by the person, if applicable (ISO 3166-1 alpha-2). */\n @IsOptional()\n @IsISO31661Alpha2()\n secondNationality?: string;\n\n /* The person's date of birth. */\n @IsoDateField()\n dateOfBirth: Date;\n\n /* The city/country where the person was born. */\n @IsOptional()\n @IsString()\n placeOfBirth?: string;\n\n /* The state, region or territory within a country where the person was born. */\n @IsOptional()\n @IsString()\n regionOfBirth?: string;\n\n /* Whether the person is stateless (holds no nationality). */\n @IsOptional()\n @IsBoolean()\n stateless?: boolean;\n\n /* Whether the person holds refugee status. */\n @IsOptional()\n @IsBoolean()\n refugeeStatus?: boolean;\n\n /* Whether the person holds subsidiary protection status (below refugee status). */\n @IsOptional()\n @IsBoolean()\n subsidiaryProtectionStatus?: boolean;\n\n /* A national identification number (e.g. DNI in Spain, PESEL in Poland) — distinct from the document number. */\n @IsOptional()\n @IsString()\n nationalIdNumber?: string;\n\n /* The person's Tax Identification Number (TIN/VAT number) as issued by a tax authority. */\n @IsOptional()\n @IsString()\n taxIdNumber?: string;\n\n /* The country that issued the person's Tax Identification Number. */\n @IsOptional()\n @IsISO31661Alpha2()\n taxIdIssuingCountry?: string;\n\n /* Country where the person is tax-resident. May differ from the TIN-issuing country. */\n @IsOptional()\n @IsISO31661Alpha2()\n taxResidenceCountry?: string;\n\n /* The person's Social Security Number (US). */\n @IsOptional()\n @IsString()\n ssn?: string;\n}\n","import { IsOptional, IsString, IsISO31661Alpha2, IsMimeType, IsEnum } from \"class-validator\";\n\nimport { ResidentialAddressSources, type ResidentialAddressSource } from \"../enums\";\nimport { Base85FileField, IsoDateField, RequiredWhen } from \"../utils\";\n\nexport class ResidentialAddress {\n /* How the address was obtained: typed in, autocompleted, from GPS, an external database, or read from an identity or proof-of-address document. */\n @IsEnum(ResidentialAddressSources)\n source: ResidentialAddressSource;\n\n /* Street address. */\n @IsString()\n street: string;\n\n /* House number. */\n @IsOptional()\n @IsString()\n houseNumber?: string;\n\n /* Additional address information (e.g. apartment number). */\n @IsOptional()\n @IsString()\n additionalAddressInfo?: string;\n\n /* Region (e.g. state, province). */\n @IsOptional()\n @IsString()\n region?: string;\n\n /* Locality (e.g. city, town). */\n @IsString()\n city: string;\n\n /* Postal code. */\n @IsOptional()\n @IsString()\n postalCode?: string;\n\n /* Country (ISO 3166-1 alpha-2). */\n @IsISO31661Alpha2()\n country: string;\n\n /* Type of document provided to verify the address (e.g. utility bill, bank statement). */\n @RequiredWhen((address: ResidentialAddress) => address.source === \"PROOF_OF_ADDRESS\")\n @IsString()\n proofCategory?: string;\n\n /* Date the address proof document was issued. */\n @IsOptional()\n @IsoDateField()\n proofDateOfIssue?: Date;\n\n /* The document provided as address proof. */\n @RequiredWhen((address: ResidentialAddress) => address.source === \"PROOF_OF_ADDRESS\")\n @Base85FileField()\n proofFile?: Buffer;\n\n /* Type of the document provided as address proof. */\n @RequiredWhen((address: ResidentialAddress) => address.source === \"PROOF_OF_ADDRESS\")\n @IsString()\n @IsMimeType()\n proofFileType?: string;\n\n /* Name of the document provided as address proof. */\n @RequiredWhen((address: ResidentialAddress) => address.source === \"PROOF_OF_ADDRESS\")\n @IsString()\n proofFileName?: string;\n\n /* Country code derived from the IP address used when the applicant registered. */\n @IsOptional()\n @IsISO31661Alpha2()\n ipCountry?: string;\n}\n","import { IsIn, IsNumber, IsOptional, Max, Min } from \"class-validator\";\n\nimport { ScreeningResults, type ScreeningResult } from \"../enums\";\n\nexport class Screening {\n /* Whether the person appears on any sanctions lists (e.g. CLEAR, NOT_CHECKED). */\n @IsIn(ScreeningResults)\n sanctionsCheckResult: ScreeningResult;\n\n /* A confidence score (0–100) for the sanctions screening result. */\n @IsOptional()\n @IsNumber()\n @Min(0)\n @Max(100)\n sanctionsConfidenceScore?: number;\n\n /* The result of the PEP (Politically Exposed Person) screening check. */\n @IsIn(ScreeningResults)\n pepCheckResult: ScreeningResult;\n\n /* A confidence score (0–100) for the PEP screening result. */\n @IsOptional()\n @IsNumber()\n @Min(0)\n @Max(100)\n pepConfidenceScore?: number;\n}\n","import { IsIn, IsOptional } from \"class-validator\";\n\nimport {\n ApproximateNetWorths,\n Currencies,\n SourceOfWealthTypes,\n YearlyGrossIncomes,\n type ApproximateNetWorth,\n type Currency,\n type SourceOfWealthType,\n type YearlyGrossIncome,\n} from \"../enums\";\nimport { Base85FileField, RequiredWith } from \"../utils\";\n\nexport class SourceOfWealth {\n /* The category of wealth source declared by the person (e.g. SALARY, INVESTMENTS). */\n @IsIn(SourceOfWealthTypes)\n type: SourceOfWealthType;\n\n /* The person's yearly gross income, as a band. */\n @IsOptional()\n @IsIn(YearlyGrossIncomes)\n yearlyGrossIncome?: YearlyGrossIncome;\n\n /* The currency of the person's yearly gross income. */\n @RequiredWith(\"yearlyGrossIncome\")\n @IsIn(Currencies)\n yearlyGrossIncomeCurrency?: Currency;\n\n /* The person's approximate net worth, as a band. */\n @IsOptional()\n @IsIn(ApproximateNetWorths)\n approximateNetWorth?: ApproximateNetWorth;\n\n /* The currency of the person's approximate net worth. */\n @RequiredWith(\"approximateNetWorth\")\n @IsIn(Currencies)\n approximateNetWorthCurrency?: Currency;\n\n /* A file containing proof of the person's source of wealth. */\n @IsOptional()\n @Base85FileField()\n sourceOfWealthProofFile?: Buffer;\n}\n","import { IsDefined, IsOptional, IsString } from \"class-validator\";\n\nimport { Section } from \"../utils\";\nimport { Biometric } from \"./Biometric\";\nimport { Contact } from \"./Contact\";\nimport { EDD } from \"./EDD\";\nimport { IdDocument } from \"./IdDocument\";\nimport { Onboarding } from \"./Onboarding\";\nimport { Person } from \"./Person\";\nimport { ResidentialAddress } from \"./ResidentialAddress\";\nimport { Screening } from \"./Screening\";\nimport { SourceOfWealth } from \"./SourceOfWealth\";\n\n/** The credential subject: the sections that get flattened onto the wire. */\nexport class Subject {\n @IsString()\n id: string;\n\n @Section(() => Person)\n @IsDefined()\n person: Person;\n\n @Section(() => IdDocument)\n @IsOptional()\n idDocument?: IdDocument;\n\n @Section(() => Contact)\n @IsOptional()\n contact?: Contact;\n\n @Section(() => Biometric)\n @IsOptional()\n biometric?: Biometric;\n\n @Section(() => ResidentialAddress)\n @IsOptional()\n residentialAddress?: ResidentialAddress;\n\n @Section(() => Screening)\n @IsOptional()\n screening?: Screening;\n\n @Section(() => EDD)\n @IsOptional()\n edd?: EDD;\n\n @Section(() => SourceOfWealth)\n @IsOptional()\n sourceOfWealth?: SourceOfWealth;\n\n @Section(() => Onboarding)\n @IsOptional()\n onboarding?: Onboarding;\n}\n","import type { PublicNotes } from \"../types\";\n\nimport { CONTEXT_IDOS_CREDENTIAL_V2, CONTEXT_IDOS_CREDENTIAL_V3_SUBJECT } from \"../../utils/loader\";\nimport { EnvelopeV2 } from \"../Envelope\";\nimport { VerifiableCredentialBase } from \"../VerifiableCredential\";\nimport { Subject } from \"./Subject\";\n\nexport class KycV3 extends VerifiableCredentialBase<EnvelopeV2, Subject> {\n static readonly envelopeContext: string = CONTEXT_IDOS_CREDENTIAL_V2;\n static readonly subjectContext: string = CONTEXT_IDOS_CREDENTIAL_V3_SUBJECT;\n\n constructor() {\n super(EnvelopeV2, Subject);\n }\n\n override level(): string {\n const {\n residentialAddress,\n biometric,\n contact,\n edd,\n sourceOfWealth,\n screening,\n onboarding,\n person,\n idDocument,\n } = this.subject;\n\n // A verified address with a proof is the sign of plus.\n let base = \"unverified\";\n\n // When we have a idDocument and person, we can set \"basic\"\n if (person && idDocument) {\n base = \"basic\";\n }\n\n // When we also have a verified address, we can set \"plus\"\n if (\n base === \"basic\" &&\n residentialAddress?.proofFile &&\n residentialAddress.city &&\n residentialAddress.proofCategory &&\n residentialAddress.source === \"PROOF_OF_ADDRESS\" &&\n residentialAddress.country\n ) {\n base = \"plus\";\n }\n\n const addons = [\n biometric?.selfieFile && \"liveness\",\n contact?.email && \"email\",\n contact?.phoneNumber && \"phoneNumber\",\n edd && \"edd\",\n sourceOfWealth && \"sow\",\n screening && \"screening\",\n onboarding && \"onboarding\",\n ].filter(Boolean);\n\n return [base, ...addons].join(\"+\");\n }\n\n kycLevel(): number {\n const { person, idDocument, biometric, residentialAddress, sourceOfWealth, onboarding } =\n this.subject;\n\n let kycLevel = 0;\n\n // basic+liveness are always at least kycLevel = 1\n if (biometric?.selfieFile && person && idDocument) {\n kycLevel = 1;\n }\n\n // plus+liveness are always at least kycLevel = 2\n if (\n kycLevel >= 1 &&\n residentialAddress?.proofFile &&\n residentialAddress.source === \"PROOF_OF_ADDRESS\"\n ) {\n kycLevel = 2;\n }\n\n // full SOW and onboarding questionnaire are always at least kycLevel = 3\n if (kycLevel >= 2 && sourceOfWealth && onboarding) {\n kycLevel = 3;\n }\n\n return kycLevel;\n }\n\n override publicNotes(): PublicNotes {\n return {\n type: \"kyc\",\n level: this.level(),\n kycLevel: this.kycLevel(),\n };\n }\n\n protected override setMissingFields(): void {\n super.setMissingFields();\n\n // A kycLevel of 0 means \"none reached\", which the envelope expresses by omission.\n if (this.envelope.kycLevel === undefined && this.kycLevel() > 0) {\n this.envelope.kycLevel = this.kycLevel();\n }\n\n this.envelope.expirationDate ??= this.subject.idDocument?.dateOfExpiry;\n }\n}\n"],"mappings":"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"}
@@ -1,134 +1,2 @@
1
- import { Ed25519VerificationKey2020, Ed25519VerificationKey2020Options } from "@digitalbazaar/ed25519-verification-key-2020";
2
- import * as z from "zod";
3
- //#region src/types/credentials.d.ts
4
- type idOSCredential = {
5
- id: string;
6
- user_id: string;
7
- public_notes: string;
8
- content: string;
9
- encryptor_public_key: string;
10
- issuer_auth_public_key: string;
11
- original_id?: string | null;
12
- };
13
- type InsertableIDOSCredential = Omit<idOSCredential, "id" | "original_id"> & {
14
- id?: idOSCredential["id"];
15
- content_hash?: string;
16
- public_notes_signature: string;
17
- broader_signature: string;
18
- };
19
- declare const CredentialFieldsSchema: z.ZodObject<{
20
- id: z.ZodString;
21
- level: z.ZodString;
22
- issued: z.ZodOptional<z.ZodDate>;
23
- approvedAt: z.ZodOptional<z.ZodDate>;
24
- expirationDate: z.ZodOptional<z.ZodDate>;
25
- }>;
26
- type CredentialFields = z.infer<typeof CredentialFieldsSchema>;
27
- declare const CredentialResidentialAddressSchema: z.ZodObject<{
28
- street: z.ZodString;
29
- houseNumber: z.ZodOptional<z.ZodString>;
30
- additionalAddressInfo: z.ZodOptional<z.ZodString>;
31
- region: z.ZodOptional<z.ZodString>;
32
- city: z.ZodString;
33
- postalCode: z.ZodOptional<z.ZodString>;
34
- country: z.ZodString;
35
- proofCategory: z.ZodString;
36
- proofDateOfIssue: z.ZodOptional<z.ZodDate>;
37
- proofFile: z.ZodType<Buffer<ArrayBufferLike>>;
38
- }>;
39
- type CredentialResidentialAddress = z.infer<typeof CredentialResidentialAddressSchema>;
40
- declare const IDDocumentTypeSchema: z.ZodEnum<{
41
- PASSPORT: "PASSPORT";
42
- DRIVERS: "DRIVERS";
43
- ID_CARD: "ID_CARD";
44
- VOTING_CARD: "VOTING_CARD";
45
- PAN_CARD: "PAN_CARD";
46
- INTERNAL_PASSPORT: "INTERNAL_PASSPORT";
47
- RESIDENCE_PERMIT: "RESIDENCE_PERMIT";
48
- }>;
49
- type IDDocumentType = z.infer<typeof IDDocumentTypeSchema>;
50
- declare const GenderSchema: z.ZodEnum<{
51
- M: "M";
52
- F: "F";
53
- OTHER: "OTHER";
54
- }>;
55
- type Gender = z.infer<typeof GenderSchema>;
56
- declare const CredentialSubjectSchema: z.ZodObject<{
57
- id: z.ZodString;
58
- firstName: z.ZodOptional<z.ZodString>;
59
- middleName: z.ZodOptional<z.ZodString>;
60
- ssn: z.ZodOptional<z.ZodString>;
61
- gender: z.ZodOptional<typeof GenderSchema>;
62
- nationality: z.ZodOptional<z.ZodString>;
63
- familyName: z.ZodOptional<z.ZodString>;
64
- maidenName: z.ZodOptional<z.ZodString>;
65
- email: z.ZodOptional<z.ZodEmail>;
66
- phoneNumber: z.ZodOptional<z.ZodString>;
67
- dateOfBirth: z.ZodDate;
68
- placeOfBirth: z.ZodOptional<z.ZodString>;
69
- idDocumentCountry: z.ZodString;
70
- idDocumentNumber: z.ZodString;
71
- idDocumentType: typeof IDDocumentTypeSchema;
72
- idDocumentDateOfIssue: z.ZodOptional<z.ZodDate>;
73
- idDocumentDateOfExpiry: z.ZodOptional<z.ZodDate>;
74
- idDocumentFrontFile: z.ZodType<Buffer<ArrayBufferLike>>;
75
- idDocumentBackFile: z.ZodOptional<z.ZodType<Buffer<ArrayBufferLike>>>;
76
- selfieFile: z.ZodType<Buffer<ArrayBufferLike>>;
77
- residentialAddress: z.ZodOptional<typeof CredentialResidentialAddressSchema>;
78
- }>;
79
- type CredentialSubject = z.infer<typeof CredentialSubjectSchema>;
80
- interface VerifiableCredentialSubject extends Omit<CredentialSubject, "residentialAddress" | "idDocumentBackFile" | "idDocumentFrontFile" | "selfieFile" | "idDocumentDateOfIssue" | "idDocumentDateOfExpiry" | "dateOfBirth"> {
81
- "@context": string;
82
- idDocumentFrontFile?: string;
83
- idDocumentBackFile?: string;
84
- selfieFile?: string;
85
- dateOfBirth?: string;
86
- idDocumentDateOfIssue?: string;
87
- idDocumentDateOfExpiry?: string;
88
- residentialAddressStreet?: string;
89
- residentialAddressHouseNumber?: string;
90
- residentialAddressAdditionalAddressInfo?: string;
91
- residentialAddressRegion?: string;
92
- residentialAddressCity?: string;
93
- residentialAddressPostalCode?: string;
94
- residentialAddressCountry?: string;
95
- residentialAddressProofCategory?: string;
96
- residentialAddressProofDateOfIssue?: string;
97
- residentialAddressProofFile?: string;
98
- }
99
- interface VerifiedCredentialsProof {
100
- type: string;
101
- created: string;
102
- verificationMethod: string;
103
- proofValue: string;
104
- proofPurpose: string;
105
- }
106
- declare const CredentialSubjectFaceIdSchema: z.ZodObject<{
107
- faceSignUserId: z.ZodString;
108
- }>;
109
- type CredentialSubjectFaceId = z.infer<typeof CredentialSubjectFaceIdSchema>;
110
- interface VerifiedCredentials<K> {
111
- "@context": string[];
112
- type: string[];
113
- issuer: string;
114
- id: string;
115
- level: string;
116
- issued: string;
117
- approvedAt: string;
118
- expirationDate: string;
119
- credentialSubject: K;
120
- issuanceDate: string;
121
- proof: VerifiedCredentialsProof;
122
- }
123
- type VerifiableCredential<K> = VerifiedCredentials<K>;
124
- //#endregion
125
- //#region src/types/issuers.d.ts
126
- interface CustomIssuerType {
127
- issuer: string;
128
- publicKeyMultibase: string;
129
- privateKeyMultibase?: string;
130
- }
131
- type AvailableIssuerType = Omit<Ed25519VerificationKey2020Options, "type"> | Ed25519VerificationKey2020 | CustomIssuerType;
132
- //#endregion
133
- export { AvailableIssuerType, CredentialFields, CredentialFieldsSchema, CredentialResidentialAddress, CredentialResidentialAddressSchema, CredentialSubject, CredentialSubjectFaceId, CredentialSubjectFaceIdSchema, CredentialSubjectSchema, CustomIssuerType, Gender, GenderSchema, IDDocumentType, IDDocumentTypeSchema, InsertableIDOSCredential, VerifiableCredential, VerifiableCredentialSubject, VerifiedCredentials, VerifiedCredentialsProof, idOSCredential };
134
- //# sourceMappingURL=index.d.mts.map
1
+ import { a as VerifiableCredentialProof, i as VerifiableCredential, n as CustomIssuerType, o as idOSCredential, r as SignedCredentialContentReference, s as idOSCredentialRecord, t as AvailableIssuerType } from "../index-WW372Tf5.mjs";
2
+ export { AvailableIssuerType, CustomIssuerType, SignedCredentialContentReference, VerifiableCredential, VerifiableCredentialProof, idOSCredential, idOSCredentialRecord };
@@ -1,63 +1 @@
1
- import * as z from "zod";
2
- //#region src/types/credentials.ts
3
- const CredentialFieldsSchema = z.object({
4
- id: z.string(),
5
- level: z.string(),
6
- issued: z.date().optional(),
7
- approvedAt: z.date().optional(),
8
- expirationDate: z.date().optional()
9
- });
10
- const CredentialResidentialAddressSchema = z.object({
11
- street: z.string(),
12
- houseNumber: z.string().optional(),
13
- additionalAddressInfo: z.string().optional(),
14
- region: z.string().optional(),
15
- city: z.string(),
16
- postalCode: z.string().optional(),
17
- country: z.string().min(2).max(2),
18
- proofCategory: z.string(),
19
- proofDateOfIssue: z.date().optional(),
20
- proofFile: z.instanceof(Buffer)
21
- });
22
- const IDDocumentTypeSchema = z.enum([
23
- "PASSPORT",
24
- "DRIVERS",
25
- "ID_CARD",
26
- "VOTING_CARD",
27
- "PAN_CARD",
28
- "INTERNAL_PASSPORT",
29
- "RESIDENCE_PERMIT"
30
- ]);
31
- const GenderSchema = z.enum([
32
- "M",
33
- "F",
34
- "OTHER"
35
- ]);
36
- const CredentialSubjectSchema = z.object({
37
- id: z.string(),
38
- firstName: z.string().optional(),
39
- middleName: z.string().optional(),
40
- ssn: z.string().min(9).max(9).optional(),
41
- nationality: z.string().min(2).max(2).optional(),
42
- gender: GenderSchema.optional(),
43
- familyName: z.string().optional(),
44
- maidenName: z.string().optional(),
45
- dateOfBirth: z.date(),
46
- placeOfBirth: z.string().optional(),
47
- email: z.email().optional(),
48
- phoneNumber: z.string().optional(),
49
- idDocumentCountry: z.string().min(2).max(2),
50
- idDocumentNumber: z.string(),
51
- idDocumentType: IDDocumentTypeSchema,
52
- idDocumentDateOfIssue: z.date().optional(),
53
- idDocumentDateOfExpiry: z.date().optional(),
54
- idDocumentFrontFile: z.instanceof(Buffer),
55
- idDocumentBackFile: z.instanceof(Buffer).optional(),
56
- selfieFile: z.instanceof(Buffer),
57
- residentialAddress: CredentialResidentialAddressSchema.optional()
58
- }).refine((data) => data.firstName || data.familyName, { message: "At least one of firstName or familyName must be provided" });
59
- const CredentialSubjectFaceIdSchema = z.object({ faceSignUserId: z.string() });
60
- //#endregion
61
- export { CredentialFieldsSchema, CredentialResidentialAddressSchema, CredentialSubjectFaceIdSchema, CredentialSubjectSchema, GenderSchema, IDDocumentTypeSchema };
62
-
63
- //# sourceMappingURL=index.mjs.map
1
+ export{};
@@ -1,27 +1,49 @@
1
- import { AvailableIssuerType, CredentialFields, CredentialResidentialAddress, CredentialSubject, CredentialSubjectFaceId, InsertableIDOSCredential } from "../types/index.mjs";
1
+ import { o as idOSCredential, r as SignedCredentialContentReference, t as AvailableIssuerType } from "../index-WW372Tf5.mjs";
2
2
  import { Ed25519VerificationKey2020 } from "@digitalbazaar/ed25519-verification-key-2020";
3
+ //#region src/utils/issuer.d.ts
4
+ export declare function issuerToKey(issuer: AvailableIssuerType): Promise<Ed25519VerificationKey2020>;
5
+ //#endregion
3
6
  //#region src/utils/index.d.ts
4
- declare function capitalizeFirstLetter(str: string): string;
5
- declare function issuerToKey(issuer: AvailableIssuerType): Promise<Ed25519VerificationKey2020>;
6
- declare function convertValues<K extends CredentialFields | CredentialSubject | CredentialResidentialAddress | CredentialSubjectFaceId>(fields: K, prefix?: string): Record<string, unknown>;
7
- type BaseLevel = "basic" | "plus";
8
- type Addon = "liveness" | "email" | "phoneNumber";
9
- declare function deriveLevel(credential: CredentialSubject): string;
10
- declare function parseLevel(level: string): {
7
+ export type BaseLevel = "unverified" | "basic" | "plus";
8
+ export type Addon = "liveness" | "email" | "phoneNumber" | "edd" | "sow" | "screening" | "onboarding";
9
+ export declare function parseLevel(level: string): {
11
10
  base: BaseLevel;
12
11
  addons: Addon[];
13
12
  };
14
- declare function matchLevelOrHigher(level: BaseLevel, requiredAddons: Addon[], currentLevel: string): boolean;
15
- declare function levelScore(level: string): number;
16
- declare function pickHighestMatchingLevel(levels: string[], requiredLevel: BaseLevel, requiredAddons: Addon[]): string | null;
17
- declare function highestMatchingCredential<K extends {
13
+ export declare function assertNoExtraFields(section: string, expectedFields: ReadonlySet<string>, value: object | undefined): void;
14
+ export declare function matchLevelOrHigher(level: BaseLevel, requiredAddons: Addon[], currentLevel: string): boolean;
15
+ export declare function levelScore(level: string): number;
16
+ export declare function pickHighestMatchingLevel(levels: string[], requiredLevel: BaseLevel, requiredAddons: Addon[]): string | null;
17
+ export declare function highestMatchingCredential<K extends {
18
18
  public_notes: string;
19
19
  }>(credentials: K[], requiredLevel: BaseLevel, { addons: requiredAddons, publicNotesConstraint }: {
20
20
  addons?: Addon[];
21
21
  publicNotesConstraint?: Record<string, number | string>;
22
22
  }): K | undefined;
23
- declare function recordFilter(rec: Record<string, unknown>, pick: Record<string, unknown[]>, omit: Record<string, unknown[]>): boolean;
24
- declare function buildInsertableIDOSCredential(userId: string, publicNotes: string, content: string, encryptorPublicKey: string): InsertableIDOSCredential;
23
+ export declare function recordFilter(rec: Record<string, unknown>, pick: Record<string, unknown[]>, omit: Record<string, unknown[]>): boolean;
24
+ export declare function buildSignedCredentialContentReference(publicNotes: string, contentUri: string, issuerSigningSecretKey: Uint8Array): SignedCredentialContentReference;
25
+ /** User-issued share copy: sign with a fresh ephemeral key (need not match original issuer). */
26
+ export declare function buildEphemeralSignedCredentialContentReference(publicNotes: string, contentUri: string): SignedCredentialContentReference;
27
+ export type PreliminaryIDOSCredential = {
28
+ id: string;
29
+ contentUri: string;
30
+ contentSize: number;
31
+ encryptedContent: Uint8Array;
32
+ publicNotes: string;
33
+ publicNotesSignature: string;
34
+ broaderSignature: string;
35
+ issuerAuthPublicKey: string;
36
+ encryptorPublicKey: string;
37
+ };
38
+ export declare function mapPreliminaryToIDOSCredential(preliminaryCredential: PreliminaryIDOSCredential): Omit<idOSCredential, "user_id">;
39
+ export interface BuildPreliminaryIDOSCredentialArgs {
40
+ publicNotes: string;
41
+ plaintextContent: Uint8Array;
42
+ recipientEncryptionPublicKey: Uint8Array;
43
+ issuerSigningSecretKey?: Uint8Array;
44
+ /** When set (MM / `ukyc://`), skip IPFS CID hashing. */
45
+ contentUri?: string;
46
+ }
47
+ export declare function buildPreliminaryIDOSCredential({ publicNotes, plaintextContent, recipientEncryptionPublicKey, issuerSigningSecretKey, contentUri }: BuildPreliminaryIDOSCredentialArgs): Promise<Omit<PreliminaryIDOSCredential, "id">>;
25
48
  //#endregion
26
- export { buildInsertableIDOSCredential, capitalizeFirstLetter, convertValues, deriveLevel, highestMatchingCredential, issuerToKey, levelScore, matchLevelOrHigher, parseLevel, pickHighestMatchingLevel, recordFilter };
27
49
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/utils/index.ts"],"mappings":";;;iBAsBgB,sBAAsB;iBAuBhB,YACpB,QAAQ,sBACP,QAAQ;iBAkBK,cACd,UACI,mBACA,oBACA,+BACA,yBACJ,QAAQ,GAAG,kBAAkB;KAqB1B;KACA;iBAEW,YAAY,YAAY;iBAyBxB,WAAW;EACzB,MAAM;EACN,QAAQ;;iBAMM,mBACd,OAAO,WACP,gBAAgB,SAChB;iBAYc,WAAW;iBAaX,yBACd,kBACA,eAAe,WACf,gBAAgB;iBAaF,0BAA0B;EAAY;GACpD,aAAa,KACb,eAAe,aAEb,QAAQ,gBACR;EAEA,SAAS;EACT,wBAAwB;IAEzB;iBAsCa,aACd,KAAK,yBACL,MAAM,2BACN,MAAM;iBAkBQ,8BACd,gBACA,qBACA,iBACA,6BACC"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/utils/issuer.ts","../../src/utils/index.ts"],"mappings":";;;wBAuBsB,YACpB,QAAQ,sBACP,QAAQ;;;YCdC;YACA;wBASI,WAAW;EACzB,MAAM;EACN,QAAQ;;wBAMM,oBACd,iBACA,gBAAgB,qBAChB;wBASc,mBACd,OAAO,WACP,gBAAgB,SAChB;wBAiBc,WAAW;wBAiBX,yBACd,kBACA,eAAe,WACf,gBAAgB;wBAaF,0BAA0B;EAAY;GACpD,aAAa,KACb,eAAe,aAEb,QAAQ,gBACR;EAEA,SAAS;EACT,wBAAwB;IAEzB;wBAsCa,aACd,KAAK,yBACL,MAAM,2BACN,MAAM;wBAkBQ,sCACd,qBACA,oBACA,wBAAwB,aACvB;;wBAqBa,+CACd,qBACA,qBACC;YAQS;EACV;EACA;EACA;EACA,kBAAkB;EAClB;EACA;EACA;EACA;EACA;;wBAGc,+BACd,uBAAuB,4BACtB,KAAK;iBAWS;EACf;EACA,kBAAkB;EAClB,8BAA8B;EAC9B,yBAAyB;;EAEzB;;wBAGoB,iCACpB,aACA,kBACA,8BAGA,wBACA,cACC,qCAAqC,QAAQ,KAAK"}
@@ -1,117 +1,2 @@
1
- import { Ed25519VerificationKey2020 } from "@digitalbazaar/ed25519-verification-key-2020";
2
- import { base64Decode, base64Encode, fileToBase85, hexEncode, utf8Encode } from "@idos-network/utils/codecs";
3
- import { every, get } from "es-toolkit/compat";
4
- import invariant from "tiny-invariant";
5
- import nacl from "tweetnacl";
6
- //#region src/utils/index.ts
7
- function capitalizeFirstLetter(str) {
8
- return str[0].toUpperCase() + str.slice(1);
9
- }
10
- function isIssuerKey(issuer) {
11
- return typeof issuer === "object" && issuer !== null && "type" in issuer && "id" in issuer && "controller" in issuer;
12
- }
13
- function isCustomIssuerType(issuer) {
14
- return typeof issuer === "object" && issuer !== null && "issuer" in issuer && "publicKeyMultibase" in issuer;
15
- }
16
- async function issuerToKey(issuer) {
17
- if (isIssuerKey(issuer)) return issuer;
18
- if (isCustomIssuerType(issuer)) return await Ed25519VerificationKey2020.from({
19
- id: `${issuer.issuer}/keys/1`,
20
- controller: `${issuer.issuer}/issuers/1`,
21
- publicKeyMultibase: issuer.publicKeyMultibase,
22
- privateKeyMultibase: issuer.privateKeyMultibase,
23
- type: "Ed25519VerificationKey2020"
24
- });
25
- return await Ed25519VerificationKey2020.from({
26
- ...issuer,
27
- type: "Ed25519VerificationKey2020"
28
- });
29
- }
30
- function convertValues(fields, prefix) {
31
- const acc = {};
32
- for (const key in fields) if (Object.hasOwn(fields, key)) {
33
- const value = fields[key];
34
- const name = prefix ? `${prefix}${capitalizeFirstLetter(key)}` : key;
35
- if (value instanceof Date) acc[name] = value.toISOString();
36
- else if (value instanceof Buffer) acc[name] = fileToBase85(value);
37
- else acc[name] = value;
38
- }
39
- return acc;
40
- }
41
- function deriveLevel(credential) {
42
- let level = "basic";
43
- const address = credential.residentialAddress;
44
- if (address?.proofFile && address?.city && address?.proofCategory) level = "plus";
45
- const addons = [];
46
- if (credential.selfieFile) addons.push("liveness");
47
- if (credential.email) addons.push("email");
48
- if (credential.phoneNumber) addons.push("phoneNumber");
49
- return [level, ...addons].join("+");
50
- }
51
- function parseLevel(level) {
52
- const [base, ...addons] = level.split("+");
53
- return {
54
- base,
55
- addons
56
- };
57
- }
58
- function matchLevelOrHigher(level, requiredAddons, currentLevel) {
59
- const { base: currentBaseLevel, addons: currentAddons } = parseLevel(currentLevel);
60
- if (level === "plus" && currentBaseLevel !== "plus") return false;
61
- return requiredAddons.every((addon) => currentAddons.includes(addon));
62
- }
63
- function levelScore(level) {
64
- const { base, addons } = parseLevel(level);
65
- let score = 0;
66
- if (base === "plus") score += 100;
67
- score += addons.length * 10;
68
- return score;
69
- }
70
- function pickHighestMatchingLevel(levels, requiredLevel, requiredAddons) {
71
- return levels.filter((currentLevel) => matchLevelOrHigher(requiredLevel, requiredAddons, currentLevel)).sort((a, b) => {
72
- const aAddons = levelScore(a);
73
- return levelScore(b) - aAddons;
74
- })[0] ?? null;
75
- }
76
- function highestMatchingCredential(credentials, requiredLevel, { addons: requiredAddons = [], publicNotesConstraint = {} }) {
77
- return credentials.map((credential) => {
78
- return {
79
- credential,
80
- publicNotes: JSON.parse(credential.public_notes || "{}")
81
- };
82
- }).filter(({ publicNotes }) => {
83
- const level = publicNotes.level;
84
- if (!level) return false;
85
- if (!matchLevelOrHigher(requiredLevel, requiredAddons, level)) return false;
86
- for (const key in publicNotesConstraint) if (publicNotes[key] !== publicNotesConstraint[key]) return false;
87
- return true;
88
- }).sort((a, b) => {
89
- const aLevel = a.publicNotes.level;
90
- const bLevel = b.publicNotes.level;
91
- return levelScore(bLevel) - levelScore(aLevel);
92
- }).map(({ credential }) => credential)[0];
93
- }
94
- function recordFilter(rec, pick, omit) {
95
- const matchCriteria = (content, criteria) => every(Object.entries(criteria), ([path, targetSet]) => targetSet.includes(get(content, path)));
96
- if (Object.keys(pick).length > 0 && !matchCriteria(rec, pick)) return false;
97
- if (Object.keys(omit).length > 0 && matchCriteria(rec, omit)) return false;
98
- return true;
99
- }
100
- function buildInsertableIDOSCredential(userId, publicNotes, content, encryptorPublicKey) {
101
- invariant(encryptorPublicKey, "Missing `encryptorPublicKey`");
102
- const ephemeralAuthenticationKeyPair = nacl.sign.keyPair();
103
- const publicNotesSignature = nacl.sign.detached(utf8Encode(publicNotes), ephemeralAuthenticationKeyPair.secretKey);
104
- return {
105
- user_id: userId,
106
- content,
107
- public_notes: publicNotes,
108
- public_notes_signature: base64Encode(publicNotesSignature),
109
- broader_signature: base64Encode(nacl.sign.detached(Uint8Array.from([...publicNotesSignature, ...base64Decode(content)]), ephemeralAuthenticationKeyPair.secretKey)),
110
- issuer_auth_public_key: hexEncode(ephemeralAuthenticationKeyPair.publicKey, true),
111
- encryptor_public_key: encryptorPublicKey
112
- };
113
- }
114
- //#endregion
115
- export { buildInsertableIDOSCredential, capitalizeFirstLetter, convertValues, deriveLevel, highestMatchingCredential, issuerToKey, levelScore, matchLevelOrHigher, parseLevel, pickHighestMatchingLevel, recordFilter };
116
-
1
+ import{createBlobContentReference as e}from"@idos-network/utils/blob-gateway";import{base64Encode as t,hexEncode as n,utf8Encode as r}from"@idos-network/utils/codecs";import{encryptContent as i}from"@idos-network/utils/cryptography";import{every as a,get as o}from"es-toolkit/compat";import s from"tweetnacl";import{Ed25519VerificationKey2020 as c}from"@digitalbazaar/ed25519-verification-key-2020";function l(e){return typeof e==`object`&&!!e&&`type`in e&&`id`in e&&`controller`in e}function u(e){return typeof e==`object`&&!!e&&`issuer`in e&&`publicKeyMultibase`in e}async function d(e){return l(e)?e:u(e)?await c.from({id:`${e.issuer}/keys/1`,controller:`${e.issuer}/issuers/1`,publicKeyMultibase:e.publicKeyMultibase,privateKeyMultibase:e.privateKeyMultibase,type:`Ed25519VerificationKey2020`}):await c.from({...e,type:`Ed25519VerificationKey2020`})}function f(e){let[t,...n]=e.split(`+`);return{base:t,addons:n}}function p(e,t,n){let r=Object.keys(n??{}).filter(e=>!t.has(e));if(r.length>0)throw Error(`Unexpected ${e} fields: ${r.join(`, `)}`)}function m(e,t,n){let{base:r,addons:i}=f(n);return e===`basic`&&r===`unverified`||e===`plus`&&r!==`plus`?!1:t.every(e=>i.includes(e))}function h(e){let{base:t,addons:n}=f(e),r=0;return t===`basic`&&(r+=50),t===`plus`&&(r+=100),r+=n.length*10,r}function g(e,t,n){return e.filter(e=>m(t,n,e)).sort((e,t)=>{let n=h(e);return h(t)-n})[0]??null}function _(e,t,{addons:n=[],publicNotesConstraint:r={}}){return e.map(e=>({credential:e,publicNotes:JSON.parse(e.public_notes||`{}`)})).filter(({publicNotes:e})=>{let i=e.level;if(!i||!m(t,n,i))return!1;for(let t in r)if(e[t]!==r[t])return!1;return!0}).sort((e,t)=>{let n=e.publicNotes.level,r=t.publicNotes.level;return h(r)-h(n)}).map(({credential:e})=>e)[0]}function v(e,t,n){let r=(e,t)=>a(Object.entries(t),([t,n])=>n.includes(o(e,t)));return!(Object.keys(t).length>0&&!r(e,t)||Object.keys(n).length>0&&r(e,n))}function y(e,i,a){let{publicKey:o,secretKey:c}=s.sign.keyPair.fromSecretKey(a),l=s.sign.detached(r(e),c);return{public_notes:e,public_notes_signature:t(l),broader_signature:t(s.sign.detached(Uint8Array.from([...l,...r(i)]),c)),issuer_auth_public_key:n(o,!0)}}function b(e,t){return y(e,t,s.sign.keyPair().secretKey)}function x(e){return{id:e.id,content_uri:e.contentUri,content_size:e.contentSize,public_notes:e.publicNotes,issuer_auth_public_key:e.issuerAuthPublicKey,encryptor_public_key:e.encryptorPublicKey}}async function S({publicNotes:n,plaintextContent:r,recipientEncryptionPublicKey:a,issuerSigningSecretKey:o=s.sign.keyPair().secretKey,contentUri:c}){let l=s.box.keyPair(),u=i(r,a,l.secretKey),d=c?{uri:c,size:u.byteLength}:await e(u),f=y(n,d.uri,o);return{contentUri:d.uri,contentSize:d.size,encryptedContent:u,publicNotes:n,publicNotesSignature:f.public_notes_signature,broaderSignature:f.broader_signature,issuerAuthPublicKey:f.issuer_auth_public_key,encryptorPublicKey:t(l.publicKey)}}export{p as assertNoExtraFields,b as buildEphemeralSignedCredentialContentReference,S as buildPreliminaryIDOSCredential,y as buildSignedCredentialContentReference,_ as highestMatchingCredential,d as issuerToKey,h as levelScore,x as mapPreliminaryToIDOSCredential,m as matchLevelOrHigher,f as parseLevel,g as pickHighestMatchingLevel,v as recordFilter};
117
2
  //# sourceMappingURL=index.mjs.map