Full lesson
SafeTx-Protocol
A Solana testnet dashboard that detects congestion, queues transactions, and auto-retries for a smoother user experience.
What it does
From the project README:
Live Demo | API Docs | Video Demo | Slides Live Demo | Documentation | API Docs | Video Demo | Slides
- Original
- rohan911438/SafeTx-Protocol
- SuperStack fork
- Blockchains/SafeTx-Protocol @
1bb53ca - Stars
- 1
- Last push (original)
- 2025-10-22
- Languages
- TypeScript, JavaScript, Rust, Shell, CSS, HTML
- Detected stack
- Native Rustweb3.js
- Categories
- Other
- Licence
- MIT
- Homepage
- https://safetx-protocol.lovable.app/
Architecture
84 source files. By extension: .tsx ×66, .ts ×13, .js ×4, .rs ×1.
| Top-level directory | Source files |
|---|---|
src | 74 |
(root) | 4 |
packages | 3 |
safetx-backend | 2 |
contracts | 1 |
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/safetx-protocol/. 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.
contracts/solana/safetx-program/src/lib.rs L61–84 @ 1bb53ca · MIT · original let ix = SafetxIx::try_from_slice(data).map_err(|_| ProgramError::InvalidInstructionData)?; match ix { SafetxIx::InitRegistry => init_registry(program_id, accounts), SafetxIx::PushMetric(s) => push_metric(program_id, accounts, s), }} fn init_registry(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult { let acc_iter = &mut accounts.iter(); let admin = next_account_info(acc_iter)?; // signer who becomes admin let registry = next_account_info(acc_iter)?; // PDA to be created let system_program = next_account_info(acc_iter)?; if !admin.is_signer { return Err(ProgramError::MissingRequiredSignature); } // Derive PDA: seeds = [b"safetx", admin] let (pda, bump) = Pubkey::find_program_address(&[b"safetx", admin.key.as_ref()], program_id); if pda != *registry.key { msg!("Registry PDA mismatch"); return Err(ProgramError::InvalidSeeds); }- Line 79
// Derive PDA: seeds = [b"safetx", admin]: Declares the PDA seeds. Anchor re-derives the address and rejects the account if it doesn't match. - Line 80
let (pda, bump) = Pubkey::find_program_address(&[b"safetx", admin.key.as_ref()], program_i: Derives a PDA from seeds and the program ID and returns the address with its canonical bump. - Line 80
let (pda, bump) = Pubkey::find_program_address(&[b"safetx", admin.key.as_ref()], program_i: Uses the bump seed, the extra byte that pushes the derived address off the ed25519 curve. - Line 82
msg!("Registry PDA mismatch");: Logs to the program log, which is visible in explorers and the test output.
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 |
|---|---|---|
. | npm run dev | vite |
. | npm run build | vite build |
. | npm run lint | eslint . |
safetx-backend | npm run dev | node --watch server.js |
safetx-backend | npm run start | node server.js |
packages/safetx-client | npm run build | tsup src/index.ts --format cjs,esm --dts |
What you could build from it
- Fork the SuperStack copy and extend it within the Other gaps listed on the idea page.
- Learn the pattern first: Program Derived Addresses (PDAs)
- Learn the pattern first: Cross-Program Invocations (CPIs)