noah-avalanche-sdk 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +892 -0
- package/dist/core/APIClient.d.ts +71 -0
- package/dist/core/APIClient.d.ts.map +1 -0
- package/dist/core/APIClient.js +92 -0
- package/dist/core/APIClient.js.map +1 -0
- package/dist/core/ContractClient.d.ts +38 -0
- package/dist/core/ContractClient.d.ts.map +1 -0
- package/dist/core/ContractClient.js +209 -0
- package/dist/core/ContractClient.js.map +1 -0
- package/dist/core/NoahSDK.d.ts +43 -0
- package/dist/core/NoahSDK.d.ts.map +1 -0
- package/dist/core/NoahSDK.js +93 -0
- package/dist/core/NoahSDK.js.map +1 -0
- package/dist/core/WalletAdapter.d.ts +188 -0
- package/dist/core/WalletAdapter.d.ts.map +1 -0
- package/dist/core/WalletAdapter.js +425 -0
- package/dist/core/WalletAdapter.js.map +1 -0
- package/dist/hooks/index.d.ts +18 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +15 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/useCredentials.d.ts +136 -0
- package/dist/hooks/useCredentials.d.ts.map +1 -0
- package/dist/hooks/useCredentials.js +217 -0
- package/dist/hooks/useCredentials.js.map +1 -0
- package/dist/hooks/useProtocol.d.ts +117 -0
- package/dist/hooks/useProtocol.d.ts.map +1 -0
- package/dist/hooks/useProtocol.js +165 -0
- package/dist/hooks/useProtocol.js.map +1 -0
- package/dist/hooks/useUser.d.ts +159 -0
- package/dist/hooks/useUser.d.ts.map +1 -0
- package/dist/hooks/useUser.js +188 -0
- package/dist/hooks/useUser.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/issuer/IssuerClient.d.ts +98 -0
- package/dist/issuer/IssuerClient.d.ts.map +1 -0
- package/dist/issuer/IssuerClient.js +159 -0
- package/dist/issuer/IssuerClient.js.map +1 -0
- package/dist/protocol/ProtocolClient.d.ts +124 -0
- package/dist/protocol/ProtocolClient.d.ts.map +1 -0
- package/dist/protocol/ProtocolClient.js +265 -0
- package/dist/protocol/ProtocolClient.js.map +1 -0
- package/dist/protocol/RequirementsManager.d.ts +9 -0
- package/dist/protocol/RequirementsManager.d.ts.map +1 -0
- package/dist/protocol/RequirementsManager.js +9 -0
- package/dist/protocol/RequirementsManager.js.map +1 -0
- package/dist/user/ProofGenerator.d.ts +49 -0
- package/dist/user/ProofGenerator.d.ts.map +1 -0
- package/dist/user/ProofGenerator.js +80 -0
- package/dist/user/ProofGenerator.js.map +1 -0
- package/dist/user/UserClient.d.ts +191 -0
- package/dist/user/UserClient.d.ts.map +1 -0
- package/dist/user/UserClient.js +338 -0
- package/dist/user/UserClient.js.map +1 -0
- package/dist/utils/credentials.d.ts +47 -0
- package/dist/utils/credentials.d.ts.map +1 -0
- package/dist/utils/credentials.js +99 -0
- package/dist/utils/credentials.js.map +1 -0
- package/dist/utils/identity.d.ts +22 -0
- package/dist/utils/identity.d.ts.map +1 -0
- package/dist/utils/identity.js +35 -0
- package/dist/utils/identity.js.map +1 -0
- package/dist/utils/jurisdiction.d.ts +21 -0
- package/dist/utils/jurisdiction.d.ts.map +1 -0
- package/dist/utils/jurisdiction.js +64 -0
- package/dist/utils/jurisdiction.js.map +1 -0
- package/dist/utils/mrz.d.ts +16 -0
- package/dist/utils/mrz.d.ts.map +1 -0
- package/dist/utils/mrz.js +91 -0
- package/dist/utils/mrz.js.map +1 -0
- package/dist/utils/ocr.d.ts +31 -0
- package/dist/utils/ocr.d.ts.map +1 -0
- package/dist/utils/ocr.js +69 -0
- package/dist/utils/ocr.js.map +1 -0
- package/dist/utils/types.d.ts +122 -0
- package/dist/utils/types.d.ts.map +1 -0
- package/dist/utils/types.js +2 -0
- package/dist/utils/types.js.map +1 -0
- package/package.json +53 -0
- package/src/core/APIClient.ts +165 -0
- package/src/core/ContractClient.ts +266 -0
- package/src/core/NoahSDK.ts +123 -0
- package/src/core/WalletAdapter.ts +546 -0
- package/src/hooks/index.ts +31 -0
- package/src/hooks/types.d.ts +18 -0
- package/src/hooks/useCredentials.ts +359 -0
- package/src/hooks/useProtocol.ts +284 -0
- package/src/hooks/useUser.ts +331 -0
- package/src/index.ts +80 -0
- package/src/issuer/IssuerClient.ts +209 -0
- package/src/protocol/ProtocolClient.ts +330 -0
- package/src/protocol/RequirementsManager.ts +16 -0
- package/src/user/ProofGenerator.ts +113 -0
- package/src/user/UserClient.ts +440 -0
- package/src/utils/credentials.ts +122 -0
- package/src/utils/identity.ts +46 -0
- package/src/utils/jurisdiction.ts +83 -0
- package/src/utils/mrz.ts +113 -0
- package/src/utils/ocr.ts +84 -0
- package/src/utils/types.ts +144 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/utils/credentials.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvE;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,cAAc,GACvB,oBAAoB,CAuCtB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAO3D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAUvD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAMzD"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { ethers } from 'ethers';
|
|
2
|
+
import { jurisdictionStringToHash } from './jurisdiction.js';
|
|
3
|
+
/**
|
|
4
|
+
* Generate a credential hash from user data
|
|
5
|
+
*
|
|
6
|
+
* The credential hash is computed using Keccak256 from a formatted string containing:
|
|
7
|
+
* - User address
|
|
8
|
+
* - Age
|
|
9
|
+
* - Jurisdiction (converted to hash)
|
|
10
|
+
* - Accredited status
|
|
11
|
+
* - Timestamp
|
|
12
|
+
*
|
|
13
|
+
* @param userData - The credential data to hash
|
|
14
|
+
* @returns Object containing the credential hash, jurisdiction hash, credential data string, and timestamp
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* const credential = {
|
|
19
|
+
* userAddress: "0x1234...",
|
|
20
|
+
* age: 25,
|
|
21
|
+
* jurisdiction: "US",
|
|
22
|
+
* accredited: true
|
|
23
|
+
* };
|
|
24
|
+
*
|
|
25
|
+
* const result = generateCredentialHash(credential);
|
|
26
|
+
* console.log(result.credentialHash); // "0x..."
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export function generateCredentialHash(userData) {
|
|
30
|
+
const { userAddress, age, jurisdiction, accredited } = userData;
|
|
31
|
+
// Validate required fields
|
|
32
|
+
if (!userAddress || typeof userAddress !== 'string') {
|
|
33
|
+
throw new Error('userAddress must be a non-empty string');
|
|
34
|
+
}
|
|
35
|
+
if (typeof age !== 'number' || age < 0 || !Number.isInteger(age)) {
|
|
36
|
+
throw new Error('age must be a non-negative integer');
|
|
37
|
+
}
|
|
38
|
+
if (!jurisdiction || typeof jurisdiction !== 'string') {
|
|
39
|
+
throw new Error('jurisdiction must be a non-empty string');
|
|
40
|
+
}
|
|
41
|
+
if (typeof accredited !== 'boolean') {
|
|
42
|
+
throw new Error('accredited must be a boolean');
|
|
43
|
+
}
|
|
44
|
+
// Convert jurisdiction string to hash
|
|
45
|
+
const jurisdictionHash = jurisdictionStringToHash(jurisdiction, true);
|
|
46
|
+
// Create credential data string
|
|
47
|
+
// Format: user:address,age:number,jurisdiction:hash,accredited:number,timestamp:timestamp
|
|
48
|
+
const timestamp = userData.timestamp ?? Date.now();
|
|
49
|
+
const accreditedValue = accredited ? 1 : 0;
|
|
50
|
+
const credentialData = `user:${userAddress},age:${age},jurisdiction:${jurisdictionHash},accredited:${accreditedValue},timestamp:${timestamp}`;
|
|
51
|
+
// Hash the credential data
|
|
52
|
+
const credentialHash = ethers.keccak256(ethers.toUtf8Bytes(credentialData));
|
|
53
|
+
return {
|
|
54
|
+
credentialHash,
|
|
55
|
+
jurisdictionHash,
|
|
56
|
+
credentialData,
|
|
57
|
+
timestamp,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Validate a credential hash format
|
|
62
|
+
* @param hash - The credential hash to validate
|
|
63
|
+
* @returns True if the hash is valid (starts with 0x and is 66 characters)
|
|
64
|
+
*/
|
|
65
|
+
export function isValidCredentialHash(hash) {
|
|
66
|
+
if (typeof hash !== 'string') {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
// Must start with 0x and be 66 characters (0x + 64 hex chars)
|
|
70
|
+
return /^0x[a-fA-F0-9]{64}$/.test(hash);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Validate a user address format
|
|
74
|
+
* @param address - The Ethereum address to validate
|
|
75
|
+
* @returns True if the address is valid
|
|
76
|
+
*/
|
|
77
|
+
export function isValidAddress(address) {
|
|
78
|
+
if (typeof address !== 'string') {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
return ethers.isAddress(address);
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Normalize an Ethereum address to checksum format
|
|
90
|
+
* @param address - The address to normalize
|
|
91
|
+
* @returns The checksummed address
|
|
92
|
+
*/
|
|
93
|
+
export function toChecksumAddress(address) {
|
|
94
|
+
if (!isValidAddress(address)) {
|
|
95
|
+
throw new Error('Invalid Ethereum address');
|
|
96
|
+
}
|
|
97
|
+
return ethers.getAddress(address);
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/utils/credentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAG7D;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,sBAAsB,CACpC,QAAwB;IAExB,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,QAAQ,CAAC;IAEhE,2BAA2B;IAC3B,IAAI,CAAC,WAAW,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IAC5D,CAAC;IAED,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;QACjE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,CAAC,YAAY,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE,CAAC;QACtD,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IAED,IAAI,OAAO,UAAU,KAAK,SAAS,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAClD,CAAC;IAED,sCAAsC;IACtC,MAAM,gBAAgB,GAAG,wBAAwB,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;IAEtE,gCAAgC;IAChC,0FAA0F;IAC1F,MAAM,SAAS,GAAG,QAAQ,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;IACnD,MAAM,eAAe,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAE3C,MAAM,cAAc,GAAG,QAAQ,WAAW,QAAQ,GAAG,iBAAiB,gBAAgB,eAAe,eAAe,cAAc,SAAS,EAAE,CAAC;IAE9I,2BAA2B;IAC3B,MAAM,cAAc,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC,CAAC;IAE5E,OAAO;QACL,cAAc;QACd,gBAAgB;QAChB,cAAc;QACd,SAAS;KACV,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,8DAA8D;IAC9D,OAAO,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAChC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC;QACH,OAAO,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC/C,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC9C,CAAC;IAED,OAAO,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type MRZData } from './mrz.js';
|
|
2
|
+
export interface IdentityProfile extends MRZData {
|
|
3
|
+
confidence: number;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* IdentityManager - Orchestrates OCR and MRZ parsing for Noah SDK
|
|
7
|
+
*/
|
|
8
|
+
export declare class IdentityManager {
|
|
9
|
+
private ocr;
|
|
10
|
+
constructor();
|
|
11
|
+
/**
|
|
12
|
+
* Extract identity profile from a document image
|
|
13
|
+
* @param imageSource - URL, File, or Blob of the document
|
|
14
|
+
* @returns IdentityProfile containing parsed data and OCR confidence
|
|
15
|
+
*/
|
|
16
|
+
extractFromImage(imageSource: string | File | Blob): Promise<IdentityProfile>;
|
|
17
|
+
/**
|
|
18
|
+
* Cleanup resources
|
|
19
|
+
*/
|
|
20
|
+
cleanup(): Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/utils/identity.ts"],"names":[],"mappings":"AACA,OAAO,EAAY,KAAK,OAAO,EAAE,MAAM,UAAU,CAAC;AAElD,MAAM,WAAW,eAAgB,SAAQ,OAAO;IAC5C,UAAU,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,qBAAa,eAAe;IACxB,OAAO,CAAC,GAAG,CAAe;;IAM1B;;;;OAIG;IACG,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC;IAiBnF;;OAEG;IACG,OAAO;CAGhB"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { OCRExtractor } from './ocr.js';
|
|
2
|
+
import { parseTD3 } from './mrz.js';
|
|
3
|
+
/**
|
|
4
|
+
* IdentityManager - Orchestrates OCR and MRZ parsing for Noah SDK
|
|
5
|
+
*/
|
|
6
|
+
export class IdentityManager {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.ocr = new OCRExtractor();
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Extract identity profile from a document image
|
|
12
|
+
* @param imageSource - URL, File, or Blob of the document
|
|
13
|
+
* @returns IdentityProfile containing parsed data and OCR confidence
|
|
14
|
+
*/
|
|
15
|
+
async extractFromImage(imageSource) {
|
|
16
|
+
const ocrResult = await this.ocr.extractMRZ(imageSource);
|
|
17
|
+
if (ocrResult.mrzLines.length < 2) {
|
|
18
|
+
throw new Error(`Failed to detect MRZ lines in image. Raw text: ${ocrResult.rawText.substring(0, 100)}...`);
|
|
19
|
+
}
|
|
20
|
+
// Attempt to parse the detected lines (assuming TD3/Passport for now)
|
|
21
|
+
// TD3 expects two lines of 44 characters
|
|
22
|
+
const mrzData = parseTD3(ocrResult.mrzLines[0], ocrResult.mrzLines[1]);
|
|
23
|
+
return {
|
|
24
|
+
...mrzData,
|
|
25
|
+
confidence: ocrResult.confidence,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Cleanup resources
|
|
30
|
+
*/
|
|
31
|
+
async cleanup() {
|
|
32
|
+
await this.ocr.terminate();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/utils/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAgB,MAAM,UAAU,CAAC;AAMlD;;GAEG;AACH,MAAM,OAAO,eAAe;IAGxB;QACI,IAAI,CAAC,GAAG,GAAG,IAAI,YAAY,EAAE,CAAC;IAClC,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,gBAAgB,CAAC,WAAiC;QACpD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;QAEzD,IAAI,SAAS,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,kDAAkD,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;QAChH,CAAC;QAED,sEAAsE;QACtE,yCAAyC;QACzC,MAAM,OAAO,GAAG,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAEvE,OAAO;YACH,GAAG,OAAO;YACV,UAAU,EAAE,SAAS,CAAC,UAAU;SACnC,CAAC;IACN,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO;QACT,MAAM,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;IAC/B,CAAC;CACJ"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert a jurisdiction string (e.g., "US", "UK", "CA") to a hash number
|
|
3
|
+
* Uses keccak256 to hash the string, then converts to a BigInt
|
|
4
|
+
* @param jurisdiction - Jurisdiction string (e.g., "US", "UK", "CA")
|
|
5
|
+
* @param returnHex - If true, return hex string instead of decimal string
|
|
6
|
+
* @returns Hash as a string number or hex string (for contract compatibility)
|
|
7
|
+
*/
|
|
8
|
+
export declare function jurisdictionStringToHash(jurisdiction: string, returnHex?: boolean): string;
|
|
9
|
+
/**
|
|
10
|
+
* Convert multiple jurisdiction strings to hash numbers
|
|
11
|
+
* @param jurisdictions - Array of jurisdiction strings
|
|
12
|
+
* @returns Array of hash numbers as strings
|
|
13
|
+
*/
|
|
14
|
+
export declare function jurisdictionStringsToHashes(jurisdictions: string[]): string[];
|
|
15
|
+
/**
|
|
16
|
+
* Parse jurisdiction input (comma-separated string) and convert to hashes
|
|
17
|
+
* @param input - Comma-separated jurisdiction strings or numbers
|
|
18
|
+
* @returns Array of hash numbers as strings
|
|
19
|
+
*/
|
|
20
|
+
export declare function parseJurisdictions(input: string): string[];
|
|
21
|
+
//# sourceMappingURL=jurisdiction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jurisdiction.d.ts","sourceRoot":"","sources":["../../src/utils/jurisdiction.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,YAAY,EAAE,MAAM,EACpB,SAAS,GAAE,OAAe,GACzB,MAAM,CAsBR;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,aAAa,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAiB7E;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAW1D"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { ethers } from 'ethers';
|
|
2
|
+
/**
|
|
3
|
+
* Convert a jurisdiction string (e.g., "US", "UK", "CA") to a hash number
|
|
4
|
+
* Uses keccak256 to hash the string, then converts to a BigInt
|
|
5
|
+
* @param jurisdiction - Jurisdiction string (e.g., "US", "UK", "CA")
|
|
6
|
+
* @param returnHex - If true, return hex string instead of decimal string
|
|
7
|
+
* @returns Hash as a string number or hex string (for contract compatibility)
|
|
8
|
+
*/
|
|
9
|
+
export function jurisdictionStringToHash(jurisdiction, returnHex = false) {
|
|
10
|
+
if (!jurisdiction || typeof jurisdiction !== 'string') {
|
|
11
|
+
throw new Error('Jurisdiction must be a non-empty string');
|
|
12
|
+
}
|
|
13
|
+
// Normalize the jurisdiction string (uppercase, trim)
|
|
14
|
+
const normalized = jurisdiction.trim().toUpperCase();
|
|
15
|
+
// Hash using keccak256
|
|
16
|
+
const hash = ethers.keccak256(ethers.toUtf8Bytes(normalized));
|
|
17
|
+
if (returnHex) {
|
|
18
|
+
// Return as hex string (backend can convert to BigInt)
|
|
19
|
+
return hash;
|
|
20
|
+
}
|
|
21
|
+
// Convert hex hash to BigInt, then to string for JSON serialization
|
|
22
|
+
// The contract expects uint256, so we use the full hash as a number
|
|
23
|
+
const hashBigInt = BigInt(hash);
|
|
24
|
+
// Return as string to avoid precision issues with large numbers
|
|
25
|
+
return hashBigInt.toString();
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Convert multiple jurisdiction strings to hash numbers
|
|
29
|
+
* @param jurisdictions - Array of jurisdiction strings
|
|
30
|
+
* @returns Array of hash numbers as strings
|
|
31
|
+
*/
|
|
32
|
+
export function jurisdictionStringsToHashes(jurisdictions) {
|
|
33
|
+
if (!Array.isArray(jurisdictions)) {
|
|
34
|
+
throw new Error('Jurisdictions must be an array');
|
|
35
|
+
}
|
|
36
|
+
return jurisdictions
|
|
37
|
+
.map((j) => j.trim())
|
|
38
|
+
.filter((j) => j.length > 0)
|
|
39
|
+
.map((j) => {
|
|
40
|
+
// If it's already a number string, return as-is
|
|
41
|
+
// This allows mixing strings and numbers
|
|
42
|
+
if (/^\d+$/.test(j)) {
|
|
43
|
+
return j;
|
|
44
|
+
}
|
|
45
|
+
// Otherwise, convert string to hash
|
|
46
|
+
return jurisdictionStringToHash(j);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Parse jurisdiction input (comma-separated string) and convert to hashes
|
|
51
|
+
* @param input - Comma-separated jurisdiction strings or numbers
|
|
52
|
+
* @returns Array of hash numbers as strings
|
|
53
|
+
*/
|
|
54
|
+
export function parseJurisdictions(input) {
|
|
55
|
+
if (!input || typeof input !== 'string') {
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
const jurisdictions = input
|
|
59
|
+
.split(',')
|
|
60
|
+
.map((j) => j.trim())
|
|
61
|
+
.filter((j) => j.length > 0);
|
|
62
|
+
return jurisdictionStringsToHashes(jurisdictions);
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=jurisdiction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jurisdiction.js","sourceRoot":"","sources":["../../src/utils/jurisdiction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC;;;;;;GAMG;AACH,MAAM,UAAU,wBAAwB,CACtC,YAAoB,EACpB,YAAqB,KAAK;IAE1B,IAAI,CAAC,YAAY,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE,CAAC;QACtD,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IAED,sDAAsD;IACtD,MAAM,UAAU,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAErD,uBAAuB;IACvB,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC;IAE9D,IAAI,SAAS,EAAE,CAAC;QACd,uDAAuD;QACvD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,oEAAoE;IACpE,oEAAoE;IACpE,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAEhC,gEAAgE;IAChE,OAAO,UAAU,CAAC,QAAQ,EAAE,CAAC;AAC/B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CAAC,aAAuB;IACjE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IAED,OAAO,aAAa;SACjB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;SAC3B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,gDAAgD;QAChD,yCAAyC;QACzC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YACpB,OAAO,CAAC,CAAC;QACX,CAAC;QACD,oCAAoC;QACpC,OAAO,wBAAwB,CAAC,CAAC,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;AACP,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACxC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,aAAa,GAAG,KAAK;SACxB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAE/B,OAAO,2BAA2B,CAAC,aAAa,CAAC,CAAC;AACpD,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface MRZData {
|
|
2
|
+
documentType: string;
|
|
3
|
+
issuingState: string;
|
|
4
|
+
lastName: string;
|
|
5
|
+
firstName: string;
|
|
6
|
+
passportNumber: string;
|
|
7
|
+
nationality: string;
|
|
8
|
+
dateOfBirth: Date;
|
|
9
|
+
gender: string;
|
|
10
|
+
expiryDate: Date;
|
|
11
|
+
personalNumber: string;
|
|
12
|
+
age: number;
|
|
13
|
+
}
|
|
14
|
+
export declare function validateCheckDigit(str: string, checkDigit: string): boolean;
|
|
15
|
+
export declare function parseTD3(line1: string, line2: string): MRZData;
|
|
16
|
+
//# sourceMappingURL=mrz.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mrz.d.ts","sourceRoot":"","sources":["../../src/utils/mrz.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,OAAO;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,IAAI,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,IAAI,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,GAAG,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAgB3E;AAwBD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CA0D9D"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
export function validateCheckDigit(str, checkDigit) {
|
|
2
|
+
const weights = [7, 3, 1];
|
|
3
|
+
let sum = 0;
|
|
4
|
+
for (let i = 0; i < str.length; i++) {
|
|
5
|
+
const char = str[i];
|
|
6
|
+
let value = 0;
|
|
7
|
+
if (char === '<') {
|
|
8
|
+
value = 0;
|
|
9
|
+
}
|
|
10
|
+
else if (/[0-9]/.test(char)) {
|
|
11
|
+
value = parseInt(char);
|
|
12
|
+
}
|
|
13
|
+
else if (/[A-Z]/.test(char)) {
|
|
14
|
+
value = char.charCodeAt(0) - 65 + 10;
|
|
15
|
+
}
|
|
16
|
+
sum += value * weights[i % 3];
|
|
17
|
+
}
|
|
18
|
+
return (sum % 10) === parseInt(checkDigit);
|
|
19
|
+
}
|
|
20
|
+
function parseDate(str, isDOB = false) {
|
|
21
|
+
const yearStr = str.substring(0, 2);
|
|
22
|
+
const month = parseInt(str.substring(2, 4)) - 1;
|
|
23
|
+
const day = parseInt(str.substring(4, 6));
|
|
24
|
+
let year = parseInt(yearStr);
|
|
25
|
+
const currentYear = new Date().getFullYear() % 100;
|
|
26
|
+
if (isDOB) {
|
|
27
|
+
if (year > currentYear) {
|
|
28
|
+
year += 1900;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
year += 2000;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
// For expiry date, assume 20xx
|
|
36
|
+
year += 2000;
|
|
37
|
+
}
|
|
38
|
+
return new Date(year, month, day);
|
|
39
|
+
}
|
|
40
|
+
export function parseTD3(line1, line2) {
|
|
41
|
+
if (line1.length !== 44 || line2.length !== 44) {
|
|
42
|
+
throw new Error('Invalid TD3 MRZ length');
|
|
43
|
+
}
|
|
44
|
+
const documentType = line1.substring(0, 2).replace(/</g, '');
|
|
45
|
+
const issuingState = line1.substring(2, 5).replace(/</g, '');
|
|
46
|
+
const namesPart = line1.substring(5);
|
|
47
|
+
const [lastNamePart, firstNamePart] = namesPart.split('<<');
|
|
48
|
+
const lastName = lastNamePart.replace(/</g, ' ').trim();
|
|
49
|
+
const firstName = (firstNamePart || '').replace(/</g, ' ').trim();
|
|
50
|
+
const passportNumber = line2.substring(0, 9).replace(/</g, '');
|
|
51
|
+
const passportCheck = line2.substring(9, 10);
|
|
52
|
+
if (!validateCheckDigit(line2.substring(0, 9), passportCheck)) {
|
|
53
|
+
throw new Error('Invalid passport number check digit');
|
|
54
|
+
}
|
|
55
|
+
const nationality = line2.substring(10, 13).replace(/</g, '');
|
|
56
|
+
const dobStr = line2.substring(13, 19);
|
|
57
|
+
const dobCheck = line2.substring(19, 20);
|
|
58
|
+
if (!validateCheckDigit(dobStr, dobCheck)) {
|
|
59
|
+
throw new Error('Invalid date of birth check digit');
|
|
60
|
+
}
|
|
61
|
+
const dateOfBirth = parseDate(dobStr, true);
|
|
62
|
+
const gender = line2.substring(20, 21);
|
|
63
|
+
const expiryStr = line2.substring(21, 27);
|
|
64
|
+
const expiryCheck = line2.substring(27, 28);
|
|
65
|
+
if (!validateCheckDigit(expiryStr, expiryCheck)) {
|
|
66
|
+
throw new Error('Invalid expiry date check digit');
|
|
67
|
+
}
|
|
68
|
+
const expiryDate = parseDate(expiryStr, false);
|
|
69
|
+
const personalNumber = line2.substring(28, 42).replace(/</g, '');
|
|
70
|
+
// Calculate age
|
|
71
|
+
const today = new Date();
|
|
72
|
+
let age = today.getFullYear() - dateOfBirth.getFullYear();
|
|
73
|
+
const m = today.getMonth() - dateOfBirth.getMonth();
|
|
74
|
+
if (m < 0 || (m === 0 && today.getDate() < dateOfBirth.getDate())) {
|
|
75
|
+
age--;
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
documentType,
|
|
79
|
+
issuingState,
|
|
80
|
+
lastName,
|
|
81
|
+
firstName,
|
|
82
|
+
passportNumber,
|
|
83
|
+
nationality,
|
|
84
|
+
dateOfBirth,
|
|
85
|
+
gender,
|
|
86
|
+
expiryDate,
|
|
87
|
+
personalNumber,
|
|
88
|
+
age,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=mrz.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mrz.js","sourceRoot":"","sources":["../../src/utils/mrz.ts"],"names":[],"mappings":"AAcA,MAAM,UAAU,kBAAkB,CAAC,GAAW,EAAE,UAAkB;IAC9D,MAAM,OAAO,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1B,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;YACf,KAAK,GAAG,CAAC,CAAC;QACd,CAAC;aAAM,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;aAAM,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;QACzC,CAAC;QACD,GAAG,IAAI,KAAK,GAAG,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,CAAC,GAAG,GAAG,EAAE,CAAC,KAAK,QAAQ,CAAC,UAAU,CAAC,CAAC;AAC/C,CAAC;AAED,SAAS,SAAS,CAAC,GAAW,EAAE,QAAiB,KAAK;IAClD,MAAM,OAAO,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACpC,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAChD,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAE1C,IAAI,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC7B,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,GAAG,GAAG,CAAC;IAEnD,IAAI,KAAK,EAAE,CAAC;QACR,IAAI,IAAI,GAAG,WAAW,EAAE,CAAC;YACrB,IAAI,IAAI,IAAI,CAAC;QACjB,CAAC;aAAM,CAAC;YACJ,IAAI,IAAI,IAAI,CAAC;QACjB,CAAC;IACL,CAAC;SAAM,CAAC;QACJ,+BAA+B;QAC/B,IAAI,IAAI,IAAI,CAAC;IACjB,CAAC;IAED,OAAO,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,KAAa,EAAE,KAAa;IACjD,IAAI,KAAK,CAAC,MAAM,KAAK,EAAE,IAAI,KAAK,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC9C,CAAC;IAED,MAAM,YAAY,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAC7D,MAAM,YAAY,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAE7D,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IACrC,MAAM,CAAC,YAAY,EAAE,aAAa,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACxD,MAAM,SAAS,GAAG,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAElE,MAAM,cAAc,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAC/D,MAAM,aAAa,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC7C,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,aAAa,CAAC,EAAE,CAAC;QAC5D,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,WAAW,GAAG,KAAK,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACvC,MAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACzC,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACzD,CAAC;IACD,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAE5C,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACvC,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC1C,MAAM,WAAW,GAAG,KAAK,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC5C,IAAI,CAAC,kBAAkB,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACvD,CAAC;IACD,MAAM,UAAU,GAAG,SAAS,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAE/C,MAAM,cAAc,GAAG,KAAK,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAEjE,gBAAgB;IAChB,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC;IACzB,IAAI,GAAG,GAAG,KAAK,CAAC,WAAW,EAAE,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC;IAC1D,MAAM,CAAC,GAAG,KAAK,CAAC,QAAQ,EAAE,GAAG,WAAW,CAAC,QAAQ,EAAE,CAAC;IACpD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,GAAG,WAAW,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;QAChE,GAAG,EAAE,CAAC;IACV,CAAC;IAED,OAAO;QACH,YAAY;QACZ,YAAY;QACZ,QAAQ;QACR,SAAS;QACT,cAAc;QACd,WAAW;QACX,WAAW;QACX,MAAM;QACN,UAAU;QACV,cAAc;QACd,GAAG;KACN,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export interface OCROutput {
|
|
2
|
+
rawText: string;
|
|
3
|
+
mrzLines: string[];
|
|
4
|
+
confidence: number;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* OCR Extractor for processing identity documents in the browser
|
|
8
|
+
*/
|
|
9
|
+
export declare class OCRExtractor {
|
|
10
|
+
private worker;
|
|
11
|
+
private initialized;
|
|
12
|
+
/**
|
|
13
|
+
* Initialize the Tesseract worker
|
|
14
|
+
*/
|
|
15
|
+
initialize(): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Extract MRZ data from an image
|
|
18
|
+
* @param imageSource - URL, File, or Blob of the document image
|
|
19
|
+
* @returns Extracted text and MRZ lines
|
|
20
|
+
*/
|
|
21
|
+
extractMRZ(imageSource: string | File | Blob): Promise<OCROutput>;
|
|
22
|
+
/**
|
|
23
|
+
* Filter and clean MRZ lines from raw OCR text
|
|
24
|
+
*/
|
|
25
|
+
private filterMRZLines;
|
|
26
|
+
/**
|
|
27
|
+
* Terminate the worker to free resources
|
|
28
|
+
*/
|
|
29
|
+
terminate(): Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=ocr.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ocr.d.ts","sourceRoot":"","sources":["../../src/utils/ocr.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,SAAS;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,qBAAa,YAAY;IACrB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,WAAW,CAAkB;IAErC;;OAEG;IACG,UAAU;IAOhB;;;;OAIG;IACG,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC;IAyBvE;;OAEG;IACH,OAAO,CAAC,cAAc;IAetB;;OAEG;IACG,SAAS;CAOlB"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { createWorker } from 'tesseract.js';
|
|
2
|
+
/**
|
|
3
|
+
* OCR Extractor for processing identity documents in the browser
|
|
4
|
+
*/
|
|
5
|
+
export class OCRExtractor {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.worker = null;
|
|
8
|
+
this.initialized = false;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Initialize the Tesseract worker
|
|
12
|
+
*/
|
|
13
|
+
async initialize() {
|
|
14
|
+
if (this.initialized)
|
|
15
|
+
return;
|
|
16
|
+
this.worker = await createWorker('eng'); // MRZ is always Latin characters
|
|
17
|
+
this.initialized = true;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Extract MRZ data from an image
|
|
21
|
+
* @param imageSource - URL, File, or Blob of the document image
|
|
22
|
+
* @returns Extracted text and MRZ lines
|
|
23
|
+
*/
|
|
24
|
+
async extractMRZ(imageSource) {
|
|
25
|
+
await this.initialize();
|
|
26
|
+
if (!this.worker) {
|
|
27
|
+
throw new Error('OCR Worker not initialized');
|
|
28
|
+
}
|
|
29
|
+
// Set parameters to optimize for MRZ
|
|
30
|
+
// MRZ uses a specific OCR-B font, but standard 'eng' is usually sufficient
|
|
31
|
+
// We can restrict characters to A-Z, 0-9, and '<'
|
|
32
|
+
await this.worker.setParameters({
|
|
33
|
+
tessedit_char_whitelist: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789<',
|
|
34
|
+
});
|
|
35
|
+
const { data: { text, confidence } } = await this.worker.recognize(imageSource);
|
|
36
|
+
const mrzLines = this.filterMRZLines(text);
|
|
37
|
+
return {
|
|
38
|
+
rawText: text,
|
|
39
|
+
mrzLines,
|
|
40
|
+
confidence,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Filter and clean MRZ lines from raw OCR text
|
|
45
|
+
*/
|
|
46
|
+
filterMRZLines(text) {
|
|
47
|
+
const lines = text.split('\n').map(l => l.trim().replace(/\s/g, ''));
|
|
48
|
+
// TD3 MRZ (Passport) is 2 lines of 44 characters
|
|
49
|
+
// TD1 (ID Card) is 3 lines of 30 characters
|
|
50
|
+
// We look for lines containing multiple '<' characters
|
|
51
|
+
return lines.filter(line => {
|
|
52
|
+
const charCount = line.length;
|
|
53
|
+
const chevronCount = (line.match(/</g) || []).length;
|
|
54
|
+
// Heuristic: MRZ lines are long and have many chevrons
|
|
55
|
+
return (charCount >= 30 && chevronCount >= 2);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Terminate the worker to free resources
|
|
60
|
+
*/
|
|
61
|
+
async terminate() {
|
|
62
|
+
if (this.worker) {
|
|
63
|
+
await this.worker.terminate();
|
|
64
|
+
this.worker = null;
|
|
65
|
+
this.initialized = false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=ocr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ocr.js","sourceRoot":"","sources":["../../src/utils/ocr.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAe,MAAM,cAAc,CAAC;AAQzD;;GAEG;AACH,MAAM,OAAO,YAAY;IAAzB;QACY,WAAM,GAAkB,IAAI,CAAC;QAC7B,gBAAW,GAAY,KAAK,CAAC;IAsEzC,CAAC;IApEG;;OAEG;IACH,KAAK,CAAC,UAAU;QACZ,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO;QAE7B,IAAI,CAAC,MAAM,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,iCAAiC;QAC1E,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IAC5B,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,UAAU,CAAC,WAAiC;QAC9C,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QAExB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAClD,CAAC;QAED,qCAAqC;QACrC,2EAA2E;QAC3E,kDAAkD;QAClD,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC;YAC5B,uBAAuB,EAAE,uCAAuC;SACnE,CAAC,CAAC;QAEH,MAAM,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAEhF,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QAE3C,OAAO;YACH,OAAO,EAAE,IAAI;YACb,QAAQ;YACR,UAAU;SACb,CAAC;IACN,CAAC;IAED;;OAEG;IACK,cAAc,CAAC,IAAY;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;QAErE,iDAAiD;QACjD,4CAA4C;QAC5C,uDAAuD;QACvD,OAAO,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;YACvB,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC;YAC9B,MAAM,YAAY,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;YAErD,uDAAuD;YACvD,OAAO,CAAC,SAAS,IAAI,EAAE,IAAI,YAAY,IAAI,CAAC,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;IACP,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,SAAS;QACX,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACd,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YAC9B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YACnB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QAC7B,CAAC;IACL,CAAC;CACJ"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import type { Provider, ContractTransactionReceipt, EventLog, Log } from 'ethers';
|
|
2
|
+
/**
|
|
3
|
+
* Contract addresses configuration
|
|
4
|
+
*/
|
|
5
|
+
export interface ContractAddresses {
|
|
6
|
+
CredentialRegistry: string;
|
|
7
|
+
ZKVerifier: string;
|
|
8
|
+
ProtocolAccessControl: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Protocol requirements structure
|
|
12
|
+
*/
|
|
13
|
+
export interface Requirements {
|
|
14
|
+
minAge: number;
|
|
15
|
+
allowedJurisdictions: string[];
|
|
16
|
+
requireAccredited: boolean;
|
|
17
|
+
isSet?: boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Issuer information structure
|
|
21
|
+
*/
|
|
22
|
+
export interface IssuerInfo {
|
|
23
|
+
isTrusted: boolean;
|
|
24
|
+
name: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* ZK Proof structure (Groth16 format)
|
|
28
|
+
*/
|
|
29
|
+
export interface Proof {
|
|
30
|
+
a: [string, string];
|
|
31
|
+
b: [[string, string], [string, string]];
|
|
32
|
+
c: [string, string];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* ZK Proof structure (alias for compatibility)
|
|
36
|
+
*/
|
|
37
|
+
export type ZKProof = Proof;
|
|
38
|
+
/**
|
|
39
|
+
* Transaction result
|
|
40
|
+
*/
|
|
41
|
+
export interface TransactionResult {
|
|
42
|
+
transactionHash: string;
|
|
43
|
+
receipt: ContractTransactionReceipt | null;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Contract client configuration options
|
|
47
|
+
*/
|
|
48
|
+
export interface ContractClientConfig {
|
|
49
|
+
provider?: Provider;
|
|
50
|
+
contractAddresses?: ContractAddresses;
|
|
51
|
+
rpcUrl?: string;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Protocol client configuration
|
|
55
|
+
*/
|
|
56
|
+
export interface ProtocolClientConfig {
|
|
57
|
+
protocolAccessControlAddress?: string;
|
|
58
|
+
provider?: Provider;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Set requirements parameters
|
|
62
|
+
*/
|
|
63
|
+
export interface SetRequirementsParams {
|
|
64
|
+
minAge: number;
|
|
65
|
+
jurisdictions: string[] | number[];
|
|
66
|
+
requireAccredited: boolean;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Verify user access parameters
|
|
70
|
+
*/
|
|
71
|
+
export interface VerifyUserAccessParams {
|
|
72
|
+
userAddress: string;
|
|
73
|
+
proof: Proof;
|
|
74
|
+
publicSignals: string[] | number[];
|
|
75
|
+
credentialHash: string;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Credential issued event payload
|
|
79
|
+
*/
|
|
80
|
+
export interface CredentialIssuedEvent {
|
|
81
|
+
user: string;
|
|
82
|
+
credentialHash: string;
|
|
83
|
+
issuer: string;
|
|
84
|
+
timestamp: bigint;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Access granted event payload
|
|
88
|
+
*/
|
|
89
|
+
export interface AccessGrantedEvent {
|
|
90
|
+
user: string;
|
|
91
|
+
protocol: string;
|
|
92
|
+
credentialHash: string;
|
|
93
|
+
timestamp: bigint;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Contract event listener callback type
|
|
97
|
+
*/
|
|
98
|
+
export type EventCallback<T = any> = (...args: T[]) => void | Promise<void>;
|
|
99
|
+
/**
|
|
100
|
+
* Contract event payload type
|
|
101
|
+
*/
|
|
102
|
+
export type ContractEventPayload = EventLog | Log;
|
|
103
|
+
/**
|
|
104
|
+
* Credential data structure for hash generation
|
|
105
|
+
*/
|
|
106
|
+
export interface CredentialData {
|
|
107
|
+
userAddress: string;
|
|
108
|
+
age: number;
|
|
109
|
+
jurisdiction: string;
|
|
110
|
+
accredited: boolean;
|
|
111
|
+
timestamp?: number;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Credential hash generation result
|
|
115
|
+
*/
|
|
116
|
+
export interface CredentialHashResult {
|
|
117
|
+
credentialHash: string;
|
|
118
|
+
jurisdictionHash: string;
|
|
119
|
+
credentialData: string;
|
|
120
|
+
timestamp: number;
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/utils/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/utils/types.ts"],"names":[],"mappings":""}
|