Skip to content

rasputin2525/Stellar-Spend

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

449 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Stellar-Spend

CI License: MIT Next.js TypeScript

Convert Stellar stablecoins (USDC / USDT) to fiat currencies and receive funds directly in your bank account — non-custodial, real-time, global.


Table of Contents


Overview

Stellar-Spend is a production-grade off-ramp application that lets users convert Stellar-based stablecoins to local fiat currencies (NGN, KES, GHS, etc.) with direct bank transfers. It bridges Stellar → Base via Allbridge, then routes the Base USDC to a Paycrest payout order that settles to the beneficiary's bank account.

Architecture

Stellar-Spend Architecture

Full-resolution SVG: public/architecture.svg

The diagram shows the complete data flow:

  1. User signs a Soroban XDR in their Stellar wallet (Freighter / Lobstr)
  2. Next.js API builds the bridge transaction and submits it to Stellar
  3. Allbridge detects the Stellar deposit and releases USDC on Base
  4. Server creates a Paycrest payout order and sends Base USDC to the settlement address
  5. Paycrest converts USDC → fiat and initiates the bank transfer
  6. Beneficiary receives local currency (NGN, KES, GHS, …)

Key Features

  • Connect Freighter or Lobstr wallet (auto-detect)
  • Real-time FX rate display (live USDC/NGN ticker)
  • Dual input mode: enter crypto amount or fiat amount
  • Automatic fee calculation (XLM or USDC gas fee)
  • Non-custodial: the server never holds user funds
  • Transaction history stored in browser localStorage
  • PWA-installable on mobile

Architecture

graph LR
    A([User / Browser]) -->|1. Signs XDR| B[Stellar Network]
    B -->|2. Bridge transfer| C[Allbridge Protocol]
    C -->|3. USDC on Base| D[Base Chain]
    D -->|4. Server sends USDC| E[Paycrest API]
    E -->|5. Fiat settlement| F([Beneficiary Bank])

    subgraph "Stellar-Spend Server"
        G[Next.js API Routes]
        G --> D
        G --> E
    end

    A -->|Quote / Build TX| G
    B -->|TX hash| G
Loading

Data flow summary:

Step Actor Action
1 Browser Fetches quote, builds Soroban XDR, user signs in wallet
2 Stellar Signed transaction submitted; Allbridge bridge contract invoked
3 Allbridge Detects Stellar deposit, releases USDC on Base
4 Server Polls bridge status; sends Base USDC to Paycrest settlement address
5 Paycrest Converts USDC → fiat, initiates bank transfer
6 Bank Beneficiary receives local currency

Offramp Flow

sequenceDiagram
    participant U as User
    participant App as Browser App
    participant API as Next.js API
    participant Stellar as Stellar Network
    participant Bridge as Allbridge
    participant Base as Base Chain
    participant PC as Paycrest

    U->>App: Enter amount + bank details
    App->>API: POST /api/offramp/quote
    API-->>App: { rate, destinationAmount, fees }
    App->>API: POST /api/offramp/bridge/build-tx
    API-->>App: { xdr }
    App->>U: Prompt wallet signature
    U->>App: Signed XDR
    App->>API: POST /api/offramp/bridge/submit-soroban
    API->>Stellar: Submit signed transaction
    Stellar-->>Bridge: Bridge contract triggered
    App->>API: GET /api/offramp/bridge/status/:txHash (poll)
    Bridge-->>Base: USDC released on Base
    API->>PC: POST /api/offramp/paycrest/order (create payout)
    API->>Base: Send USDC to settlement address
    App->>API: GET /api/offramp/status/:orderId (poll)
    PC-->>U: Bank transfer settled
Loading

Tech Stack

Technology Version Purpose
Next.js 15.5 App framework (App Router, API routes)
React 19.0 UI library
TypeScript 5.7 Type safety
Tailwind CSS 4.2 Styling
@stellar/stellar-sdk 14.6 Stellar / Soroban transaction building
@stellar/freighter-api 6.0 Freighter wallet integration
@allbridge/bridge-core-sdk 3.29 Stellar → Base bridge
viem 2.47 Base chain interaction
Paycrest API v1 Fiat payout / bank settlement
Sentry 10.46 Error monitoring
Vitest 4.1 Unit testing
Playwright 1.58 E2E testing

Setup Guide

Prerequisites

  • Node.js ≥ 20
  • A Paycrest account (API key + webhook secret)
  • A Base wallet private key (for the server-side payout wallet)
  • A Base RPC URL (e.g. from Alchemy or Infura)

1. Clone

git clone https://github.com/whiteghost0001/Stellar-Spend.git
cd Stellar-Spend

2. Install dependencies

npm install

3. Configure environment

cp .env.example .env.local

Then fill in .env.local — see Environment Variables below.

4. Run development server

npm run dev

Open http://localhost:3001.

5. Run tests

npm test          # unit tests (vitest)
npm run test:e2e  # end-to-end tests (playwright, requires running server)

6. Build for production

npm run build
npm start

7. Bundle analysis

npm run build:analyze

Environment Variables

All variables are documented in .env.example. The table below summarises each one.

Variable Required Exposed to browser Description
PAYCREST_API_KEY Paycrest dashboard API key
PAYCREST_WEBHOOK_SECRET Paycrest webhook HMAC signing secret
BASE_PRIVATE_KEY Private key of the Base payout wallet (hex, 0x…)
BASE_RETURN_ADDRESS Base address for returns / treasury routing
BASE_RPC_URL Base chain RPC provider URL
STELLAR_SOROBAN_RPC_URL Soroban RPC endpoint (server-side)
STELLAR_HORIZON_URL Horizon endpoint (server-side)
NEXT_PUBLIC_STELLAR_SOROBAN_RPC_URL Soroban RPC endpoint (browser-safe)
NEXT_PUBLIC_BASE_RETURN_ADDRESS Base return address (browser-safe)
NEXT_PUBLIC_STELLAR_USDC_ISSUER Stellar USDC issuer account (for trustline filtering)

⚠️ Never prefix secrets with NEXT_PUBLIC_. The app validates this at startup and throws if a secret is accidentally exposed.


API Reference

Offramp

Method Path Description
POST /api/offramp/quote Get a conversion quote with FX rate and fees
GET /api/offramp/currencies List supported fiat currencies
GET /api/offramp/institutions/[currency] List banks / institutions for a currency
POST /api/offramp/verify-account Verify a beneficiary account number
GET /api/offramp/rate Get live USDC/NGN spot rate

Bridge

Method Path Description
POST /api/offramp/bridge/build-tx Build Soroban XDR for the bridge transfer
POST /api/offramp/bridge/submit-soroban Submit a signed Soroban XDR
GET /api/offramp/bridge/status/[txHash] Poll Allbridge transfer status
GET /api/offramp/bridge/tx-status/[hash] Poll Stellar on-chain transaction status
GET /api/offramp/bridge/gas-fee-options Get available gas fee options (XLM / USDC)

Payout

Method Path Description
POST /api/offramp/paycrest/order Create a Paycrest payout order
GET /api/offramp/status/[orderId] Poll payout order status
POST /api/offramp/execute-payout Trigger Base USDC transfer to Paycrest

Webhooks & Health

Method Path Description
POST /api/webhooks/paycrest Receive Paycrest webhook events (HMAC-verified)
GET /api/health Health check endpoint

Example: Get Quote

Request

POST /api/offramp/quote
Content-Type: application/json

{
  "amount": "100",
  "currency": "NGN",
  "feeMethod": "USDC"
}

Response

{
  "destinationAmount": "158202.00",
  "rate": 1598,
  "currency": "NGN",
  "bridgeFee": "0.5",
  "payoutFee": "0",
  "estimatedTime": 300
}

Example: Build Bridge Transaction

Request

POST /api/offramp/bridge/build-tx
Content-Type: application/json

{
  "amount": "99.5",
  "fromAddress": "GCFX...ABCD",
  "toAddress": "0xd8dA...6045",
  "feePaymentMethod": "stablecoin"
}

Response

{
  "xdr": "AAAAAgAAAAB...",
  "sourceToken": { "symbol": "USDC", "decimals": 7, "chain": "STELLAR" },
  "destinationToken": { "symbol": "USDC", "decimals": 6, "chain": "BASE" }
}

Troubleshooting

Error: Invalid environment configuration

One or more required env vars are missing. Copy .env.example to .env.local and fill in all values.

Freighter extension is not installed

Install the Freighter browser extension, or use Lobstr as a fallback.

Freighter is set to Testnet. Please switch to Mainnet.

Open Freighter → Settings → Network → select Mainnet (Public).

Insufficient XLM balance for native gas fee

Your Stellar account's XLM balance would fall below the minimum reserve after paying the gas fee. Either add more XLM or switch to USDC fee payment.

Bridge quote unavailable (502)

The Allbridge SDK could not fetch chain details. This is usually a transient network issue — retry after a few seconds.

FX rate unavailable (502)

The Paycrest rate API is unreachable. Check Paycrest status and retry.

Simulation failed: resulting balance is not within the allowed range

Your USDC balance is insufficient to cover the transfer amount plus fees.

Bundle size CI failure

The CI build fails if .next/ exceeds 150 MB. Run npm run build:analyze to identify large chunks and consider dynamic imports.


Contributing

Please read CONTRIBUTING.md for branch naming conventions, commit message format, and the pull request process.


Contact

Questions or feedback? Reach out on Telegram: t.me/Xoulomon


License

MIT © Stellar-Spend Contributors

About

No description, website, or topics provided.

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • TypeScript 93.7%
  • HCL 3.0%
  • Shell 1.9%
  • JavaScript 0.6%
  • CSS 0.5%
  • HTML 0.2%
  • Dockerfile 0.1%