Full lesson
txtx
Terraform for web3. Reproducible deployments and secure operations for Bitcoin, Ethereum and Solana.
What it does
From the project README:
Have you ever tried to deploy some open source Smart contracts on a local devnet, just to get stuck on the first steps of understanding how the deployment should be executed? Have you lost hundreds, thousands or millions of tokens because your master private key got compromised after copy/pasting in your deployment scripts, or missed some contracts initializations making your deployments vulnerable and flawed?
- Original
- solana-foundation/txtx
- SuperStack fork
- Blockchains/txtx @
4d675f8 - Stars
- 157
- Last push (original)
- 2026-10-26
- Languages
- Rust, Solidity, MDX, Shell, RenderScript
- Detected stack
- Anchor
- Categories
- Other
- Licence
- Apache-2.0
- Homepage
- https://docs.txtx.sh
Architecture
239 source files. By extension: .rs ×230, .sol ×9.
| Top-level directory | Source files |
|---|---|
crates | 148 |
addons | 91 |
On-chain programs: addons/svm/core/examples/hellosol/programs/hellosol, addons/svm/core/examples/hellosol/programs/hellosol2
Dapp: deploying
This fork is queued for its own live dapp on Sol.College, with a Devnet/Mainnet switch. It appears here, at /dapps/txtx/, 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.
addons/svm/core/src/functions.rs L769–792 @ 4d675f8 · Apache-2.0 · original fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, args: &Vec<Value>, ) -> Result<Value, Diagnostic> { arg_checker(fn_spec, args)?; let program_id = SvmValue::to_pubkey(args.get(0).unwrap()) .map_err(|e| to_diag(fn_spec, format!("invalid program id for finding pda: {e}")))?; let seeds = if let Some(val) = args.get(1) { get_seeds_from_value(val).map_err(|diag| to_diag(fn_spec, diag))? } else { vec![] }; let seed_refs: Vec<&[u8]> = seeds.iter().map(|s| s.as_slice()).collect(); let (pda, bump) = Pubkey::try_find_program_address(&seed_refs, &program_id) .ok_or(to_diag(fn_spec, "failed to find pda".to_string()))?; let obj = ObjectType::from(vec![ ("pda", Value::string(pda.to_string())), ("bump_seed", Value::integer(bump as i128)), ]) .to_value(); Ok(obj) }- Line 777
let seeds = if let Some(val) = args.get(1) {: Declares the PDA seeds. Anchor re-derives the address and rejects the account if it doesn't match. - Line 784
let (pda, bump) = Pubkey::try_find_program_address(&seed_refs, &program_id): Derives a PDA from seeds and the program ID and returns the address with its canonical bump. - Line 784
let (pda, bump) = Pubkey::try_find_program_address(&seed_refs, &program_id): Uses the bump seed, the extra byte that pushes the derived address off the ed25519 curve.
addons/svm/core/src/commands/deploy_token.rs L73–96 @ 4d675f8 · Apache-2.0 · original .map_err(|e| { diagnosed_error!("failed to create token mint initialization instruction: {}", e) }); } Err(diagnosed_error!( "unsupported token program id: {}; expected SPL Token ({}) or Token-2022 ({})", token_program_id, spl_token_interface::id(), spl_token_2022_interface::id() ))} fn create_mint_to_instruction( token_program_id: &Pubkey, mint_pubkey: &Pubkey, authority_token_account: &Pubkey, authority_pubkey: &Pubkey, signer_pubkeys: &[&Pubkey], initial_supply: u64,) -> Result<Instruction, Diagnostic> { if token_program_id == &spl_token_interface::id() { return spl_token_interface::instruction::mint_to( token_program_id,- Line 82
spl_token_2022_interface::id(): Targets the Token-2022 program instead of the original Token Program. - Line 86
fn create_mint_to_instruction(: Mints new tokens. The mint authority must sign.
addons/svm/core/src/commands/send_token.rs L49–72 @ 4d675f8 · Apache-2.0 · original token_program_id, ); let recipient_ata = spl_associated_token_account_interface::address::get_associated_token_address_with_program_id( recipient, mint_address, token_program_id, ); (sender_ata, recipient_ata)} fn create_token_transfer_instruction( token_program_id: &Pubkey, mint_pubkey: &Pubkey, sender_ata: &Pubkey, recipient_ata: &Pubkey, authority_pubkey: &Pubkey, signer_pubkeys: &[&Pubkey], amount: u64, decimals: u8,) -> Result<Instruction, Diagnostic> { spl_token_2022_interface::instruction::transfer_checked( token_program_id, sender_ata,- Line 70
spl_token_2022_interface::instruction::transfer_checked(: A checked token transfer, which also verifies the mint and decimals. - Line 70
spl_token_2022_interface::instruction::transfer_checked(: Targets the Token-2022 program instead of the original Token Program.
addons/svm/core/src/commands/srs/create_record.rs L277–300 @ 4d675f8 · Apache-2.0 · original owner_signer_state.clone(), format!("invalid name '{}' for class: {}", name_str, diag).into(), ) })?; let data = args .get_expected_string("data") .map(|d| RemainderVec::try_from_slice(d.as_bytes()).unwrap()) .map_err(|diag| (signers.clone(), owner_signer_state.clone(), diag))?; let is_frozen = args.get_bool("is_frozen"); let record_seeds = [RECORD_PREFIX, class.as_ref(), name_str.as_bytes()]; let (record, _) = Pubkey::find_program_address(&record_seeds[..], &SOLANA_RECORD_SERVICE_ID); // store the signer state so we can store it in our outputs later owner_signer_state.insert_scoped_value( &construct_did.to_string(), "record", SvmValue::pubkey(record.to_bytes().to_vec()), ); let (is_class_permissioned, is_class_frozen) = if let Ok(Some(class_account)) = client- Line 289
let record_seeds = [RECORD_PREFIX, class.as_ref(), name_str.as_bytes()];: Declares the PDA seeds. Anchor re-derives the address and rejects the account if it doesn't match. - Line 291
Pubkey::find_program_address(&record_seeds[..], &SOLANA_RECORD_SERVICE_ID);: Derives a PDA from seeds and the program ID and returns the address with its canonical bump.
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 |
|---|---|---|
addons/svm/core/examples/hellosol | anchor build | compile programs and generate IDLs |
addons/svm/core/examples/hellosol | anchor test | local validator + test suite |
addons/svm/core/examples/hellosol | anchor run test | yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts |
. | cargo build | Rust workspace build |
. | cargo test | Rust tests |
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)