Kudos is a loyalty/rewards points program where the points are a real SPL token. People sign up with an email — no wallet, no seed phrase — and the app provisions a custodial Solana wallet for each of them. A business issues a branded points token; users earn points (minted to their wallet) and redeem rewards (points burned). It’s a complete Rails 8 app running on devnet.
It’s the issuance counterpart to Lamport: both run on the custodial Wallet-per-User path through the Solana Developer Platform (SDP), where your app holds wallets for users instead of asking them to connect one. Lamport covers wallets and payments; Kudos covers token issuance — create, deploy, mint, burn.
What it does
- Email signup → auto-provisioned custody wallet — no seed phrase, no wallet extension
- Issue a points token — the business creates the token record, then deploys the mint on-chain
- Earn points — a custodial mint to the user’s wallet (a demo “Earn 10” button; a real app mints on a genuine event)
- Redeem rewards — a custodial burn from the user’s wallet, affordability-checked against a rewards catalog
- Live points balance — read from chain and pushed to the browser the moment a mint/burn settles
- Money-path safe — mints and burns are never sent twice (atomic claim, never-retried POST)
How it’s built
Kudos is the consumer that drove the issuance half of the solrengine-sdp
engine (v0.3). The whole supply path runs through SDP:
token = Solrengine::Sdp::Token.register!( # off-chain record
name: "Kudos Points", symbol: "KUDO", decimals: 0,
signing_wallet_id: treasury_wallet_id
)
token.deploy! # on-chain mint
token.mint!(destination: user.wallet_address, amount: 10) # earn
token.burn!(source: user.wallet_address, # redeem
signing_wallet_id: user.sdp_wallet_id, amount: reward.points_cost)
| Lives in Rails (SQLite) | Lives on Solana (via SDP) |
|---|---|
| Users, rewards catalog, mint/burn audit rows | The points token (a real SPL mint) |
| Affordability checks, demo earn trigger | The custodial wallet for each user |
Session auth (has_secure_password) |
Every mint and burn, signed custodially |
Each mint!/burn! records an audit row, then sends a single, never-retried
POST (SDP has no idempotency key, so a blind re-send could double-mint). An
atomic claim guarantees a mint is never sent twice. Because the app initiates
every mint and burn, the job that settles them is the doorbell: it pushes
the new balance to the browser live — no chain-WebSocket polling needed.
Running it
SDP is pre-mainnet and devnet-oriented, so there’s no hosted demo — it needs a
running SDP instance plus a managed custody provider. The full source is on
GitHub, and the
getting-started tutorial walks from rails new to
this exact app. See the Wallet-per-User docs for the prerequisites.
Built as the second SolRengine reference app (Agentic Engineering grant, M3),
on the published solana-sdp and solrengine-sdp gems.