Skip to main content

SollPay Architecture Design Overview

SollPay is a mobile application built on the Solana blockchain, providing an account abstraction wallet. This document offers a high-level overview of SollPay’s architecture. Our account abstraction approach leverages zero-knowledge proofs (ZKPs) to verify user identities without exposing any personal data.


Key Actors

1. Mobile App

  • The SollPay app serves as the wallet’s front end.
  • Users can interact with the Solana blockchain to make transactions or engage with DeFi protocols.
  • The app generates a public/private key pair in an isolated environment.

2. Google Firebase OAuth Service

  • Google provides email/SMS-based authentication.
  • Upon successful authentication, users receive a self-signed JWT token.
  • Like any standard JWT, it contains:
    • iss (issuer, always Google for us)
    • aud (audience, always SollPay)
    • sub (a unique user identifier)
    • phoneNumber (user phoneNumber)
  • We hash the field phoneNumber (Hash(phoneNumber)) to uniquely identify each user. We will use poseidon hash as the hash algorithm as it's zk friendly.

3. ZK Proving Server

  • This server operates within a trusted execution environment (TEE).
  • It generates zero-knowledge proofs based on the OAuth JWT.
  • These proofs validate ownership of an email address or phone number without revealing the actual personal information.

4. Wallet Factory Program

  • A Solana program that creates a smart wallet (i.e., a wallet account) for each user once their zero-knowledge verification is successful.

5. Wallet Program

  • Users interact with the Solana blockchain (e.g., to process transactions or use DeFi protocols) by signing transactions.
  • Each wallet program references the public key generated by the mobile app.

6. Administration Program

  • Maintains a mapping of userId -> wallet account address.
  • The userId is the hashed phone number (Hash(phoneNumber)), ensuring no personal data is exposed.
  • Specifically, the mapping structure is:
    • Key = Hash(phoneNumber)
    • Value = generated wallet account address

7. Octane

  • Octane is a gasless transaction relayer for Solana.
  • It is used so that users do not have to pay gas fees for wallet creation.
  • The relayer covers the transaction costs associated with creating new wallets.

User Workflow

This section describes how users interact with SollPay under three different scenarios:

  1. First-Time Signup
  2. Using an Existing Key Pair
  3. Re-Logging in on a New Device (or after data erasure)

Scenario 1: First-Time Login (User Signup)

When a user launches the SollPay mobile app for the first time (i.e., no existing public/private key pair on the device):

First-Time Login Diagram

  1. Generate Key Pair
    The mobile app generates a new pair of public/private keys.

  2. OAuth Login
    The user logs in via Google OAuth using SMS/Email.

    • A nonce, Hash(publicKey, timestamp), is included to prevent replay attacks.
  3. Obtain JWT
    Google’s OAuth service returns a JWT to the mobile app.

  4. Request ZK Proof
    The mobile app sends the JWT to the ZK Proving Server.

  5. Receive ZK Proof
    The ZK Proving Server returns the ZK proof to the mobile app.

  6. Create Wallet Account
    The mobile app submits the ZK proof and the user’s public key to the Wallet Factory Program.

  7. Verify Proof & Create Wallet
    The Wallet Factory Program verifies the ZK proof and lookup the userId -> wallet account address mapping table. If the wallet account doesn't exist, creates a new wallet account.

    • The user ID [Hash(phoneNumber)] is extracted from the ZK proof.
  8. Update Mapping Table
    The Administration Program updates its mapping of userId -> wallet account address with the new wallet account.

  9. Return Wallet Address
    The newly generated wallet account address is returned to the mobile app.


Scenario 2: Using an Existing Key Pair

When a user already has a valid public/private key pair stored on their device, they can transact without needing to log in via OAuth:

Using Existing Key Pair Diagram

  1. Sign Transaction
    The user signs a transaction locally using their private key.

  2. Submit Transaction
    The mobile app sends the signed transaction to the Wallet Program.

    • Since the wallet account is already linked to the user’s public key, the Wallet Program verifies and executes the transaction if the signature is valid.
  3. Return Execution Status
    The Wallet Program returns the transaction’s execution status to the mobile app.


Scenario 3: Re-Login on a New Device (or After Data Erasure)

When a user switches to a new device or erases local data, they no longer have a stored key pair and must log in again:

Re-Login Diagram

  1. Generate Key Pair
    The mobile app generates a new public/private key pair.

  2. OAuth Login
    The user logs in via Google OAuth using SMS/Email.

    • A nonce, Hash(publicKey, timestamp), is included to prevent replay attacks.
  3. Obtain JWT
    Google’s OAuth service returns a JWT to the mobile app.

  4. Request ZK Proof
    The mobile app sends the JWT to the ZK Proving Server.

  5. Receive ZK Proof
    The ZK Proving Server returns the ZK proof to the mobile app.

  6. Submit ZK Proof
    The mobile app submits the ZK proof and the new public key to the Wallet Factory Program.

  7. Verify Proof & Query Address
    The Wallet Factory Program verifies the ZK proof, then calls the Administration Program to look up the existing wallet account address.

8 & 9. Update Wallet with New Public Key
The Administration Program returns the wallet address, and the Wallet Factory Program (or Wallet Program) updates the user’s account with the new public key.

  1. Return Wallet Address
    The updated wallet account address is returned to the mobile app.

Scenario 4: Send funds to a new phoneNumber which is not associated to any account

When a user sends funds to a phoneNumber which is not associated to any account, we need to create a new smart wallet account for this phoneNumber.

Re-Login Diagram

  1. Create account request
    The mobile app calculates the User Id ([Hash(phoneNumber)]) and make a account creation request.

2 & 3. Wallet account lookup
The administion program looks up the mapping table.

  • If UserId doesn't exist in the mapping table, create a new account for the UserId and update the mapping table.
  • If UserId exists in the mapping table, return the smart wallet account address.
  1. Return Wallet Address
    The smart wallet account address is returned to the mobile app.

Mobile Local Storage

All necessary data is stored in the secure enclave of the mobile device, including:

  • The user’s public/private key pair
  • The wallet account address linked to that key pair

When a user logs in, the device securely stores these items to enable seamless transactions without repeatedly requiring OAuth verification (unless the user’s data is lost or the user switches to a new device).

Transaction signature security

The private key is generated and securely stored within the device's Secure Enclave (iOS) or Trusted Platform Module (TPM) (Android). This ensures that the private key is hardware-protected, never exported, and only accessible for signing operations.

Using Secure Enclave for Transaction Signing To sign transactions using the private key stored in the Secure Enclave, SollPay employs the ECDSA (Elliptic Curve Digital Signature Algorithm) with the curve secp256r1 (P-256). This algorithm is natively supported by most modern devices and offers a strong balance of performance and security.

Preventing Replay Attacks with Nonce To prevent replay attacks, each wallet account on the blockchain maintains an incrementing nonce. This nonce is included in every transaction and must be signed alongside the transaction data by the mobile app.

Signing Workflow:

  1. Retrieve the Nonce: Before signing a transaction, the mobile app queries the current nonce associated with the wallet account from the blockchain.
  2. Combine Nonce with Transaction Data: The nonce is concatenated with the transaction payload to form the message to be signed.
  3. Sign with Secure Enclave: The combined message is hashed using SHA-256, and the resulting digest is signed using the private key stored in the Secure Enclave.
  4. Submit Signed Transaction: The mobile app sends the signed transaction, along with the nonce, to the Wallet Program for execution.
  5. Transaction Verification in the Wallet Program: On the blockchain, the Wallet Program performs the three steps to verify the transaction.
  • Validate the Nonce
  • Verify the Signature
  • Execute the Transaction