Full lesson
sca
Solana Commerce Application
What it does
From the project README:
A Solana blockchain tool designed as Proof-Of-Concept, to illustrate how blockchain can be used to tackle real world problems. The particular problem we are addressing here is the lack of safety when selling items over the internet.
- Original
- Sergio-Flores-Torres/sca
- SuperStack fork
- Blockchains/sca @
699122f - Stars
- 0
- Last push (original)
- 2026-09-06
- Languages
- TypeScript, Rust, Shell
- Detected stack
- Native Rustweb3.js
- Categories
- Other
- Licence
- MIT
Architecture
31 source files. By extension: .ts ×25, .rs ×6.
| Top-level directory | Source files |
|---|---|
clients | 18 |
test | 7 |
program | 6 |
❌ Does not build as-is, checked 2026-11-02 Tested on 2026-11-02: full log results.json
Build it yourself: step-by-step guide
Every command below was run on 2026-11-02 by tests/run_fork.py against the pinned commit, and the results come from that run. The full output is in the committed log.
1. Prerequisites (versions we tested with)
- Rust:
rustc 1.99.1 (58cf8f9c3 2026-10-13) - Solana CLI (Agave):
solana-cli 1.18.17 (src:c027cfc3; feat:4215500110, client:Agave) - Node.js:
v24.22.1 - npm:
11.21.1 - pnpm:
10.34.6
2. Clone at the tested commit
git clone https://github.com/Blockchains/sca.git && cd sca
git checkout 699122f3f3d117d763ed286227ed026b9031d3c23. Configure
No environment file is needed.
7. Deploy to a local validator
8. Run and exercise it
| Directory | Command | Result | Time |
|---|---|---|---|
. | bash /workspace/sol-college/repo/tests/flows/sca.sh | ✅ pass | 37s |
Proof: program IDs and transactions
sca:FfqDdvxk1VJbc9XGDXqMRetnXWEpC2qZoKDDPisVUXSU(local validator)
Deploy to devnet (free)
solana config set --url devnet
solana airdrop 2 # or https://faucet.solana.com
anchor deploy --provider.cluster devnet # native: solana program deploy target/deploy/<name>.so
# point the frontend RPC env var at https://api.devnet.solana.comHow it works
Every instruction handler in the program, with the accounts struct it validates. Each link points to the line at the pinned commit.
| Instruction | Accounts | Where |
|---|---|---|
InitializeOperation | native instruction variant | program/sca/src/instruction/mod.rs:21 |
RegisterBuyer | native instruction variant | program/sca/src/instruction/mod.rs:23 |
RegisterArbiter | native instruction variant | program/sca/src/instruction/mod.rs:25 |
ParticipantApprovesArbiters | native instruction variant | program/sca/src/instruction/mod.rs:27 |
BuyerDeposit | native instruction variant | program/sca/src/instruction/mod.rs:29 |
BuyerRelease | native instruction variant | program/sca/src/instruction/mod.rs:31 |
SellerRefund | native instruction variant | program/sca/src/instruction/mod.rs:33 |
StartDispute | native instruction variant | program/sca/src/instruction/mod.rs:35 |
SellerAddInfo | native instruction variant | program/sca/src/instruction/mod.rs:37 |
BuyerAddInfo | native instruction variant | program/sca/src/instruction/mod.rs:39 |
ArbiterVote | native instruction variant | program/sca/src/instruction/mod.rs:41 |
ParticipantClaim | native instruction variant | program/sca/src/instruction/mod.rs:43 |
Extend it
- Add an integration test that runs the main flow end to end and asserts every account state change.
- Add a negative test: call each instruction with the wrong signer or account and check that it fails.
- Add an event (
emit!) to each state-changing instruction and subscribe to it from the client. - Replace any unchecked
AccountInfowith typed accounts plushas_one/seedsconstraints. - Make the frontend read the cluster from an env var, deploy it to GitHub Pages and point it at your devnet program.
- Wire the build into CI by copying this site's verify-forks workflow.
Dapp: deploying
This fork is queued for its own live dapp on Sol.College, with a Devnet/Mainnet switch. It appears here, at /dapps/sca/, once it is deployed and checked on devnet. Until then, 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.
program/sca/src/operation/mod.rs L61–84 @ 699122f · MIT · original // Check SELLER account validity is_signed_by_writable_account(seller_account_info, "SELLER account is not a valid account.")?; // Get the OPERATIONACCOUNT account let operation_account_info = next_account_info(accounts_iter)?; // Check OPERATIONACCOUNT account validity is_owned_and_writable(program_id, operation_account_info, "OPERATIONACCOUNT account is not a valid account.")?; // ================ Enforce configuration rules section // Get the estimated creation time for tracking operation validity, etc // This is in unixepoch seconds; in tests the time is days off, so it needs to be validated further let unix_timestamp = match Clock::get() { Err(_e) => { msg!("WARN: Could not get a valid Clock. Using zero time."); 0 }, Ok(clock) => clock.unix_timestamp, }; // Load the account so that we can read it and/or modify it.- Line 76
let unix_timestamp = match Clock::get() {: Reads on-chain time from the Clock sysvar. - Line 78
msg!("WARN: Could not get a valid Clock. Using zero time.");: 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 |
|---|---|---|
test | npm run start | node dist/index.js |
test | npm run build | tsc |
test | npm run test | echo "Error: no test specified" && exit 1 |
clients/seller | npm run start | OPERATION=x URL=http://localhost:8899 PROGRAMID=7f3bKvFg9WrUr3RGig5gGj8GnEFYMML86ffgxaH19ft1 JWT=x GATEWAY=x node dist/i |
clients/seller | npm run build | tsc |
clients/seller | npm run test | echo "Error: no test specified" && exit 1 |
clients/buyer | npm run start | OPERATION=x URL=http://localhost:8899 PROGRAMID=7f3bKvFg9WrUr3RGig5gGj8GnEFYMML86ffgxaH19ft1 JWT=x GATEWAY=x node dist/i |
clients/buyer | npm run build | tsc |
clients/buyer | npm run test | echo "Error: no test specified" && exit 1 |
clients/arbiter | npm run start | OPERATION=x URL=http://localhost:8899 PROGRAMID=7f3bKvFg9WrUr3RGig5gGj8GnEFYMML86ffgxaH19ft1 GATEWAY=x node dist/index.j |
clients/arbiter | npm run build | tsc |
clients/arbiter | npm run test | echo "Error: no test specified" && exit 1 |
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)