Integrations
Sera DEX

Sera Protocol Integration

Build payment solutions with Veridex authentication and Sera DEX settlement.

Sera Protocol is a decentralized exchange with an orderbook model, enabling atomic on-chain stablecoin settlement. Combined with Veridex passkey authentication, it provides a complete payment gateway solution.

Overview

Prerequisites

Quick Start

1. Install Dependencies

bun add @veridex/sdk ethers axios

2. Configure Environment

# Ethereum Sepolia RPC
NEXT_PUBLIC_RPC_URL=https://eth-sepolia.g.alchemy.com/v2/YOUR_KEY

# Sera GraphQL API
NEXT_PUBLIC_GRAPHQL_URL=https://api.goldsky.com/api/public/project_cmicv6kkbhyto01u3agb155hg/subgraphs/sera-pro/1.0.9/gn

# Settlement wallet (keep secure!)
SETTLEMENT_WALLET_KEY=your-private-key

3. Initialize Services

This uses dynamic imports to avoid SSR issues in Next.js:

import { WalletManager } from '@veridex/sdk';
import { SeraService } from './sera-service';
 
// Veridex SDK, lazy-loaded singleton to avoid SSR issues
let sdkInstance: any = null;
 
export async function getVeridexSDK() {
  if (!sdkInstance) {
    const { createSDK } = await import('@veridex/sdk');
    sdkInstance = createSDK('base', {
      network: 'testnet',
      relayerUrl: process.env.NEXT_PUBLIC_VERIDEX_RELAYER_URL,
      relayerApiKey: process.env.NEXT_PUBLIC_RELAYER_API_KEY,
    });
  }
  return sdkInstance;
}
 
// Sera for settlement
const sera = new SeraService(process.env.NEXT_PUBLIC_RPC_URL!);

The await import('@veridex/sdk') pattern ensures the SDK is only loaded in the browser, never during server-side rendering. See the Next.js Integration guide for the full pattern.

Contract Addresses

ContractAddress
Sera Router0x82bfe1b31b6c1c3d201a0256416a18d93331d99e
Market Factory0xe54648526027e236604f0d91413a6aad3a80c01e
Order Canceler0x53ad1ffcd7afb1b14c5f18be8f256606efb11b1b
Veridex VaultFactory0x07F608AFf6d63b68029488b726d895c4Bb593038
Veridex VaultImpl0xD66153fccFB6731fB6c4944FbD607ba86A76a1f6

Payment Flow

Customer Authenticates

Customer connects using Veridex passkey or WalletConnect

// Option 1: Passkey (recommended)
await veridex.passkey.authenticate();
 
// Option 2: WalletConnect
const { address } = await connectWalletConnect();
Prepare Payment

Create a payment intent and get signing challenge

const { transferId, challenge } = await veridex.prepareTransfer({
  recipient: merchantAddress,
  amount: BigInt('99990000'), // 99.99 USDC (6 decimals)
  token: USDC_ADDRESS,
});
Customer Signs

Biometric prompt for payment authorization

const signature = await veridex.passkey.sign(challenge);
Execute Payment

Submit signed transaction

const { txHash } = await veridex.executeTransfer(prepared, signature);
Settlement via Sera

Convert received payment to merchant's preferred currency

// Place limit order on Sera DEX
await sera.placeLimitBid(signer, {
  market: usdcEurcMarket,
  priceIndex: currentPrice,
  rawAmount: amount,
});
 
// Poll for fill
const orders = await sera.getOrderStatus(address, market);
 
// Claim when filled
await sera.claimProceeds(signer, orders);

Sera Service Implementation

Price Conversion

Sera uses indexed pricing:

// Price formula
price = minPrice + (tickSpace × priceIndex)
 
// Example: Convert $1.05 to price index
const priceIndex = (price - minPrice) / tickSpace;
 
// Amount conversion
quoteAmount = rawAmount × quoteUnit
rawAmount = quoteAmount / quoteUnit
💡

Always fetch current market parameters from GraphQL before placing orders to ensure accurate price indices.

Security Best Practices

Error Handling

try {
  await sera.placeLimitBid(signer, params);
} catch (error) {
  if (error.message.includes('insufficient allowance')) {
    // Approve tokens first
    await token.approve(ROUTER_ADDRESS, amount);
    await sera.placeLimitBid(signer, params);
  } else if (error.message.includes('deadline')) {
    // Retry with fresh deadline
    params.deadline = Math.floor(Date.now() / 1000) + 3600;
  } else {
    throw error;
  }
}

Example: Complete Payment Gateway

browser

Sera Dashboard

Full-featured payment dashboard with invoice management, payment links, and settlement tracking.

// Complete payment flow
async function processPayment(invoiceId: string) {
  const invoice = await db.invoice.findUnique({ where: { id: invoiceId } });
  
  // 1. Customer pays via Veridex
  const { txHash } = await executePayment(invoice.amount);
  
  // 2. Update invoice
  await db.invoice.update({
    where: { id: invoiceId },
    data: { status: 'paid', paymentTxHash: txHash },
  });
  
  // 3. Settle via Sera (if currency conversion needed)
  if (invoice.settlementCurrency !== invoice.paymentCurrency) {
    const settlement = await settleViaSera(
      invoice.amount,
      invoice.paymentCurrency,
      invoice.settlementCurrency
    );
    
    await db.invoice.update({
      where: { id: invoiceId },
      data: { 
        status: 'settled',
        settlementTxHash: settlement.txHash,
      },
    });
  }
  
  // 4. Send webhook
  await sendWebhook(invoice.merchantId, 'invoice.settled', invoice);
}

Related Guides