Allowance that grows. A Solana protocol where parents deposit USDC once into a pooled vault, the vault lends on Kamino at ~8% APY, and the kid receives a monthly allowance plus a year-end yield bonus — the décimo terceiro every Brazilian knows, but on-chain.
- Live product → seedlingsol.xyz
- Pitch deck →
Seedling — allowance that grows.pdf - Program ID →
44vix4JmG4hdoharDH38R5sc7g5MbFxjvpUpgwNDbTYN
| Network | Live on Solana mainnet |
| Program | 44vix4JmG4hdoharDH38R5sc7g5MbFxjvpUpgwNDbTYN (same address on both clusters) |
| Framework | Quasar (Pinocchio-based, single-byte discriminators, no_std) |
| Yield engine | Kamino klend — verified against klend v1.18.0 |
| Frontend | Next.js · Privy embedded wallets · 4P Pix integration (pending production activation) |
| Authority | 6Wk8mM3DX5nv6naY4webfKe7ntdJagQpwtGaJcfvc56K |
Build metrics
12 instructions · 6 user + 1 close + 5 admin / ops
36 tests · 17 Rust unit + 14 TS integration + 5 Surfpool e2e
27,504 LOC · 3,050 Rust + 24,454 TypeScript/TSX
149 KB binary · 70% smaller than the 497 KB Anchor reference build
Coming next (Q3 2026): 4P Pix delivery in production · Brazilian off-ramp · MoonPay onramp for international parents (USD/EUR cards) · Light Protocol — ZK-compressed gift wall + distribution log · Seeker App · Jupiter integration · open vault standard for partner builders.
- Parent funds the vault in USDC. One deposit; the vault CPIs into Kamino's USDC reserve and receives interest-bearing cTokens. No subscriptions.
- Allowance arrives on the 1st of every month. Drawdown is principal-first (kid spends the principal, then yield once principal exhausts). A 30-day on-chain time gate prevents abuse.
- Year-end bonus sweeps accumulated yield (everything above remaining principal) to the kid in one payout — the 13th allowance. Pure yield by construction.
- Protocol earns 10% of yield at every cToken-redeeming event (withdraw, monthly distribute, bonus). Aligned incentive: Seedling earns when families earn. Deposits are fee-free by mechanism.
- Parent custody, kid never signs — by architecture. The kid identifier is a 32-byte client-generated address that owns nothing on-chain. The parent retains custody of the principal at all times; yield is gifted at distribution. Kids hold a read-only
KidViewPDA so the kid-facing URL is canonical and shareable but cannot move funds.
The on-chain program currently exposes 12 instructions — 6 user-facing (initialize_vault, create_family, deposit, withdraw, distribute_monthly_allowance, distribute_bonus), close_family for cleanup, plus 5 admin/operations helpers (set_family_last_distribution, roll_period, set_paused, payout_kid, set_stream_rate).
parent (Privy or self-custody wallet)
│ USDC
▼
┌──────────────────────────────────────────────────┐
│ Quasar program — 12 instructions (Pinocchio) │
│ │
│ ┌──────────────┐ ┌────────────────┐ │
│ │ VaultConfig │ │ FamilyPosition │ │ ← shares pattern (kvault)
│ │ · oracles │ │ · shares │ │
│ │ cached │ │ · principal_* │ │
│ │ · period_id │ │ · last_dist │ │
│ │ · cTokens │ │ · bump │ │
│ └──────┬───────┘ └────────────────┘ │
│ │ │
│ │ PDA seed: "vault_config_v2" │
│ │ Family seed: "family_v3" + parent+kid │
└─────────┼────────────────────────────────────────┘
│ deposit_reserve_liquidity / redeem_reserve_collateral
▼
Kamino klend (mainnet · devnet)
│
▼
~8% APY USDC lending market
Frontend & runtime layers:
┌──── parent UX ─────────────┐ ┌──── kid UX ────────────────────┐
│ Privy embedded wallet │ │ /kid/<familyPda> — public, │
│ (Google login, no seed │ │ wallet-free, read-only │
│ phrase) │ │ 12-stage tree visualization │
│ │ │ countdowns + savings goals │
│ + Phantom/Solflare for │ │ bonus-ready celebration │
│ self-custody parents │ │ (halo + falling petals) │
└────────────┬───────────────┘ └────────────────────────────────┘
│
▼
Sponsor relay endpoint ← covers gas for first-time families
/api/sponsor-broadcast ← supports atomic [create_family + deposit]
bundle for lazy creation
│
▼
4P Finance — Brazilian Pix ← R$ → USDC (and back)
/api/4p/onramp ← signed webhook on USDC delivery
/api/4p/webhook
│
▼
Hot wallet → parent's USDC ATA ← idempotent, on-chain memo
(`cid:<customId>`) for replay
protection
Design notes:
- Reserve-agnostic. Kamino reserve pubkey + per-reserve oracle config cached on
VaultConfigatinitialize_vault. Address-validated on every subsequent CPI. Same program runs against mainnet's Scope-only USDC reserve and devnet's Pyth-only reserve without code changes. - kvault share math. Floor-on-mint, floor-on-redeem, ceil-on-target-asset. First-depositor donation-attack defense via Path A inflation guard. No virtual-offset field.
- Path B exchange-rate computes
total_assets = cTokens × (supply_vault + borrowed_amount_sf >> 60) / ctoken_supplydirectly from observable accounts. Avoids deserializing klend's 8624-byteReserve. - Fees collected at cToken-redeeming events only (withdraw + both distributes). Deposit is fee-free by mechanism — Day-3 design that skimmed fees from
vault_usdc_ataat deposit was caught by the Day-5 precision regression test. - Lazy family creation. Parents can add a kid without paying rent until the first deposit. Drafts live in
localStorage; the deposit transaction bundles[create_family + deposit]atomically through the sponsor-relay endpoint.
Hard-won pitfalls: GOTCHAS.md.
- Solana CLI 3.1+ · Rust stable · Node 20+
- Phantom or Solflare wallet on Solana mainnet (or just use Privy login on the live site — Google sign-in, no seed phrase)
- ~$5 USDC mainnet (Coinbase / Binance / any exchange withdraws USDC on Solana with the Circle mint
EPjFWdd5...) - A small amount of SOL for gas if running self-custody; sponsor wallet covers the first tx automatically for Privy users
cd programs/seedling-quasar
cargo build-sbfQuasar is Pinocchio-based — Anchor's CLI (anchor build, anchor test) does not apply. Build artifacts land in target/deploy/seedling_quasar.so.
cd frontend
npm install
npm run dev # http://localhost:3000Required env vars:
NEXT_PUBLIC_PRIVY_APP_ID— Privy app ID (public)NEXT_PUBLIC_HELIUS_RPC— Helius RPC URL (recommended; falls back to public mainnet RPC, which 403s aggressively against browsers)SEEDLING_HOT_WALLET_SECRET_KEY— base58-encoded keypair that funds Privy users' first tx (server-only)FOURP_API_KEY,FOURP_API_BASE,FOURP_WEBHOOK_SECRET— 4P Pix on-ramp credentials (server-only, optional for non-Pix flows)
# Terminal 1
surfpool start --network mainnet --no-tui
# Terminal 2
solana program deploy --url http://127.0.0.1:8899 target/deploy/seedling_quasar.so
ANCHOR_WALLET=~/.config/solana/id.json \
ANCHOR_PROVIDER_URL=http://127.0.0.1:8899 \
npx tsx scripts/surfpool-deposit-precision.tsOther e2e scripts in scripts/: surfpool-withdraw-e2e.ts, surfpool-distribute-e2e.ts, surfpool-bonus-e2e.ts.
.
├── programs/
│ ├── seedling-quasar/ # Quasar/Pinocchio program — production
│ │ └── src/
│ │ ├── lib.rs # 12-instruction dispatcher
│ │ ├── state.rs # VaultConfig, FamilyPosition, KidView
│ │ ├── instructions/ # admin, deposit, withdraw, distribute…
│ │ ├── utils/ # share math + harvest helpers
│ │ ├── events.rs # event types
│ │ └── errors.rs
│ └── seedling/ # Anchor reference impl (pre-Day-11) — kept for diffing
├── frontend/ # Next.js · React · TypeScript
│ ├── app/ # routes
│ │ ├── api/
│ │ │ ├── 4p/ # Pix on-ramp, webhook, sweep
│ │ │ └── sponsor-broadcast/ # atomic [create_family + deposit] relay
│ │ ├── dashboard/ # parent — two-layer account view
│ │ └── kid/[familyPda]/ # public kid view (no wallet required)
│ ├── components/
│ │ ├── dashboard/ # ParentAccountSection, FamilyCard, …
│ │ ├── PixDepositForm.tsx # Pix QR + polling
│ │ ├── TopUpAccountModal.tsx # USDC top-up tutorial (non-crypto-friendly)
│ │ └── KidView.tsx # 12-stage tree + bonus celebration
│ └── lib/
│ ├── quasar-client.ts # 12-instruction TS client
│ ├── hotWallet.ts # server-only: signs + sends USDC transfers
│ ├── fourp.ts # 4P Finance API wrapper
│ ├── draftFamilies.ts # localStorage drafts (lazy creation)
│ ├── fetchFamilies.ts # merged on-chain + draft view
│ └── i18n.tsx # PT-BR + EN
├── tests/ # LiteSVM + integration tests
├── scripts/ # Surfpool e2e + cluster-aware ops
├── docs/4p-finance-api.md # 4P Pix integration reference
├── GOTCHAS.md # hard-won pitfalls (Quasar, Kamino, devnet, 4P)
├── LICENSE # MIT
└── README.md
Per Section 9 of the Frontier rules — full disclosure:
| Layer | Dependency | License | Role |
|---|---|---|---|
| On-chain | Pinocchio | Apache 2.0 | Solana program framework — single-byte discriminators, zero-copy account access, no_std |
| On-chain | Quasar (quasar-lang) |
Apache 2.0 | Pinocchio-based authoring layer — derive macros for accounts, dispatcher, event emission |
| On-chain CPI | Kamino klend v1.18.0 | Apache 2.0 | USDC lending market — yield engine via deposit_reserve_liquidity / redeem_reserve_collateral |
| On-chain runtime | zeropod, wincode | Apache 2.0 / MIT | Zero-copy serialization helpers used by Quasar |
| Frontend wallet | Privy SDK | MIT | Embedded wallet UX — Google login, no seed phrase (showWalletUIs: false) |
| Frontend wallet | Solana wallet adapter | Apache 2.0 | Phantom / Solflare support for self-custody parents |
| Frontend SDK | @coral-xyz/anchor | Apache 2.0 | Event coder only — used to decode emitted events. We do not use the Anchor program client (which assumes 8-byte discriminators); all instruction construction is manual via quasar-client.ts. |
| Frontend SDK | @solana/web3.js (1.x) | Apache 2.0 | RPC + transaction building |
| Frontend infra | Helius RPC | commercial (free tier) | Mainnet RPC + token-account indexing |
| Off-chain integration | 4P Finance API | commercial | Brazilian Pix on-ramp integration (R$ → USDC delivery to a hot wallet) — pending production activation |
| Testing | Surfpool | Apache 2.0 | Local mainnet-fork validator with JIT account fetch |
| Testing | LiteSVM | Apache 2.0 | In-process Solana VM for fast unit-style integration tests |
| Frontend | Next.js, Tailwind | MIT | UI framework + styling |
No oracles or AI/ML services in the runtime path. No tokens minted by Seedling itself. No NFTs (yet — see roadmap).
MIT © 2026 Vicenzo Tulio
Seedling. Deposit once. Let it grow. 🌱