mirror of
https://github.com/selfxyz/self.git
synced 2026-04-05 03:00:53 -04:00
242 lines
6.8 KiB
Markdown
242 lines
6.8 KiB
Markdown
# @selfxyz/core
|
|
|
|
SDK for verifying passport proofs from Self.
|
|
|
|
## Installation
|
|
|
|
You can install with this command:
|
|
|
|
```bash
|
|
npm install @selfxyz/core
|
|
# or
|
|
yarn add @selfxyz/core
|
|
```
|
|
|
|
## Initialization
|
|
|
|
Initialize the verifier with your RPC URL and application scope:
|
|
|
|
```typescript
|
|
import { SelfBackendVerifier } from '@selfxyz/core';
|
|
|
|
const selfBackendVerifier = new SelfBackendVerifier(
|
|
process.env.CELO_RPC_URL as string, // e.g., 'https://forno.celo.org'
|
|
process.env.SCOPE as string // Your application's unique scope. Should be the same as when initializing SelfApp
|
|
);
|
|
```
|
|
|
|
## Configuration
|
|
|
|
You can configure which verification rules to apply:
|
|
|
|
```typescript
|
|
// Set minimum age verification (must be between 10-100)
|
|
selfBackendVerifier.setMinimumAge(20);
|
|
|
|
// Set nationality verification
|
|
selfBackendVerifier.setNationality('France');
|
|
|
|
// Set excluded countries verification (max 40 countries)
|
|
selfBackendVerifier.excludeCountries('Iran', 'North Korea', 'Russia', 'Syria');
|
|
|
|
// Enable passport number OFAC check (default: false)
|
|
selfBackendVerifier.enablePassportNoOfacCheck();
|
|
|
|
// Enable name and date of birth OFAC check (default: false)
|
|
selfBackendVerifier.enableNameAndDobOfacCheck();
|
|
|
|
// Enable name and year of birth OFAC check (default: false)
|
|
selfBackendVerifier.enableNameAndYobOfacCheck();
|
|
```
|
|
|
|
## Verification
|
|
|
|
Verify a proof with the received proof and public signals:
|
|
|
|
```typescript
|
|
const result = await selfBackendVerifier.verify(proof, publicSignals);
|
|
```
|
|
|
|
## Extracting User Identifier
|
|
|
|
You can extract the user identifier from the public signals:
|
|
|
|
```typescript
|
|
import { getUserIdentifier } from '@selfxyz/core';
|
|
|
|
const userId = await getUserIdentifier(publicSignals);
|
|
```
|
|
|
|
This allows linking proofs with verification requests generated by `@selfxyz/qrcode`.
|
|
|
|
## Verification Result
|
|
|
|
The `verify` method returns a detailed verification result:
|
|
|
|
```typescript
|
|
export interface SelfVerificationResult {
|
|
// Overall verification status
|
|
isValid: boolean;
|
|
|
|
// Detailed validation statuses
|
|
isValidDetails: {
|
|
isValidScope: boolean; // Proof was generated for the expected scope
|
|
isValidAttestationId: boolean; // Attestation ID matches expected value
|
|
isValidProof: boolean; // Cryptographic validity of the proof
|
|
isValidNationality: boolean; // Nationality check (when enabled)
|
|
};
|
|
|
|
// User identifier from the proof
|
|
userId: string;
|
|
|
|
// Application scope
|
|
application: string;
|
|
|
|
// Cryptographic nullifier to prevent reuse
|
|
nullifier: string;
|
|
|
|
// Revealed data from the passport
|
|
credentialSubject: {
|
|
merkle_root?: string; // Merkle root used for proof generation
|
|
attestation_id?: string; // Identity type (1 for passport)
|
|
current_date?: string; // Proof generation timestamp
|
|
issuing_state?: string; // Passport issuing country
|
|
name?: string; // User's name
|
|
passport_number?: string; // Passport number
|
|
nationality?: string; // User's nationality
|
|
date_of_birth?: string; // Date of birth
|
|
gender?: string; // Gender
|
|
expiry_date?: string; // Passport expiry date
|
|
older_than?: string; // Age verification result
|
|
passport_no_ofac?: boolean; // Passport OFAC check result.
|
|
// Gives true if the user passed the check (is not on the list),
|
|
// false if the check was not requested or if the user is in the list
|
|
name_and_dob_ofac?: boolean; // Name and DOB OFAC check result
|
|
name_and_yob_ofac?: boolean; // Name and birth year OFAC check result
|
|
};
|
|
|
|
// Original proof data
|
|
proof: {
|
|
value: {
|
|
proof: any;
|
|
publicSignals: any;
|
|
};
|
|
};
|
|
|
|
// Error information if verification failed
|
|
error?: any;
|
|
}
|
|
```
|
|
|
|
## API Implementation Example
|
|
|
|
Here's an example of implementing an API endpoint that uses the SDK:
|
|
|
|
```typescript
|
|
import { NextApiRequest, NextApiResponse } from 'next';
|
|
import { getUserIdentifier, SelfBackendVerifier, countryCodes } from '@selfxyz/core';
|
|
|
|
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|
if (req.method === 'POST') {
|
|
try {
|
|
const { proof, publicSignals } = req.body;
|
|
|
|
if (!proof || !publicSignals) {
|
|
return res.status(400).json({ message: 'Proof and publicSignals are required' });
|
|
}
|
|
|
|
// Extract user ID from the proof
|
|
const userId = await getUserIdentifier(publicSignals);
|
|
console.log('Extracted userId:', userId);
|
|
|
|
// Initialize and configure the verifier
|
|
const selfBackendVerifier = new SelfBackendVerifier(
|
|
'https://forno.celo.org',
|
|
'my-application-scope'
|
|
);
|
|
|
|
// Configure verification options
|
|
selfBackendVerifier.setMinimumAge(18);
|
|
selfBackendVerifier.excludeCountries(
|
|
countryCodes.IRN, // Iran
|
|
countryCodes.PRK // North Korea
|
|
);
|
|
selfBackendVerifier.enableNameAndDobOfacCheck();
|
|
|
|
// Verify the proof
|
|
const result = await selfBackendVerifier.verify(proof, publicSignals);
|
|
|
|
if (result.isValid) {
|
|
// Return successful verification response
|
|
return res.status(200).json({
|
|
status: 'success',
|
|
result: true,
|
|
credentialSubject: result.credentialSubject,
|
|
});
|
|
} else {
|
|
// Return failed verification response
|
|
return res.status(400).json({
|
|
status: 'error',
|
|
result: false,
|
|
message: 'Verification failed',
|
|
details: result.isValidDetails,
|
|
});
|
|
}
|
|
} catch (error) {
|
|
console.error('Error verifying proof:', error);
|
|
return res.status(500).json({
|
|
status: 'error',
|
|
result: false,
|
|
message: error instanceof Error ? error.message : 'Unknown error',
|
|
});
|
|
}
|
|
} else {
|
|
return res.status(405).json({ message: 'Method not allowed' });
|
|
}
|
|
}
|
|
```
|
|
|
|
## Working with Country Codes
|
|
|
|
The SDK provides a `countryCodes` object for referencing ISO country codes:
|
|
|
|
```typescript
|
|
import { countryCodes } from '@selfxyz/core';
|
|
|
|
// Examples of usage
|
|
const iranCode = countryCodes.IRN; // "Iran"
|
|
const northKoreaCode = countryCodes.PRK; // "North Korea"
|
|
|
|
// Use in excludeCountries
|
|
selfBackendVerifier.excludeCountries(countryCodes.IRN, countryCodes.PRK, countryCodes.SYR);
|
|
```
|
|
|
|
## Integration with SelfQRcode
|
|
|
|
This backend SDK is designed to work with the `@selfxyz/qrcode` package. When configuring your QR code, set the verification endpoint to point to your API that uses this SDK:
|
|
|
|
```typescript
|
|
import { SelfAppBuilder } from '@selfxyz/qrcode';
|
|
|
|
const selfApp = new SelfAppBuilder({
|
|
appName: 'My Application',
|
|
scope: 'my-application-scope',
|
|
endpoint: 'https://my-api.com/api/verify', // Your API using SelfBackendVerifier
|
|
logoBase64: myLogoBase64,
|
|
userId,
|
|
disclosures: {
|
|
name: true,
|
|
nationality: true,
|
|
date_of_birth: true,
|
|
passport_number: true,
|
|
minimumAge: 20,
|
|
excludedCountries: ['IRN', 'PRK'],
|
|
ofac: true,
|
|
},
|
|
}).build();
|
|
```
|
|
|
|
## Example
|
|
|
|
For a more advanced implementation example, see the [playground](https://github.com/selfxyz/playground/blob/main/pages/api/verify.ts).
|