Skip to content

Iron-Mark/Hackathon-Stellaroid_Earn

 
 

Repository files navigation

Stellaroid Earn

On-chain credential trust for Stellar PH Bootcamp 2026

Issue, verify, and pay graduates on Stellar testnet - Soroban + Freighter, end-to-end.

Live Demo Stellar Testnet Soroban SDK Next.js License: MIT

Stellaroid Earn

Live demo stellaroid.tech
Contract (current) CDMUOHMARNVOJZM3IVOCJUPGBHDTHFBMZCCZXEZPQDVJGILH3NIKTTW3
Tx evidence init · register · verify
Source verification Fresh security-hardened testnet deploy. WASM hash 59ca403e347f4c24b1dd16fbcb65662c2837cc852946e3ae88374eed509d6f7f; Stellar Expert source re-verification pending.
Submission Rise In · Stellar Smart Contract Bootcamp · Stellar PH Bootcamp 2026
Result Top 5 / 105 participants · Score: 75.00

Top 5 - Stellar Bootcamp Prize Pool


Project Status

The bootcamp/event submission is complete. Stellaroid Earn is now maintained as a living Stellar credential proof project.

www.stellaroid.tech and earn.stellaroid.tech redirect to the canonical apex URL.


30-Second Pitch

Problem - Bootcamp certificates are PDFs that anyone can fake and no one can independently verify. Employers skip verification or pay for a background check service.

Solution - Stellaroid Earn anchors credential hashes on a Soroban smart contract where approved issuers register and verify certificates, anyone checks proof at a public URL with no login, and employers pay graduates in XLM - all on-chain.

Why Stellar - Sub-cent fees and 5-second finality make issuing credentials cheap enough to never skip. simulateTransaction lets anyone verify with zero wallet setup. Native XLM via SAC closes the loop from proof to payout on one chain.


Feature Gallery

Landing page
Discover - Landing page with 3-step how-it-works flow
Verified proof block
Verify - On-chain credential with green Verified badge
App dashboard
Issue & Pay - Dual-role dashboard for issuers and employers
Mobile proof card
Share - QR-scannable proof card on any mobile browser

Live Trust Artifact

Every credential produces a public Verified Badge URL - no wallet, no login, no API key. Green means verified on-chain. Amber means issued but not yet verified.

Verified credential
Verified
Try it yourself →
Issued (locked) credential
Issued (locked)
Try it yourself →

Contract on Stellar Expert: CDMUOHMA…IKTTW3

Contract history on Stellar Expert


Architecture

Full architecture document: docs/ARCHITECTURE.md

sequenceDiagram
  autonumber
  actor Issuer as Approved Issuer
  actor Student
  actor Employer
  participant FE as Stellaroid Earn (Next.js)
  participant FR as Freighter
  participant SC as Soroban contract<br/>(stellaroid_earn)
  participant XLM as Stellar testnet

  Issuer->>FE: Open /app, paste student wallet + cert hash
  FE->>FR: requestAccess + signTransaction(register_certificate)
  FR->>XLM: Submit tx
  XLM->>SC: register_certificate(issuer, student, hash, title, cohort, uri)
  SC-->>XLM: cert_reg event
  Issuer->>FE: Click "Approve credential"
  FE->>FR: signTransaction(verify_certificate)
  FR->>XLM: Submit tx
  XLM->>SC: verify_certificate(verifier, hash)
  SC-->>XLM: cert_ver event
  Student->>FE: Share /proof/<hash> (QR or link)
  Note over FE,SC: Read-only get_certificate via simulateTransaction
  Employer->>FE: Open /app as Employer, paste hash + amount
  FE->>FR: signTransaction(link_payment)
  FR->>XLM: Submit tx (XLM transfer + payment event)
Loading

Design decisions:

  • soroban-sdk 22 with typed #[contracterror] enum (17 variants), persistent + instance storage, TTL 518k/1.04M ledgers
  • Issuer trust layer: self-register → admin approve → issue credentials. Suspended issuers are blocked on-chain
  • Two read paths: server-side RSC with revalidate=60 (CDN-cached proof pages) + client-side simulateTransaction (dashboard state)
  • One write path: Freighter signs → sendTransaction → poll for result
  • CSP locks connect-src to *.stellar.org - no third-party data leaks

Quick Start

Prerequisites

Full setup guide: setup/[ENG] Pre-Workshop Setup Guide.pdf

Smart Contract

cd contract
cargo test                    # contract test suite
stellar contract build        # builds wasm32v1-none target

# Deploy to testnet
stellar keys generate my-key --network testnet --fund
stellar contract deploy \
  --wasm target/wasm32v1-none/release/stellaroid_earn.wasm \
  --source my-key --network testnet

Frontend

cd frontend
cp .env.example .env.local    # fill in contract ID + read address
npm install
npm run dev                   # http://localhost:3000

Environment variables (.env.local):

NEXT_PUBLIC_STELLAR_RPC_URL=https://soroban-testnet.stellar.org
NEXT_PUBLIC_STELLAR_NETWORK=TESTNET
NEXT_PUBLIC_STELLAR_NETWORK_PASSPHRASE=Test SDF Network ; September 2015
NEXT_PUBLIC_SOROBAN_CONTRACT_ID=<your deployed contract ID>
NEXT_PUBLIC_STELLAR_ADMIN_ADDRESS=<your admin G... address>
NEXT_PUBLIC_STELLAR_READ_ADDRESS=<any funded testnet address for read-only calls>
NEXT_PUBLIC_SOROBAN_ASSET_ADDRESS=CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC
NEXT_PUBLIC_SOROBAN_ASSET_CODE=XLM
NEXT_PUBLIC_SOROBAN_ASSET_DECIMALS=7
NEXT_PUBLIC_STELLAR_EXPLORER_URL=https://stellar.expert/explorer/testnet
NEXT_PUBLIC_CANONICAL_URL=https://stellaroid.tech

Verifiable On-Chain

Every action in the demo flow is a real transaction on Stellar testnet. Click any hash to verify on Stellar Expert.

Action Tx Hash Result
init 37afd2a5…96bb Contract initialized with admin + XLM token
register_certificate f3d6c0f4…8c13 Demo credential hash registered for student
verify_certificate cf734925…a0b Status changed to Verified

Live certificates (testnet, contract CDMUOHMA…):

Hash Cohort Status
c02ce160…aea3 Stellar PH Bootcamp 2026 Verified

Contract Functions

Function Caller Description
init(admin, token) Deployer Initialize contract with admin address and XLM token
register_issuer(address, name, website, category) Anyone Submit issuer application (Pending status)
approve_issuer(admin, issuer) Admin Approve an issuer to register credentials
suspend_issuer(admin, issuer) Admin Suspend a misbehaving issuer
get_issuer(issuer) Anyone Read issuer record and status
register_certificate(issuer, student, cert_hash, title, cohort, metadata_uri) Approved issuer Register a credential hash for a graduate
verify_certificate(issuer, cert_hash) Admin or issuer Mark a credential Verified
revoke_certificate(issuer, cert_hash) Admin or issuer Permanently revoke a credential
suspend_certificate(issuer, cert_hash) Admin or issuer Temporarily suspend a credential
reward_student(student, cert_hash, amount) Admin Admin-initiated XLM payment to a graduate
link_payment(employer, student, cert_hash, amount) Employer Employer pays graduate in XLM, linked to credential
get_certificate(cert_hash) Anyone Read full credential record and status

Credential Status Lifecycle

Issued --> Verified  (issuer or admin calls verify_certificate)
       --> Revoked   (issuer or admin calls revoke_certificate)
       --> Suspended (issuer or admin calls suspend_certificate)
       --> Expired   (reserved status; new credentials currently use expires_at = 0 unless a future issuer flow sets expiry)

Tests

Contract tests cover the trust layer, access control, revocation, opportunity escrow, milestone caps, and events:

running 12 tests
test test::t1_happy_path_with_approved_issuer ... ok
test test::t2_unapproved_issuer_cannot_issue ... ok
test test::t3_suspended_issuer_cannot_issue ... ok
test test::t4_wrong_approved_issuer_cannot_verify ... ok
test test::t5_revoked_credential_blocks_payment ... ok
test test::t6_issuer_events_emit ... ok

test result: ok. 12 passed; 0 failed; 0 ignored
Test What it verifies
t1 Happy path: approved issuer registers + verifies credential, admin rewards student
t2 Pending (unapproved) issuer cannot register a credential
t3 Suspended issuer cannot register a credential
t4 Approved issuer A cannot verify issuer B's credential
t5 Revoked credential blocks downstream payments
t6 Events emitted correctly for init, register_issuer, approve_issuer
t7-t10 Opportunity create, fund, submit, approve, release, refund, and invalid transition behavior
t11 Opportunity milestone count is capped to prevent unbounded work/rendering
t12 Employer can refund after candidate submission to avoid escrow lock

Security

Full security checklist: docs/SECURITY.md

Covers: smart contract access control, frontend CSP/HSTS/X-Frame-Options, strict input validation, JSON-LD escaping, URL sanitization, proof-claim integrity, fee-sponsor restrictions, error normalization, SSRF prevention, and operational security.


Advanced Feature: Fee Sponsorship (Gasless Transactions)

Stellaroid Earn keeps fee bump transaction support (CAP-0015) behind a server-to-server authorization boundary. Public browser clients do not automatically send signed XDR to /api/fee-bump.

How it works:

  1. A trusted server obtains a user-signed transaction for an allowed Stellaroid Earn method
  2. The trusted server calls /api/fee-bump with Authorization: Bearer <FEE_SPONSOR_TOKEN>
  3. The route enforces XDR size, signature, operation count, network, contract ID, method allow-list, and fee-ceiling checks
  4. Only then does the sponsor key wrap the transaction as a fee bump

Implementation:

  • Server route: frontend/src/app/api/fee-bump/route.ts
  • Client helper: frontend/src/lib/fee-bump.ts
  • Config: FEE_SPONSOR_SECRET + FEE_SPONSOR_TOKEN are server-only. Public browser auto-sponsorship stays disabled; trusted server callers must provide the bearer token explicitly.
  • Browser fallback: normal user-paid Freighter transactions remain the default path.

Metrics & Monitoring

  • Metrics dashboard: /metrics - on-chain stats (events, proofs, transactions, certificates, rewards, payments) refreshed every 30s
  • Health endpoint: /api/health - cached JSON health check (config, RPC latency, contract availability)
  • Events API: /api/events - structured contract event data for external consumers
  • Vercel Analytics: Web analytics integrated via @vercel/analytics

Data Indexing

Contract events are indexed by querying Soroban RPC's getEvents method across a 60,000-ledger window (~2 days). Events are decoded from ScVal, categorized by kind (cert_reg, cert_ver, reward, payment), and served via the /api/events REST endpoint and the /metrics dashboard. The approach is lightweight and serverless - no external indexer infrastructure required.


Tech Stack

Component Version
Soroban SDK 22.0.0
Stellar CLI 26+
Next.js 15 (App Router)
React 19
@stellar/stellar-sdk latest
@stellar/freighter-api latest
Tailwind CSS v4

Project Structure

stellaroid-earn/
├── contract/
│   ├── src/
│   │   ├── lib.rs              # Soroban credential + payment contract
│   │   └── test.rs             # contract security and lifecycle tests
│   └── Cargo.toml
├── frontend/
│   ├── src/
│   │   ├── app/                # Next.js App Router pages
│   │   │   ├── app/            # Participant dashboard (issuer + employer)
│   │   │   ├── issuer/         # Issuer registration + lookup
│   │   │   └── proof/[hash]/   # Public shareable verified badge
│   │   ├── components/         # UI components (proof card, wallet, badges)
│   │   ├── hooks/              # Freighter wallet state
│   │   └── lib/                # Contract client, RPC helpers, types
│   └── .env.example
├── demo/                       # Demo script, FAQ, press kit
├── scripts/                    # Screenshot capture (Playwright)
├── images/                     # README screenshots
├── LICENSE
└── README.md

Demo Video

https://github.com/user-attachments/assets/stellaroid-earn-demo.mp4

Full walkthrough: landing page → about → app dashboard (wallet connect) → issuer console → verified proof page → on-chain evidence on Stellar Expert.

Local copy: demo/stellaroid-earn-demo.mp4

Demo Day slides: /slides (integrated into the app, arrow keys to navigate)

Submission/demo checklist: docs/DEMO_CHECKLIST.md


User Validation

Testnet Users

30+ users tested the MVP on Stellar testnet. Each wallet address is verifiable on Stellar Expert. 18 wallets have direct contract interactions (register_issuer), 12 are funded explorers.

View all 30 wallet addresses
# Wallet Address Verified On-Chain
1 GCBBBLZVJVVM2ZMXPNMDN2ATH7AJ2H4BHOKA7JOJT6EMWTOKCGRKUK6I Stellar Expert
2 GALGZBDSFG4FRTFSO7XLURBJRYC6PA34H73IF66G7BZOXXQDMWSHPXEU Stellar Expert
3 GAWJEP7LWY7WPLP7SBPR4MWQGQJIBAHVNVXYQE33F5FL2VFMFGBBFZ4B Stellar Expert
4 GCBZAJUZXRHNLVR4RCG743KSTKQSVFKXQCNYWAH4FVHDVSS5IT6DWSI3 Stellar Expert
5 GAQZJQPZI7YZBUN6YVAFACVKAH6ODNBO3DVELP34VW4MLLUBCL5DMMNS Stellar Expert
6 GAYOZX7LSYYYROU4SEBKGOOHOPUWYORPXEDHZJOXZ5Q45XZED7IMXG2U Stellar Expert
7 GDVNNL2QFO4PFYDLVLZTL2GKKOZR3YBV2AIIV7U44DXDOKKRJFIMLWCB Stellar Expert
8 GCFL24VJA3LPZLIOJ3AAVGCUGOW4A7ZUWNNEGR332IZ2MHMUWCTK3GVG Stellar Expert
9 GBNVAVBVELOM2FBBPWDTUBM5DRECBY2MKPZ6YYO3CNKKSFCUUSE3HAU5 Stellar Expert
10 GBWATJDBLCF7PPUQYBWBXCUQ5ZXRHKHZ7RAFHWZ4SLMNH45VBRPAXXYY Stellar Expert
11 GDBJYDYLU3JH7V6X6KHPWQOSRQNXTL7OYTD6HUNVGB2J6Y7CUUX4WW6R Stellar Expert
12 GA6DCDZIIP3FGLIAU5FLUZLBBFCM6XD26JDJVJCA6EL2LKY5OKA7YAQF Stellar Expert
13 GBTNI3CULIDVJWABRYF5T56W7COYTA5JCRD3EAKO3VDSDWCUT2ZHSLAO Stellar Expert
14 GD2PSTZL2YQC66C4PGFS5D64A6473IEKCZKNMIM5B7JWVLVS2N27D7QU Stellar Expert
15 GCZJCXZTC5KELSLQJU6QUIDMRZ2HFTUIDYL3PCOKGR7XRAFI373DO6PU Stellar Expert
16 GCD4WRBPCKIPMDKLQA2LRAGYOIWCVRXJI4XNW4TI2ECVNKQO3T2XUSHG Stellar Expert
17 GBJXD5H457AKCFEGTSKYMD4MRSBBMGTUCOKEBU6YQ7TKNZ7SY2W37KKY Stellar Expert
18 GAGR7D5K4VL5HNOZCL6CYZIGT5FNYZW7I5WXGX6HSBZLLVQ3NG77XBAO Stellar Expert
19 GAZXPBADNPTKWAGUWZM6KWEMIO4MQVU4GW3ZJXKHEO4BOBL5SLERSQYR Stellar Expert
20 GDANCIDPUHS4IQUNHRM5RNKVOXTRR5RKIYYEE7HVPB2RWD76J66CS2DH Stellar Expert
21 GCHZOQCDMG5J6NC2MNAR6EH5JFGI6JEP7TQWWUDRWER75Q3W3NC52HMG Stellar Expert
22 GC54CLYWNJ2AQZCAA2LVXOR2XTNGGCZYDSEJLLQBV6D4EDXN6D6DFGPX Stellar Expert
23 GDTJBRZXXMOWPF3LPMM7V4WOBIPLGR6BXTRDBYH6VCBRBL5Y76NK5JHY Stellar Expert
24 GDK5LNJFLU5LLNQDDZJ4SUPXASK7SULASCAGEHF5IT65FX2FYZ56CHAM Stellar Expert
25 GBTY2BMYVRP2SFSFJXMHFQ6XQOKUS5JEZEAF3ZI5356FK7EQN56G57QE Stellar Expert
26 GANDLIFPFLNRYMIK6PG3BQU437PVUDLKS2VBCBYAMCJOKYZPRJWGORSU Stellar Expert
27 GAVCDYPJLPA2W4EYIMDXPSGAMUJDDOCSGNVZAX7UER4B4AKLVSDZSEIT Stellar Expert
28 GARXSQZMDE4YF5IL6TWDAF4IAQG326JWAMOB5MAVAM3BOTXKM47Q6AQC Stellar Expert
29 GBS6ERMNCYSO2EK7VPAGJP6TI6IEKGRJNUTKZWJ7KDBLY7Y6MG3CFEWF Stellar Expert
30 GCOON62FGOWAW44SAWI3UKNJY52W7RD4CIBEQFZJEI2J56MWOCKUENAC Stellar Expert

Feedback Collection

Improvements Based on Feedback

After collecting feedback from testnet users, the following iteration was completed:

Feedback Improvement Commit
Users confused about which role (Issuer vs Employer) to pick after connecting wallet Added contextual role guidance hints below the persona toggle c1450bf

Community Contribution

Threads Post


Built By

Mark Siazon - Hybrid Product Designer & Full-Stack Developer

Portfolio LinkedIn
GitHub Main
GitHub Professional Acct

Acknowledgments


MIT License - see LICENSE for details.

About

Stellaroid Earn — On-chain credential registry and payment rail on Stellar. Issue, verify, and pay bootcamp graduates with Soroban + Freighter.

Topics

Resources

License

Security policy

Stars

Watchers

Forks

Sponsor this project

  •  

Contributors

Languages

  • TypeScript 91.3%
  • Rust 6.1%
  • CSS 2.5%
  • JavaScript 0.1%