Full lesson
Alight
Alight is a self-hosted observatory that sends small, budgeted test transactions called canaries through Solami
What it does
From the project README:
Bots, wallets and trading backends must choose a route, priority fee and tip before knowing whether a transaction will arrive in time. An RPC acknowledgment cannot answer that question, and a successful landing can still miss the deadline.
- Original
- hicksonhaziel/Alight
- SuperStack fork
- Blockchains/Alight @
759a597 - Stars
- 0
- Last push (original)
- 2026-10-13
- Languages
- Rust, TypeScript, Python, CSS, JavaScript, Shell
- Detected stack
- not detected
- Categories
- Infrastructure & Tooling
- Licence
- MIT
Architecture
183 source files. By extension: .rs ×125, .py ×25, .ts ×17, .tsx ×14, .js ×2.
| Top-level directory | Source files |
|---|---|
crates | 106 |
web | 28 |
scripts | 25 |
bin | 19 |
sdk | 5 |
Dapp: devnet deploy pending
⏳ Devnet deploy pending — goes live when the devnet wallet is topped up. This fork's own dapp is not deployed yet, so there is no program address or transaction to show. It is queued in dapp-queue.txt; once devnet SOL is available it is deployed, exercised with real devnet transactions, and this section switches to the live dapp at /dapps/alight/. Until then, the lesson and step-by-step guide below are complete, and you can run it locally with the commands below.
Key code, explained
Excerpts chosen automatically where the code uses the most Solana concepts, pinned to the fork's commit.
crates/alight-types/src/lib.rs L97–120 @ 759a597 · MIT · original /// Coarse block timestamps require a long window and do not measure first-seen latency. pub fn mean_slot_ms(self) -> Option<f64> { let slots = self.end_slot.checked_sub(self.start_slot)?; let seconds = self.end_unix_s.checked_sub(self.start_unix_s)?; if slots == 0 || seconds <= 0 { return None; } Some(seconds as f64 * 1000.0 / slots as f64) }} #[cfg(test)]mod tests { use super::*; #[test] fn one_process_has_one_comparable_monotonic_origin() { let (a, start) = process_clock_origin(); let (b, second) = process_clock_origin(); assert_eq!(a, b); assert_eq!(start, second); } #[test] fn expiry_needs_both_strict_height_and_absence() {- Line 99
let slots = self.end_slot.checked_sub(self.start_slot)?;: Uses checked arithmetic so overflow fails instead of wrapping. - Line 112
fn one_process_has_one_comparable_monotonic_origin() {: Checks that a stored pubkey field matches the passed account.
crates/alight-ingest/src/leaders.rs L61–84 @ 759a597 · MIT · original if bs58::decode(identity) .into_vec() .map_or(true, |b| b.len() != 32) { return Err(ProbeError::Format); } for relative in relative_slots.as_array().ok_or(ProbeError::Format)? { let relative = relative .as_u64() .filter(|s| *s < slots_in_epoch) .ok_or(ProbeError::Format)?; let slot = first_slot.checked_add(relative).ok_or(ProbeError::Format)?; if slots.insert(slot, identity.clone()).is_some() { return Err(ProbeError::Format); } } } if slots.len() as u64 != slots_in_epoch { return Err(ProbeError::Format); } let mut stakes = BTreeMap::<String, u64>::new(); for group in ["current", "delinquent"] { for vote in raw["getVoteAccounts"][group] .as_array()- Line 72
let slot = first_slot.checked_add(relative).ok_or(ProbeError::Format)?;: Uses checked arithmetic so overflow fails instead of wrapping. - Line 81
let mut stakes = BTreeMap::<String, u64>::new();: Touches staking state: the amount locked and when it was locked.
How to run, build and test
These commands come from the repo's own manifests (package.json scripts, Anchor.toml, Cargo, go.mod, Makefile). Check the README for prerequisites and environment variables.
| Directory | Command | Runs |
|---|---|---|
sdk/ts | npm run build | tsc -p tsconfig.json |
sdk/ts | npm run test | npm run build && node --test test/*.mjs |
sdk/ts | npm run lint | tsc -p tsconfig.check.json |
web | npm run dev | vite --host 127.0.0.1 |
web | npm run build | tsc --noEmit && vite build |
web | npm run test | node --experimental-strip-types --test test/*.ts |
web | npm run lint | tsc --noEmit && eslint src |
. | cargo build | Rust workspace build |
. | cargo test | Rust tests |
What you could build from it
- Fork the SuperStack copy and extend it within the Infrastructure & Tooling gaps listed on the idea page.
- Learn the pattern first: Building and sending transactions from a client
- Learn the pattern first: Anchor account constraints