A developer has shared “Loyalty Ledger,” a prototype fan loyalty tracker that records check-in streaks, badge tiers, and related history on Solana rather than in the app’s own database. The project targets a common issue in sports apps: streaks and loyalty history can reset when users stop using an app, switch services, get banned, or when the service deletes inactive accounts. In this build, a user connects a crypto wallet, selects a sport and team, and performs a “check-in” that sends an actual on-chain transaction. For FIFA World Cup, the app writes to a Solana program-owned account, updating streak counts and timestamps and supporting badge claims. The developer describes the core data structure as a small Anchor program that assigns each fan a PDA (program-derived address) keyed to the wallet, sport, and team, while storing streak-related fields and also keeping sport and team as explicit account fields to enable leaderboard queries. The interface includes a Fan Passport, derived “Fan Score,” achievement views, and a leaderboard based on on-chain state. The app uses Solana Devnet for testing, and developers can mint an SPL token badge after crossing a tier threshold; other sports mentioned in the UI are described as stubbed or sample-based.
Developer builds Loyalty Ledger on Solana to store fan check-in streaks on-chain
A developer has shared “Loyalty Ledger,” a prototype fan loyalty tracker that records check-in streaks, badge tiers, and related history on Solana rather than in the app’s own database. The project ta...
- Loyalty Ledger is a fan check-in and streak tracker that stores loyalty data on Solana instead of an app database.
- Check-ins for FIFA World Cup send on-chain transactions that create or update a program-owned account, rather than updating local/app-controlled data.
- Each fan’s record is stored in a Solana PDA keyed to wallet, sport, and team; the record includes fields for streak count and last check-in time.
- The developer adds sport and team as explicit account fields to support leaderboard-style ranking using filtered on-chain account queries.
- The app is tested on Solana Devnet via a wallet (Phantom), and tier rewards include minting an SPL token after a threshold number of check-ins.
This is a submission for Weekend Challenge: Passion Edition What I Built Loyalty Ledger — a fan loyalty tracker where your check-in streak, badges, and history live on Solana instead of some app's database. Live app: https://loyalty-ledger-blond.vercel.app Here's the problem I kept coming back to. Every sports app wants you to check in, engage, "prove your loyalty" — collect points, build a streak, unlock a badge. Cool. Except every single one of them throws that history away the second you stop opening the app. Switch apps and your streak resets to zero. Get banned, or the app shuts down, or they just quietly decide to wipe inactive accounts one day — and your history is just... gone. Because it was never actually yours. It was a number sitting in someone else's database, and they could reset it, inflate it, or delete it whenever they felt like it. You had zero say in it. And that bugged me way more than it probably should have. Like — we figured out how to make ownership portable for money, for domain names, for digital art. But "I've supported Argentina since 2019" 🇦🇷 still lives and dies inside one company's backend, and nobody's really questioned that. So I kept the weekend scope deliberately small: prove one fan's loyalty to one team, for real, end to end — instead of sketching ten features that are all half-fake. You connect a wallet, pick a sport and team, and check in. FIFA World Cup is the fully working path here ⚽ — that check-in sends an actual transaction that creates or updates a program-owned account, not a row in my database somewhere. Your streak count, your badge tier, the actual badge tokens — none of it exists anywhere I control. Which honestly felt a little weird to build, in a good way. Once that core loop worked, I built the rest of the identity around it: a Fan Passport that shows your streak, a derived "Fan Score," your tier (Rookie → Devoted → Veteran → Legend 🏆), a progress bar toward the next tier, an achievements grid with locked/unlocked states, a recent-activity feed pulled from real on-chain history, and a leaderboard ranking actual fans by actual streaks. There's also a "Demo Preview" toggle that fills the passport with sample numbers, clearly labeled as sample data — because a screen full of zeros just doesn't demo well, and I'd rather be upfront about that than pretend it's real. NBA and "Other International Sport" are in the app too, same UI and flow, but honestly? They're stubbed. Sample fixtures, no chain writes, and the app says so directly instead of hiding it. I'd rather ship one path that's completely real than three that are all a little bit fake. Demo Live app: https://loyalty-ledger-blond.vercel.app GitHub: https://github.com/ishantgupta30/Loyalty-Ledger To actually try it: Install Phantom if you don't have it, and switch it to Devnet — Settings → Developer Settings → Change Network → Devnet. This is the step almost everyone misses first, myself included the first time 🙃 Grab free devnet SOL from the faucet to cover transaction fees, which run a fraction of a cent per check-in. No real money touches this project anywhere. Open the app and click Connect Wallet, top right. Pick FIFA World Cup and a team. Hit check-in and approve the transaction Phantom pops up. Watch the streak and Fan Score update, confetti fires 🎉, and if you crossed a threshold, a badge-unlocked toast shows up. Scroll down and the full Fan Passport fills in — tier, progress bar, achievements, recent activity, your actual rank on that team's leaderboard. Once you've crossed tier 1 (3 check-ins), hit Claim Badge — it mints a real SPL token straight to your wallet. Go check Phantom's token list after, it's just sitting there. Permanently. Not a UI element pretending to be a thing 👀 Code GitHub Repository: https://github.com/ishantgupta30/Loyalty-Ledger How I Built It The account design The core piece is a small Anchor program. Every fan gets a PDA — a Program Derived Address, an account owned by the program itself, not by me — keyed to (wallet, sport, team): pub struct FandomRecord { pub wallet: Pubkey, pub streak_count: u32, pub last_checkin_ts: i64, pub bump: u8, pub highest_tier_claimed: u8, #[max_len(32)] pub sport: String, #[max_len(32)] pub team: String, } Check-in doesn't touch a database at all. It fires a check_in instruction that either creates this account (first check-in) or updates it — extends the streak, or resets it if too much time passed between check-ins. That's basically the whole point of this project in one sentence: the streak isn't something my frontend can fake, inflate, or quietly reset, because it was never my frontend's data to begin with. Anyone — not just this app — can read the account directly and verify exactly what it says. No trust required. The leaderboard problem (this one got me) This took way longer than it had any right to. My first cut of the account only stored wallet, streak_count, and last_checkin_ts — sport and team lived purely in the PDA seeds. Which is fine if you already know a wallet and want to look up their record. But it's a total dead end if you want to ask "who are the top Argentina fans," because seeds only let you derive one specific account when you already know the inputs. You can't run that backwards to enumerate every account matching a team. Learned that one the hard way mid-build. So I ended up adding sport and team as actual fields on the account data, not just seed inputs. Which meant a full account-struct change, a rebuild, and a redeploy — genuinely annoying mid-weekend — but it's what makes a real getProgramAccounts call (filtered client-side by sport/team) actually able to answer "rank every Argentina fan by streak" using real chain state instead of a cached guess or a fake list. Why Solana, specifically I wanted this to be a project where pulling out the blockchain would actually break something — not just remove a buzzword from the pitch. Check-ins are frequent and individually pretty worthless — potentially one per match, per fan, across a lot of fans over a tournament. That only works as a real product (not a novelty) if each check-in is near-free and confirms fast enough to feel like a UI action instead of a bank transfer. Solana's one of the few chains where both of those are true at once. A check-in here confirms in about a second and costs a fraction of a cent — which is the actual, boring, practical reason "check in every match, forever" is something you could really build, instead of something that only works in a demo video. There's a side effect of the PDA design I honestly didn't fully plan for going in: because the fan record is owned by the program and not by my database, any other app that knows the program id can read it directly. No API key. No integration meeting with me. No trusting my numbers. A ticketing platform could check the same record to offer a loyalty discount. A streaming service could unlock a perk off the same tier. None of that needs my permission or my infrastructure staying online. That's a meaningfully different thing from "an app that happens to use Solana" — and it kind of just fell out of choosing PDAs over a normal database, rather than being the original plan. What actually broke along the way Being honest here instead of pretending this all went smoothly: I burned a genuinely embarrassing amount of time on devnet SOL. The official faucet rate-limits per IP, and I hit that wall hard while iterating on deploys — every account-struct change meant a full redeploy, and every redeploy needed enough SOL to cover rent for a fresh program buffer. I ended up bouncing between the CLI faucet, a couple of backup faucets, and eventually just asking around, before I could get back to actually building. Prize Categories Best Use of Solana — the PDA-per-fan account design and the on-chain leaderboard aren't decorative. Pull Solana out of this project and the core claim — that a fan's streak can't be faked, inflated, or reset by the app itself — just stops being true. That was the whole point of building it this way instead of with a normal backend.
1 hour agoThis is a submission for Weekend Challenge: Passion Edition What I Built Loyalty Ledger — a fan loyalty tracker where your check-in streak, badges, and history live on Solana instead of some app's database. Live app: https://loyalty-ledger-blond.vercel.app Here's the problem I kept coming back to. Every sports app wants you to check in, engage, "prove your loyalty" — collect points, build a streak, unlock a badge. Cool. Except every single one of them throws that history away the second you stop opening the app. Switch apps and your streak resets to zero. Get banned, or the app shuts down, or they just quietly decide to wipe inactive accounts one day — and your history is just... gone. Because it was never actually yours. It was a number sitting in someone else's database, and they could reset it, inflate it, or delete it whenever they felt like it. You had zero say in it. And that bugged me way more than it probably should have. Like — we figured out how to make ownership portable for money, for domain names, for digital art. But "I've supported Argentina since 2019" 🇦🇷 still lives and dies inside one company's backend, and nobody's really questioned that. So I kept the weekend scope deliberately small: prove one fan's loyalty to one team, for real, end to end — instead of sketching ten features that are all half-fake. You connect a wallet, pick a sport and team, and check in. FIFA World Cup is the fully working path here ⚽ — that check-in sends an actual transaction that creates or updates a program-owned account, not a row in my database somewhere. Your streak count, your badge tier, the actual badge tokens — none of it exists anywhere I control. Which honestly felt a little weird to build, in a good way. Once that core loop worked, I built the rest of the identity around it: a Fan Passport that shows your streak, a derived "Fan Score," your tier (Rookie → Devoted → Veteran → Legend 🏆), a progress bar toward the next tier, an achievements grid with locked/unlocked states, a recent-activity feed pulled from real on-chain history, and a leaderboard ranking actual fans by actual streaks. There's also a "Demo Preview" toggle that fills the passport with sample numbers, clearly labeled as sample data — because a screen full of zeros just doesn't demo well, and I'd rather be upfront about that than pretend it's real. NBA and "Other International Sport" are in the app too, same UI and flow, but honestly? They're stubbed. Sample fixtures, no chain writes, and the app says so directly instead of hiding it. I'd rather ship one path that's completely real than three that are all a little bit fake. Demo Live app: https://loyalty-ledger-blond.vercel.app GitHub: https://github.com/ishantgupta30/Loyalty-Ledger To actually try it: Install Phantom if you don't have it, and switch it to Devnet — Settings → Developer Settings → Change Network → Devnet. This is the step almost everyone misses first, myself included the first time 🙃 Grab free devnet SOL from the faucet to cover transaction fees, which run a fraction of a cent per check-in. No real money touches this project anywhere. Open the app and click Connect Wallet, top right. Pick FIFA World Cup and a team. Hit check-in and approve the transaction Phantom pops up. Watch the streak and Fan Score update, confetti fires 🎉, and if you crossed a threshold, a badge-unlocked toast shows up. Scroll down and the full Fan Passport fills in — tier, progress bar, achievements, recent activity, your actual rank on that team's leaderboard. Once you've crossed tier 1 (3 check-ins), hit Claim Badge — it mints a real SPL token straight to your wallet. Go check Phantom's token list after, it's just sitting there. Permanently. Not a UI element pretending to be a thing 👀 Code GitHub Repository: https://github.com/ishantgupta30/Loyalty-Ledger How I Built It The account design The core piece is a small Anchor program. Every fan gets a PDA — a Program Derived Address, an account owned by the program itself, not by me — keyed to (wallet, sport, team): pub struct FandomRecord { pub wallet: Pubkey, pub streak_count: u32, pub last_checkin_ts: i64, pub bump: u8, pub highest_tier_claimed: u8, #[max_len(32)] pub sport: String, #[max_len(32)] pub team: String, } Check-in doesn't touch a database at all. It fires a check_in instruction that either creates this account (first check-in) or updates it — extends the streak, or resets it if too much time passed between check-ins. That's basically the whole point of this project in one sentence: the streak isn't something my frontend can fake, inflate, or quietly reset, because it was never my frontend's data to begin with. Anyone — not just this app — can read the account directly and verify exactly what it says. No trust required. The leaderboard problem (this one got me) This took way longer than it had any right to. My first cut of the account only stored wallet, streak_count, and last_checkin_ts — sport and team lived purely in the PDA seeds. Which is fine if you already know a wallet and want to look up their record. But it's a total dead end if you want to ask "who are the top Argentina fans," because seeds only let you derive one specific account when you already know the inputs. You can't run that backwards to enumerate every account matching a team. Learned that one the hard way mid-build. So I ended up adding sport and team as actual fields on the account data, not just seed inputs. Which meant a full account-struct change, a rebuild, and a redeploy — genuinely annoying mid-weekend — but it's what makes a real getProgramAccounts call (filtered client-side by sport/team) actually able to answer "rank every Argentina fan by streak" using real chain state instead of a cached guess or a fake list. Why Solana, specifically I wanted this to be a project where pulling out the blockchain would actually break something — not just remove a buzzword from the pitch. Check-ins are frequent and individually pretty worthless — potentially one per match, per fan, across a lot of fans over a tournament. That only works as a real product (not a novelty) if each check-in is near-free and confirms fast enough to feel like a UI action instead of a bank transfer. Solana's one of the few chains where both of those are true at once. A check-in here confirms in about a second and costs a fraction of a cent — which is the actual, boring, practical reason "check in every match, forever" is something you could really build, instead of something that only works in a demo video. There's a side effect of the PDA design I honestly didn't fully plan for going in: because the fan record is owned by the program and not by my database, any other app that knows the program id can read it directly. No API key. No integration meeting with me. No trusting my numbers. A ticketing platform could check the same record to offer a loyalty discount. A streaming service could unlock a perk off the same tier. None of that needs my permission or my infrastructure staying online. That's a meaningfully different thing from "an app that happens to use Solana" — and it kind of just fell out of choosing PDAs over a normal database, rather than being the original plan. What actually broke along the way Being honest here instead of pretending this all went smoothly: I burned a genuinely embarrassing amount of time on devnet SOL. The official faucet rate-limits per IP, and I hit that wall hard while iterating on deploys — every account-struct change meant a full redeploy, and every redeploy needed enough SOL to cover rent for a fresh program buffer. I ended up bouncing between the CLI faucet, a couple of backup faucets, and eventually just asking around, before I could get back to actually building. Prize Categories Best Use of Solana — the PDA-per-fan account design and the on-chain leaderboard aren't decorative. Pull Solana out of this project and the core claim — that a fan's streak can't be faked, inflated, or reset by the app itself — just stops being true. That was the whole point of building it this way instead of with a normal backend.
6 hours agoThis is a submission for Weekend Challenge: Passion Edition What I Built Loyalty Ledger — a fan loyalty tracker where your check-in streak, badges, and history live on Solana instead of some app's database. Live app: https://loyalty-ledger-blond.vercel.app Here's the problem I kept coming back to. Every sports app wants you to check in, engage, "prove your loyalty" — collect points, build a streak, unlock a badge. And every single one of them throws that history away the moment you stop using it. Switch apps and your streak resets to zero. Get banned, or the app shuts down, or they just decide to wipe inactive accounts — your history is gone, because it was never really yours. It was a number in someone else's database, and they could reset it, inflate it, or delete it whenever they felt like it, and you'd have zero recourse. That felt like a weirdly solvable problem to just... not solve. We figured out how to make ownership portable for money, for domain names, for digital art. But "I've supported Argentina since 2019" still lives and dies inside one company's backend. So the scope for the weekend was deliberately narrow: prove one fan's loyalty to one team, for real, end to end, rather than sketch out ten features that are all half-fake. You connect a wallet, pick a sport and team, and check in. FIFA World Cup is the fully working path — that check-in sends a real transaction that creates or updates a program-owned account, not a row in my database. Your streak count, your badge tier, the actual badge tokens — none of it exists anywhere I control. Once that core loop worked, I built out the rest of the identity around it: a Fan Passport that shows your streak, a derived "Fan Score," your tier (Rookie → Devoted → Veteran → Legend), a progress bar toward the next tier, an achievements grid with locked/unlocked states, a recent-activity feed pulled from real on-chain transaction history, and a leaderboard ranking real fans by real streaks. There's also a "Demo Preview" toggle that shows the passport filled in with sample numbers — clearly labeled as sample data — because a screen full of zeros doesn't demo well, and I'd rather be upfront about that than pretend it's real. NBA and "Other International Sport" are in the app too, using the exact same UI and flow, but they're honestly stubbed — sample fixtures, no chain writes, and the app says so directly rather than hiding it. I'd rather ship one path that's completely real than three that are all a little bit fake. Demo Live app: https://loyalty-ledger-blond.vercel.app github : https://github.com/ishantgupta30/Loyalty-Ledger To actually try it: Install Phantom if you don't have it, and switch it to Devnet — Settings → Developer Settings → Change Network → Devnet. This is the step almost everyone misses first. Grab free devnet SOL from the faucet to cover transaction fees, which run a fraction of a cent per check-in. No real money touches this project anywhere. Open the app and click Connect Wallet, top right. Pick FIFA World Cup and a team. Hit check-in and approve the transaction Phantom pops up. Watch the streak and Fan Score update, confetti fire, and — if you crossed a threshold — a badge-unlocked toast appear. Scroll down to see the full Fan Passport fill in: tier, progress bar, achievements, recent activity, and your real rank on that team's leaderboard. Once you've crossed tier 1 (3 check-ins), hit Claim Badge — it mints an actual SPL token to your wallet. Check Phantom's token list afterward; it's sitting there, permanently, not just a UI element. Code How I Built It The account design The core piece is a small Anchor program. Every fan gets a PDA — a Program Derived Address, an account owned by the program itself, not by me — keyed to (wallet, sport, team): pub struct FandomRecord { pub wallet: Pubkey, pub streak_count: u32, pub last_checkin_ts: i64, pub bump: u8, pub highest_tier_claimed: u8, #[max_len(32)] pub sport: String, #[max_len(32)] pub team: String, } Check-in doesn't touch a database. It sends a check_in instruction that either creates this account (first check-in) or updates it (extends the streak, or resets it if too much time passed between check-ins). That's the entire point of the project in one line: the streak isn't something my frontend can fake, inflate, or quietly reset, because it isn't my frontend's data to begin with. Anyone — not just this app — can read the account directly and verify exactly what it says. The leaderboard problem This was the part that took longer than expected. My first cut of the account only stored wallet, streak_count, and last_checkin_ts — sport and team lived purely in the PDA seeds. Which works fine if you already know a wallet and want to look up their record, but it's a dead end if you want to ask "who are the top Argentina fans." Seeds let you derive one specific account when you already know the inputs; you can't run that backwards to enumerate every account matching a team. So I added sport and team as actual fields on the account data, not just seed inputs. That meant a full account-struct change, a rebuild, and a redeploy — annoying mid-weekend, but it's what makes a real getProgramAccounts call (filtered client-side by sport/team) able to answer "rank every Argentina fan by streak" using actual chain state instead of a cached guess or a fabricated list. Why Solana, specifically I wanted this to be a project where pulling out the blockchain would actually break something, not just remove a buzzword from the pitch. Check-ins are frequent and individually worthless — potentially one per match, per fan, across a lot of fans over a tournament. That only works as a real product, not a novelty, if each check-in is near-free and confirms fast enough that it feels like a UI action instead of a bank transfer. Solana is one of the few chains where both of those are true at once. A check-in here confirms in about a second and costs a fraction of a cent, which is the actual reason "check in every match, forever" is a plausible thing to build instead of something that only works in a demo video. There's a side effect of the PDA design I didn't fully plan for going in: because the fan record is owned by the program and not by my database, any other app that knows the program id can read it directly — no API key, no integration meeting with me, no trusting my numbers. A ticketing platform could check the same record to offer a loyalty discount. A streaming service could unlock a perk off the same tier. None of that requires my permission or my infrastructure staying online. That's a meaningfully different thing from "an app that happens to use Solana," and it more or less fell out of choosing PDAs over a normal database rather than being the original plan. What actually broke along the way In the spirit of being honest about this instead of writing it up like everything went smoothly: I burned a genuinely embarrassing amount of time on devnet SOL. The official faucet rate-limits per IP, and I hit that limit hard while iterating on deploys — every account-struct change meant a full redeploy, and every redeploy needed enough SOL to cover rent for a fresh program buffer. I ended up bouncing between the CLI faucet, a couple of alternate faucets, and eventually just asking around, before I could get back to actually building. Prize Categories Best Use of Solana — the PDA-per-fan account design and the on-chain leaderboard aren't decorative. Pull Solana out of this project and the core claim — that a fan's streak can't be faked, inflated, or reset by the app itself — stops being true. That was the whole point of building it this way instead of with a normal backend.
9 hours agoThis is a submission for Weekend Challenge: Passion Edition What I Built Loyalty Ledger — a fan loyalty tracker where your check-in streak, badges, and history live on Solana instead of some app's database. Live app: https://loyalty-ledger-blond.vercel.app Here's the problem I kept coming back to. Every sports app wants you to check in, engage, "prove your loyalty" — collect points, build a streak, unlock a badge. And every single one of them throws that history away the moment you stop using it. Switch apps and your streak resets to zero. Get banned, or the app shuts down, or they just decide to wipe inactive accounts — your history is gone, because it was never really yours. It was a number in someone else's database, and they could reset it, inflate it, or delete it whenever they felt like it, and you'd have zero recourse. That felt like a weirdly solvable problem to just... not solve. We figured out how to make ownership portable for money, for domain names, for digital art. But "I've supported Argentina since 2019" still lives and dies inside one company's backend. So the scope for the weekend was deliberately narrow: prove one fan's loyalty to one team, for real, end to end, rather than sketch out ten features that are all half-fake. You connect a wallet, pick a sport and team, and check in. FIFA World Cup is the fully working path — that check-in sends a real transaction that creates or updates a program-owned account, not a row in my database. Your streak count, your badge tier, the actual badge tokens — none of it exists anywhere I control. Once that core loop worked, I built out the rest of the identity around it: a Fan Passport that shows your streak, a derived "Fan Score," your tier (Rookie → Devoted → Veteran → Legend), a progress bar toward the next tier, an achievements grid with locked/unlocked states, a recent-activity feed pulled from real on-chain transaction history, and a leaderboard ranking real fans by real streaks. There's also a "Demo Preview" toggle that shows the passport filled in with sample numbers — clearly labeled as sample data — because a screen full of zeros doesn't demo well, and I'd rather be upfront about that than pretend it's real. NBA and "Other International Sport" are in the app too, using the exact same UI and flow, but they're honestly stubbed — sample fixtures, no chain writes, and the app says so directly rather than hiding it. I'd rather ship one path that's completely real than three that are all a little bit fake. Demo Live app: https://loyalty-ledger-blond.vercel.app To actually try it: Install Phantom if you don't have it, and switch it to Devnet — Settings → Developer Settings → Change Network → Devnet. This is the step almost everyone misses first. Grab free devnet SOL from the faucet to cover transaction fees, which run a fraction of a cent per check-in. No real money touches this project anywhere. Open the app and click Connect Wallet, top right. Pick FIFA World Cup and a team. Hit check-in and approve the transaction Phantom pops up. Watch the streak and Fan Score update, confetti fire, and — if you crossed a threshold — a badge-unlocked toast appear. Scroll down to see the full Fan Passport fill in: tier, progress bar, achievements, recent activity, and your real rank on that team's leaderboard. Once you've crossed tier 1 (3 check-ins), hit Claim Badge — it mints an actual SPL token to your wallet. Check Phantom's token list afterward; it's sitting there, permanently, not just a UI element. Code How I Built It The account design The core piece is a small Anchor program. Every fan gets a PDA — a Program Derived Address, an account owned by the program itself, not by me — keyed to (wallet, sport, team): pub struct FandomRecord { pub wallet: Pubkey, pub streak_count: u32, pub last_checkin_ts: i64, pub bump: u8, pub highest_tier_claimed: u8, #[max_len(32)] pub sport: String, #[max_len(32)] pub team: String, } Check-in doesn't touch a database. It sends a check_in instruction that either creates this account (first check-in) or updates it (extends the streak, or resets it if too much time passed between check-ins). That's the entire point of the project in one line: the streak isn't something my frontend can fake, inflate, or quietly reset, because it isn't my frontend's data to begin with. Anyone — not just this app — can read the account directly and verify exactly what it says. The leaderboard problem This was the part that took longer than expected. My first cut of the account only stored wallet, streak_count, and last_checkin_ts — sport and team lived purely in the PDA seeds. Which works fine if you already know a wallet and want to look up their record, but it's a dead end if you want to ask "who are the top Argentina fans." Seeds let you derive one specific account when you already know the inputs; you can't run that backwards to enumerate every account matching a team. So I added sport and team as actual fields on the account data, not just seed inputs. That meant a full account-struct change, a rebuild, and a redeploy — annoying mid-weekend, but it's what makes a real getProgramAccounts call (filtered client-side by sport/team) able to answer "rank every Argentina fan by streak" using actual chain state instead of a cached guess or a fabricated list. Why Solana, specifically I wanted this to be a project where pulling out the blockchain would actually break something, not just remove a buzzword from the pitch. Check-ins are frequent and individually worthless — potentially one per match, per fan, across a lot of fans over a tournament. That only works as a real product, not a novelty, if each check-in is near-free and confirms fast enough that it feels like a UI action instead of a bank transfer. Solana is one of the few chains where both of those are true at once. A check-in here confirms in about a second and costs a fraction of a cent, which is the actual reason "check in every match, forever" is a plausible thing to build instead of something that only works in a demo video. There's a side effect of the PDA design I didn't fully plan for going in: because the fan record is owned by the program and not by my database, any other app that knows the program id can read it directly — no API key, no integration meeting with me, no trusting my numbers. A ticketing platform could check the same record to offer a loyalty discount. A streaming service could unlock a perk off the same tier. None of that requires my permission or my infrastructure staying online. That's a meaningfully different thing from "an app that happens to use Solana," and it more or less fell out of choosing PDAs over a normal database rather than being the original plan. What actually broke along the way In the spirit of being honest about this instead of writing it up like everything went smoothly: I burned a genuinely embarrassing amount of time on devnet SOL. The official faucet rate-limits per IP, and I hit that limit hard while iterating on deploys — every account-struct change meant a full redeploy, and every redeploy needed enough SOL to cover rent for a fresh program buffer. I ended up bouncing between the CLI faucet, a couple of alternate faucets, and eventually just asking around, before I could get back to actually building. Prize Categories Best Use of Solana — the PDA-per-fan account design and the on-chain leaderboard aren't decorative. Pull Solana out of this project and the core claim — that a fan's streak can't be faked, inflated, or reset by the app itself — stops being true. That was the whole point of building it this way instead of with a normal backend.
11 hours agoLebanon death toll rises to about 4,321 as Israeli strikes continue
Lebanon’s Health Ministry says Israeli military attacks since 2 March 2026 have killed about 4,321 people and injured mo...
Several Toyota Land Cruiser Models Listed on Bring a Trailer, From FJ40 to URJ200
Multiple Toyota Land Cruiser listings are currently featured on Bring a Trailer, spanning classic FJ-series pickups and...
Noskova defeats Kostyuk to set up all-Czech Wimbledon final with Muchová
Linda Noskova reaches the women’s singles final at Wimbledon after beating Marta Kostyuk in the semi-final. Multiple out...