Skip to content
Β 
Β 

Repository files navigation

Fluxa

License: MIT PRs Welcome

Cross-border payment infrastructure for emerging markets.

Fluxa is a programmable payments API built on the Stellar network. It gives fintech products and developers the primitives to move value across borders β€” wallet management, internal transfers, FX conversion via Stellar path payments, and settlement β€” behind a clean REST API.

Status: Active development β€” testnet only.


What it does

  • βœ… Wallets β€” create Stellar accounts with AES-256-GCM encrypted secrets; never expose raw keys
  • βœ… Transfers β€” async payment submission with queue-backed retry and status polling
  • βœ… FX / Conversion β€” quote and execute cross-asset swaps via Stellar DEX path payments
  • βœ… Settlement β€” background worker submits transactions to Stellar, handles retries, confirms on-chain
  • βœ… Ledger indexer β€” streams Horizon events to keep local state in sync
  • βœ… Multi-tenant β€” API key + JWT auth; individual developers and business organizations each get scoped access
  • βœ… Webhooks β€” signed delivery of payment events to developer endpoints
  • πŸ”œ Sandbox mode β€” sk_test_ keys route to Stellar testnet for safe integration testing
  • βœ… Recurring payouts β€” scheduled transfers with daily/weekly/monthly cadence
  • βœ… Fiat rails β€” deposit/withdrawal via Flutterwave integration
  • βœ… Organization management β€” invite members, role-based access control (owner/admin/dev/viewer)

Architecture

Client Applications
        β”‚  Authorization: Bearer sk_live_... or sk_test_...
        β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      Fluxa REST API                             β”‚
β”‚  Chi router β”‚ JWT + API key auth β”‚ Rate limiting β”‚ Tenant scope β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚
        β”œβ”€β”€ Wallet Service       ──► postgres: wallets, balances
        β”œβ”€β”€ Transfer Service     ──► postgres: transactions
        β”œβ”€β”€ FX Service           ──► Stellar DEX + rate cache (Redis)
        β”œβ”€β”€ Fee Service          ──► postgres: fees, fee_collections
        └── Webhook Dispatcher   ──► postgres: webhook_endpoints, deliveries
                β”‚
                β–Ό  (Asynq job queue)
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚           Background Worker             β”‚
        β”‚  Settlement Engine β”‚ Ledger Indexer     β”‚
        β”‚  Reconciliation    β”‚ Scheduler          β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                β”‚
                β–Ό
        Stellar Network (Horizon API + Soroban RPC)
        testnet: horizon-testnet.stellar.org
        mainnet: horizon.stellar.org

Two processes

Binary Role
cmd/api HTTP server β€” handles all REST requests, enqueues async work
cmd/worker Asynq worker β€” settles transfers, runs ledger indexer, processes webhooks

Transfers are asynchronous. POST /v1/transfers returns 202 Accepted with a pending transaction immediately. Poll GET /v1/transfers/:id or receive a transfer.settled webhook for the final status.


Project Structure

fluxa/
β”œβ”€β”€ cmd/
β”‚   β”œβ”€β”€ api/main.go           # HTTP server entry point
β”‚   └── worker/main.go        # Background worker entry point
β”œβ”€β”€ internal/
β”‚   β”œβ”€β”€ config/               # Viper env config
β”‚   β”œβ”€β”€ domain/               # Core types: Wallet, Transaction, Conversion, errors
β”‚   β”œβ”€β”€ crypto/               # AES-256-GCM encrypt/decrypt (stdlib only)
β”‚   β”œβ”€β”€ assets/               # Asset registry: USDC/EURC issuers per network
β”‚   β”œβ”€β”€ stellar/              # Horizon client, keypair generation, signer interface
β”‚   β”œβ”€β”€ postgres/             # pgx/v5 repository implementations
β”‚   β”œβ”€β”€ queue/                # Asynq client + task type definitions
β”‚   β”œβ”€β”€ wallet/               # Wallet service + HTTP handler
β”‚   β”œβ”€β”€ transfer/             # Transfer service + HTTP handler
β”‚   β”œβ”€β”€ batch/                # Batch transfers + CSV export, reuses transfer settlement
β”‚   β”œβ”€β”€ schedule/             # Recurring payouts + Asynq periodic task
β”‚   β”œβ”€β”€ fx/                   # FX service + rate providers + HTTP handler
β”‚   β”œβ”€β”€ fees/                 # Fee calculation and collection
β”‚   β”œβ”€β”€ settlement/           # Settlement engine + Asynq task handler
β”‚   β”œβ”€β”€ indexer/              # Ledger indexer + Asynq periodic task
β”‚   β”œβ”€β”€ webhook/              # Webhook dispatcher + delivery worker
β”‚   β”œβ”€β”€ reconcile/            # DB vs on-chain reconciliation
β”‚   β”œβ”€β”€ apikey/               # API key generation, hashing, verification
β”‚   β”œβ”€β”€ auth/                 # User registration, login, JWT
β”‚   β”œβ”€β”€ org/                  # Organization members, roles
β”‚   β”œβ”€β”€ fiat/                 # Fiat rail abstraction + provider adapters
β”‚   β”œβ”€β”€ alerting/             # Alerting client for platform notifications
β”‚   β”œβ”€β”€ tenant/               # Tenant context helpers
β”‚   β”œβ”€β”€ server/               # Chi router setup, middleware
β”‚   └── api/                  # Shared request validation + response helpers
└── db/
    └── migrations/           # golang-migrate SQL files (numbered up/down pairs)

Getting Started

Prerequisites

  • Go 1.22+
  • PostgreSQL 15+
  • Redis 7+

The repository root is a Go backend workspace. It does not require root-level Node.js, TypeScript, Prisma, or BullMQ tooling to build or run the API and worker.

1. Clone and install

git clone https://github.com/Savitura/Fluxa
cd Fluxa
go mod tidy

2. Configure environment

cp .env.example .env
Variable Description
PORT HTTP listen port (default: 3000)
DATABASE_URL PostgreSQL connection string
REDIS_URL Redis connection string
STELLAR_NETWORK testnet or mainnet
STELLAR_HORIZON_URL Horizon endpoint
STELLAR_USDC_ISSUER USDC issuer public key
MASTER_ENCRYPTION_KEY 64 hex chars (32 bytes) β€” encrypts stored wallet secrets
PLATFORM_FEE_WALLET_PUBLIC_KEY Stellar address where platform fees are collected
TREASURY_SECRET_KEY Stellar key that funds new accounts (testnet: leave empty, use Friendbot)

Generate a master key:

openssl rand -hex 32

3. Run migrations

make migrate

4. Start the API and worker

# Terminal 1
make run-api

# Terminal 2
make run-worker

API Reference

All endpoints are prefixed /v1. Auth: Authorization: Bearer <api_key_or_jwt>. Errors:

{ "error": { "code": "WALLET_NOT_FOUND", "message": "wallet not found" } }

Authentication

POST /v1/auth/register     Create account (individual or organization)
POST /v1/auth/login        Login β€” returns JWT
POST /v1/auth/refresh      Refresh access token
POST /v1/keys              Create API key  β†’  sk_live_... or sk_test_...
GET  /v1/keys              List keys (prefix only, never raw)
DELETE /v1/keys/:id        Revoke key

Wallets

POST /v1/wallets           Create wallet β€” returns public key only
GET  /v1/wallets/:id/balances   Live balances from Horizon (all assets)
POST /v1/wallets/:id/trustlines  Add Stellar trustline for a new asset

Transfers

POST /v1/transfers         Initiate transfer (202 Accepted β€” async)
GET  /v1/transfers/:id     Poll status
GET  /v1/transfers         List (filter by wallet, status, date)
POST /v1/transfers/batch   Up to 100 transfers in one call
GET  /v1/transfers/batch/:batchId          Batch status with per-transfer breakdown
GET  /v1/transfers/batch/:batchId/export   CSV download of batch results

Status flow: pending β†’ confirmed | failed

Batch status is derived live from its linked transactions: pending β†’ processing β†’ partial | completed | failed.

Scheduled Payouts

POST   /v1/schedules       Create a recurring transfer (daily | weekly | monthly)
GET    /v1/schedules       List schedules
PATCH  /v1/schedules/:id   Pause, resume, or update amount/frequency/end_date
DELETE /v1/schedules/:id   Cancel a schedule

A background worker checks for due schedules every minute and enqueues a normal transfer for each one β€” a paused schedule is skipped until resumed.

FX

POST /v1/fx/quote          Get a 30-second exchange rate quote
POST /v1/fx/convert        Execute a currency swap
GET  /v1/fx/rates          Live rates for a currency pair

Webhooks

POST   /v1/webhooks        Register endpoint + event subscriptions
GET    /v1/webhooks        List endpoints
DELETE /v1/webhooks/:id    Remove endpoint
GET    /v1/webhooks/:id/deliveries  Delivery log

Event types: transfer.initiated Β· transfer.settled Β· transfer.failed Β· wallet.funded Β· conversion.completed

Fees

GET /v1/fees               Your fee schedule (transfer/conversion fee rates)

Organization

POST /v1/org/members/invite     Invite member to organization
GET  /v1/org/members            List organization members
PATCH  /v1/org/members/{userId}   Update member role
DELETE /v1/org/members/{userId}   Remove member
POST /v1/org/invites/accept     Accept organization invite (public)

Fiat Rails

POST /v1/wallets/{id}/deposit/fiat   Initiate fiat deposit
POST /v1/wallets/{id}/withdraw/fiat  Initiate fiat withdrawal
POST /v1/webhooks/fiat/{provider}   Fiat provider webhook receiver

Health

GET /health                Health check

Security

  • Key storage: Stellar secrets are encrypted with AES-256-GCM before storage. The 32-byte master key lives only in env β€” never in the database or logs.
  • No key exposure: Secret keys are never returned by any API endpoint.
  • Signer abstraction: stellar.Signer in internal/stellar/signer.go isolates all signing. Swap EnvSigner for HSM or AWS KMS without touching the settlement engine.
  • Decimal arithmetic: All monetary values use shopspring/decimal β€” no floating-point.
  • API key hashing: Raw keys are SHA-256 hashed before storage; the plaintext is shown exactly once on creation.

Development

make test          # go test ./... -race
make test-cover    # with HTML coverage report
make lint          # golangci-lint
make build         # outputs bin/api + bin/worker
make tidy          # go mod tidy

Fund a testnet wallet:

curl "https://friendbot.stellar.org?addr=<PUBLIC_KEY>"

Part of Savitura

  • CrowdPay β€” crowdfunding platform built on top of Fluxa payment rails
  • SaviTools β€” developer tools: API playground, transaction inspector, wallet sandbox

Contributing

See CONTRIBUTING.md.

License

MIT

About

Cross-border payment infrastructure

Resources

Code of conduct

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages