Skip to content

What is Comet Engine?

Comet Engine is the on-chain settlement layer of FusionFi. It manages custodial EVM wallets, mints/burns ERC-20 tokens on Celo, executes token swaps via Uniswap V2 AMM, and tokenizes real-world assets like mobile airtime.

Key Features

  • Custodial EVM Wallets — one wallet address works on all configured EVM chains; AES-256-GCM encrypted keys, never exposed
  • Dynamic Asset Registry — add new tokens at runtime via env vars or admin API; no code changes
  • Airtime Tokenization — mint/burn the airtime-backed asset (IMC) against the platform's real airtime float, with backing-aware journaling
  • Uniswap V2 AMM — on-chain token-to-token swaps with gas relaying
  • Multi-Tenant — isolated wallet/journal state per tenant with per-tenant API keys
  • Double-Entry Ledger — append-only accounting journal for every on-chain operation
  • Gas Relaying — platform relayer pays gas for all user transactions

Architecture

┌─────────────────────────────────────────────────────────┐
│                    Your Backend                          │
│              (app-core-backend, etc.)                    │
│                                                         │
│   HTTP calls with X-API-Key + X-API-Secret              │
│   or X-Service-Token header                             │
└──────────────────────┬──────────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
│               Comet Engine (Go :8100)                    │
│                                                         │
│  ┌─────────┐  ┌──────────┐  ┌──────────┐  ┌─────────┐ │
│  │ Wallets │  │  Assets  │  │   AMM    │  │ Journal │ │
│  │ (EVM)   │  │ (ERC-20) │  │ (Uni V2) │  │ (Audit) │ │
│  └────┬────┘  └────┬─────┘  └────┬─────┘  └────┬────┘ │
└───────┼────────────┼─────────────┼──────────────┼──────┘
        │            │             │              │
        ▼            ▼             ▼              ▼
   ┌─────────┐ ┌──────────┐ ┌──────────┐  ┌──────────┐
   │  Celo   │ │  MockUSDT│ │ Uniswap  │  │ MongoDB  │
   │  EVM    │ │  MockUSDC│ │ V2 Router│  │          │
   │  Chain  │ │  IMC     │ │ + Factory│  │          │
   └─────────┘ └──────────┘ └──────────┘  └──────────┘

Supported Chains & Tokens

ChainTokenContractDecimalsPurpose
Celo SepoliaUSDT0x3C8EB6c8DF02B43a7bae71314917aCBdd60edDDF6Testnet stablecoin
Celo SepoliaUSDC0x82DD8420f1a403a947c6cFFBFaEa81e0296262A76Testnet stablecoin
Celo SepoliaIMC0xF150E30B1C7Ab81938d650567D1454Ee0132d5A26ImpalaCoin — airtime-backed (ARTM mirror)

What Comet Engine Can Do

1. Tokenize Real-World Assets

Convert real-world value (airtime, deposits, loyalty points) into on-chain tokens and back. The engine enforces proof-of-reserve: airtime-backed tokens can only be minted/burned against registered airtime assets.

Airtime tokenization:

bash
# User pays KES → mint IMC (on-chain airtime claim)
POST /api/v1/tokenize/airtime
# => mints IMC to user's custodial wallet

# Airtime delivered → burn IMC (remove on-chain mirror)
POST /api/v1/assets/imc/burn-by-holder
# => burns IMC, credits airtime inventory account

Any asset tokenization:

bash
# Register a new asset at runtime
POST /api/v1/admin/assets/:symbol/register

# Mint it to users
POST /api/v1/assets/:symbol/mint

2. Manage Custodial Wallets

Create and manage server-custodial EVM wallets. Users never see private keys — the engine signs transactions on their behalf.

bash
# Create wallet (idempotent)
POST /api/v1/wallets/create
# => {"address": "0x...", "existing": true}

# Check balances (native + all tokens)
GET /api/v1/wallets/balance?userId=123

The same wallet address works on ALL configured EVM chains.

3. Mint, Send, Burn ERC-20 Tokens

Full lifecycle for any registered token:

bash
# Mint tokens to a user
POST /api/v1/assets/:symbol/mint

# Transfer between wallets
POST /api/v1/assets/:symbol/send

# Approve relayer to spend
POST /api/v1/assets/:symbol/approve

# Burn (relayer-initiated, requires approval)
POST /api/v1/assets/:symbol/burn

# Burn (holder-initiated, no approval needed)
POST /api/v1/assets/:symbol/burn-by-holder

# Check balance
GET /api/v1/assets/:symbol/balance?userId=123

4. Swap Tokens via AMM

On-chain token-to-token swaps through Uniswap V2. Gas relayed by the platform.

bash
# Get price quote
GET /api/v1/swap/quote?from=USDT&to=IMC&amountIn=1000000

# Execute swap
POST /api/v1/swap/tokens

# List liquidity pools
GET /api/v1/swap/pools

5. Double-Entry Accounting

Every on-chain operation is recorded in an append-only journal with debit/credit pairs:

bash
# List journal entries
GET /api/v1/journal?type=mint&limit=50

# Get account balances
GET /api/v1/journal/balances

Airtime-backed assets use special accounts: mints debit the airtime inventory, burns credit it. This keeps on-chain supply honestly backed.

6. Multi-Tenant Isolation

Each tenant gets isolated wallets, journal entries, and API access:

bash
# Create a new tenant (admin only)
POST /api/v1/admin/tenants

# Rotate API secret
POST /api/v1/admin/tenants/:id/rotate-secret

Tokenization Examples

Example 1: Buy Airtime (Complete Flow)

A user buys KES 100 of Airtel airtime through FusionFy:

User pays KES 100 via M-Pesa


┌─ app-core-backend ─────────────────────────────────────┐
│  1. Verify M-Pesa payment                              │
│  2. Check ImpalaPay float balance (KES ≥ 100?)         │
│  3. Deduct KES 100 from user's DB wallet               │
│  4. Call tokenize/airtime → mints 100 IMC on-chain     │
│  5. Call ImpalaPay to deliver airtime to user's phone   │
│  6. Call burn-by-holder → burns 100 IMC on-chain        │
│  7. Update DB: ARTM balance unchanged (1:1 with IMC)   │
└─────────────────────────────────────────────────────────┘

Step 4 — Tokenize:

bash
curl -X POST http://localhost:8100/api/v1/tokenize/airtime \
  -H "X-Service-Token: your-token" \
  -H "Content-Type: application/json" \
  -d '{
    "userId": 24,
    "amountBase": "100000000",
    "externalId": "airtime-tx-001"
  }'

Step 6 — Burn:

bash
curl -X POST http://localhost:8100/api/v1/assets/imc/burn-by-holder \
  -H "X-Service-Token: your-token" \
  -H "Content-Type: application/json" \
  -d '{
    "userId": 24,
    "amountBase": 100000000,
    "externalId": "airtime-tx-001"
  }'

Example 2: Buy ARTM (USDT → IMC via AMM)

A user buys ARTM by swapping USDT through the on-chain AMM:

bash
# 1. User deposits KES → backend mints USDT
POST /api/v1/assets/usdt/mint
# => 10 USDT (10000000 base units) minted to user's wallet

# 2. Approve Uniswap router to spend user's USDT
POST /api/v1/assets/usdt/approve
# => router approved for 10 USDT

# 3. Swap USDT → IMC
POST /api/v1/swap/tokens
# => 10 USDT swapped for ~9.95 IMC (minus 0.3% fee)

# 4. Check IMC balance
GET /api/v1/assets/imc/balance?userId=24
# => 9950000 base units (9.95 IMC)

Example 3: Sell ARTM (IMC → USDT via AMM)

A user sells ARTM back to USDT:

bash
# 1. Get quote
GET /api/v1/swap/quote?from=IMC&to=USDT&amountIn=5000000
# => expected output: ~4975000 USDT (5 USDT minus 0.3% fee)

# 2. Execute swap
POST /api/v1/swap/tokens
# => 5 IMC swapped for ~4.975 USDT

# 3. User can withdraw USDT (handled by app-core-backend)

Example 4: Cross-Border Payment

Send money across borders using stablecoins:

bash
# 1. Sender deposits KES → backend mints USDC
POST /api/v1/assets/usdc/mint
# => 50 USDC minted to sender's wallet

# 2. Send USDC to recipient's wallet
POST /api/v1/assets/usdc/send
# => 50 USDC transferred on-chain

# 3. Recipient's backend burns USDC → credits local currency
POST /api/v1/assets/usdc/burn-from
# => 50 USDC burned, recipient credited

Example 5: Loyalty / Reward Tokens

Register a custom loyalty token and distribute rewards:

bash
# 1. Deploy ERC-20 contract, register in comet-engine
POST /api/v1/admin/assets/POINTS/register
# => POINTS token registered

# 2. Mint rewards to users
POST /api/v1/assets/points/mint
# => 1000 POINTS minted to user's wallet

# 3. User redeems points for airtime
POST /api/v1/assets/points/burn-by-holder
# => 500 POINTS burned, airtime delivered

Example 6: Deposit Stablecoin

User deposits fiat, receives stablecoin on-chain:

bash
# 1. User sends KES via M-Pesa (handled by backend)

# 2. Backend mints USDT to user
POST /api/v1/assets/usdt/mint
# => 1000 USDT (1000000000 base units) minted

# 3. User now holds USDT on Celo
GET /api/v1/assets/usdt/balance?userId=24
# => 1000000000 (1000 USDT)

Released under the MIT License.