{"id":26739001,"url":"https://github.com/ilertha/solana-steel-framework","last_synced_at":"2025-03-28T03:46:50.831Z","repository":{"id":263252014,"uuid":"877044743","full_name":"ilertha/solana-steel-framework","owner":"ilertha","description":"solana steel framework introduction","archived":false,"fork":false,"pushed_at":"2025-02-14T03:03:02.000Z","size":54,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-26T20:11:36.900Z","etag":null,"topics":["boilerplate","framework","macro","rust","smart-contracts","solana","steel","unopinionated"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ilertha.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-10-23T01:49:57.000Z","updated_at":"2025-02-14T03:03:06.000Z","dependencies_parsed_at":"2024-11-17T10:31:00.004Z","dependency_job_id":"5e72a87b-ba0e-4b34-a62c-978403810a09","html_url":"https://github.com/ilertha/solana-steel-framework","commit_stats":null,"previous_names":["rizzolib/solana-steel-framework","ilertha/solana-steel-framework"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ilertha%2Fsolana-steel-framework","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ilertha%2Fsolana-steel-framework/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ilertha%2Fsolana-steel-framework/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ilertha%2Fsolana-steel-framework/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ilertha","download_url":"https://codeload.github.com/ilertha/solana-steel-framework/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245966932,"owners_count":20701759,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["boilerplate","framework","macro","rust","smart-contracts","solana","steel","unopinionated"],"created_at":"2025-03-28T03:46:50.307Z","updated_at":"2025-03-28T03:46:50.824Z","avatar_url":"https://github.com/ilertha.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🏗️ Steel \n\n**Steel is a new framework for building smart contracts on Solana.** It provides a library of helper functions, macros, and code patterns for implementing secure and maintainable smart contracts. Steel is generally designed to be unopinionated, minimizing boilerplate code and maximizing developer flexibility.\n\n## Notes\n\n- **Steel is under active development. All interfaces are subject to change.**\n- **This code is unaudited. Use at your own risk**\n\n## Todos\n\n- [ ] Localnet toolchain.\n- [ ] IDL generation.\n- [ ] ~~Helper functions for simple lamport transfers between AccountInfos.~~\n- [x] ~~Helper functions to emit events (wrap sol_log_data).~~\n- [x] ~~Custom error messages on account validation checks.~~\n- [x] ~~Helper function to close AccountInfos (wrap realloc and lamport return).~~\n- [x] ~~CLI with init script.~~\n- [x] ~~Account parsers and validation.~~\n\n## Getting started\n\nTo start building with Steel, install the CLI:\n```sh\ncargo install steel-cli\n```\n\nSpin up a new project with `new` command:\n```sh\nsteel new my-project\n```\n\nTo compile your program, use the standard Solana toolchain:\n```sh\ncargo build-sbf\n```\n\n## Folder structure\n\nWhile not strictly enforced, we recommend organizing your Solana program with the following file structure. We have found this pattern improves code readability, separating the contract interface from its implementation, and scales well as contract complexity increases. \n\n```\nCargo.toml (workspace)\n⌙ api\n  ⌙ Cargo.toml\n  ⌙ src\n    ⌙ consts.rs\n    ⌙ error.rs\n    ⌙ event.rs\n    ⌙ instruction.rs\n    ⌙ lib.rs\n    ⌙ loaders.rs\n    ⌙ sdk.rs\n    ⌙ state\n      ⌙ mod.rs\n      ⌙ account_1.rs\n      ⌙ account_2.rs\n⌙ program\n  ⌙ Cargo.toml\n  ⌙ src\n    ⌙ lib.rs\n    ⌙ instruction_1.rs\n    ⌙ instruction_2.rs\n```\n\n## API\n\nSteel offers a collection of simple macros for defining the interface and building blocks of your program. \n\n### Accounts\n\nFor accounts, Steel uses a single enum to manage discriminators and a struct for each account type. The `account!` macro helps link these types and implements basic serialization logic.\n\n```rs\nuse steel::*;\n\n/// Enum for account discriminators.\n#[repr(u8)]\n#[derive(Clone, Copy, Debug, Eq, PartialEq, IntoPrimitive, TryFromPrimitive)]\npub enum MyAccount {\n    Counter = 0,\n}\n\n/// Struct for account state.\n#[repr(C)]\n#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)]\npub struct Counter {\n    pub value: u64,\n}\n\naccount!(MyAccount, Counter);\n```\n\n### Instructions\n\nFor instructions, Steel similarly uses a single enum to manage discriminators and a struct for each instruction args type. The `instruction!` macro helps link these types and implement basic serialization logic.\n\n```rs\nuse steel::*;\n\n/// Enum for instruction discriminators.\n#[repr(u8)]\n#[derive(Clone, Copy, Debug, Eq, PartialEq, TryFromPrimitive)]\npub enum MyInstruction {\n    Initialize = 0,\n    Add = 1,\n}\n\n/// Struct for instruction args.\n#[repr(C)]\n#[derive(Clone, Copy, Debug, Pod, Zeroable)]\npub struct Initialize {}\n\n/// Struct for instruction args.\n#[repr(C)]\n#[derive(Clone, Copy, Debug, Pod, Zeroable)]\npub struct Add {\n    pub value: u64,\n}\n\ninstruction!(MyInstruction, Initialize);\ninstruction!(MyInstruction, Add);\n\n```\n\n### Errors\n\nCustom program errors can be created simply by defining an enum for your error messages and passing it to the `error!` macro. \n\n```rs\nuse steel::*;\n\n/// Enum for error types.\n#[repr(u32)]\n#[derive(Debug, Error, Clone, Copy, PartialEq, Eq, IntoPrimitive)]\npub enum MyError {\n    #[error(\"You did something wrong\")]\n    Dummy = 0,\n}\n\nerror!(MyError);\n```\n\n### Events\n\nSimilarly, custom program events can be created by defining the event struct and passing it to the `event!` macro. \n\n```rs\nuse steel::*;\n\n/// Struct for logged events.\n#[repr(C)]\n#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)]\npub struct MyEvent {\n    pub value: u64,\n}\n\nevent!(MyEvent);\n```\n\n## Program\n\nIn your contract implementation, Steel offers a series of composable functions to parse accounts, validate state, and execute CPIs. \n\n### Entrypoint\n\nSteel provides a utility function to streamline the program entrypoint. Securely parse incoming instruction data and dispatch it to a handler.\n\n```rs\nmod add;\nmod initialize;\n\nuse add::*;\nuse initialize::*;\n\nuse example_api::prelude::*;\nuse steel::*;\n\npub fn process_instruction(\n    program_id: \u0026Pubkey,\n    accounts: \u0026[AccountInfo],\n    data: \u0026[u8],\n) -\u003e ProgramResult {\n    let (ix, data) = parse_instruction::\u003cMyInstruction\u003e(\u0026example_api::ID, program_id, data)?;\n\n    match ix {\n        MyInstruction::Initialize =\u003e process_initialize(accounts, data)?,\n        MyInstruction::Add =\u003e process_add(accounts, data)?,\n    }\n\n    Ok(())\n}\n\nentrypoint!(process_instruction);\n```\n\n### Validation\n\nSteel provides a library of composable functions for validating account data. You can chain these functions together to validate arbitrary account state and parse it into whatever type you need. \n\n```rs \nuse example_api::prelude::*;\nuse steel::*;\n\npub fn process_add(accounts: \u0026[AccountInfo\u003c'_\u003e], _data: \u0026[u8]) -\u003e ProgramResult {\n    // Load accounts.\n    let [signer_info, counter_info] = accounts else {\n        return Err(ProgramError::NotEnoughAccountKeys);\n    };\n\n    // Validate signer.\n    signer_info.is_signer()?;\n\n    // Parse and validate account.\n    let counter = counter_info\n        .to_account_mut::\u003cCounter\u003e(\u0026example_api::ID)? \n        .check_mut(|c| c.value \u003c= 42)?;\n\n    // Update state.\n    counter.value += 1;\n\n    // Return.\n    Ok(())\n}\n```\n\n### CPIs\n\nSteel offers a handful of helper functions for executing common CPIs such as creating accounts, creating token accounts, minting tokens, burning tokens, and more. \n\n\n```rs\nuse steel::*;\n\npub fn process_transfer(accounts: \u0026[AccountInfo\u003c'_\u003e], data: \u0026[u8]) -\u003e ProgramResult {\n    // Load accounts.\n    let [signer_info, mint_info, sender_info, receiver_info, token_program] = accounts else {\n        return Err(ProgramError::NotEnoughAccountKeys);\n    };\n\n    signer_info.is_signer()?;\n\n    mint_info.to_mint()?;\n\n    sender_info\n        .is_writable()?\n        .to_token_account()?\n        .check(|t| t.owner == *signer_info.key)?\n        .check(|t| t.mint == *mint_info.key)?;\n\n    receiver_info\n        .is_writable()?\n        .to_token_account()?\n        .check(|t| t.mint == *mint_info.key)?;\n\n    token_program.is_program(\u0026spl_token::ID)?;\n\n    // Transfer tokens.\n    let amount = 42;\n    transfer(\n        signer_info,\n        sender_info,\n        receiver_info,\n        token_program,\n        amount,\n    )?;\n\n    // Return.\n    Ok(())\n}\n```\n\nThanks.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Filertha%2Fsolana-steel-framework","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Filertha%2Fsolana-steel-framework","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Filertha%2Fsolana-steel-framework/lists"}