System Architecture
identiPay is a full-stack privacy protocol combining blockchain smart contracts, zero-knowledge circuits, backend indexers, and mobile applications. The architecture ensures that transactions are anonymous on-chain while still enabling verifiable compliance checks like age gates.High-Level Component Diagram
Layer 1: Smart Contracts (Sui Move)
All protocol logic runs on Sui blockchain using Move smart contracts. The package consists of 9 interdependent modules:Settlement Module
Location:contracts/sources/settlement.move
The core orchestrator for atomic commerce transactions. The execute_commerce entry function is the main entry point for all payments:
- Atomicity: All operations succeed or fail together - no partial execution
- Replay protection: Tracks executed intent hashes in
SettlementState.executed_intents - Expiry enforcement: Rejects proposals past their timestamp
- Artifact delivery: Mints encrypted
Receiptand optionalWarrantyNFTs to buyer’s stealth address
The settlement module emits
SettlementEvent indexed by intent_hash, NOT buyer identity, preserving anonymity.Shielded Pool Module
Location:contracts/sources/shielded_pool.move
A privacy firewall for coin merging. When users need to combine funds from multiple stealth addresses, they deposit into the pool and withdraw to a fresh address via zero-knowledge proof.
poseidon::poseidon_bn254 function, ensuring compatibility with Circom circuits.
ZK Verifier Module
Location:contracts/sources/zk_verifier.move
Verifies Groth16 zero-knowledge proofs on-chain using the BN254 elliptic curve. Verification keys are stored as shared objects:
identity_registrationVK (for name registration)age_checkVK (for age-gated transactions)pool_spendVK (for shielded pool withdrawals)
Meta Address Registry
Location:contracts/sources/meta_address_registry.move
Maps human-readable names (@alice.idpay) to stealth address public key pairs:
- Names are unique and immutable once registered
- Identity commitment must be unique (prevents Sybil attacks)
- Registration requires ZK proof of valid passport credentials
Trust Registry
Location:contracts/sources/trust_registry.move
Stores merchant DIDs (Decentralized Identifiers) for verification:
Announcements Module
Location:contracts/sources/announcements.move
Broadcasts stealth address outputs so recipients can discover incoming payments:
- Filtering by view tag (1-byte fast check)
- Computing ECDH shared secret with ephemeral key
- Deriving stealth private key if the address belongs to them
Receipt Module
Mints encrypted receipt NFTs to buyer’s stealth address. Contains purchase details, merchant signature, and ECDH-encrypted payload.
Warranty Module
Optional encrypted warranty NFTs. Can be transferred to new owners if
transferable: true.Intent Module
Verifies Ed25519 signatures over canonical intent hashes to prove buyer authorization.
Layer 2: Backend Services (Deno + Hono)
Location:backend/src/
The backend is a Deno runtime application using Hono web framework, Drizzle ORM, and PostgreSQL. It provides:
REST API
Base URL:https://api.idpay.dev/api/identipay/v1
POST /proposals
POST /proposals
Auth: API key (merchant only)Create a payment proposal with constraints:Returns QR code, transaction ID, and intent hash.
GET /intents/:txId
GET /intents/:txId
Auth: PublicResolve a proposal by transaction ID. Wallets fetch this to display transaction details before signing.Response includes:
- Intent hash (canonical transaction identifier)
- Merchant info (name, DID, public key, Sui address)
- Amount, currency, description
- Constraints (age gates, etc.)
- Expiry timestamp
GET /announcements
GET /announcements
Auth: PublicQuery stealth announcements with pagination:The
viewTag parameter is OPTIONAL - wallets SHOULD fetch all and filter locally to avoid revealing their view tag set to the backend (privacy invariant).GET /names/:name
GET /names/:name
Auth: PublicResolve a meta-address name to public keys:Used by senders to derive stealth addresses for recipients.
POST /merchants/register
POST /merchants/register
Auth: Admin keyRegister a new merchant on-chain and issue API key:Backend generates DID, submits to
trust_registry, and returns API key.Event Indexers
Polling Architecture: The backend runs two polling loops at 3-second intervals to index blockchain events:- Subscribes to
settlement::SettlementEvent - Updates proposal status from
pending→settled - Pushes WebSocket notifications to waiting clients
- Subscribes to
announcements::StealthAnnouncement - Stores announcements in PostgreSQL for efficient wallet scanning
- Allows filtering by view tag and timestamp
Gas Sponsorship
Merchants can sponsor user transactions via the/transactions/sponsor-send endpoint:
- User signs with stealth private key (owns the coin)
- Gas sponsor signs with backend key (owns the gas)
Layer 3: Mobile Applications (Android/Kotlin)
Two Android apps built with Jetpack Compose:Wallet App
Location:android/wallet-app/
Key Modules:
Crypto Layer
crypto/ - Native implementations:PoseidonHash.kt- BN254 field arithmeticStealthAddress.kt- ECDH key exchange, address derivationEd25519Ops.kt- Signing with raw scalarsIdentityCommitment.kt- Passport → commitmentSeedManager.kt- BIP39 + passport-based KDF
ZK Proof Generation
zk/ProofGenerator.kt - JNI bridge to Rust- Loads compiled R1CS circuits
- Generates Groth16 proofs on-device
- Serializes proofs for Sui verification
Data Layer
data/ - Room database + Repositories:StealthAddressDao- Tracks owned addressesNoteDao- Tracks shielded pool notesTransactionDao- HistoryPaymentRepository- Send/receive logicPoolRepository- Shielded pool interactions
NFC Scanner
nfc/PassportReader.kt - ICAO 9303 reader:- BAC (Basic Access Control) authentication
- DG1 (MRZ data) extraction
- DG15 (public key) for active auth
- SOD (Document Security Object) parsing
- Fetching announcements from backend
- Computing ECDH shared secret for each ephemeral key
- Deriving expected stealth address
- If match → store stealth private key, query on-chain balance
POS/Merchant App
Location:android/identipayPOS/
Simplified app for merchants to:
- Create payment proposals
- Display QR codes
- Monitor settlement status via WebSocket
- Print receipts on settlement
Layer 4: Zero-Knowledge Circuits (Circom)
Location:circuits/
Identity Registration Circuit
File:identity_registration.circom (~700 constraints)
Age Check Circuit
File:age_check.circom (~1.2K constraints)
Proves currentYear - birthYear >= minAge without revealing exact birthdate. Uses range proofs via bit decomposition.
Pool Spend Circuit
File:pool_spend.circom (~35K constraints)
The most complex circuit. Proves:
- You own a note in the Merkle tree (membership proof)
- The nullifier is correctly derived (prevents double-spend)
- Withdraw amount ≤ note amount (range check via
Num2Bits(64)) - Change commitment is valid if partial withdraw
All circuits use Poseidon hashing over BN254 scalar field for Merkle trees, matching Sui’s native
poseidon::poseidon_bn254 implementation.Security Properties
Transaction Anonymity
Transaction Anonymity
On-chain observers see:
- Random-looking stealth addresses (no linkage)
- Transfer amounts (unavoidable for token transfers)
- Settlement events indexed by intent hash (NOT user identity)
- User’s real identity or meta-address name
- Buyer’s other transactions (no address reuse)
- Relationship between different stealth addresses
Identity Privacy
Identity Privacy
Identity commitments hide:
- Passport number
- Date of birth
- Nationality
- Issuing authority
Merchant Privacy
Merchant Privacy
Merchants are NOT anonymous - they are registered in
trust_registry with:- DID (public identifier)
- Sui address (for receiving payments)
- Public key (for encrypting receipts)
Receipt Confidentiality
Receipt Confidentiality
Receipts are encrypted via ECDH:
- Merchant generates ephemeral X25519 keypair
- Derives shared secret with buyer’s view public key
- Encrypts receipt JSON with AES-256-GCM
- Stores encrypted blob on-chain
Deployment Architecture
- Blockchain: Sui Testnet
- Backend: Cloud-hosted Deno service (PostgreSQL)
- Mobile: Android APK (Google Play internal testing)
- Circuits: Pre-compiled to R1CS, proving keys embedded in APK
Next Steps
Smart Contracts
Detailed contract specifications and Move API reference
ZK Circuits
Circuit design, constraint analysis, and proving system details
Backend API
Complete REST API documentation with request/response schemas
Mobile SDK
Integration guide for building on top of identiPay
