Sol.College

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 directorySource files
crates148
addons91

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.

solana-foundation/txtx · 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)    }
  1. 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.
  2. 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.
  3. 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.
solana-foundation/txtx · 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,
  1. Line 82 spl_token_2022_interface::id(): Targets the Token-2022 program instead of the original Token Program.
  2. Line 86 fn create_mint_to_instruction(: Mints new tokens. The mint authority must sign.
solana-foundation/txtx · 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,
  1. Line 70 spl_token_2022_interface::instruction::transfer_checked(: A checked token transfer, which also verifies the mint and decimals.
  2. Line 70 spl_token_2022_interface::instruction::transfer_checked(: Targets the Token-2022 program instead of the original Token Program.
solana-foundation/txtx · 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
  1. 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.
  2. 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.

DirectoryCommandRuns
addons/svm/core/examples/hellosolanchor buildcompile programs and generate IDLs
addons/svm/core/examples/hellosolanchor testlocal validator + test suite
addons/svm/core/examples/hellosolanchor run testyarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts
.cargo buildRust workspace build
.cargo testRust tests

What you could build from it