A responsive KES point-of-sale terminal that routes each checkout through a Minmo Partner OTC desk as an onramp swap. The customer pays in KES over M-Pesa and the merchant receives BTC at a configured Lightning address.
- The server requests a fresh BTC/KES quote for the configured automated Partner agent.
- The cashier enters the KES amount and the customer's M-Pesa phone number.
The phone field shows
+254; the cashier enters the remaining nine digits (for example712345678). Pasting0712345678also works. - The server validates the phone against the M-Pesa channel schema and creates
an
onrampswap withfiatPaymentDetails.phoneNumberfor the STK collection anduserPaymentDetails.lightningAddressfor merchant settlement. - The customer approves the M-Pesa prompt on their phone. The POS polls the authoritative swap state until settlement or another terminal state.
Agent transaction limits are satoshi amounts. The POS compares the quoted BTC principal against those limits and displays the range in sats.
On first checkout, the terminal generates a Nostr keypair in the browser. The
64-character hex public key is used as Minmo's beneficiaryId; the private key
never leaves local storage. Any older random terminal identifier is replaced
automatically.
The API key, Partner ID, and agent ID are used only by Next.js server routes. The merchant enters their Lightning address on first launch. It is validated against the wallet's LNURL-pay endpoint and stored only in that browser's local storage.
Copy .env.example to .env.local and set:
MINMO_PARTNER_ID=your-partner-id
MINMO_API_KEY=your-server-only-api-key
MINMO_BASE_URL=https://api.staging.minmo.to/api/v1
MINMO_OTC_AGENT_ID=your-automated-partner-agent-idThe agent must be active, associated with MINMO_PARTNER_ID, and have an
enabled M-Pesa phone onramp automation route.
On first launch, the setup dialog requires a valid Lightning address before the POS can request quotes or create a checkout. The Settings control can be used to validate and replace the address later.
npm install
npm run devThen open http://localhost:3000.
npm run typecheck
npm run lint
npm run buildCreating a checkout is a live staging mutation. Automated verification should use invalid requests or read-only quotes; it must not create a swap.
