ZingPay Docs
esc

    Walletless Onboarding

    The most innovative aspect of ZingPay is its ability to onboard users who have never interacted with a blockchain before. No wallet apps. No seed phrases. No browser extensions. Just a phone number and a browser.


    The Problem

    In traditional crypto flows, receiving funds requires:

    1. Understanding what a wallet is
    2. Downloading a wallet app (Phantom, Solflare, etc.)
    3. Writing down and securely storing a 12-24 word seed phrase
    4. Sharing your public key with the sender

    This creates massive friction for non-crypto users, especially in regions where digital literacy varies widely.

    The ZingPay thesis: If we can defer the wallet setup to after the user has already received funds, we dramatically lower the barrier to entry. The incentive to learn is built-in. There's already money waiting for them.


    The Solution: Ephemeral Keypairs

    ZingPay implements a three-step walletless claiming process:

    1

    Ephemeral Generation

    When an un-onboarded user visits the claim page, ZingPay generates a temporary Solana Keypair entirely within the browser context using Keypair.generate(). No server involvement. No external API calls.

    2

    Delegated Claiming

    This temporary keypair acts as the delegated identity to sign the transaction that claims the funds from the Escrow PDA. The smart contract verifies the phone hash, confirms the escrow exists, and releases the SOL to the ephemeral wallet.

    3

    Non-Custodial Export

    The secret key array is serialized to JSON and triggered as a browser download (solpay-keypair.json). The user retains absolute custody of their temporary wallet without relying on browser local storage, cookies, or centralized databases.


    Implementation

    // walletless.ts: Core logic
    
    import { Keypair } from '@solana/web3.js';
    
    function generateEphemeralWallet(): Keypair {
      // Generate a fresh keypair in the browser
      return Keypair.generate();
    }
    
    function exportKeypair(keypair: Keypair): void {
      const secretArray = Array.from(keypair.secretKey);
      const blob = new Blob(
        [JSON.stringify(secretArray)],
        { type: 'application/json' }
      );
      
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = 'solpay-keypair.json';
      a.click();
      URL.revokeObjectURL(url);
    }
    

    Security Considerations

    ConcernMitigation
    Keypair lives in browser memoryKeypair is generated fresh per session and never persisted to localStorage
    Key export could be interceptedDownload is initiated via Blob URL. No network request is made
    User might lose the fileThe UI prominently warns users to back up their keypair file
    Ephemeral key has no SOL for feesThe claim transaction fee is deducted from the escrowed amount

    What happens after claiming? The user now has a funded Solana wallet in the form of a JSON file. They can import this keypair into any Solana wallet app (Phantom, Solflare, Backpack) to manage their funds going forward.


    Why Not Use Existing Wallet Adapters?

    ZingPay intentionally avoids wallet adapter libraries (like @solana/wallet-adapter) for the claiming flow because:

    • No wallet installed: The target user literally does not have a browser extension or app
    • Zero dependencies: The ephemeral keypair approach requires only @solana/web3.js
    • True non-custodial: At no point does any server or third party hold the private key

    The sending flow does use wallet adapters, since senders are expected to already have Solana wallets. The walletless architecture applies exclusively to the receiver onboarding path.