@idos-network/credentials 2.2.2 → 2.3.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.
@@ -308,11 +308,23 @@ declare class Onboarding {
308
308
  //#region src/schemas/KycV3/Person.d.ts
309
309
  declare class Person {
310
310
  firstName?: string;
311
+ readonly firstNameIcao?: string;
312
+ readonly firstNameLatin?: Promise<string | undefined>;
311
313
  familyName?: string;
314
+ readonly familyNameIcao?: string;
315
+ readonly familyNameLatin?: Promise<string | undefined>;
312
316
  middleName?: string;
317
+ readonly middleNameIcao?: string;
318
+ readonly middleNameLatin?: Promise<string | undefined>;
313
319
  fatherName?: string;
320
+ readonly fatherNameIcao?: string;
321
+ readonly fatherNameLatin?: Promise<string | undefined>;
314
322
  maidenName?: string;
323
+ readonly maidenNameIcao?: string;
324
+ readonly maidenNameLatin?: Promise<string | undefined>;
315
325
  motherName?: string;
326
+ readonly motherNameIcao?: string;
327
+ readonly motherNameLatin?: Promise<string | undefined>;
316
328
  gender?: Gender;
317
329
  nationality?: string;
318
330
  secondNationality?: string;
@@ -333,10 +345,18 @@ declare class Person {
333
345
  declare class ResidentialAddress {
334
346
  source: ResidentialAddressSource;
335
347
  street: string;
348
+ readonly streetIcao?: string;
349
+ readonly streetLatin?: Promise<string | undefined>;
336
350
  houseNumber?: string;
337
351
  additionalAddressInfo?: string;
352
+ readonly additionalAddressInfoIcao?: string;
353
+ readonly additionalAddressInfoLatin?: Promise<string | undefined>;
338
354
  region?: string;
355
+ readonly regionIcao?: string;
356
+ readonly regionLatin?: Promise<string | undefined>;
339
357
  city: string;
358
+ readonly cityIcao?: string;
359
+ readonly cityLatin?: Promise<string | undefined>;
340
360
  postalCode?: string;
341
361
  country: string;
342
362
  proofCategory?: string;
@@ -392,4 +412,4 @@ declare class KycV3 extends VerifiableCredentialBase<EnvelopeV2, Subject> {
392
412
  }
393
413
  //#endregion
394
414
  export { Occupations as A, Gender as C, IntendedUse as D, IDDocumentTypes as E, SourceOfWealthType as F, SourceOfWealthTypes as I, YearlyGrossIncome as L, ResidentialAddressSources as M, ScreeningResult as N, IntendedUses as O, ScreeningResults as P, YearlyGrossIncomes as R, ExpectedMonthlyTransactionVolumes as S, IDDocumentType as T, EmploymentStatus as _, FaceIdV1 as a, ExpectedMonthlyTransactionCounts as b, EnvelopeV2 as c, VerifiableCredentialBase as d, PublicNotes as f, Currency as g, Currencies as h, KycV1 as i, ResidentialAddressSource as j, Occupation as k, OwnFields as l, ApproximateNetWorths as m, Subject as n, EddV1 as o, ApproximateNetWorth as p, KycV2 as r, EnvelopeV1 as s, KycV3 as t, Sections as u, EmploymentStatuses as v, Genders as w, ExpectedMonthlyTransactionVolume as x, ExpectedMonthlyTransactionCount as y };
395
- //# sourceMappingURL=index-0NqXMjNk.d.mts.map
415
+ //# sourceMappingURL=index-DW2Pbn6A.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-0NqXMjNk.d.mts","names":[],"sources":["../src/schemas/enums.ts","../src/schemas/types.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"],"mappings":"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"}
1
+ {"version":3,"file":"index-DW2Pbn6A.d.mts","names":[],"sources":["../src/schemas/enums.ts","../src/schemas/types.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"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { i as VerifiableCredential } from "../index-WW372Tf5.mjs";
2
- import { a as FaceIdV1, i as KycV1, o as EddV1, r as KycV2, t as KycV3 } from "../index-0NqXMjNk.mjs";
2
+ import { a as FaceIdV1, i as KycV1, o as EddV1, r as KycV2, t as KycV3 } from "../index-DW2Pbn6A.mjs";
3
3
  //#region src/parser/index.d.ts
4
4
  type CredentialWithContext = VerifiableCredential<unknown>;
5
5
  /** Every version `parseCredential` can return. */
@@ -1,2 +1,2 @@
1
- import{a as e,i as t,o as n,r,t as i}from"../schemas-BVGuUlPe.mjs";const a=[n,e,t,r,i];function o(e,t){if(typeof e.credentialSubject!=`object`||e.credentialSubject===null||Array.isArray(e.credentialSubject))return!1;let n=e.credentialSubject[`@context`];return Array.isArray(n)?n.includes(t):n===t}async function s(e){for(let t of a){if(!o(e,t.subjectContext))continue;let n=new t;return await n.deserialize(e),n.checkValidity(),n}throw Error(`Unknown credential`)}export{s as parseCredential};
1
+ import{a as e,i as t,o as n,r,t as i}from"../schemas-9ZR7Wydc.mjs";const a=[n,e,t,r,i];function o(e,t){if(typeof e.credentialSubject!=`object`||e.credentialSubject===null||Array.isArray(e.credentialSubject))return!1;let n=e.credentialSubject[`@context`];return Array.isArray(n)?n.includes(t):n===t}async function s(e){for(let t of a){if(!o(e,t.subjectContext))continue;let n=new t;return await n.deserialize(e),n.checkValidity(),n}throw Error(`Unknown credential`)}export{s as parseCredential};
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1,2 +1,2 @@
1
- import { A as Occupations, C as Gender, D as IntendedUse, E as IDDocumentTypes, F as SourceOfWealthType, I as SourceOfWealthTypes, L as YearlyGrossIncome, M as ResidentialAddressSources, N as ScreeningResult, O as IntendedUses, P as ScreeningResults, R as YearlyGrossIncomes, S as ExpectedMonthlyTransactionVolumes, T as IDDocumentType, _ as EmploymentStatus, a as FaceIdV1, b as ExpectedMonthlyTransactionCounts, c as EnvelopeV2, d as VerifiableCredentialBase, f as PublicNotes, g as Currency, h as Currencies, i as KycV1, j as ResidentialAddressSource, k as Occupation, l as OwnFields, m as ApproximateNetWorths, n as Subject, o as EddV1, p as ApproximateNetWorth, r as KycV2, s as EnvelopeV1, t as KycV3, u as Sections, v as EmploymentStatuses, w as Genders, x as ExpectedMonthlyTransactionVolume, y as ExpectedMonthlyTransactionCount } from "../index-0NqXMjNk.mjs";
1
+ import { A as Occupations, C as Gender, D as IntendedUse, E as IDDocumentTypes, F as SourceOfWealthType, I as SourceOfWealthTypes, L as YearlyGrossIncome, M as ResidentialAddressSources, N as ScreeningResult, O as IntendedUses, P as ScreeningResults, R as YearlyGrossIncomes, S as ExpectedMonthlyTransactionVolumes, T as IDDocumentType, _ as EmploymentStatus, a as FaceIdV1, b as ExpectedMonthlyTransactionCounts, c as EnvelopeV2, d as VerifiableCredentialBase, f as PublicNotes, g as Currency, h as Currencies, i as KycV1, j as ResidentialAddressSource, k as Occupation, l as OwnFields, m as ApproximateNetWorths, n as Subject, o as EddV1, p as ApproximateNetWorth, r as KycV2, s as EnvelopeV1, t as KycV3, u as Sections, v as EmploymentStatuses, w as Genders, x as ExpectedMonthlyTransactionVolume, y as ExpectedMonthlyTransactionCount } from "../index-DW2Pbn6A.mjs";
2
2
  export { ApproximateNetWorth, ApproximateNetWorths, Currencies, Currency, EmploymentStatus, EmploymentStatuses, EnvelopeV1, EnvelopeV2, ExpectedMonthlyTransactionCount, ExpectedMonthlyTransactionCounts, ExpectedMonthlyTransactionVolume, ExpectedMonthlyTransactionVolumes, Gender, Genders, IDDocumentType, IDDocumentTypes, IntendedUse, IntendedUses, Occupation, Occupations, type OwnFields, type PublicNotes, ResidentialAddressSource, ResidentialAddressSources, ScreeningResult, ScreeningResults, type Sections, SourceOfWealthType, SourceOfWealthTypes, VerifiableCredentialBase, EddV1 as VerifiableCredentialEddV1, FaceIdV1 as VerifiableCredentialFaceIdV1, KycV1 as VerifiableCredentialKycV1, KycV2 as VerifiableCredentialKycV2, KycV3 as VerifiableCredentialKycV3, Subject as VerifiableCredentialKycV3Subject, YearlyGrossIncome, YearlyGrossIncomes };
@@ -1 +1 @@
1
- import{S as e,_ as t,a as n,b as r,c as i,d as a,f as o,g as s,h as c,i as l,l as u,m as d,n as f,o as p,p as m,r as h,s as g,t as _,u as v,v as y,x as b,y as x}from"../schemas-BVGuUlPe.mjs";export{v as ApproximateNetWorths,a as Currencies,o as EmploymentStatuses,g as EnvelopeV1,i as EnvelopeV2,m as ExpectedMonthlyTransactionCounts,d as ExpectedMonthlyTransactionVolumes,c as Genders,s as IDDocumentTypes,t as IntendedUses,y as Occupations,x as ResidentialAddressSources,r as ScreeningResults,b as SourceOfWealthTypes,u as VerifiableCredentialBase,p as VerifiableCredentialEddV1,n as VerifiableCredentialFaceIdV1,l as VerifiableCredentialKycV1,h as VerifiableCredentialKycV2,_ as VerifiableCredentialKycV3,f as VerifiableCredentialKycV3Subject,e as YearlyGrossIncomes};
1
+ import{S as e,_ as t,a as n,b as r,c as i,d as a,f as o,g as s,h as c,i as l,l as u,m as d,n as f,o as p,p as m,r as h,s as g,t as _,u as v,v as y,x as b,y as x}from"../schemas-9ZR7Wydc.mjs";export{v as ApproximateNetWorths,a as Currencies,o as EmploymentStatuses,g as EnvelopeV1,i as EnvelopeV2,m as ExpectedMonthlyTransactionCounts,d as ExpectedMonthlyTransactionVolumes,c as Genders,s as IDDocumentTypes,t as IntendedUses,y as Occupations,x as ResidentialAddressSources,r as ScreeningResults,b as SourceOfWealthTypes,u as VerifiableCredentialBase,p as VerifiableCredentialEddV1,n as VerifiableCredentialFaceIdV1,l as VerifiableCredentialKycV1,h as VerifiableCredentialKycV2,_ as VerifiableCredentialKycV3,f as VerifiableCredentialKycV3Subject,e as YearlyGrossIncomes};
@@ -0,0 +1,2 @@
1
+ import{assertNoExtraFields as e,issuerToKey as t,transliterateIcao as n,transliterateLatin as r}from"./utils/index.mjs";import{a as i,c as a,i as o,l as s,n as c,o as l,r as ee,s as te,t as ne,u as re}from"./loader-Cg6hs1-P.mjs";import{base85ToFile as ie,fileToBase85 as ae}from"@idos-network/utils/codecs";import{Ed25519Signature2020 as oe}from"@digitalbazaar/ed25519-signature-2020";import*as se from"@digitalbazaar/vc";import"reflect-metadata";import{Transform as u,Type as ce,instanceToPlain as le,plainToInstance as ue}from"class-transformer";import{IsBoolean as d,IsDate as de,IsDefined as fe,IsEmail as f,IsEnum as pe,IsISO31661Alpha2 as p,IsIn as m,IsInstance as me,IsInt as he,IsMimeType as h,IsNumber as g,IsOptional as _,IsPositive as ge,IsString as v,Length as y,Max as _e,Min as ve,ValidateIf as ye,ValidateNested as be,getMetadataStorage as xe,validateSync as Se}from"class-validator";const Ce=[`INVESTING`,`PAYMENT_TO_FRIENDS_FAMILY_OR_OTHERS`,`PURCHASE_DIGITAL_ASSETS`,`ONLINE_PURCHASES_OF_GOODS_OR_SERVICES`,`TRADING`],we=[`PASSPORT`,`DRIVERS`,`ID_CARD`,`VOTING_CARD`,`PAN_CARD`,`INTERNAL_PASSPORT`,`RESIDENCE_PERMIT`],b=[`MANUAL`,`GPS`,`EXTERNAL_DB`,`PROOF_OF_ADDRESS`,`PROOF_OF_IDENTITY`,`AUTO_COMPLETE`],x=[`CLEAR`,`NOT_CHECKED`],Te=[`M`,`F`,`OTHER`],Ee=[`EMPLOYED`,`SELF_EMPLOYED`,`UNEMPLOYED`,`RETIRED`,`STUDENT`],De=[`LESS_THAN_5`,`BETWEEN_5_AND_10`,`MORE_THAN_10`],Oe=[`LESS_THAN_500`,`MORE_THAN_500_LESS_THAN_2000`,`MORE_THAN_2000`],ke=[`SALARY`,`SAVINGS`,`INVESTMENTS`,`CRYPTO_TRADING`,`OTHER`],Ae=[`LESS_THAN_20000`,`FROM_20001_TO_30000`,`FROM_30001_TO_40000`,`FROM_40001_TO_50000`,`FROM_50001_TO_60000`,`FROM_60001_TO_70000`,`FROM_70001_TO_80000`,`FROM_80001_TO_90000`,`FROM_90001_TO_100000`,`FROM_100001_TO_110000`,`FROM_110001_TO_120000`,`FROM_120001_TO_130000`,`FROM_130001_TO_140000`,`FROM_140001_TO_150000`,`FROM_150001_TO_200000`,`FROM_200001_TO_500000`,`MORE_THAN_500000`],je=[`UP_TO_25000`,`BETWEEN_25001_AND_50000`,`BETWEEN_50001_AND_100000`,`BETWEEN_100001_AND_300000`,`BETWEEN_300001_AND_500000`,`BETWEEN_500001_AND_1000000`,`OVER_1000001`],S=[`AGRICULTURE`,`ARTS_AND_ENTERTAINMENT`,`CONSTRUCTION`,`EDUCATION`,`FINANCIAL_SERVICES`,`INFORMATION_AND_TECHNOLOGY`,`RETAIL`,`REAL_ESTATE`,`OTHER`,`BUSINESS_OWNER`,`HEALTHCARE`,`INDUSTRIAL`,`LEGAL_SERVICES`,`PUBLIC_SECTOR`,`SENIOR_MANAGEMENT`],C=[`EUR`,`USD`,`GBP`,`OTHER`],w=Symbol(`idos:sections`);function T(e,t){return e?`${e}${t.charAt(0).toUpperCase()}${t.slice(1)}`:t}function E(e,t){return(n,r)=>{let i=String(r),a=Reflect.getOwnMetadata(w,n.constructor)??[...Reflect.getMetadata(w,n.constructor)??[]];a.push({property:i,prefix:t??i,type:e}),Reflect.defineMetadata(w,a,n.constructor),ce(e)(n,r),be()(n,r)}}function D(e){return Reflect.getMetadata(w,e)??[]}function O(){return(e,t)=>{let i=String(t);Object.defineProperty(e,`${i}Icao`,{configurable:!0,get(){let e=this[i];return typeof e==`string`?n(e):void 0}}),Object.defineProperty(e,`${i}Latin`,{configurable:!0,get(){let e=this[i];if(typeof e!=`string`)return Promise.resolve(void 0);let t=r(e);return t.catch(()=>{}),t}})}}function k(e){let t=xe().getTargetValidationMetadatas(e,e.name,!0,!1);return[...new Set(t.map(e=>e.propertyName))]}function Me(e){let t=le(e),n=new Map(D(e.constructor).map(({property:e,prefix:t})=>[e,t])),r={};for(let[e,i]of Object.entries(t)){if(!n.has(e)){i!==void 0&&(r[e]=i);continue}if(!i)continue;let t=n.get(e);for(let[e,n]of Object.entries(i))n!==void 0&&(r[T(t,e)]=n)}return r}function Ne(e){let t=D(e),n=new Set(t.map(({property:e})=>e)),r=k(e).filter(e=>!n.has(e));for(let{prefix:e,type:n}of t)for(let t of k(n()))r.push(T(e,t));return new Set(r)}function Pe(e,t){let n=D(e),r=new Set(n.map(({property:e})=>e)),i={};for(let n of k(e))!r.has(n)&&Object.hasOwn(t,n)&&(i[n]=t[n]);for(let{property:e,prefix:r,type:a}of n){let n={};for(let e of k(a())){let i=T(r,e);Object.hasOwn(t,i)&&(n[e]=t[i])}Object.keys(n).length>0&&(i[e]=n)}return ue(e,i)}function Fe(e,t){let n=ue(e,t);return Object.fromEntries(Object.keys(t).map(e=>[e,n[e]]))}function Ie(e,t=``){return e.flatMap(e=>{let n=t?`${t}.${e.property}`:e.property;return[...Object.values(e.constraints??{}).map(e=>`${n}: ${e}`),...Ie(e.children??[],n)]})}var Le=class extends Error{errors;name=`CredentialValidationError`;constructor(e,t){super(`Invalid ${e}: ${Ie(t).join(`; `)}`),this.errors=t}};function A(e,t){let n=Se(t);if(n.length>0)throw new Le(e,n)}function j(e){return(t,n)=>ye(t=>e(t)||t[String(n)]!==void 0)(t,n)}function Re(e){return j(t=>t[e]!==void 0)}function ze(...e){return(t,n)=>{for(let r of e)r(t,n)}}function M(){return ze(u(({value:e})=>e instanceof Date?e.toISOString():e,{toPlainOnly:!0}),u(({value:e})=>typeof e==`string`?new Date(e):e,{toClassOnly:!0}),de())}const Be=/^<~[\s\S]*~>$/;function N(){return ze(u(({value:e})=>Buffer.isBuffer(e)?ae(e):e,{toPlainOnly:!0}),u(({value:e})=>typeof e!=`string`||!Be.test(e)?e:ie(e)||e,{toClassOnly:!0}),me(Buffer,{message:({property:e})=>`${e} must be a file encoded as delimited ascii85`}))}var P=class{envelopeClass;subjectClass;envelope={};subject={};constructor(e,t){this.envelopeClass=e,this.subjectClass=t}addSection(e,t,n=!0){let r=D(this.subjectClass).find(({property:t})=>t===e);if(!r)throw Error(`Unknown section: ${String(e)}`);let i=r.type(),a=new Set(k(i)),o=Object.keys(t).filter(e=>!a.has(e));if(o.length>0)throw Error(`Unexpected ${String(e)} fields: ${o.join(`, `)}`);let s=Object.assign(new i,t);return n&&A(String(e),s),this.subject[e]=s,this}setSubject(e){return Object.assign(this.subject,this.ownFields(`subject`,this.subjectClass,e)),this}setEnvelope(e){return Object.assign(this.envelope,this.ownFields(`envelope`,this.envelopeClass,e)),this}checkValidity(){this.setMissingFields(),A(`envelope`,Object.assign(new this.envelopeClass,this.envelope)),A(`subject`,Object.assign(new this.subjectClass,this.subject))}serializeSubject(){return this.checkValidity(),{"@context":[this.contexts.subjectContext],...Me(Object.assign(new this.subjectClass,this.subject))}}serializeEnvelope(){return this.checkValidity(),Me(Object.assign(new this.envelopeClass,this.envelope))}async issue(e){let n=await t(e),r={"@context":[s,this.contexts.envelopeContext,ne],type:[`VerifiableCredential`],issuer:n.controller,...this.serializeEnvelope(),credentialSubject:this.serializeSubject()};return se.issue({credential:r,suite:new oe({key:n}),documentLoader:re})}async deserialize(t){let{credentialSubject:n,...r}=t,{"@context":i,...a}=n;e(`subject`,Ne(this.subjectClass),a),Object.assign(this.envelope,Pe(this.envelopeClass,r)),Object.assign(this.subject,Pe(this.subjectClass,n))}ownFields(t,n,r){let i=new Set(D(n).map(({property:e})=>e)),a=k(n).filter(e=>!i.has(e));return e(t,new Set(a),r),Fe(n,r)}get contexts(){return this.constructor}setMissingFields(){this.envelope.level??=this.level()}};function F(e,t,n,r){var i=arguments.length,a=i<3?t:r===null?r=Object.getOwnPropertyDescriptor(t,n):r,o;if(typeof Reflect==`object`&&typeof Reflect.decorate==`function`)a=Reflect.decorate(e,t,n,r);else for(var s=e.length-1;s>=0;s--)(o=e[s])&&(a=(i<3?o(a):i>3?o(t,n,a):o(t,n))||a);return i>3&&a&&Object.defineProperty(t,n,a),a}var I=class{id;level;approvedAt};F([v()],I.prototype,`id`,void 0),F([v()],I.prototype,`level`,void 0),F([_(),M()],I.prototype,`approvedAt`,void 0);var L=class extends I{kycLevel;issued;expirationDate};F([_(),he(),ge()],L.prototype,`kycLevel`,void 0),F([_(),M()],L.prototype,`issued`,void 0),F([_(),M()],L.prototype,`expirationDate`,void 0);var R=class{occupation;sourceOfFundsCategory;sourceOfFundsProofFile};F([_(),m(S)],R.prototype,`occupation`,void 0),F([_(),v()],R.prototype,`sourceOfFundsCategory`,void 0),F([_(),N()],R.prototype,`sourceOfFundsProofFile`,void 0);var z=class{id;edd};F([v()],z.prototype,`id`,void 0),F([E(()=>R),fe()],z.prototype,`edd`,void 0);var Ve=class extends P{static envelopeContext=c;static subjectContext=ee;constructor(){super(I,z)}level(){return`edd`}publicNotes(){return{type:`edd`,level:this.level()}}},He=class{faceSignUserId};F([v()],He.prototype,`faceSignUserId`,void 0);var Ue=class extends P{static envelopeContext=c;static subjectContext=o;constructor(){super(I,He)}level(){return`human`}publicNotes(){return{type:`pop`,level:this.level()}}},B=class{country;number;type;dateOfIssue;dateOfExpiry;frontFile;backFile};F([_(),p()],B.prototype,`country`,void 0),F([_(),v()],B.prototype,`number`,void 0),F([_(),v()],B.prototype,`type`,void 0),F([_(),M()],B.prototype,`dateOfIssue`,void 0),F([_(),M()],B.prototype,`dateOfExpiry`,void 0),F([_(),N()],B.prototype,`frontFile`,void 0),F([_(),N()],B.prototype,`backFile`,void 0);var V=class{street;houseNumber;additionalAddressInfo;region;city;postalCode;country;proofCategory;proofDateOfIssue;proofFile};F([_(),v()],V.prototype,`street`,void 0),F([_(),v()],V.prototype,`houseNumber`,void 0),F([_(),v()],V.prototype,`additionalAddressInfo`,void 0),F([_(),v()],V.prototype,`region`,void 0),F([_(),v()],V.prototype,`city`,void 0),F([_(),v()],V.prototype,`postalCode`,void 0),F([_(),p()],V.prototype,`country`,void 0),F([_(),v()],V.prototype,`proofCategory`,void 0),F([_(),M()],V.prototype,`proofDateOfIssue`,void 0),F([_(),N()],V.prototype,`proofFile`,void 0);var H=class{id;applicantId;inquiryId;firstName;middleName;nationality;familyName;maidenName;gender;governmentId;governmentIdType;email;ssn;phoneNumber;dateOfBirth;placeOfBirth;selfieFile;idDocument;residentialAddress};F([v()],H.prototype,`id`,void 0),F([_(),v()],H.prototype,`applicantId`,void 0),F([_(),v()],H.prototype,`inquiryId`,void 0),F([_(),v()],H.prototype,`firstName`,void 0),F([_(),v()],H.prototype,`middleName`,void 0),F([_(),p()],H.prototype,`nationality`,void 0),F([_(),v()],H.prototype,`familyName`,void 0),F([_(),v()],H.prototype,`maidenName`,void 0),F([_(),v()],H.prototype,`gender`,void 0),F([_(),v()],H.prototype,`governmentId`,void 0),F([_(),v()],H.prototype,`governmentIdType`,void 0),F([_(),f()],H.prototype,`email`,void 0),F([_(),v()],H.prototype,`ssn`,void 0),F([_(),v()],H.prototype,`phoneNumber`,void 0),F([_(),M()],H.prototype,`dateOfBirth`,void 0),F([_(),v()],H.prototype,`placeOfBirth`,void 0),F([_(),N()],H.prototype,`selfieFile`,void 0),F([E(()=>B),_()],H.prototype,`idDocument`,void 0),F([E(()=>V),_()],H.prototype,`residentialAddress`,void 0);var We=class extends P{static envelopeContext=c;static subjectContext=i;constructor(){super(I,H)}level(){let{residentialAddress:e,selfieFile:t,email:n,phoneNumber:r}=this.subject;return[e?.proofFile&&e.city&&e.proofCategory&&e.country?`plus`:`basic`,...[t&&`liveness`,n&&`email`,r&&`phoneNumber`].filter(Boolean)].join(`+`)}publicNotes(){return{type:`kyc`,level:this.level()}}},U=class{id;firstName;middleName;nationality;familyName;maidenName;gender;email;phoneNumber;ssn;dateOfBirth;placeOfBirth;selfieFile;idDocument;residentialAddress};F([v()],U.prototype,`id`,void 0),F([_(),v()],U.prototype,`firstName`,void 0),F([_(),v()],U.prototype,`middleName`,void 0),F([_(),p()],U.prototype,`nationality`,void 0),F([_(),v()],U.prototype,`familyName`,void 0),F([_(),v()],U.prototype,`maidenName`,void 0),F([_(),v()],U.prototype,`gender`,void 0),F([_(),f()],U.prototype,`email`,void 0),F([_(),v()],U.prototype,`phoneNumber`,void 0),F([_(),v()],U.prototype,`ssn`,void 0),F([_(),M()],U.prototype,`dateOfBirth`,void 0),F([_(),v()],U.prototype,`placeOfBirth`,void 0),F([_(),N()],U.prototype,`selfieFile`,void 0),F([E(()=>B),_()],U.prototype,`idDocument`,void 0),F([E(()=>V),_()],U.prototype,`residentialAddress`,void 0);var Ge=class extends P{static envelopeContext=l;static subjectContext=te;constructor(){super(L,U)}level(){let{residentialAddress:e,selfieFile:t,email:n,phoneNumber:r}=this.subject;return[e?.proofFile&&e.city&&e.proofCategory&&e.country?`plus`:`basic`,...[t&&`liveness`,n&&`email`,r&&`phoneNumber`].filter(Boolean)].join(`+`)}publicNotes(){return{type:`kyc`,level:this.level()}}},W=class{selfieFile;selfieMatch};F([N()],W.prototype,`selfieFile`,void 0),F([_(),g()],W.prototype,`selfieMatch`,void 0);var G=class{email;phoneNumber};F([_(),f()],G.prototype,`email`,void 0),F([_(),v()],G.prototype,`phoneNumber`,void 0);var K=class{occupation;sourceOfFundsCategory;sourceOfFundsProofFile;sourceOfFundsProofFileType;sourceOfFundsProofFileName};F([_(),m(S)],K.prototype,`occupation`,void 0),F([_(),v()],K.prototype,`sourceOfFundsCategory`,void 0),F([_(),N()],K.prototype,`sourceOfFundsProofFile`,void 0),F([j(e=>!!e.sourceOfFundsProofFile),v(),h()],K.prototype,`sourceOfFundsProofFileType`,void 0),F([j(e=>!!e.sourceOfFundsProofFile),v()],K.prototype,`sourceOfFundsProofFileName`,void 0);var q=class{type;number;country;dateOfExpiry;dateOfIssue;issuingAuthority;frontFile;frontFileType;frontFileName;backFile;backFileType;backFileName;mrzLine1;title;extendedValidUntil;additionalNumber;ethnicity;issuingSubdivision};F([m(we)],q.prototype,`type`,void 0),F([y(1,255)],q.prototype,`number`,void 0),F([p()],q.prototype,`country`,void 0),F([_(),M()],q.prototype,`dateOfExpiry`,void 0),F([_(),M()],q.prototype,`dateOfIssue`,void 0),F([_(),y(1,255)],q.prototype,`issuingAuthority`,void 0),F([N()],q.prototype,`frontFile`,void 0),F([v(),h()],q.prototype,`frontFileType`,void 0),F([v()],q.prototype,`frontFileName`,void 0),F([_(),N()],q.prototype,`backFile`,void 0),F([j(e=>!!e.backFile),v(),h()],q.prototype,`backFileType`,void 0),F([j(e=>!!e.backFile),v()],q.prototype,`backFileName`,void 0),F([_(),y(1,255)],q.prototype,`mrzLine1`,void 0),F([_(),y(1,255)],q.prototype,`title`,void 0),F([_(),M()],q.prototype,`extendedValidUntil`,void 0),F([_(),y(1,255)],q.prototype,`additionalNumber`,void 0),F([_(),y(1,255)],q.prototype,`ethnicity`,void 0),F([_(),y(1,255)],q.prototype,`issuingSubdivision`,void 0);var J=class{intendedUse;employmentStatus;expectedMonthlyTransactionCount;expectedMonthlyTransactionVolume;expectedMonthlyTransactionVolumeCurrency};F([m(Ce)],J.prototype,`intendedUse`,void 0),F([m(Ee)],J.prototype,`employmentStatus`,void 0),F([m(De)],J.prototype,`expectedMonthlyTransactionCount`,void 0),F([m(Oe)],J.prototype,`expectedMonthlyTransactionVolume`,void 0),F([m(C)],J.prototype,`expectedMonthlyTransactionVolumeCurrency`,void 0);var Y=class{firstName;familyName;middleName;fatherName;maidenName;motherName;gender;nationality;secondNationality;dateOfBirth;placeOfBirth;regionOfBirth;stateless;refugeeStatus;subsidiaryProtectionStatus;nationalIdNumber;taxIdNumber;taxIdIssuingCountry;taxResidenceCountry;ssn};F([O(),j(e=>!e.familyName),v()],Y.prototype,`firstName`,void 0),F([O(),_(),v()],Y.prototype,`familyName`,void 0),F([O(),_(),v()],Y.prototype,`middleName`,void 0),F([O(),_(),v()],Y.prototype,`fatherName`,void 0),F([O(),_(),v()],Y.prototype,`maidenName`,void 0),F([O(),_(),v()],Y.prototype,`motherName`,void 0),F([_(),m(Te)],Y.prototype,`gender`,void 0),F([j(e=>!e.stateless&&!e.secondNationality),p()],Y.prototype,`nationality`,void 0),F([_(),p()],Y.prototype,`secondNationality`,void 0),F([M()],Y.prototype,`dateOfBirth`,void 0),F([_(),v()],Y.prototype,`placeOfBirth`,void 0),F([_(),v()],Y.prototype,`regionOfBirth`,void 0),F([_(),d()],Y.prototype,`stateless`,void 0),F([_(),d()],Y.prototype,`refugeeStatus`,void 0),F([_(),d()],Y.prototype,`subsidiaryProtectionStatus`,void 0),F([_(),v()],Y.prototype,`nationalIdNumber`,void 0),F([_(),v()],Y.prototype,`taxIdNumber`,void 0),F([_(),p()],Y.prototype,`taxIdIssuingCountry`,void 0),F([_(),p()],Y.prototype,`taxResidenceCountry`,void 0),F([_(),v()],Y.prototype,`ssn`,void 0);var X=class{source;street;houseNumber;additionalAddressInfo;region;city;postalCode;country;proofCategory;proofDateOfIssue;proofFile;proofFileType;proofFileName;ipCountry};F([pe(b)],X.prototype,`source`,void 0),F([O(),v()],X.prototype,`street`,void 0),F([_(),v()],X.prototype,`houseNumber`,void 0),F([O(),_(),v()],X.prototype,`additionalAddressInfo`,void 0),F([O(),_(),v()],X.prototype,`region`,void 0),F([O(),v()],X.prototype,`city`,void 0),F([_(),v()],X.prototype,`postalCode`,void 0),F([p()],X.prototype,`country`,void 0),F([j(e=>e.source===`PROOF_OF_ADDRESS`),v()],X.prototype,`proofCategory`,void 0),F([_(),M()],X.prototype,`proofDateOfIssue`,void 0),F([j(e=>e.source===`PROOF_OF_ADDRESS`),N()],X.prototype,`proofFile`,void 0),F([j(e=>e.source===`PROOF_OF_ADDRESS`),v(),h()],X.prototype,`proofFileType`,void 0),F([j(e=>e.source===`PROOF_OF_ADDRESS`),v()],X.prototype,`proofFileName`,void 0),F([_(),p()],X.prototype,`ipCountry`,void 0);var Z=class{sanctionsCheckResult;sanctionsConfidenceScore;pepCheckResult;pepConfidenceScore};F([m(x)],Z.prototype,`sanctionsCheckResult`,void 0),F([_(),g(),ve(0),_e(100)],Z.prototype,`sanctionsConfidenceScore`,void 0),F([m(x)],Z.prototype,`pepCheckResult`,void 0),F([_(),g(),ve(0),_e(100)],Z.prototype,`pepConfidenceScore`,void 0);var Q=class{type;yearlyGrossIncome;yearlyGrossIncomeCurrency;approximateNetWorth;approximateNetWorthCurrency;sourceOfWealthProofFile};F([m(ke)],Q.prototype,`type`,void 0),F([_(),m(Ae)],Q.prototype,`yearlyGrossIncome`,void 0),F([Re(`yearlyGrossIncome`),m(C)],Q.prototype,`yearlyGrossIncomeCurrency`,void 0),F([_(),m(je)],Q.prototype,`approximateNetWorth`,void 0),F([Re(`approximateNetWorth`),m(C)],Q.prototype,`approximateNetWorthCurrency`,void 0),F([_(),N()],Q.prototype,`sourceOfWealthProofFile`,void 0);var $=class{id;person;idDocument;contact;biometric;residentialAddress;screening;edd;sourceOfWealth;onboarding};F([v()],$.prototype,`id`,void 0),F([E(()=>Y),fe()],$.prototype,`person`,void 0),F([E(()=>q),_()],$.prototype,`idDocument`,void 0),F([E(()=>G),_()],$.prototype,`contact`,void 0),F([E(()=>W),_()],$.prototype,`biometric`,void 0),F([E(()=>X),_()],$.prototype,`residentialAddress`,void 0),F([E(()=>Z),_()],$.prototype,`screening`,void 0),F([E(()=>K),_()],$.prototype,`edd`,void 0),F([E(()=>Q),_()],$.prototype,`sourceOfWealth`,void 0),F([E(()=>J),_()],$.prototype,`onboarding`,void 0);var Ke=class extends P{static envelopeContext=l;static subjectContext=a;constructor(){super(L,$)}level(){let{residentialAddress:e,biometric:t,contact:n,edd:r,sourceOfWealth:i,screening:a,onboarding:o,person:s,idDocument:c}=this.subject,l=`unverified`;s&&c&&(l=`basic`),l===`basic`&&e?.proofFile&&e.city&&e.proofCategory&&e.source===`PROOF_OF_ADDRESS`&&e.country&&(l=`plus`);let ee=[t?.selfieFile&&`liveness`,n?.email&&`email`,n?.phoneNumber&&`phoneNumber`,r&&`edd`,i&&`sow`,a&&`screening`,o&&`onboarding`].filter(Boolean);return[l,...ee].join(`+`)}kycLevel(){let{person:e,idDocument:t,biometric:n,residentialAddress:r,sourceOfWealth:i,onboarding:a}=this.subject,o=0;return n?.selfieFile&&e&&t&&(o=1),o>=1&&r?.proofFile&&r.source===`PROOF_OF_ADDRESS`&&(o=2),o>=2&&i&&a&&(o=3),o}publicNotes(){return{type:`kyc`,level:this.level(),kycLevel:this.kycLevel()}}setMissingFields(){super.setMissingFields(),this.envelope.kycLevel===void 0&&this.kycLevel()>0&&(this.envelope.kycLevel=this.kycLevel()),this.envelope.expirationDate??=this.subject.idDocument?.dateOfExpiry}};export{Ae as S,Ce as _,Ue as a,x as b,L as c,C as d,Ee as f,we as g,Te as h,We as i,P as l,Oe as m,$ as n,Ve as o,De as p,Ge as r,I as s,Ke as t,je as u,S as v,ke as x,b as y};
2
+ //# sourceMappingURL=schemas-9ZR7Wydc.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas-9ZR7Wydc.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\nimport { transliterateIcao, transliterateLatin } from \"../utils/transliterate\";\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 * Marks a string field kept in its original script (Cyrillic, umlauts, …) and adds two\n * read-only siblings, derived from it on every read and never serialized:\n *\n * - `<field>Icao`: ICAO 9303, as a passport's MRZ prints it; `undefined` for a script the\n * ICAO tables do not cover.\n * - `<field>Latin`: the conventional spelling, a promise because its tables load on first\n * use; the app supplies them through `registerTransliteration()`.\n *\n * TypeScript cannot see members a decorator adds, so declare both next to the field.\n */\nexport function Transliterate(): PropertyDecorator {\n return (target, propertyKey) => {\n const field = String(propertyKey);\n\n // On the prototype rather than the instance, so serialization, which reads own keys, skips them.\n Object.defineProperty(target, `${field}Icao`, {\n configurable: true,\n get(this: Record<string, unknown>) {\n const value = this[field];\n\n return typeof value === \"string\" ? transliterateIcao(value) : undefined;\n },\n });\n\n Object.defineProperty(target, `${field}Latin`, {\n configurable: true,\n get(this: Record<string, unknown>) {\n const value = this[field];\n if (typeof value !== \"string\") return Promise.resolve(undefined);\n\n const latin = transliterateLatin(value);\n // A read nobody awaits (a logger walking getters) must not crash Node with an unhandled rejection; awaiters still get the error.\n latin.catch(() => {});\n\n return latin;\n },\n });\n };\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, Transliterate } from \"../utils\";\n\nexport class Person {\n /* The person's first/given name(s) as on their identity document. */\n @Transliterate()\n @RequiredWhen((person: Person) => !person.familyName)\n @IsString()\n firstName?: string;\n declare readonly firstNameIcao?: string;\n declare readonly firstNameLatin?: Promise<string | undefined>;\n\n /* The person's family/last name as on their identity document. */\n @Transliterate()\n @IsOptional()\n @IsString()\n familyName?: string;\n declare readonly familyNameIcao?: string;\n declare readonly familyNameLatin?: Promise<string | undefined>;\n\n /* The person's middle name(s). */\n @Transliterate()\n @IsOptional()\n @IsString()\n middleName?: string;\n declare readonly middleNameIcao?: string;\n declare readonly middleNameLatin?: Promise<string | undefined>;\n\n /* The person's father's name / patronymic — required in some jurisdictions (e.g. Greece). */\n @Transliterate()\n @IsOptional()\n @IsString()\n fatherName?: string;\n declare readonly fatherNameIcao?: string;\n declare readonly fatherNameLatin?: Promise<string | undefined>;\n\n /* The person's maiden name (family name before marriage). */\n @Transliterate()\n @IsOptional()\n @IsString()\n maidenName?: string;\n declare readonly maidenNameIcao?: string;\n declare readonly maidenNameLatin?: Promise<string | undefined>;\n\n /* The person's mother's birth name — required in some jurisdictions (e.g. Hungary). */\n @Transliterate()\n @IsOptional()\n @IsString()\n motherName?: string;\n declare readonly motherNameIcao?: string;\n declare readonly motherNameLatin?: Promise<string | undefined>;\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, Transliterate } 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 @Transliterate()\n @IsString()\n street: string;\n declare readonly streetIcao?: string;\n declare readonly streetLatin?: Promise<string | undefined>;\n\n /* House number. */\n @IsOptional()\n @IsString()\n houseNumber?: string;\n\n /* Additional address information (e.g. apartment number). */\n @Transliterate()\n @IsOptional()\n @IsString()\n additionalAddressInfo?: string;\n declare readonly additionalAddressInfoIcao?: string;\n declare readonly additionalAddressInfoLatin?: Promise<string | undefined>;\n\n /* Region (e.g. state, province). */\n @Transliterate()\n @IsOptional()\n @IsString()\n region?: string;\n declare readonly regionIcao?: string;\n declare readonly regionLatin?: Promise<string | undefined>;\n\n /* Locality (e.g. city, town). */\n @Transliterate()\n @IsString()\n city: string;\n declare readonly cityIcao?: string;\n declare readonly cityLatin?: Promise<string | undefined>;\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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"}
@@ -3,6 +3,36 @@ import { Ed25519VerificationKey2020 } from "@digitalbazaar/ed25519-verification-
3
3
  //#region src/utils/issuer.d.ts
4
4
  export declare function issuerToKey(issuer: AvailableIssuerType): Promise<Ed25519VerificationKey2020>;
5
5
  //#endregion
6
+ //#region src/utils/transliterate.d.ts
7
+ /**
8
+ * Transliterates `value` to ASCII Latin per ICAO 9303, keeping its letter case (`Жанна` ->
9
+ * `Zhanna`, `Müller` -> `Mueller`). Returns `undefined` when a character has no transliteration,
10
+ * rather than a half-Latin string.
11
+ *
12
+ * shortcut: Latin and Cyrillic only; Greek, Arabic, CJK and others yield `undefined`, add their
13
+ * tables when a credential needs them.
14
+ */
15
+ export declare function transliterateIcao(value: string): string | undefined;
16
+ type TransliterationLoader = () => Promise<{
17
+ transliterate: (value: string) => string;
18
+ }>;
19
+ /**
20
+ * Hands this package the `transliteration` library that `<field>Latin` reads. It is an
21
+ * optional peer dependency this package never imports itself: its tables are ~55 KB gzipped,
22
+ * and an import here would fail the build of every app that has not installed it. The app
23
+ * owns the import, so its bundler splits the tables into a chunk loaded on first use:
24
+ *
25
+ * ```ts
26
+ * registerTransliteration(() => import("transliteration"));
27
+ * ```
28
+ */
29
+ export declare function registerTransliteration(load: TransliterationLoader): void;
30
+ /**
31
+ * Transliterates `value` to the conventional Latin spelling a reader expects (`Юлия` ->
32
+ * `Yuliya`), covering nearly every script. Needs `registerTransliteration()` first.
33
+ */
34
+ export declare function transliterateLatin(value: string): Promise<string>;
35
+ //#endregion
6
36
  //#region src/utils/index.d.ts
7
37
  export type BaseLevel = "unverified" | "basic" | "plus";
8
38
  export type Addon = "liveness" | "email" | "phoneNumber" | "edd" | "sow" | "screening" | "onboarding";
@@ -1 +1 @@
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
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/utils/issuer.ts","../../src/utils/transliterate.ts","../../src/utils/index.ts"],"mappings":";;;wBAuBsB,YACpB,QAAQ,sBACP,QAAQ;;;;;;;;;;;wBC0EK,kBAAkB;KAQ7B,8BAA8B;EAAU,gBAAgB;;;;;;;;;;;;wBAc7C,wBAAwB,MAAM;;;;;wBAQxB,mBAAmB,gBAAgB;;;YCrH7C;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,2 +1,2 @@
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};
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`})}const f={Ä:`AE`,Å:`AA`,Æ:`AE`,Ð:`D`,Ö:`OE`,Ø:`OE`,Ü:`UE`,Þ:`TH`,ß:`SS`,ẞ:`SS`,Đ:`D`,Ħ:`H`,IJ:`IJ`,Ŀ:`L`,Ł:`L`,Ŋ:`N`,Œ:`OE`,Ŧ:`T`,А:`A`,Б:`B`,В:`V`,Г:`G`,Д:`D`,Е:`E`,Ё:`E`,Ж:`ZH`,З:`Z`,И:`I`,Й:`I`,К:`K`,Л:`L`,М:`M`,Н:`N`,О:`O`,П:`P`,Р:`R`,С:`S`,Т:`T`,У:`U`,Ф:`F`,Х:`KH`,Ц:`TS`,Ч:`CH`,Ш:`SH`,Щ:`SHCH`,Ъ:`IE`,Ы:`Y`,Ь:``,Э:`E`,Ю:`IU`,Я:`IA`,Ђ:`D`,Ѓ:`G`,Є:`IE`,Ѕ:`DZ`,І:`I`,Ї:`I`,Ј:`J`,Љ:`LJ`,Њ:`NJ`,Ћ:`C`,Ќ:`K`,Ў:`U`,Џ:`DZ`,Ґ:`G`};function p(e,t){let n=e.toUpperCase(),r=f[e]??f[n];return r===void 0?e.normalize(`NFD`).replace(/\p{M}/gu,``):e===n?t!==void 0&&t!==t.toUpperCase()?r.charAt(0)+r.slice(1).toLowerCase():r:r.toLowerCase()}function m(e){let t=[...e.normalize(`NFC`)],n=t.map((e,n)=>p(e,t[n+1])).join(``);return/^[\x00-\x7F]*$/.test(n)?n:void 0}let h;function g(e){h=e}async function _(e){if(!h)throw Error(`Latin transliteration needs the "transliteration" package: install it, then call registerTransliteration(() => import("transliteration")) from @idos-network/credentials/utils once at startup`);let{transliterate:t}=await h();return t(e)}function v(e){let[t,...n]=e.split(`+`);return{base:t,addons:n}}function y(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 b(e,t,n){let{base:r,addons:i}=v(n);return e===`basic`&&r===`unverified`||e===`plus`&&r!==`plus`?!1:t.every(e=>i.includes(e))}function x(e){let{base:t,addons:n}=v(e),r=0;return t===`basic`&&(r+=50),t===`plus`&&(r+=100),r+=n.length*10,r}function S(e,t,n){return e.filter(e=>b(t,n,e)).sort((e,t)=>{let n=x(e);return x(t)-n})[0]??null}function C(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||!b(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 x(r)-x(n)}).map(({credential:e})=>e)[0]}function w(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 T(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 E(e,t){return T(e,t,s.sign.keyPair().secretKey)}function D(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 O({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=T(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{y as assertNoExtraFields,E as buildEphemeralSignedCredentialContentReference,O as buildPreliminaryIDOSCredential,T as buildSignedCredentialContentReference,C as highestMatchingCredential,d as issuerToKey,x as levelScore,D as mapPreliminaryToIDOSCredential,b as matchLevelOrHigher,v as parseLevel,S as pickHighestMatchingLevel,w as recordFilter,g as registerTransliteration,m as transliterateIcao,_ as transliterateLatin};
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/utils/issuer.ts","../../src/utils/index.ts"],"sourcesContent":["import { Ed25519VerificationKey2020 } from \"@digitalbazaar/ed25519-verification-key-2020\";\n\nimport type { AvailableIssuerType, CustomIssuerType } from \"../types\";\n\nfunction isIssuerKey(issuer: AvailableIssuerType): issuer is Ed25519VerificationKey2020 {\n return (\n typeof issuer === \"object\" &&\n issuer !== null &&\n \"type\" in issuer &&\n \"id\" in issuer &&\n \"controller\" in issuer\n );\n}\n\nfunction isCustomIssuerType(issuer: AvailableIssuerType): issuer is CustomIssuerType {\n return (\n typeof issuer === \"object\" &&\n issuer !== null &&\n \"issuer\" in issuer &&\n \"publicKeyMultibase\" in issuer\n );\n}\n\nexport async function issuerToKey(\n issuer: AvailableIssuerType,\n): Promise<Ed25519VerificationKey2020> {\n if (isIssuerKey(issuer)) {\n return issuer;\n }\n\n if (isCustomIssuerType(issuer)) {\n return await Ed25519VerificationKey2020.from({\n id: `${issuer.issuer}/keys/1`,\n controller: `${issuer.issuer}/issuers/1`,\n publicKeyMultibase: issuer.publicKeyMultibase,\n privateKeyMultibase: issuer.privateKeyMultibase,\n type: \"Ed25519VerificationKey2020\",\n });\n }\n\n return await Ed25519VerificationKey2020.from({ ...issuer, type: \"Ed25519VerificationKey2020\" });\n}\n","import { createBlobContentReference } from \"@idos-network/utils/blob-gateway\";\nimport { base64Encode, hexEncode, utf8Encode } from \"@idos-network/utils/codecs\";\nimport { encryptContent } from \"@idos-network/utils/cryptography\";\nimport { every, get } from \"es-toolkit/compat\";\nimport nacl from \"tweetnacl\";\n\nimport type { idOSCredential, SignedCredentialContentReference } from \"../types\";\n\n// Proxying functions\nexport * from \"./issuer\";\n\nexport type BaseLevel = \"unverified\" | \"basic\" | \"plus\";\nexport type Addon =\n | \"liveness\"\n | \"email\"\n | \"phoneNumber\"\n | \"edd\"\n | \"sow\"\n | \"screening\"\n | \"onboarding\";\n\nexport function parseLevel(level: string): {\n base: BaseLevel;\n addons: Addon[];\n} {\n const [base, ...addons] = level.split(\"+\") as [BaseLevel, ...Addon[]];\n return { base, addons };\n}\n\nexport function assertNoExtraFields(\n section: string,\n expectedFields: ReadonlySet<string>,\n value: object | undefined,\n): void {\n const extraFields = Object.keys(value ?? {}).filter((field) => !expectedFields.has(field));\n\n if (extraFields.length > 0) {\n throw new Error(`Unexpected ${section} fields: ${extraFields.join(\", \")}`);\n }\n}\n\nexport function matchLevelOrHigher(\n level: BaseLevel,\n requiredAddons: Addon[],\n currentLevel: string,\n): boolean {\n const { base: currentBaseLevel, addons: currentAddons } = parseLevel(currentLevel);\n\n // Basic can only match basic or plus not unverified\n if (level === \"basic\" && currentBaseLevel === \"unverified\") {\n return false;\n }\n\n // Plus can only match plus\n if (level === \"plus\" && currentBaseLevel !== \"plus\") {\n return false;\n }\n\n return requiredAddons.every((addon) => currentAddons.includes(addon));\n}\n\nexport function levelScore(level: string): number {\n const { base, addons } = parseLevel(level);\n let score = 0;\n\n if (base === \"basic\") {\n score += 50;\n }\n\n if (base === \"plus\") {\n score += 100;\n }\n\n score += addons.length * 10;\n\n return score;\n}\n\nexport function pickHighestMatchingLevel(\n levels: string[],\n requiredLevel: BaseLevel,\n requiredAddons: Addon[],\n): string | null {\n return (\n levels\n .filter((currentLevel) => matchLevelOrHigher(requiredLevel, requiredAddons, currentLevel))\n .sort((a, b) => {\n const aAddons = levelScore(a);\n const bAddons = levelScore(b);\n return bAddons - aAddons; // descending\n })[0] ?? null\n );\n}\n\nexport function highestMatchingCredential<K extends { public_notes: string }>(\n credentials: K[],\n requiredLevel: BaseLevel,\n {\n addons: requiredAddons = [],\n publicNotesConstraint = {},\n }: {\n addons?: Addon[];\n publicNotesConstraint?: Record<string, number | string>;\n },\n): K | undefined {\n const matchingCredentials = credentials\n .map((credential) => {\n const publicNotes = JSON.parse(credential.public_notes || \"{}\");\n return {\n credential,\n publicNotes,\n };\n })\n .filter(({ publicNotes }) => {\n const level = publicNotes.level;\n\n if (!level) {\n return false;\n }\n\n if (!matchLevelOrHigher(requiredLevel, requiredAddons, level)) {\n return false;\n }\n\n for (const key in publicNotesConstraint) {\n if (publicNotes[key] !== publicNotesConstraint[key]) {\n return false;\n }\n }\n\n return true;\n })\n .sort((a, b) => {\n const aLevel = a.publicNotes.level;\n const bLevel = b.publicNotes.level;\n return levelScore(bLevel) - levelScore(aLevel); // descending\n })\n .map(({ credential }) => credential);\n\n return matchingCredentials[0];\n}\n\nexport function recordFilter(\n rec: Record<string, unknown>,\n pick: Record<string, unknown[]>,\n omit: Record<string, unknown[]>,\n): boolean {\n const matchCriteria = (content: Record<string, unknown>, criteria: Record<string, unknown[]>) =>\n every(Object.entries(criteria), ([path, targetSet]) => targetSet.includes(get(content, path)));\n\n if (Object.keys(pick).length > 0 && !matchCriteria(rec, pick)) {\n // Fast fail on pick criteria\n return false;\n }\n\n if (Object.keys(omit).length > 0 && matchCriteria(rec, omit)) {\n // Fast fail on omit criteria\n return false;\n }\n\n return true;\n}\n\nexport function buildSignedCredentialContentReference(\n publicNotes: string,\n contentUri: string,\n issuerSigningSecretKey: Uint8Array,\n): SignedCredentialContentReference {\n const { publicKey, secretKey } = nacl.sign.keyPair.fromSecretKey(issuerSigningSecretKey);\n\n const publicNotesSignature = nacl.sign.detached(utf8Encode(publicNotes), secretKey);\n\n return {\n public_notes: publicNotes,\n public_notes_signature: base64Encode(publicNotesSignature),\n\n broader_signature: base64Encode(\n nacl.sign.detached(\n Uint8Array.from([...publicNotesSignature, ...utf8Encode(contentUri)]),\n secretKey,\n ),\n ),\n\n issuer_auth_public_key: hexEncode(publicKey, true),\n };\n}\n\n/** User-issued share copy: sign with a fresh ephemeral key (need not match original issuer). */\nexport function buildEphemeralSignedCredentialContentReference(\n publicNotes: string,\n contentUri: string,\n): SignedCredentialContentReference {\n return buildSignedCredentialContentReference(\n publicNotes,\n contentUri,\n nacl.sign.keyPair().secretKey,\n );\n}\n\nexport type PreliminaryIDOSCredential = {\n id: string;\n contentUri: string;\n contentSize: number;\n encryptedContent: Uint8Array;\n publicNotes: string;\n publicNotesSignature: string;\n broaderSignature: string;\n issuerAuthPublicKey: string;\n encryptorPublicKey: string;\n};\n\nexport function mapPreliminaryToIDOSCredential(\n preliminaryCredential: PreliminaryIDOSCredential,\n): Omit<idOSCredential, \"user_id\"> {\n return {\n id: preliminaryCredential.id,\n content_uri: preliminaryCredential.contentUri,\n content_size: preliminaryCredential.contentSize,\n public_notes: preliminaryCredential.publicNotes,\n issuer_auth_public_key: preliminaryCredential.issuerAuthPublicKey,\n encryptor_public_key: preliminaryCredential.encryptorPublicKey,\n };\n}\n\nexport interface BuildPreliminaryIDOSCredentialArgs {\n publicNotes: string;\n plaintextContent: Uint8Array;\n recipientEncryptionPublicKey: Uint8Array;\n issuerSigningSecretKey?: Uint8Array;\n /** When set (MM / `ukyc://`), skip IPFS CID hashing. */\n contentUri?: string;\n}\n\nexport async function buildPreliminaryIDOSCredential({\n publicNotes,\n plaintextContent,\n recipientEncryptionPublicKey,\n // For user-issued credentials, use a fresh ephemeral key for the signed reference\n // For issuer-side, use the signing key pair\n issuerSigningSecretKey = nacl.sign.keyPair().secretKey,\n contentUri,\n}: BuildPreliminaryIDOSCredentialArgs): Promise<Omit<PreliminaryIDOSCredential, \"id\">> {\n const ephemeralKeyPair = nacl.box.keyPair();\n const encryptedContent = encryptContent(\n plaintextContent,\n recipientEncryptionPublicKey, // user or dwg recipient\n ephemeralKeyPair.secretKey,\n );\n\n const contentReference = contentUri\n ? { uri: contentUri, size: encryptedContent.byteLength }\n : await createBlobContentReference(encryptedContent);\n const signedReference = buildSignedCredentialContentReference(\n publicNotes,\n contentReference.uri,\n issuerSigningSecretKey,\n );\n\n return {\n contentUri: contentReference.uri,\n contentSize: contentReference.size,\n encryptedContent,\n publicNotes,\n publicNotesSignature: signedReference.public_notes_signature,\n broaderSignature: signedReference.broader_signature,\n issuerAuthPublicKey: signedReference.issuer_auth_public_key,\n encryptorPublicKey: base64Encode(ephemeralKeyPair.publicKey),\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/utils/issuer.ts","../../src/utils/transliterate.ts","../../src/utils/index.ts"],"sourcesContent":["import { Ed25519VerificationKey2020 } from \"@digitalbazaar/ed25519-verification-key-2020\";\n\nimport type { AvailableIssuerType, CustomIssuerType } from \"../types\";\n\nfunction isIssuerKey(issuer: AvailableIssuerType): issuer is Ed25519VerificationKey2020 {\n return (\n typeof issuer === \"object\" &&\n issuer !== null &&\n \"type\" in issuer &&\n \"id\" in issuer &&\n \"controller\" in issuer\n );\n}\n\nfunction isCustomIssuerType(issuer: AvailableIssuerType): issuer is CustomIssuerType {\n return (\n typeof issuer === \"object\" &&\n issuer !== null &&\n \"issuer\" in issuer &&\n \"publicKeyMultibase\" in issuer\n );\n}\n\nexport async function issuerToKey(\n issuer: AvailableIssuerType,\n): Promise<Ed25519VerificationKey2020> {\n if (isIssuerKey(issuer)) {\n return issuer;\n }\n\n if (isCustomIssuerType(issuer)) {\n return await Ed25519VerificationKey2020.from({\n id: `${issuer.issuer}/keys/1`,\n controller: `${issuer.issuer}/issuers/1`,\n publicKeyMultibase: issuer.publicKeyMultibase,\n privateKeyMultibase: issuer.privateKeyMultibase,\n type: \"Ed25519VerificationKey2020\",\n });\n }\n\n return await Ed25519VerificationKey2020.from({ ...issuer, type: \"Ed25519VerificationKey2020\" });\n}\n","// cspell:disable -- transliteration table and examples of names in other scripts\n/*\n * ICAO Doc 9303 Part 3, section 6: the transliteration passports print in their Latin fields\n * and MRZ, so a name comes out the way the document itself spells it. Keys are uppercase; a\n * Latin letter missing here just loses its diacritics (Č -> C), as the standard prescribes.\n */\nconst ICAO: Record<string, string> = {\n // Latin letters with a transliteration of their own (Table A).\n Ä: \"AE\",\n Å: \"AA\",\n Æ: \"AE\",\n Ð: \"D\",\n Ö: \"OE\",\n Ø: \"OE\",\n Ü: \"UE\",\n Þ: \"TH\",\n ß: \"SS\",\n ẞ: \"SS\",\n Đ: \"D\",\n Ħ: \"H\",\n IJ: \"IJ\",\n Ŀ: \"L\",\n Ł: \"L\",\n Ŋ: \"N\",\n Œ: \"OE\",\n Ŧ: \"T\",\n\n // Cyrillic (Table B).\n А: \"A\",\n Б: \"B\",\n В: \"V\",\n Г: \"G\",\n Д: \"D\",\n Е: \"E\",\n Ё: \"E\",\n Ж: \"ZH\",\n З: \"Z\",\n И: \"I\",\n Й: \"I\",\n К: \"K\",\n Л: \"L\",\n М: \"M\",\n Н: \"N\",\n О: \"O\",\n П: \"P\",\n Р: \"R\",\n С: \"S\",\n Т: \"T\",\n У: \"U\",\n Ф: \"F\",\n Х: \"KH\",\n Ц: \"TS\",\n Ч: \"CH\",\n Ш: \"SH\",\n Щ: \"SHCH\",\n Ъ: \"IE\",\n Ы: \"Y\",\n Ь: \"\",\n Э: \"E\",\n Ю: \"IU\",\n Я: \"IA\",\n Ђ: \"D\",\n Ѓ: \"G\",\n Є: \"IE\",\n Ѕ: \"DZ\",\n І: \"I\",\n Ї: \"I\",\n Ј: \"J\",\n Љ: \"LJ\",\n Њ: \"NJ\",\n Ћ: \"C\",\n Ќ: \"K\",\n Ў: \"U\",\n Џ: \"DZ\",\n Ґ: \"G\",\n};\n\nfunction transliterateChar(char: string, next: string | undefined): string {\n const upper = char.toUpperCase();\n // `ß` is looked up as itself: its uppercase is the two letters `SS`.\n const latin = ICAO[char] ?? ICAO[upper];\n\n if (latin === undefined) return char.normalize(\"NFD\").replace(/\\p{M}/gu, \"\");\n if (char !== upper) return latin.toLowerCase();\n\n // A capital opening a lowercase word reads `Zh`, one inside an all-caps word `ZH`.\n return next !== undefined && next !== next.toUpperCase()\n ? latin.charAt(0) + latin.slice(1).toLowerCase()\n : latin;\n}\n\n/**\n * Transliterates `value` to ASCII Latin per ICAO 9303, keeping its letter case (`Жанна` ->\n * `Zhanna`, `Müller` -> `Mueller`). Returns `undefined` when a character has no transliteration,\n * rather than a half-Latin string.\n *\n * shortcut: Latin and Cyrillic only; Greek, Arabic, CJK and others yield `undefined`, add their\n * tables when a credential needs them.\n */\nexport function transliterateIcao(value: string): string | undefined {\n const chars = [...value.normalize(\"NFC\")];\n const latin = chars.map((char, index) => transliterateChar(char, chars[index + 1])).join(\"\");\n\n // oxlint-disable-next-line no-control-regex\n return /^[\\x00-\\x7F]*$/.test(latin) ? latin : undefined;\n}\n\ntype TransliterationLoader = () => Promise<{ transliterate: (value: string) => string }>;\n\nlet loadLibrary: TransliterationLoader | undefined;\n\n/**\n * Hands this package the `transliteration` library that `<field>Latin` reads. It is an\n * optional peer dependency this package never imports itself: its tables are ~55 KB gzipped,\n * and an import here would fail the build of every app that has not installed it. The app\n * owns the import, so its bundler splits the tables into a chunk loaded on first use:\n *\n * ```ts\n * registerTransliteration(() => import(\"transliteration\"));\n * ```\n */\nexport function registerTransliteration(load: TransliterationLoader): void {\n loadLibrary = load;\n}\n\n/**\n * Transliterates `value` to the conventional Latin spelling a reader expects (`Юлия` ->\n * `Yuliya`), covering nearly every script. Needs `registerTransliteration()` first.\n */\nexport async function transliterateLatin(value: string): Promise<string> {\n if (!loadLibrary) {\n throw new Error(\n 'Latin transliteration needs the \"transliteration\" package: install it, then call registerTransliteration(() => import(\"transliteration\")) from @idos-network/credentials/utils once at startup',\n );\n }\n\n const { transliterate } = await loadLibrary();\n\n return transliterate(value);\n}\n","import { createBlobContentReference } from \"@idos-network/utils/blob-gateway\";\nimport { base64Encode, hexEncode, utf8Encode } from \"@idos-network/utils/codecs\";\nimport { encryptContent } from \"@idos-network/utils/cryptography\";\nimport { every, get } from \"es-toolkit/compat\";\nimport nacl from \"tweetnacl\";\n\nimport type { idOSCredential, SignedCredentialContentReference } from \"../types\";\n\n// Proxying functions\nexport * from \"./issuer\";\nexport * from \"./transliterate\";\n\nexport type BaseLevel = \"unverified\" | \"basic\" | \"plus\";\nexport type Addon =\n | \"liveness\"\n | \"email\"\n | \"phoneNumber\"\n | \"edd\"\n | \"sow\"\n | \"screening\"\n | \"onboarding\";\n\nexport function parseLevel(level: string): {\n base: BaseLevel;\n addons: Addon[];\n} {\n const [base, ...addons] = level.split(\"+\") as [BaseLevel, ...Addon[]];\n return { base, addons };\n}\n\nexport function assertNoExtraFields(\n section: string,\n expectedFields: ReadonlySet<string>,\n value: object | undefined,\n): void {\n const extraFields = Object.keys(value ?? {}).filter((field) => !expectedFields.has(field));\n\n if (extraFields.length > 0) {\n throw new Error(`Unexpected ${section} fields: ${extraFields.join(\", \")}`);\n }\n}\n\nexport function matchLevelOrHigher(\n level: BaseLevel,\n requiredAddons: Addon[],\n currentLevel: string,\n): boolean {\n const { base: currentBaseLevel, addons: currentAddons } = parseLevel(currentLevel);\n\n // Basic can only match basic or plus not unverified\n if (level === \"basic\" && currentBaseLevel === \"unverified\") {\n return false;\n }\n\n // Plus can only match plus\n if (level === \"plus\" && currentBaseLevel !== \"plus\") {\n return false;\n }\n\n return requiredAddons.every((addon) => currentAddons.includes(addon));\n}\n\nexport function levelScore(level: string): number {\n const { base, addons } = parseLevel(level);\n let score = 0;\n\n if (base === \"basic\") {\n score += 50;\n }\n\n if (base === \"plus\") {\n score += 100;\n }\n\n score += addons.length * 10;\n\n return score;\n}\n\nexport function pickHighestMatchingLevel(\n levels: string[],\n requiredLevel: BaseLevel,\n requiredAddons: Addon[],\n): string | null {\n return (\n levels\n .filter((currentLevel) => matchLevelOrHigher(requiredLevel, requiredAddons, currentLevel))\n .sort((a, b) => {\n const aAddons = levelScore(a);\n const bAddons = levelScore(b);\n return bAddons - aAddons; // descending\n })[0] ?? null\n );\n}\n\nexport function highestMatchingCredential<K extends { public_notes: string }>(\n credentials: K[],\n requiredLevel: BaseLevel,\n {\n addons: requiredAddons = [],\n publicNotesConstraint = {},\n }: {\n addons?: Addon[];\n publicNotesConstraint?: Record<string, number | string>;\n },\n): K | undefined {\n const matchingCredentials = credentials\n .map((credential) => {\n const publicNotes = JSON.parse(credential.public_notes || \"{}\");\n return {\n credential,\n publicNotes,\n };\n })\n .filter(({ publicNotes }) => {\n const level = publicNotes.level;\n\n if (!level) {\n return false;\n }\n\n if (!matchLevelOrHigher(requiredLevel, requiredAddons, level)) {\n return false;\n }\n\n for (const key in publicNotesConstraint) {\n if (publicNotes[key] !== publicNotesConstraint[key]) {\n return false;\n }\n }\n\n return true;\n })\n .sort((a, b) => {\n const aLevel = a.publicNotes.level;\n const bLevel = b.publicNotes.level;\n return levelScore(bLevel) - levelScore(aLevel); // descending\n })\n .map(({ credential }) => credential);\n\n return matchingCredentials[0];\n}\n\nexport function recordFilter(\n rec: Record<string, unknown>,\n pick: Record<string, unknown[]>,\n omit: Record<string, unknown[]>,\n): boolean {\n const matchCriteria = (content: Record<string, unknown>, criteria: Record<string, unknown[]>) =>\n every(Object.entries(criteria), ([path, targetSet]) => targetSet.includes(get(content, path)));\n\n if (Object.keys(pick).length > 0 && !matchCriteria(rec, pick)) {\n // Fast fail on pick criteria\n return false;\n }\n\n if (Object.keys(omit).length > 0 && matchCriteria(rec, omit)) {\n // Fast fail on omit criteria\n return false;\n }\n\n return true;\n}\n\nexport function buildSignedCredentialContentReference(\n publicNotes: string,\n contentUri: string,\n issuerSigningSecretKey: Uint8Array,\n): SignedCredentialContentReference {\n const { publicKey, secretKey } = nacl.sign.keyPair.fromSecretKey(issuerSigningSecretKey);\n\n const publicNotesSignature = nacl.sign.detached(utf8Encode(publicNotes), secretKey);\n\n return {\n public_notes: publicNotes,\n public_notes_signature: base64Encode(publicNotesSignature),\n\n broader_signature: base64Encode(\n nacl.sign.detached(\n Uint8Array.from([...publicNotesSignature, ...utf8Encode(contentUri)]),\n secretKey,\n ),\n ),\n\n issuer_auth_public_key: hexEncode(publicKey, true),\n };\n}\n\n/** User-issued share copy: sign with a fresh ephemeral key (need not match original issuer). */\nexport function buildEphemeralSignedCredentialContentReference(\n publicNotes: string,\n contentUri: string,\n): SignedCredentialContentReference {\n return buildSignedCredentialContentReference(\n publicNotes,\n contentUri,\n nacl.sign.keyPair().secretKey,\n );\n}\n\nexport type PreliminaryIDOSCredential = {\n id: string;\n contentUri: string;\n contentSize: number;\n encryptedContent: Uint8Array;\n publicNotes: string;\n publicNotesSignature: string;\n broaderSignature: string;\n issuerAuthPublicKey: string;\n encryptorPublicKey: string;\n};\n\nexport function mapPreliminaryToIDOSCredential(\n preliminaryCredential: PreliminaryIDOSCredential,\n): Omit<idOSCredential, \"user_id\"> {\n return {\n id: preliminaryCredential.id,\n content_uri: preliminaryCredential.contentUri,\n content_size: preliminaryCredential.contentSize,\n public_notes: preliminaryCredential.publicNotes,\n issuer_auth_public_key: preliminaryCredential.issuerAuthPublicKey,\n encryptor_public_key: preliminaryCredential.encryptorPublicKey,\n };\n}\n\nexport interface BuildPreliminaryIDOSCredentialArgs {\n publicNotes: string;\n plaintextContent: Uint8Array;\n recipientEncryptionPublicKey: Uint8Array;\n issuerSigningSecretKey?: Uint8Array;\n /** When set (MM / `ukyc://`), skip IPFS CID hashing. */\n contentUri?: string;\n}\n\nexport async function buildPreliminaryIDOSCredential({\n publicNotes,\n plaintextContent,\n recipientEncryptionPublicKey,\n // For user-issued credentials, use a fresh ephemeral key for the signed reference\n // For issuer-side, use the signing key pair\n issuerSigningSecretKey = nacl.sign.keyPair().secretKey,\n contentUri,\n}: BuildPreliminaryIDOSCredentialArgs): Promise<Omit<PreliminaryIDOSCredential, \"id\">> {\n const ephemeralKeyPair = nacl.box.keyPair();\n const encryptedContent = encryptContent(\n plaintextContent,\n recipientEncryptionPublicKey, // user or dwg recipient\n ephemeralKeyPair.secretKey,\n );\n\n const contentReference = contentUri\n ? { uri: contentUri, size: encryptedContent.byteLength }\n : await createBlobContentReference(encryptedContent);\n const signedReference = buildSignedCredentialContentReference(\n publicNotes,\n contentReference.uri,\n issuerSigningSecretKey,\n );\n\n return {\n contentUri: contentReference.uri,\n contentSize: contentReference.size,\n encryptedContent,\n publicNotes,\n publicNotesSignature: signedReference.public_notes_signature,\n broaderSignature: signedReference.broader_signature,\n issuerAuthPublicKey: signedReference.issuer_auth_public_key,\n encryptorPublicKey: base64Encode(ephemeralKeyPair.publicKey),\n };\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@idos-network/credentials",
3
- "version": "2.2.2",
3
+ "version": "2.3.0",
4
4
  "description": "idOS Credentials JavaScript SDK",
5
5
  "homepage": "https://idos.network",
6
6
  "license": "MIT",
@@ -53,7 +53,7 @@
53
53
  "@digitalbazaar/ed25519-signature-2020": "^5.4.0",
54
54
  "@digitalbazaar/ed25519-verification-key-2020": "^4.2.0",
55
55
  "@digitalbazaar/vc": "^7.3.0",
56
- "@idos-network/utils": "2.2.2",
56
+ "@idos-network/utils": "2.3.0",
57
57
  "class-transformer": "^0.5.1",
58
58
  "class-validator": "^0.15.1",
59
59
  "es-toolkit": "^1.50.0",
@@ -66,14 +66,21 @@
66
66
  "devDependencies": {
67
67
  "@types/node": "25.9.5",
68
68
  "@vitest/coverage-v8": "4.1.11",
69
+ "transliteration": "2.6.1",
69
70
  "tsdown": "^0.23.0",
70
71
  "typescript": "^5.9.3",
71
72
  "vitest": "4.1.11",
72
73
  "web-streams-polyfill": "3.3.3"
73
74
  },
74
75
  "peerDependencies": {
76
+ "transliteration": "^2.6.1",
75
77
  "typescript": "^5.9.3"
76
78
  },
79
+ "peerDependenciesMeta": {
80
+ "transliteration": {
81
+ "optional": true
82
+ }
83
+ },
77
84
  "engines": {
78
85
  "node": ">=22.19.0"
79
86
  },
@@ -1,38 +1,56 @@
1
1
  import { IsBoolean, IsIn, IsOptional, IsString, IsISO31661Alpha2 } from "class-validator";
2
2
 
3
3
  import { Genders, type Gender } from "../enums";
4
- import { IsoDateField, RequiredWhen } from "../utils";
4
+ import { IsoDateField, RequiredWhen, Transliterate } from "../utils";
5
5
 
6
6
  export class Person {
7
7
  /* The person's first/given name(s) as on their identity document. */
8
+ @Transliterate()
8
9
  @RequiredWhen((person: Person) => !person.familyName)
9
10
  @IsString()
10
11
  firstName?: string;
12
+ declare readonly firstNameIcao?: string;
13
+ declare readonly firstNameLatin?: Promise<string | undefined>;
11
14
 
12
15
  /* The person's family/last name as on their identity document. */
16
+ @Transliterate()
13
17
  @IsOptional()
14
18
  @IsString()
15
19
  familyName?: string;
20
+ declare readonly familyNameIcao?: string;
21
+ declare readonly familyNameLatin?: Promise<string | undefined>;
16
22
 
17
23
  /* The person's middle name(s). */
24
+ @Transliterate()
18
25
  @IsOptional()
19
26
  @IsString()
20
27
  middleName?: string;
28
+ declare readonly middleNameIcao?: string;
29
+ declare readonly middleNameLatin?: Promise<string | undefined>;
21
30
 
22
31
  /* The person's father's name / patronymic — required in some jurisdictions (e.g. Greece). */
32
+ @Transliterate()
23
33
  @IsOptional()
24
34
  @IsString()
25
35
  fatherName?: string;
36
+ declare readonly fatherNameIcao?: string;
37
+ declare readonly fatherNameLatin?: Promise<string | undefined>;
26
38
 
27
39
  /* The person's maiden name (family name before marriage). */
40
+ @Transliterate()
28
41
  @IsOptional()
29
42
  @IsString()
30
43
  maidenName?: string;
44
+ declare readonly maidenNameIcao?: string;
45
+ declare readonly maidenNameLatin?: Promise<string | undefined>;
31
46
 
32
47
  /* The person's mother's birth name — required in some jurisdictions (e.g. Hungary). */
48
+ @Transliterate()
33
49
  @IsOptional()
34
50
  @IsString()
35
51
  motherName?: string;
52
+ declare readonly motherNameIcao?: string;
53
+ declare readonly motherNameLatin?: Promise<string | undefined>;
36
54
 
37
55
  /* The person's gender (M, F, or OTHER). */
38
56
  @IsOptional()
@@ -1,7 +1,7 @@
1
1
  import { IsOptional, IsString, IsISO31661Alpha2, IsMimeType, IsEnum } from "class-validator";
2
2
 
3
3
  import { ResidentialAddressSources, type ResidentialAddressSource } from "../enums";
4
- import { Base85FileField, IsoDateField, RequiredWhen } from "../utils";
4
+ import { Base85FileField, IsoDateField, RequiredWhen, Transliterate } from "../utils";
5
5
 
6
6
  export class ResidentialAddress {
7
7
  /* How the address was obtained: typed in, autocompleted, from GPS, an external database, or read from an identity or proof-of-address document. */
@@ -9,8 +9,11 @@ export class ResidentialAddress {
9
9
  source: ResidentialAddressSource;
10
10
 
11
11
  /* Street address. */
12
+ @Transliterate()
12
13
  @IsString()
13
14
  street: string;
15
+ declare readonly streetIcao?: string;
16
+ declare readonly streetLatin?: Promise<string | undefined>;
14
17
 
15
18
  /* House number. */
16
19
  @IsOptional()
@@ -18,18 +21,27 @@ export class ResidentialAddress {
18
21
  houseNumber?: string;
19
22
 
20
23
  /* Additional address information (e.g. apartment number). */
24
+ @Transliterate()
21
25
  @IsOptional()
22
26
  @IsString()
23
27
  additionalAddressInfo?: string;
28
+ declare readonly additionalAddressInfoIcao?: string;
29
+ declare readonly additionalAddressInfoLatin?: Promise<string | undefined>;
24
30
 
25
31
  /* Region (e.g. state, province). */
32
+ @Transliterate()
26
33
  @IsOptional()
27
34
  @IsString()
28
35
  region?: string;
36
+ declare readonly regionIcao?: string;
37
+ declare readonly regionLatin?: Promise<string | undefined>;
29
38
 
30
39
  /* Locality (e.g. city, town). */
40
+ @Transliterate()
31
41
  @IsString()
32
42
  city: string;
43
+ declare readonly cityIcao?: string;
44
+ declare readonly cityLatin?: Promise<string | undefined>;
33
45
 
34
46
  /* Postal code. */
35
47
  @IsOptional()
@@ -4,6 +4,7 @@ import { describe, expect, it } from "vitest";
4
4
  import type { VerifiableCredential } from "../../types";
5
5
 
6
6
  import { KycV3 } from ".";
7
+ import { registerTransliteration } from "../../utils/transliterate";
7
8
 
8
9
  /** A credential with the required sections filled in, ready to be extended per test. */
9
10
  function basicCredential(): KycV3 {
@@ -333,6 +334,68 @@ describe("KycV3 derived fields", () => {
333
334
  expect(credential.envelope.expirationDate).toEqual(new Date("2030-06-01"));
334
335
  });
335
336
 
337
+ // cspell:disable
338
+ it("transliterates names in their original script without serializing the Latin form", async () => {
339
+ registerTransliteration(() => import("transliteration"));
340
+
341
+ const credential = basicCredential();
342
+ credential.addSection("person", {
343
+ firstName: "Юлия",
344
+ familyName: "Müller",
345
+ fatherName: "Αλέξανδρος",
346
+ nationality: "DE",
347
+ dateOfBirth: new Date("1990-01-01"),
348
+ });
349
+
350
+ credential.addSection("residentialAddress", {
351
+ source: "MANUAL",
352
+ street: "вулиця Хрещатик",
353
+ houseNumber: "22",
354
+ additionalAddressInfo: "квартира 5",
355
+ city: "Київ",
356
+ country: "UA",
357
+ });
358
+
359
+ // Each marked field as [<field>Icao, await <field>Latin].
360
+ const siblings = async ({ person, residentialAddress: address }: KycV3["subject"]) => ({
361
+ firstName: [person?.firstNameIcao, await person?.firstNameLatin],
362
+ familyName: [person?.familyNameIcao, await person?.familyNameLatin],
363
+ fatherName: [person?.fatherNameIcao, await person?.fatherNameLatin],
364
+ middleName: [person?.middleNameIcao, await person?.middleNameLatin],
365
+ street: [address?.streetIcao, await address?.streetLatin],
366
+ additionalAddressInfo: [
367
+ address?.additionalAddressInfoIcao,
368
+ await address?.additionalAddressInfoLatin,
369
+ ],
370
+ city: [address?.cityIcao, await address?.cityLatin],
371
+ });
372
+ const expected = {
373
+ firstName: ["Iuliia", "Yuliya"],
374
+ familyName: ["Mueller", "Muller"],
375
+ // ICAO has no Greek table; an absent field has neither form.
376
+ fatherName: [undefined, "Alexandros"],
377
+ middleName: [undefined, undefined],
378
+ street: ["vulitsia Khreshchatik", "vulicya Hreshchatik"],
379
+ additionalAddressInfo: ["kvartira 5", "kvartira 5"],
380
+ city: ["Kiiv", "Kiyiv"],
381
+ };
382
+
383
+ expect(await siblings(credential.subject)).toEqual(expected);
384
+ expect(
385
+ Object.keys(credential.subject.person ?? {}).filter((key) => /latin|icao/i.test(key)),
386
+ ).toEqual([]);
387
+
388
+ const serialized = credential.serializeSubject();
389
+ expect(serialized.personFirstName).toBe("Юлия");
390
+ expect(Object.keys(serialized).filter((key) => /latin|icao/i.test(key))).toEqual([]);
391
+
392
+ const roundTrip = new KycV3();
393
+ await roundTrip.deserialize(serializedCredential(serialized));
394
+
395
+ expect(await siblings(roundTrip.subject)).toEqual(expected);
396
+ });
397
+ // cspell:enable
398
+
336
399
  it("reaches plus and kycLevel 3 with a verified address, SOW and onboarding", () => {
337
400
  const credential = basicCredential();
338
401
  credential.addSection("biometric", { selfieFile: Buffer.from("Selfie"), selfieMatch: 99 });
@@ -11,6 +11,8 @@ import {
11
11
  validateSync,
12
12
  } from "class-validator";
13
13
 
14
+ import { transliterateIcao, transliterateLatin } from "../utils/transliterate";
15
+
14
16
  /*
15
17
  * A credential subject travels the wire flat: every section is merged into one object with
16
18
  * its own name as a prefix (`person` + `firstName` -> `personFirstName`), while `root`
@@ -65,6 +67,47 @@ export function sectionsOf(cls: Ctor<object>): SectionMeta[] {
65
67
  return (Reflect.getMetadata(SECTIONS, cls) as SectionMeta[] | undefined) ?? [];
66
68
  }
67
69
 
70
+ /**
71
+ * Marks a string field kept in its original script (Cyrillic, umlauts, …) and adds two
72
+ * read-only siblings, derived from it on every read and never serialized:
73
+ *
74
+ * - `<field>Icao`: ICAO 9303, as a passport's MRZ prints it; `undefined` for a script the
75
+ * ICAO tables do not cover.
76
+ * - `<field>Latin`: the conventional spelling, a promise because its tables load on first
77
+ * use; the app supplies them through `registerTransliteration()`.
78
+ *
79
+ * TypeScript cannot see members a decorator adds, so declare both next to the field.
80
+ */
81
+ export function Transliterate(): PropertyDecorator {
82
+ return (target, propertyKey) => {
83
+ const field = String(propertyKey);
84
+
85
+ // On the prototype rather than the instance, so serialization, which reads own keys, skips them.
86
+ Object.defineProperty(target, `${field}Icao`, {
87
+ configurable: true,
88
+ get(this: Record<string, unknown>) {
89
+ const value = this[field];
90
+
91
+ return typeof value === "string" ? transliterateIcao(value) : undefined;
92
+ },
93
+ });
94
+
95
+ Object.defineProperty(target, `${field}Latin`, {
96
+ configurable: true,
97
+ get(this: Record<string, unknown>) {
98
+ const value = this[field];
99
+ if (typeof value !== "string") return Promise.resolve(undefined);
100
+
101
+ const latin = transliterateLatin(value);
102
+ // A read nobody awaits (a logger walking getters) must not crash Node with an unhandled rejection; awaiters still get the error.
103
+ latin.catch(() => {});
104
+
105
+ return latin;
106
+ },
107
+ });
108
+ };
109
+ }
110
+
68
111
  /**
69
112
  * The field names of a class, taken from its validation metadata — which is why every
70
113
  * field needs at least one validation decorator to survive a round trip. Inherited fields
@@ -8,6 +8,7 @@ import type { idOSCredential, SignedCredentialContentReference } from "../types"
8
8
 
9
9
  // Proxying functions
10
10
  export * from "./issuer";
11
+ export * from "./transliterate";
11
12
 
12
13
  export type BaseLevel = "unverified" | "basic" | "plus";
13
14
  export type Addon =
@@ -0,0 +1,68 @@
1
+ // cspell:disable -- names in other scripts
2
+ import { describe, expect, it, vi } from "vitest";
3
+
4
+ import { registerTransliteration, transliterateIcao, transliterateLatin } from "./transliterate";
5
+
6
+ describe("transliterateIcao", () => {
7
+ it.each([
8
+ ["John", "John"],
9
+ ["Müller", "Mueller"],
10
+ ["MÜLLER", "MUELLER"],
11
+ ["Straße", "Strasse"],
12
+ ["Øyvind Åsen", "Oeyvind Aasen"],
13
+ ["Dvořák", "Dvorak"],
14
+ ["Łukasz", "Lukasz"],
15
+ ["Жанна", "Zhanna"],
16
+ ["ЖАННА", "ZHANNA"],
17
+ ["Щукин", "Shchukin"],
18
+ ["Юлия Ильинична", "Iuliia Ilinichna"],
19
+ ["Объедков", "Obieedkov"],
20
+ ["Ђорђе Јовановић", "Dorde Jovanovic"],
21
+ ["O'Brien-Smith", "O'Brien-Smith"],
22
+ // Decomposed input lands on the same table entry as precomposed.
23
+ ["Mu\u0308ller", "Mueller"],
24
+ ])("%s -> %s", (input, output) => {
25
+ expect(transliterateIcao(input)).toBe(output);
26
+ });
27
+
28
+ it("returns undefined for a script it has no table for", () => {
29
+ expect(transliterateIcao("Αλέξανδρος")).toBeUndefined();
30
+ expect(transliterateIcao("王伟")).toBeUndefined();
31
+ });
32
+ });
33
+
34
+ describe("transliterateLatin", () => {
35
+ it("says how to register the library until an app does", async () => {
36
+ // A fresh copy of the module, so a registration elsewhere cannot leak in.
37
+ vi.resetModules();
38
+ const fresh = await import("./transliterate");
39
+
40
+ await expect(fresh.transliterateLatin("Юлия")).rejects.toThrow(
41
+ /registerTransliteration\(\(\) => import\("transliteration"\)\)/,
42
+ );
43
+ });
44
+
45
+ it("leaves an unawaited <field>Latin read without an unhandled rejection", async () => {
46
+ vi.resetModules();
47
+ const { Transliterate } = await import("../schemas/utils");
48
+ const proto = {};
49
+ Transliterate()(proto, "name");
50
+ const person = Object.assign(Object.create(proto), { name: "Юлия" });
51
+ const unhandled = vi.fn();
52
+ process.on("unhandledRejection", unhandled);
53
+
54
+ void person.nameLatin;
55
+ await new Promise((resolve) => setTimeout(resolve, 10));
56
+ process.off("unhandledRejection", unhandled);
57
+
58
+ expect(unhandled).not.toHaveBeenCalled();
59
+ await expect(person.nameLatin).rejects.toThrow(/registerTransliteration/);
60
+ });
61
+
62
+ it("covers scripts the ICAO tables do not once registered", async () => {
63
+ registerTransliteration(() => import("transliteration"));
64
+
65
+ expect(await transliterateLatin("Юлия")).toBe("Yuliya");
66
+ expect(await transliterateLatin("Αλέξανδρος")).toBe("Alexandros");
67
+ });
68
+ });
@@ -0,0 +1,140 @@
1
+ // cspell:disable -- transliteration table and examples of names in other scripts
2
+ /*
3
+ * ICAO Doc 9303 Part 3, section 6: the transliteration passports print in their Latin fields
4
+ * and MRZ, so a name comes out the way the document itself spells it. Keys are uppercase; a
5
+ * Latin letter missing here just loses its diacritics (Č -> C), as the standard prescribes.
6
+ */
7
+ const ICAO: Record<string, string> = {
8
+ // Latin letters with a transliteration of their own (Table A).
9
+ Ä: "AE",
10
+ Å: "AA",
11
+ Æ: "AE",
12
+ Ð: "D",
13
+ Ö: "OE",
14
+ Ø: "OE",
15
+ Ü: "UE",
16
+ Þ: "TH",
17
+ ß: "SS",
18
+ ẞ: "SS",
19
+ Đ: "D",
20
+ Ħ: "H",
21
+ IJ: "IJ",
22
+ Ŀ: "L",
23
+ Ł: "L",
24
+ Ŋ: "N",
25
+ Œ: "OE",
26
+ Ŧ: "T",
27
+
28
+ // Cyrillic (Table B).
29
+ А: "A",
30
+ Б: "B",
31
+ В: "V",
32
+ Г: "G",
33
+ Д: "D",
34
+ Е: "E",
35
+ Ё: "E",
36
+ Ж: "ZH",
37
+ З: "Z",
38
+ И: "I",
39
+ Й: "I",
40
+ К: "K",
41
+ Л: "L",
42
+ М: "M",
43
+ Н: "N",
44
+ О: "O",
45
+ П: "P",
46
+ Р: "R",
47
+ С: "S",
48
+ Т: "T",
49
+ У: "U",
50
+ Ф: "F",
51
+ Х: "KH",
52
+ Ц: "TS",
53
+ Ч: "CH",
54
+ Ш: "SH",
55
+ Щ: "SHCH",
56
+ Ъ: "IE",
57
+ Ы: "Y",
58
+ Ь: "",
59
+ Э: "E",
60
+ Ю: "IU",
61
+ Я: "IA",
62
+ Ђ: "D",
63
+ Ѓ: "G",
64
+ Є: "IE",
65
+ Ѕ: "DZ",
66
+ І: "I",
67
+ Ї: "I",
68
+ Ј: "J",
69
+ Љ: "LJ",
70
+ Њ: "NJ",
71
+ Ћ: "C",
72
+ Ќ: "K",
73
+ Ў: "U",
74
+ Џ: "DZ",
75
+ Ґ: "G",
76
+ };
77
+
78
+ function transliterateChar(char: string, next: string | undefined): string {
79
+ const upper = char.toUpperCase();
80
+ // `ß` is looked up as itself: its uppercase is the two letters `SS`.
81
+ const latin = ICAO[char] ?? ICAO[upper];
82
+
83
+ if (latin === undefined) return char.normalize("NFD").replace(/\p{M}/gu, "");
84
+ if (char !== upper) return latin.toLowerCase();
85
+
86
+ // A capital opening a lowercase word reads `Zh`, one inside an all-caps word `ZH`.
87
+ return next !== undefined && next !== next.toUpperCase()
88
+ ? latin.charAt(0) + latin.slice(1).toLowerCase()
89
+ : latin;
90
+ }
91
+
92
+ /**
93
+ * Transliterates `value` to ASCII Latin per ICAO 9303, keeping its letter case (`Жанна` ->
94
+ * `Zhanna`, `Müller` -> `Mueller`). Returns `undefined` when a character has no transliteration,
95
+ * rather than a half-Latin string.
96
+ *
97
+ * shortcut: Latin and Cyrillic only; Greek, Arabic, CJK and others yield `undefined`, add their
98
+ * tables when a credential needs them.
99
+ */
100
+ export function transliterateIcao(value: string): string | undefined {
101
+ const chars = [...value.normalize("NFC")];
102
+ const latin = chars.map((char, index) => transliterateChar(char, chars[index + 1])).join("");
103
+
104
+ // oxlint-disable-next-line no-control-regex
105
+ return /^[\x00-\x7F]*$/.test(latin) ? latin : undefined;
106
+ }
107
+
108
+ type TransliterationLoader = () => Promise<{ transliterate: (value: string) => string }>;
109
+
110
+ let loadLibrary: TransliterationLoader | undefined;
111
+
112
+ /**
113
+ * Hands this package the `transliteration` library that `<field>Latin` reads. It is an
114
+ * optional peer dependency this package never imports itself: its tables are ~55 KB gzipped,
115
+ * and an import here would fail the build of every app that has not installed it. The app
116
+ * owns the import, so its bundler splits the tables into a chunk loaded on first use:
117
+ *
118
+ * ```ts
119
+ * registerTransliteration(() => import("transliteration"));
120
+ * ```
121
+ */
122
+ export function registerTransliteration(load: TransliterationLoader): void {
123
+ loadLibrary = load;
124
+ }
125
+
126
+ /**
127
+ * Transliterates `value` to the conventional Latin spelling a reader expects (`Юлия` ->
128
+ * `Yuliya`), covering nearly every script. Needs `registerTransliteration()` first.
129
+ */
130
+ export async function transliterateLatin(value: string): Promise<string> {
131
+ if (!loadLibrary) {
132
+ throw new Error(
133
+ 'Latin transliteration needs the "transliteration" package: install it, then call registerTransliteration(() => import("transliteration")) from @idos-network/credentials/utils once at startup',
134
+ );
135
+ }
136
+
137
+ const { transliterate } = await loadLibrary();
138
+
139
+ return transliterate(value);
140
+ }
@@ -1,2 +0,0 @@
1
- import{assertNoExtraFields as e,issuerToKey as t}from"./utils/index.mjs";import{a as n,c as r,i,l as a,n as o,o as s,r as c,s as l,t as ee,u as te}from"./loader-Cg6hs1-P.mjs";import{base85ToFile as ne,fileToBase85 as re}from"@idos-network/utils/codecs";import{Ed25519Signature2020 as ie}from"@digitalbazaar/ed25519-signature-2020";import*as ae from"@digitalbazaar/vc";import"reflect-metadata";import{Transform as u,Type as oe,instanceToPlain as se,plainToInstance as ce}from"class-transformer";import{IsBoolean as d,IsDate as le,IsDefined as ue,IsEmail as f,IsEnum as de,IsISO31661Alpha2 as p,IsIn as m,IsInstance as fe,IsInt as pe,IsMimeType as h,IsNumber as g,IsOptional as _,IsPositive as me,IsString as v,Length as y,Max as he,Min as ge,ValidateIf as _e,ValidateNested as ve,getMetadataStorage as ye,validateSync as be}from"class-validator";const xe=[`INVESTING`,`PAYMENT_TO_FRIENDS_FAMILY_OR_OTHERS`,`PURCHASE_DIGITAL_ASSETS`,`ONLINE_PURCHASES_OF_GOODS_OR_SERVICES`,`TRADING`],b=[`PASSPORT`,`DRIVERS`,`ID_CARD`,`VOTING_CARD`,`PAN_CARD`,`INTERNAL_PASSPORT`,`RESIDENCE_PERMIT`],Se=[`MANUAL`,`GPS`,`EXTERNAL_DB`,`PROOF_OF_ADDRESS`,`PROOF_OF_IDENTITY`,`AUTO_COMPLETE`],x=[`CLEAR`,`NOT_CHECKED`],Ce=[`M`,`F`,`OTHER`],S=[`EMPLOYED`,`SELF_EMPLOYED`,`UNEMPLOYED`,`RETIRED`,`STUDENT`],we=[`LESS_THAN_5`,`BETWEEN_5_AND_10`,`MORE_THAN_10`],Te=[`LESS_THAN_500`,`MORE_THAN_500_LESS_THAN_2000`,`MORE_THAN_2000`],Ee=[`SALARY`,`SAVINGS`,`INVESTMENTS`,`CRYPTO_TRADING`,`OTHER`],De=[`LESS_THAN_20000`,`FROM_20001_TO_30000`,`FROM_30001_TO_40000`,`FROM_40001_TO_50000`,`FROM_50001_TO_60000`,`FROM_60001_TO_70000`,`FROM_70001_TO_80000`,`FROM_80001_TO_90000`,`FROM_90001_TO_100000`,`FROM_100001_TO_110000`,`FROM_110001_TO_120000`,`FROM_120001_TO_130000`,`FROM_130001_TO_140000`,`FROM_140001_TO_150000`,`FROM_150001_TO_200000`,`FROM_200001_TO_500000`,`MORE_THAN_500000`],Oe=[`UP_TO_25000`,`BETWEEN_25001_AND_50000`,`BETWEEN_50001_AND_100000`,`BETWEEN_100001_AND_300000`,`BETWEEN_300001_AND_500000`,`BETWEEN_500001_AND_1000000`,`OVER_1000001`],C=[`AGRICULTURE`,`ARTS_AND_ENTERTAINMENT`,`CONSTRUCTION`,`EDUCATION`,`FINANCIAL_SERVICES`,`INFORMATION_AND_TECHNOLOGY`,`RETAIL`,`REAL_ESTATE`,`OTHER`,`BUSINESS_OWNER`,`HEALTHCARE`,`INDUSTRIAL`,`LEGAL_SERVICES`,`PUBLIC_SECTOR`,`SENIOR_MANAGEMENT`],w=[`EUR`,`USD`,`GBP`,`OTHER`],T=Symbol(`idos:sections`);function E(e,t){return e?`${e}${t.charAt(0).toUpperCase()}${t.slice(1)}`:t}function D(e,t){return(n,r)=>{let i=String(r),a=Reflect.getOwnMetadata(T,n.constructor)??[...Reflect.getMetadata(T,n.constructor)??[]];a.push({property:i,prefix:t??i,type:e}),Reflect.defineMetadata(T,a,n.constructor),oe(e)(n,r),ve()(n,r)}}function O(e){return Reflect.getMetadata(T,e)??[]}function k(e){let t=ye().getTargetValidationMetadatas(e,e.name,!0,!1);return[...new Set(t.map(e=>e.propertyName))]}function ke(e){let t=se(e),n=new Map(O(e.constructor).map(({property:e,prefix:t})=>[e,t])),r={};for(let[e,i]of Object.entries(t)){if(!n.has(e)){i!==void 0&&(r[e]=i);continue}if(!i)continue;let t=n.get(e);for(let[e,n]of Object.entries(i))n!==void 0&&(r[E(t,e)]=n)}return r}function Ae(e){let t=O(e),n=new Set(t.map(({property:e})=>e)),r=k(e).filter(e=>!n.has(e));for(let{prefix:e,type:n}of t)for(let t of k(n()))r.push(E(e,t));return new Set(r)}function je(e,t){let n=O(e),r=new Set(n.map(({property:e})=>e)),i={};for(let n of k(e))!r.has(n)&&Object.hasOwn(t,n)&&(i[n]=t[n]);for(let{property:e,prefix:r,type:a}of n){let n={};for(let e of k(a())){let i=E(r,e);Object.hasOwn(t,i)&&(n[e]=t[i])}Object.keys(n).length>0&&(i[e]=n)}return ce(e,i)}function Me(e,t){let n=ce(e,t);return Object.fromEntries(Object.keys(t).map(e=>[e,n[e]]))}function Ne(e,t=``){return e.flatMap(e=>{let n=t?`${t}.${e.property}`:e.property;return[...Object.values(e.constraints??{}).map(e=>`${n}: ${e}`),...Ne(e.children??[],n)]})}var Pe=class extends Error{errors;name=`CredentialValidationError`;constructor(e,t){super(`Invalid ${e}: ${Ne(t).join(`; `)}`),this.errors=t}};function A(e,t){let n=be(t);if(n.length>0)throw new Pe(e,n)}function j(e){return(t,n)=>_e(t=>e(t)||t[String(n)]!==void 0)(t,n)}function Fe(e){return j(t=>t[e]!==void 0)}function Ie(...e){return(t,n)=>{for(let r of e)r(t,n)}}function M(){return Ie(u(({value:e})=>e instanceof Date?e.toISOString():e,{toPlainOnly:!0}),u(({value:e})=>typeof e==`string`?new Date(e):e,{toClassOnly:!0}),le())}const Le=/^<~[\s\S]*~>$/;function N(){return Ie(u(({value:e})=>Buffer.isBuffer(e)?re(e):e,{toPlainOnly:!0}),u(({value:e})=>typeof e!=`string`||!Le.test(e)?e:ne(e)||e,{toClassOnly:!0}),fe(Buffer,{message:({property:e})=>`${e} must be a file encoded as delimited ascii85`}))}var P=class{envelopeClass;subjectClass;envelope={};subject={};constructor(e,t){this.envelopeClass=e,this.subjectClass=t}addSection(e,t,n=!0){let r=O(this.subjectClass).find(({property:t})=>t===e);if(!r)throw Error(`Unknown section: ${String(e)}`);let i=r.type(),a=new Set(k(i)),o=Object.keys(t).filter(e=>!a.has(e));if(o.length>0)throw Error(`Unexpected ${String(e)} fields: ${o.join(`, `)}`);let s=Object.assign(new i,t);return n&&A(String(e),s),this.subject[e]=s,this}setSubject(e){return Object.assign(this.subject,this.ownFields(`subject`,this.subjectClass,e)),this}setEnvelope(e){return Object.assign(this.envelope,this.ownFields(`envelope`,this.envelopeClass,e)),this}checkValidity(){this.setMissingFields(),A(`envelope`,Object.assign(new this.envelopeClass,this.envelope)),A(`subject`,Object.assign(new this.subjectClass,this.subject))}serializeSubject(){return this.checkValidity(),{"@context":[this.contexts.subjectContext],...ke(Object.assign(new this.subjectClass,this.subject))}}serializeEnvelope(){return this.checkValidity(),ke(Object.assign(new this.envelopeClass,this.envelope))}async issue(e){let n=await t(e),r={"@context":[a,this.contexts.envelopeContext,ee],type:[`VerifiableCredential`],issuer:n.controller,...this.serializeEnvelope(),credentialSubject:this.serializeSubject()};return ae.issue({credential:r,suite:new ie({key:n}),documentLoader:te})}async deserialize(t){let{credentialSubject:n,...r}=t,{"@context":i,...a}=n;e(`subject`,Ae(this.subjectClass),a),Object.assign(this.envelope,je(this.envelopeClass,r)),Object.assign(this.subject,je(this.subjectClass,n))}ownFields(t,n,r){let i=new Set(O(n).map(({property:e})=>e)),a=k(n).filter(e=>!i.has(e));return e(t,new Set(a),r),Me(n,r)}get contexts(){return this.constructor}setMissingFields(){this.envelope.level??=this.level()}};function F(e,t,n,r){var i=arguments.length,a=i<3?t:r===null?r=Object.getOwnPropertyDescriptor(t,n):r,o;if(typeof Reflect==`object`&&typeof Reflect.decorate==`function`)a=Reflect.decorate(e,t,n,r);else for(var s=e.length-1;s>=0;s--)(o=e[s])&&(a=(i<3?o(a):i>3?o(t,n,a):o(t,n))||a);return i>3&&a&&Object.defineProperty(t,n,a),a}var I=class{id;level;approvedAt};F([v()],I.prototype,`id`,void 0),F([v()],I.prototype,`level`,void 0),F([_(),M()],I.prototype,`approvedAt`,void 0);var L=class extends I{kycLevel;issued;expirationDate};F([_(),pe(),me()],L.prototype,`kycLevel`,void 0),F([_(),M()],L.prototype,`issued`,void 0),F([_(),M()],L.prototype,`expirationDate`,void 0);var R=class{occupation;sourceOfFundsCategory;sourceOfFundsProofFile};F([_(),m(C)],R.prototype,`occupation`,void 0),F([_(),v()],R.prototype,`sourceOfFundsCategory`,void 0),F([_(),N()],R.prototype,`sourceOfFundsProofFile`,void 0);var z=class{id;edd};F([v()],z.prototype,`id`,void 0),F([D(()=>R),ue()],z.prototype,`edd`,void 0);var Re=class extends P{static envelopeContext=o;static subjectContext=c;constructor(){super(I,z)}level(){return`edd`}publicNotes(){return{type:`edd`,level:this.level()}}},ze=class{faceSignUserId};F([v()],ze.prototype,`faceSignUserId`,void 0);var Be=class extends P{static envelopeContext=o;static subjectContext=i;constructor(){super(I,ze)}level(){return`human`}publicNotes(){return{type:`pop`,level:this.level()}}},B=class{country;number;type;dateOfIssue;dateOfExpiry;frontFile;backFile};F([_(),p()],B.prototype,`country`,void 0),F([_(),v()],B.prototype,`number`,void 0),F([_(),v()],B.prototype,`type`,void 0),F([_(),M()],B.prototype,`dateOfIssue`,void 0),F([_(),M()],B.prototype,`dateOfExpiry`,void 0),F([_(),N()],B.prototype,`frontFile`,void 0),F([_(),N()],B.prototype,`backFile`,void 0);var V=class{street;houseNumber;additionalAddressInfo;region;city;postalCode;country;proofCategory;proofDateOfIssue;proofFile};F([_(),v()],V.prototype,`street`,void 0),F([_(),v()],V.prototype,`houseNumber`,void 0),F([_(),v()],V.prototype,`additionalAddressInfo`,void 0),F([_(),v()],V.prototype,`region`,void 0),F([_(),v()],V.prototype,`city`,void 0),F([_(),v()],V.prototype,`postalCode`,void 0),F([_(),p()],V.prototype,`country`,void 0),F([_(),v()],V.prototype,`proofCategory`,void 0),F([_(),M()],V.prototype,`proofDateOfIssue`,void 0),F([_(),N()],V.prototype,`proofFile`,void 0);var H=class{id;applicantId;inquiryId;firstName;middleName;nationality;familyName;maidenName;gender;governmentId;governmentIdType;email;ssn;phoneNumber;dateOfBirth;placeOfBirth;selfieFile;idDocument;residentialAddress};F([v()],H.prototype,`id`,void 0),F([_(),v()],H.prototype,`applicantId`,void 0),F([_(),v()],H.prototype,`inquiryId`,void 0),F([_(),v()],H.prototype,`firstName`,void 0),F([_(),v()],H.prototype,`middleName`,void 0),F([_(),p()],H.prototype,`nationality`,void 0),F([_(),v()],H.prototype,`familyName`,void 0),F([_(),v()],H.prototype,`maidenName`,void 0),F([_(),v()],H.prototype,`gender`,void 0),F([_(),v()],H.prototype,`governmentId`,void 0),F([_(),v()],H.prototype,`governmentIdType`,void 0),F([_(),f()],H.prototype,`email`,void 0),F([_(),v()],H.prototype,`ssn`,void 0),F([_(),v()],H.prototype,`phoneNumber`,void 0),F([_(),M()],H.prototype,`dateOfBirth`,void 0),F([_(),v()],H.prototype,`placeOfBirth`,void 0),F([_(),N()],H.prototype,`selfieFile`,void 0),F([D(()=>B),_()],H.prototype,`idDocument`,void 0),F([D(()=>V),_()],H.prototype,`residentialAddress`,void 0);var Ve=class extends P{static envelopeContext=o;static subjectContext=n;constructor(){super(I,H)}level(){let{residentialAddress:e,selfieFile:t,email:n,phoneNumber:r}=this.subject;return[e?.proofFile&&e.city&&e.proofCategory&&e.country?`plus`:`basic`,...[t&&`liveness`,n&&`email`,r&&`phoneNumber`].filter(Boolean)].join(`+`)}publicNotes(){return{type:`kyc`,level:this.level()}}},U=class{id;firstName;middleName;nationality;familyName;maidenName;gender;email;phoneNumber;ssn;dateOfBirth;placeOfBirth;selfieFile;idDocument;residentialAddress};F([v()],U.prototype,`id`,void 0),F([_(),v()],U.prototype,`firstName`,void 0),F([_(),v()],U.prototype,`middleName`,void 0),F([_(),p()],U.prototype,`nationality`,void 0),F([_(),v()],U.prototype,`familyName`,void 0),F([_(),v()],U.prototype,`maidenName`,void 0),F([_(),v()],U.prototype,`gender`,void 0),F([_(),f()],U.prototype,`email`,void 0),F([_(),v()],U.prototype,`phoneNumber`,void 0),F([_(),v()],U.prototype,`ssn`,void 0),F([_(),M()],U.prototype,`dateOfBirth`,void 0),F([_(),v()],U.prototype,`placeOfBirth`,void 0),F([_(),N()],U.prototype,`selfieFile`,void 0),F([D(()=>B),_()],U.prototype,`idDocument`,void 0),F([D(()=>V),_()],U.prototype,`residentialAddress`,void 0);var He=class extends P{static envelopeContext=s;static subjectContext=l;constructor(){super(L,U)}level(){let{residentialAddress:e,selfieFile:t,email:n,phoneNumber:r}=this.subject;return[e?.proofFile&&e.city&&e.proofCategory&&e.country?`plus`:`basic`,...[t&&`liveness`,n&&`email`,r&&`phoneNumber`].filter(Boolean)].join(`+`)}publicNotes(){return{type:`kyc`,level:this.level()}}},W=class{selfieFile;selfieMatch};F([N()],W.prototype,`selfieFile`,void 0),F([_(),g()],W.prototype,`selfieMatch`,void 0);var G=class{email;phoneNumber};F([_(),f()],G.prototype,`email`,void 0),F([_(),v()],G.prototype,`phoneNumber`,void 0);var K=class{occupation;sourceOfFundsCategory;sourceOfFundsProofFile;sourceOfFundsProofFileType;sourceOfFundsProofFileName};F([_(),m(C)],K.prototype,`occupation`,void 0),F([_(),v()],K.prototype,`sourceOfFundsCategory`,void 0),F([_(),N()],K.prototype,`sourceOfFundsProofFile`,void 0),F([j(e=>!!e.sourceOfFundsProofFile),v(),h()],K.prototype,`sourceOfFundsProofFileType`,void 0),F([j(e=>!!e.sourceOfFundsProofFile),v()],K.prototype,`sourceOfFundsProofFileName`,void 0);var q=class{type;number;country;dateOfExpiry;dateOfIssue;issuingAuthority;frontFile;frontFileType;frontFileName;backFile;backFileType;backFileName;mrzLine1;title;extendedValidUntil;additionalNumber;ethnicity;issuingSubdivision};F([m(b)],q.prototype,`type`,void 0),F([y(1,255)],q.prototype,`number`,void 0),F([p()],q.prototype,`country`,void 0),F([_(),M()],q.prototype,`dateOfExpiry`,void 0),F([_(),M()],q.prototype,`dateOfIssue`,void 0),F([_(),y(1,255)],q.prototype,`issuingAuthority`,void 0),F([N()],q.prototype,`frontFile`,void 0),F([v(),h()],q.prototype,`frontFileType`,void 0),F([v()],q.prototype,`frontFileName`,void 0),F([_(),N()],q.prototype,`backFile`,void 0),F([j(e=>!!e.backFile),v(),h()],q.prototype,`backFileType`,void 0),F([j(e=>!!e.backFile),v()],q.prototype,`backFileName`,void 0),F([_(),y(1,255)],q.prototype,`mrzLine1`,void 0),F([_(),y(1,255)],q.prototype,`title`,void 0),F([_(),M()],q.prototype,`extendedValidUntil`,void 0),F([_(),y(1,255)],q.prototype,`additionalNumber`,void 0),F([_(),y(1,255)],q.prototype,`ethnicity`,void 0),F([_(),y(1,255)],q.prototype,`issuingSubdivision`,void 0);var J=class{intendedUse;employmentStatus;expectedMonthlyTransactionCount;expectedMonthlyTransactionVolume;expectedMonthlyTransactionVolumeCurrency};F([m(xe)],J.prototype,`intendedUse`,void 0),F([m(S)],J.prototype,`employmentStatus`,void 0),F([m(we)],J.prototype,`expectedMonthlyTransactionCount`,void 0),F([m(Te)],J.prototype,`expectedMonthlyTransactionVolume`,void 0),F([m(w)],J.prototype,`expectedMonthlyTransactionVolumeCurrency`,void 0);var Y=class{firstName;familyName;middleName;fatherName;maidenName;motherName;gender;nationality;secondNationality;dateOfBirth;placeOfBirth;regionOfBirth;stateless;refugeeStatus;subsidiaryProtectionStatus;nationalIdNumber;taxIdNumber;taxIdIssuingCountry;taxResidenceCountry;ssn};F([j(e=>!e.familyName),v()],Y.prototype,`firstName`,void 0),F([_(),v()],Y.prototype,`familyName`,void 0),F([_(),v()],Y.prototype,`middleName`,void 0),F([_(),v()],Y.prototype,`fatherName`,void 0),F([_(),v()],Y.prototype,`maidenName`,void 0),F([_(),v()],Y.prototype,`motherName`,void 0),F([_(),m(Ce)],Y.prototype,`gender`,void 0),F([j(e=>!e.stateless&&!e.secondNationality),p()],Y.prototype,`nationality`,void 0),F([_(),p()],Y.prototype,`secondNationality`,void 0),F([M()],Y.prototype,`dateOfBirth`,void 0),F([_(),v()],Y.prototype,`placeOfBirth`,void 0),F([_(),v()],Y.prototype,`regionOfBirth`,void 0),F([_(),d()],Y.prototype,`stateless`,void 0),F([_(),d()],Y.prototype,`refugeeStatus`,void 0),F([_(),d()],Y.prototype,`subsidiaryProtectionStatus`,void 0),F([_(),v()],Y.prototype,`nationalIdNumber`,void 0),F([_(),v()],Y.prototype,`taxIdNumber`,void 0),F([_(),p()],Y.prototype,`taxIdIssuingCountry`,void 0),F([_(),p()],Y.prototype,`taxResidenceCountry`,void 0),F([_(),v()],Y.prototype,`ssn`,void 0);var X=class{source;street;houseNumber;additionalAddressInfo;region;city;postalCode;country;proofCategory;proofDateOfIssue;proofFile;proofFileType;proofFileName;ipCountry};F([de(Se)],X.prototype,`source`,void 0),F([v()],X.prototype,`street`,void 0),F([_(),v()],X.prototype,`houseNumber`,void 0),F([_(),v()],X.prototype,`additionalAddressInfo`,void 0),F([_(),v()],X.prototype,`region`,void 0),F([v()],X.prototype,`city`,void 0),F([_(),v()],X.prototype,`postalCode`,void 0),F([p()],X.prototype,`country`,void 0),F([j(e=>e.source===`PROOF_OF_ADDRESS`),v()],X.prototype,`proofCategory`,void 0),F([_(),M()],X.prototype,`proofDateOfIssue`,void 0),F([j(e=>e.source===`PROOF_OF_ADDRESS`),N()],X.prototype,`proofFile`,void 0),F([j(e=>e.source===`PROOF_OF_ADDRESS`),v(),h()],X.prototype,`proofFileType`,void 0),F([j(e=>e.source===`PROOF_OF_ADDRESS`),v()],X.prototype,`proofFileName`,void 0),F([_(),p()],X.prototype,`ipCountry`,void 0);var Z=class{sanctionsCheckResult;sanctionsConfidenceScore;pepCheckResult;pepConfidenceScore};F([m(x)],Z.prototype,`sanctionsCheckResult`,void 0),F([_(),g(),ge(0),he(100)],Z.prototype,`sanctionsConfidenceScore`,void 0),F([m(x)],Z.prototype,`pepCheckResult`,void 0),F([_(),g(),ge(0),he(100)],Z.prototype,`pepConfidenceScore`,void 0);var Q=class{type;yearlyGrossIncome;yearlyGrossIncomeCurrency;approximateNetWorth;approximateNetWorthCurrency;sourceOfWealthProofFile};F([m(Ee)],Q.prototype,`type`,void 0),F([_(),m(De)],Q.prototype,`yearlyGrossIncome`,void 0),F([Fe(`yearlyGrossIncome`),m(w)],Q.prototype,`yearlyGrossIncomeCurrency`,void 0),F([_(),m(Oe)],Q.prototype,`approximateNetWorth`,void 0),F([Fe(`approximateNetWorth`),m(w)],Q.prototype,`approximateNetWorthCurrency`,void 0),F([_(),N()],Q.prototype,`sourceOfWealthProofFile`,void 0);var $=class{id;person;idDocument;contact;biometric;residentialAddress;screening;edd;sourceOfWealth;onboarding};F([v()],$.prototype,`id`,void 0),F([D(()=>Y),ue()],$.prototype,`person`,void 0),F([D(()=>q),_()],$.prototype,`idDocument`,void 0),F([D(()=>G),_()],$.prototype,`contact`,void 0),F([D(()=>W),_()],$.prototype,`biometric`,void 0),F([D(()=>X),_()],$.prototype,`residentialAddress`,void 0),F([D(()=>Z),_()],$.prototype,`screening`,void 0),F([D(()=>K),_()],$.prototype,`edd`,void 0),F([D(()=>Q),_()],$.prototype,`sourceOfWealth`,void 0),F([D(()=>J),_()],$.prototype,`onboarding`,void 0);var Ue=class extends P{static envelopeContext=s;static subjectContext=r;constructor(){super(L,$)}level(){let{residentialAddress:e,biometric:t,contact:n,edd:r,sourceOfWealth:i,screening:a,onboarding:o,person:s,idDocument:c}=this.subject,l=`unverified`;s&&c&&(l=`basic`),l===`basic`&&e?.proofFile&&e.city&&e.proofCategory&&e.source===`PROOF_OF_ADDRESS`&&e.country&&(l=`plus`);let ee=[t?.selfieFile&&`liveness`,n?.email&&`email`,n?.phoneNumber&&`phoneNumber`,r&&`edd`,i&&`sow`,a&&`screening`,o&&`onboarding`].filter(Boolean);return[l,...ee].join(`+`)}kycLevel(){let{person:e,idDocument:t,biometric:n,residentialAddress:r,sourceOfWealth:i,onboarding:a}=this.subject,o=0;return n?.selfieFile&&e&&t&&(o=1),o>=1&&r?.proofFile&&r.source===`PROOF_OF_ADDRESS`&&(o=2),o>=2&&i&&a&&(o=3),o}publicNotes(){return{type:`kyc`,level:this.level(),kycLevel:this.kycLevel()}}setMissingFields(){super.setMissingFields(),this.envelope.kycLevel===void 0&&this.kycLevel()>0&&(this.envelope.kycLevel=this.kycLevel()),this.envelope.expirationDate??=this.subject.idDocument?.dateOfExpiry}};export{De as S,xe as _,Be as a,x as b,L as c,w as d,S as f,b as g,Ce as h,Ve as i,P as l,Te as m,$ as n,Re as o,we as p,He as r,I as s,Ue as t,Oe as u,C as v,Ee as x,Se as y};
2
- //# sourceMappingURL=schemas-BVGuUlPe.mjs.map
@@ -1 +0,0 @@
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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"}