Skip to content

minghinmatthewlam/acme-tempo

Repository files navigation

Acme Tempo

Tempo on/off-ramp for AcmeUSD, built on the Tempo L1 with passkey wallets, a bank-like UX, and scripted TIP-20 setup.

Table of Contents

Getting Started

Prerequisites

  • Node 20+
  • Postgres database (Supabase or local Postgres)
  • Access to Tempo testnet RPC (defaults are provided)

1. Install dependencies

npm install

2. Configure environment

Copy the example file and edit values for your environment:

cp .env.example .env.local

Do not commit real secrets. The example values are placeholders for local development.

3. Set up the database

Run Prisma migrations against your Postgres database:

npx prisma migrate deploy

For local iterating you can also use:

npx prisma migrate dev

4. Run the app

Start the dev server:

npm run dev

Then open http://localhost:3000 in your browser.

Features

  • Deposit USD into an AcmeUSD balance via a mock card/bank provider (onramp).
  • Withdraw AcmeUSD back to an attached payment method (offramp), with 1:1 backing.
  • Send dollars between Tempo wallets and view all activity in a unified History view.
  • Pay Tempo network fees using AcmeUSD via a fee liquidity pool (AcmeUSD/alphaUSD).

Architecture Overview

  • Web app (Next.js App Router)

    • Pages under src/app: home, onramp, offramp, transfer, history.
    • Client-side wagmi hooks for Tempo passkey wallets and AcmeUSD transfers.
  • Tempo integration

    • tempo.ts / viem client in src/lib/tempoClient.ts for backend/scripts.
    • wagmi config in src/lib/wagmiConfig.tsx for passkeys and fee token defaults.
    • Uses TIP-20 AcmeUSD token deployed via Tempo’s TIP-20 factory (see scripts).
  • Data / persistence (Postgres + Prisma)

    • Prisma schema in prisma/schema.prisma with models for:
      • User, PaymentMethod – wallet address + attached card/bank method.
      • AuthChallenge, Session – challenge-response auth and session tracking.
      • OnrampOrder, OfframpRequest, Payout – fiat rails and off-ramp lifecycle.
      • Transfer – peer-to-peer AcmeUSD transfers (for History).
      • BackingSnapshot – snapshots of fiat vs on-chain supply for backing checks.
      • IndexerState, ProcessedOfframpLog – off-ramp indexer cursor and logs.
      • IdempotencyKey – request idempotency records for sensitive operations.
  • Offramp flow (client notify + on-chain verification)

    • Primary path: client sends an AcmeUSD transfer to the treasury address, waits for Tempo’s fast finality, then calls /api/offramp/notify with the transaction hash and log index.
    • Backend independently verifies the transaction and log on-chain before updating the OfframpRequest, recording a Payout, and burning supply via backing snapshots.
    • A cursor-based scanner in src/lib/indexer/offrampIndexer.ts is kept as a safety/backfill mechanism but is no longer the main correctness path.
  • Payment provider & API routes

    • API handlers in src/app/api implement:
      • Onramp creation, payment success, and minting.
      • Offramp request creation, notify endpoint for client-submitted tx receipts, and payouts.
    • Real card/bank rails (e.g., Stripe) can replace the current implementation behind the same interface.

Scripts

Token + fee pool

  • Deploy AcmeUSD via TIP-20 factory and set roles

    npm run script:deploy-acme

    Outputs the token address to place in NEXT_PUBLIC_ACMEUSD_ADDRESS.

  • Check fee pool reserves (AcmeUSD vs alphaUSD)

    npm run script:check-fee-pool
  • Seed fee pool with validator-side fee liquidity

    Seeds the AcmeUSD/alphaUSD fee pool using alphaUSD only (validator token on testnet; no AcmeUSD deposit required).

    npm run script:seed-fee-pool
  • Sanity check paying fees in AcmeUSD

    Mints a small amount of AcmeUSD to the admin account, performs a self-transfer paying fees in AcmeUSD, then burns back to zero float.

    npm run script:test-fee-acme

[DEPRECATED] Offramp indexer worker

Was previously the primary service that updated the backend for offramps, but now serves mainly as a reconciliation example.

  • Scan off-ramp logs once

    npm run script:offramp-worker
  • Watch mode (continuous scanning)

    npm run script:offramp-worker -- --watch

App scripts

  • npm run dev – Next dev server.
  • npm run lint – ESLint.
  • npm run format / npm run format:write – Prettier check/write.
  • npm run typechecktsc --noEmit.

Backing & fee liquidity model

  • No AcmeUSD is pre-minted for fee liquidity; user onramps are the only source of AcmeUSD.
  • Offramps burn AcmeUSD when received so total supply stays fully backed by USD deposits.
  • Fee pool is AcmeUSD (user token) vs alphaUSD (validator token on testnet), with validator-side liquidity provided in alphaUSD. Validate reserves before/after seeding with npm run script:check-fee-pool.
  • Fiat fields (OnrampOrder.usdAmount, OfframpRequest.usdAmount, Payout.amountUsd, backing totals) are stored in cents (minor units).

Production-readiness notes

  • Auth for API routes – Session-based auth is in place (/api/auth/* + acme_session cookie) and onramp/offramp routes derive identity from the session. Remaining work: implement/verify Tempo passkey signature verification (WebAuthn/P256/keychain) server-side so non-secp256k1 accounts can authenticate reliably.
  • Env validation – Enforce required env vars (RPC URLs, ACMEUSD address, treasury/issuer keys + addresses, admin list, DB URLs) with a runtime schema (e.g., zod) so the app fails fast on misconfiguration.
  • Payment rails – Mock provider only. Real card/bank rails must handle KYC/AML, idempotency, retries, and webhook verification.
  • Backend service boundaries – Move domain logic out of route handlers into explicit services (e.g., OnrampService, OfframpSettlementService, TransferService) so retries, idempotency, and reconciliation are consistent across API routes, jobs, and scripts.
  • Observability (logs + metrics) – Replace console.* with a structured logger and standardize fields (requestId, orderId, txHash, logIndex). Emit metrics/traces for onramp/offramp errors, payout queue depth, and backing deltas (fiat deposits – withdrawals vs on-chain supply). Alert on any mismatch, stuck settlements, or stalled payouts.
  • Secrets & ops – Use secure secret management and key rotation for treasury/issuer keys. Remove dev faucet or lock behind verified admin identity in production.
  • Indexer (deprecated) – The off-ramp scanner is backfill-only. Prefer the client-driven notify flow; Add alerting and retries.
  • CI gates – Run npm run lint, npm run typecheck, npm run build (and tests when added) in CI; block merges on failure.

About

Tempo L1 app: passkey auth, TIP‑20 on/offramp, and fee‑pool flows.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages