0.0.25 • Published 9 months ago

@selfxyz/core v0.0.25

Weekly downloads
-
License
MIT
Repository
github
Last release
9 months ago

@selfxyz/core

SDK for verifying passport proofs from Self.

Installation

You can install with this command:

npm install @selfxyz/core
# or
yarn add @selfxyz/core

Initialization

Initialize the verifier with your RPC URL and application scope:

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:

// 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:

const result = await selfBackendVerifier.verify(proof, publicSignals);

Extracting User Identifier

You can extract the user identifier from the public signals:

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:

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:

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:

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:

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.

0.0.25

9 months ago

0.0.24

10 months ago

0.0.23

10 months ago

0.0.22

10 months ago

0.0.21

10 months ago

0.0.20

10 months ago

0.0.19

10 months ago

0.0.18

10 months ago

0.0.17

10 months ago

0.0.16

10 months ago

0.0.15

10 months ago

0.0.14

10 months ago

0.0.13

10 months ago

0.0.12

10 months ago

0.0.11

11 months ago

0.0.10

11 months ago

0.0.9

11 months ago

0.0.7

11 months ago

0.0.6

11 months ago

0.0.5

11 months ago

0.0.4

11 months ago

0.0.3

11 months ago

0.0.2

11 months ago

0.0.1

11 months ago