* feat: selfrica circuit and tests * chore: remove unused code * feat: test for ofac,date and olderthan * fix: public signal constant * feat: add contract tests * feat: helper function to gen TEE input * feat: gen circuit inputs with signature * feat: seralized base64 * fix: DateIsLessFullYear componenet * feat: register circuit for selfrica * feat: selfrica disclose circuit and test * fix: common module error * feat: add more test and fix constant * fix: commitment calculation * feat: selfrica contracts * test: selfrica register using unified circuit * feat: register persona and selfrica circuit * feat: selfrica circuit and tests * chore: remove unused code * feat: test for ofac,date and olderthan * fix: public signal constant * feat: add contract tests * feat: helper function to gen TEE input * feat: gen circuit inputs with signature * feat: seralized base64 * fix: DateIsLessFullYear componenet * feat: register circuit for selfrica * feat: selfrica disclose circuit and test * fix: common module error * feat: add more test and fix constant * fix: commitment calculation * feat: selfrica contracts * test: selfrica register using unified circuit * feat: register persona and selfrica circuit * refactor: contract size reduction for IdentityVerificationHubImplV2 export function logic to external libs, reduce compiler runs to 200, update deploy scripts to link new libs * feat: disclose circuit for persona * feat: update persona ofac trees * feat; register circuit for selfper * feat: disclose test for selfper * chore: refactor * chore : remove unused circuits * chore: rename selfper to kyc * chore: update comments * feat: constrain s to be 251 bit * feat: add range check on majority ASCII and comments * feat: range check on neg_r_inv * chore: remove is pk zero constrain * merge dev * feat: add registerPubkey function to Selfrica with GCPJWT Verification * test: add testing for GCPJWT verification on Selfrica * fix: script that calls register_selfrica circuits (ptau:14 -> ptau:15) * fix: get remaining Selfrica tests working with proper import paths * refactor: store pubkeys as string also add some comment code for registerPubkey function * refactor: remove registerPubkeyCommitment function some tests now skipped as awaiting changes to how pubkeys are stored (string instead of uint256) * feat: use hex decoding for the pubkey commitment * test: adjust tests for pubkey being string again * fix: remove old references to registerPubkey * docs: add full natspec for IdentityRegistrySelfricaImplV1 * docs: update files in rest of the repo for Selfrica attestation type * test: fix broken tests * fix: builds and move to kyc from selfrica * fix: constrain r_inv, Rx, s, T * feat: eddsa * feat: add onlyTEE check to registerPubkeyCommitment onlyOwner is able to change onlyTEE * refactor: update gcpRootCAPubkeyHash to be changeable by owner * feat: add events for update functions * style: move functions to be near other similar functions * fix: kyc happy flow * fix: all contract tests passing | fix: timestamp conversion with Date(), migrate to V2 for endToEnd test, scope formatting, fix register aadhaar issue by using block.timestamp instead of Date.now(), fix changed getter function name, enable MockGCPJWTVerifier with updated file paths, add missing LeanIMT import, fix user identifier format * audit: bind key offset-value offset and ensure image_digest only occurs once in the payload * fix: constrain bracket * chore: update comment * audit: hardcode attestation id * audit: make sure R and pubkey are on the curve * audit: ensure pubkey is within bounds * fix: all contract tests passing * feat: change max length to 99 from 74 * audit: don't check sha256 padding * audit: check the last window as well * audit: single occurance for eat_nonce and image_digest * audit: check if the certs are expired * audit: add the timestamp check to the contract * audit: make sure the person is less than 255 years of age * audit fixes * chore: yarn.lock * fix: build fixes * fix: aadhaar timestamp * lint * fix: types * format --------- Co-authored-by: vishal <vishalkoolkarni0045@gmail.com> Co-authored-by: Evi Nova <tranquil_flow@protonmail.com>
Self Protocol Go SDK
A Go SDK for integrating with the Self protocol for privacy-preserving identity verification using zero-knowledge proofs and passport/ID card attestations.
Installation
go get github.com/selfxyz/self/sdk/sdk-go@main
Quick Start
Basic Usage
package main
import (
"context"
"fmt"
"log"
"github.com/selfxyz/self/sdk/sdk-go"
"github.com/selfxyz/self/sdk/sdk-go/common"
)
func main() {
// Create a verification configuration
config := self.VerificationConfig{
MinimumAge: &[]int{18}[0], // Require 18+ years
ExcludedCountries: []common.Country3LetterCode{common.USA}, // Exclude USA
Ofac: &[]bool{false}[0], // Allow OFAC flagged individuals
}
// Create a config store
configStore := self.NewDefaultConfigStore(config)
// Define allowed attestation types
allowedIds := map[self.AttestationId]bool{
self.Passport: true,
self.EUCard: true,
}
// Initialize the verifier
verifier, err := self.NewBackendVerifier(
"my-app-scope", // Your application scope
"https://my-app.com", // Your application endpoint
false, // Use mainnet (true for testnet)
allowedIds, // Allowed attestation types
configStore, // Configuration storage
self.UserIDTypeHex, // User identifier type
)
if err != nil {
log.Fatal(err)
}
// Verify a proof (these would come from your frontend)
ctx := context.Background()
result, err := verifier.Verify(
ctx,
"1", // Attestation ID (passport)
proof, // Zero-knowledge proof from frontend
publicSignals, // Public signals from frontend
userContextData, // User context data from frontend
)
if err != nil {
log.Printf("Verification failed: %v", err)
return
}
// Check verification results
if result.IsValidDetails.IsValid {
fmt.Printf("✅ Verification successful!\n")
fmt.Printf("User ID: %s\n", result.UserData.UserIdentifier)
fmt.Printf("Age verification: %v\n", result.IsValidDetails.IsMinimumAgeValid)
fmt.Printf("OFAC verification: %v\n", result.IsValidDetails.IsOfacValid)
fmt.Printf("Nationality: %s\n", result.DiscloseOutput.Nationality)
} else {
fmt.Printf("❌ Verification failed\n")
}
}
Configuration
Verification Config
The VerificationConfig struct allows you to specify verification requirements:
type VerificationConfig struct {
MinimumAge *int // Minimum age requirement (nil to disable)
ExcludedCountries []common.Country3LetterCode // Countries to exclude
Ofac *bool // OFAC compliance (nil to ignore)
}
Config Storage
Implement the ConfigStore interface for custom configuration management:
type ConfigStore interface {
GetConfig(ctx context.Context, id string) (VerificationConfig, error)
SetConfig(ctx context.Context, id string, config VerificationConfig) (bool, error)
GetActionId(ctx context.Context, userIdentifier string, actionId string) (string, error)
}
For simple use cases, use DefaultConfigStore:
configStore := self.NewDefaultConfigStore(config)
For more complex scenarios, implement your own:
type DatabaseConfigStore struct {
db *sql.DB
}
func (d *DatabaseConfigStore) GetConfig(ctx context.Context, id string) (self.VerificationConfig, error) {
// Your database logic here
}
func (d *DatabaseConfigStore) SetConfig(ctx context.Context, id string, config self.VerificationConfig) (bool, error) {
// Your database logic here
}
func (d *DatabaseConfigStore) GetActionId(ctx context.Context, userIdentifier string, actionId string) (string, error) {
// Your database logic here
}
Attestation Types
The SDK supports two attestation types:
self.Passport: Traditional passport verificationself.EUCard: European ID card verification
Network Configuration
Mainnet (Production)
verifier, err := self.NewBackendVerifier(
scope, endpoint, false, // mockPassport = false for mainnet
allowedIds, configStore, userIdType,
)
Testnet (Development)
verifier, err := self.NewBackendVerifier(
scope, endpoint, true, // mockPassport = true for testnet
allowedIds, configStore, userIdType,
)
User Identifier Types
Choose how user identifiers are formatted:
self.UserIDTypeHex // Hex format: 0x1234...
self.UserIDTypeUUID // UUID format: 12345678-1234-1234-1234-123456789abc
Country Codes
Use 3-letter ISO country codes for exclusions:
import "github.com/selfxyz/self/sdk/sdk-go/common"
excludedCountries := []common.Country3LetterCode{
common.USA, // United States
common.RUS, // Russia
common.CHN, // China
}
Error Handling
The SDK provides detailed error information through ConfigMismatchError:
result, err := verifier.Verify(ctx, attestationId, proof, signals, contextData)
if err != nil {
if configErr, ok := err.(*self.ConfigMismatchError); ok {
fmt.Println("Configuration issues:")
for _, issue := range configErr.Issues {
fmt.Printf("- %s: %s\n", issue.Type, issue.Message)
}
} else {
fmt.Printf("Other error: %v\n", err)
}
return
}
Verification Result
The VerificationResult contains comprehensive verification information:
type VerificationResult struct {
AttestationId AttestationId // Type of attestation verified
IsValidDetails IsValidDetails // Validation status details
ForbiddenCountriesList []string // List of forbidden countries
DiscloseOutput GenericDiscloseOutput // Disclosed identity information
UserData UserData // User-specific data
}
type IsValidDetails struct {
IsValid bool // Overall proof validity
IsMinimumAgeValid bool // Age requirement met
IsOfacValid bool // OFAC compliance
}
type GenericDiscloseOutput struct {
Nullifier string // Unique nullifier for this proof
IssuingState string // Country that issued the document
Name string // Full name
IdNumber string // Document ID number
Nationality string // Nationality
DateOfBirth string // Date of birth
Gender string // Gender
ExpiryDate string // Document expiry date
MinimumAge string // Minimum age disclosed
Ofac []bool // OFAC check results
}
Examples
Age Verification (18+)
config := self.VerificationConfig{
MinimumAge: &[]int{18}[0],
}
Country Restrictions
config := self.VerificationConfig{
ExcludedCountries: []common.Country3LetterCode{
common.USA,
common.RUS,
common.IRN,
},
}
OFAC Compliance
config := self.VerificationConfig{
Ofac: &[]bool{true}[0], // Require OFAC compliance
}
Combined Requirements
config := self.VerificationConfig{
MinimumAge: &[]int{21}[0],
ExcludedCountries: []common.Country3LetterCode{common.USA},
Ofac: &[]bool{true}[0],
}
Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
For support and questions:
- Create an issue in this repository
- Check the Self Protocol documentation
- Join our Discord community