Checking

Send money onchain, in naira or dollars

Kobo moves NGNm and dollar stablecoins on Celo. The network fee comes out of the token you send, so one balance is enough and you never hold CELO.

MiniPay is the wallet. Kobo adds what a wallet does not: send naira itself, not only dollars, share a payment link that carries an onchain receipt anyone can verify, run a savings circle, and let an app or agent pay and check on its own.

Your balance
000,000.00NGNm
Not connected

Kobo never holds your money. You sign each transfer in your own wallet, so the money stays yours until it reaches whoever you sent it to.

Inside MiniPay it connects on its own. Other Celo wallets work too, but one that cannot pay fees in tokens, MetaMask among them, will ask for a little CELO.

New here? Three steps
  1. Get MiniPay. A free stablecoin wallet from Opera. Install it.
  2. Add a little money. MiniPay holds dollars: USD₮, USDC or USDm. Add cash in MiniPay.
  3. Open Kobo in your wallet and send. Paste their address, or open the payment link they sent you. The fee is paid in a token you already hold, so in MiniPay you never need CELO.
What it costs
Send
₦5,000
They receive
₦5,000.00
Network fee
₦2.88
Leaves your balance
₦5,002.88

The fee is charged in naira, not CELO, and it is the same whether you send ₦100 or ₦100,000. Read from Celo when this page was built, not an estimate.

Your balance is shown as NGNm, which is naira. It is the Mento naira on Celo, and one NGNm is one naira. Kobo also sends cNGN, the SEC-regulated naira, whose fee comes out of NGNm or dollars you hold because cNGN cannot pay for its own gas, and USD₮, USDC and USDm, which pay their own.

Proof, on Celo mainnet

The claim is that the fee comes out of naira and your CELO is never touched. These are real transfers. Open either one and check the Fee Currency field yourself.

Sending naira, fee paid in naira
10 NGNm delivered, fee 1.7575 NGNm, CELO spent 0. Balance before and after the block was identical to the wei: 8.413580680861054656.
0xa9a66398…ce8d9065
Sending cNGN, fee still paid in naira
cNGN cannot pay for its own gas, so the fee came out of NGNm instead. 50 cNGN delivered in full, fee 2.7110 NGNm, CELO spent 0.
0xf030c1ac…67ed377a
Where the rule comes from
Celo keeps a governance-controlled list of what may pay for gas, and Kobo reads it on every health check rather than assuming. NGNm is on it. cNGN is not. That is why the fee lands where it does, and if that ever changes the app will say so instead of failing at your wallet.
For agents

Kobo is not only a page. There is a skill file and an MCP server at /mcp, so software can send naira, quote a rate or read a circle without a browser. Same rails, same contracts.

One call is paid. GET /v1/receipt/:hash tells an agent whether a payment really landed and paid who it should, for $0.01 over x402 in USD₮ or USDC. The agent signs, the Celo facilitator settles, and nobody needs gas. Prices are at /v1/paid.

The API, with real responses

Every response below was produced by calling this server when the page was built, not written by hand. Errors are always {"error": "..."} with a 4xx, phrased to be acted on rather than logged.

GET /healthz

{
  "ok": true,
  "service": "kobo",
  "feeCurrency": "NGNm",
  "accepted": true
}
GET /v1/cost?amount=5000

{
  "example": "5000",
  "arrives": "5000",
  "feeCurrency": "NGNm",
  "estimatedFee": "2.8788301445889",
  "maximumFee": "10.991896915703",
  "total": "5002.8788301445889",
  "senderNeedsCelo": false,
  "nairaAcceptedAsGas": true
}
GET /v1/quote?from=0xE23c44...&to=0xF70A02...&amount=1000

{
  "token": "NGNm",
  "to": "0xF70A02D74970FAFF6b0bE6D0dD558965E1B4d855",
  "amount": "1000",
  "arrives": "1000",
  "feeCurrency": "NGNm",
  "estimatedFee": "2.8788301445889",
  "maximumFee": "10.991896915703",
  "senderNeedsCelo": false,
  "balance": "332.924924380576759279",
  "sufficient": false
}
GET /v1/tokens

{
  "tokens": [
    {
      "symbol": "NGNm",
      "label": "Mento naira",
      "kind": "naira",
      "address": "0xE2702Bd97ee33c88c8f6f92DA3B733608aa76F71",
      "decimals": 18,
      "canPayOwnGas": true
    },
    {
      "symbol": "cNGN",
      "label": "Regulated naira",
      "kind": "naira",
      "address": "0xF6829D7393dAe24509eb1E52eE8e572e2E271a4f",
      "decimals": 6,
      "canPayOwnGas": false
    },
    {
      "symbol": "USDT",
      "label": "Tether dollars",
      "kind": "dollar",
      "address": "0x48065fbBE25f71C9282ddf5e1cD6D6A887483D5e",
      "decimals": 6,
      "canPayOwnGas": false
    },
    {
      "symbol": "USDC",
      "label": "Circle dollars",
      "kind": "dollar",
      "address": "0xcebA9300f2b948710d2653dD7B07f33A8B32118C",
      "decimals": 6,
      "canPayOwnGas": false
    },
    {
      "symbol": "USDm",
      "label": "Mento dollars",
      "kind": "dollar",
      "address": "0x765DE816845861e75A25fCA122bb6898B8B1282a",
      "decimals": 18,
      "canPayOwnGas": true
    }
  ],
  "feePaidIn": "whichever allowlisted token the sender already holds, naira first"
}
GET /v1/receipt/0xf030c1ac...   (paid, $0.01 over x402)

{
  "hash": "0xf030c1ace60441026509f128b4daa19091863ca25528526b2ae2be4667ed377a",
  "found": true,
  "status": "confirmed",
  "block": 77168455,
  "time": "2026-09-10T19:40:13.000Z",
  "confirmations": 1550870,
  "from": "0xe23c44dd4a51456786c6681cfe928aacfa00d619",
  "transfers": [
    {
      "token": "cNGN",
      "from": "0xE23c44Dd4a51456786c6681cFE928AAcfa00d619",
      "to": "0xF70A02D74970FAFF6b0bE6D0dD558965E1B4d855",
      "amount": "50"
    }
  ],
  "fee": {
    "currency": "NGNm",
    "amount": "2.711032419072168772"
  },
  "celoSpentOnFee": "0",
  "sentWithKobo": true,
  "paid": true,
  "verdict": "Confirmed. 50 cNGN to 0xF70A...d855."
}
GET /v1/quote?amount=-5   (an error)

{
  "error": "amount must be a number, like 5000 or 1500.50"
}

What the fields mean, so nothing has to be guessed:

amount, arrives
What you asked to send, and what lands with the recipient. They are equal on purpose: the fee is charged on top, never taken out of the transfer, so nobody receives less than the number you typed.
estimatedFee, maximumFee
What it should cost, and the ceiling you authorise. Under EIP-1559 you pay base plus tip and the rest is refunded, so the real cost lands near the estimate. Check affordability against the maximum, not the estimate, or a busy block turns a quote that said yes into a transfer that fails.
feeCurrency
Which token the fee comes out of, chosen from what the sender already holds. It is not always the token being sent, because cNGN cannot pay for its own gas. Never CELO.
sufficient, gasSufficient
Whether the balance covers the transfer, and separately whether anything on hand can cover the fee. They are separate because the two can come from different tokens. When either is false, note says what to do about it.
feeOptions
Every token Celo accepts as gas that this wallet holds, with the fee priced in each. Shown so a caller can see why one was picked rather than trusting the choice.
payouts
On /v1/currencies: the currencies a naira balance can be paid out in, not currencies you can hold here. Send naira, the recipient gets shillings.