{"id":28947691,"url":"https://github.com/pumpfun-max/carbon-cli-ys","last_synced_at":"2025-10-28T20:06:31.799Z","repository":{"id":298141412,"uuid":"998827982","full_name":"PUMPFUN-max/carbon-cli-ys","owner":"PUMPFUN-max","description":"This repo is a fork of carbon-cli and modified to support yellowstone Instruction types.","archived":false,"fork":false,"pushed_at":"2025-06-09T16:28:36.000Z","size":60,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-06-23T10:02:00.161Z","etag":null,"topics":["anchor","codama","decoder","parser","solana","solanatransaction","yellowstone","yellowstonegrpc"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PUMPFUN-max.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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,"zenodo":null}},"created_at":"2025-06-09T10:10:41.000Z","updated_at":"2025-06-09T16:28:39.000Z","dependencies_parsed_at":"2025-06-09T16:43:49.583Z","dependency_job_id":"bfef86e1-9056-49a1-b022-a12dd975bf5c","html_url":"https://github.com/PUMPFUN-max/carbon-cli-ys","commit_stats":null,"previous_names":["pumpfun-max/carbon-cli-ys"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/PUMPFUN-max/carbon-cli-ys","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PUMPFUN-max%2Fcarbon-cli-ys","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PUMPFUN-max%2Fcarbon-cli-ys/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PUMPFUN-max%2Fcarbon-cli-ys/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PUMPFUN-max%2Fcarbon-cli-ys/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PUMPFUN-max","download_url":"https://codeload.github.com/PUMPFUN-max/carbon-cli-ys/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PUMPFUN-max%2Fcarbon-cli-ys/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261458422,"owners_count":23161175,"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":["anchor","codama","decoder","parser","solana","solanatransaction","yellowstone","yellowstonegrpc"],"created_at":"2025-06-23T10:01:48.110Z","updated_at":"2025-10-28T20:06:31.794Z","avatar_url":"https://github.com/PUMPFUN-max.png","language":"Rust","readme":"# Carbon CLI YS\nYou can now pass the yellowstone compiled instruction type to the generated decoder. \nOfficial carbon cli link: https://github.com/sevenlabs-hq/carbon\n## Overview\n\nCarbon CLI streamlines the development of Solana transaction parsing infrastructure by:\n\n- **IDL Parsing**: Converting Anchor and Codama IDL files into Rust decoders\n- **Code Generation**: Creating type-safe parsers for accounts, instructions, events, and types\n\n\n\n\n## Installation\n\n```bash\ngit clone \u003crepository-url\u003e\ncd carbon-cli-ys\ncargo build --release\n```\n\n## Quick Start\n\n### Parse an IDL file\n```bash\n# Parse from local IDL file\ncargo run parse --idl ./path/to/program.json --output ./decoders --as-crate\n\n# Parse from program address\ncargo run parse --idl \u003cPROGRAM_ADDRESS\u003e --url mainnet-beta --output ./decoders --as-crate\n```\n\n### Scaffold a new project\nDONT USE IT, IT WILL ADD THE CRATES FROM ACTUAL CARBON CLI.\n\n## Commands\n\n### `parse`\nGenerate decoder code from IDL files or program addresses. \n\n**Options:**\n- `-i, --idl \u003cSOURCE\u003e` - IDL file path (.json) or Solana program address\n- `-o, --output \u003cPATH\u003e` - Output directory for generated code\n- `-c, --as-crate` - Generate as a Rust crate (includes Cargo.toml)\n- `-s, --standard \u003cSTANDARD\u003e` - IDL standard: `anchor` (default) or `codama`\n- `-e, --event-hints \u003cHINTS\u003e` - Comma-separated event type names (Codama only)\n- `-u, --url \u003cURL\u003e` - Network URL: `mainnet-beta`, `devnet`, or custom RPC URL\n\n**Examples:**\n```bash\n# Parse Anchor IDL from file\ncargo run parse --idl ./jupiter.json --output ./decoders --as-crate\n\n# Parse from program address\ncargo run parse --idl JUP4Fb2cqiRUcaTHdrPC8h2gNsA2ETXiPDD33WcGuJB --url mainnet-beta --output ./decoders --as-crate\n\n# Parse Codama IDL with event hints\ncargo run parse --idl ./program.json --standard codama --event-hints SwapEvent,LiquidityEvent --output ./decoders --as-crate\n```\n\n\n\n## Generated Code Structure\n\n```\ngenerated-decoder/\n├── Cargo.toml          # Rust crate configuration\n├── src/\n│   ├── lib.rs          # Main library file\n│   ├── accounts/       # Account type definitions\n│   ├── instructions/   # Instruction parsers\n│   ├── events/         # Event definitions (if applicable)\n│   └── types/          # Custom type definitions\n```\n\n## Usage Example\n\nAfter generating a decoder, use it in your Rust code:\n\n```rust\n// returns data params\nlet only_data = RaydiumAmmV4Decoder.decode_compiled_instruction_params(\u0026txn_ix);\n// returns data params and structured accounts u8 (u8 is the index in the actual account keys of ys transaction)\nlet data_acc = RaydiumAmmV4Decoder.decode_compiled_instruction(\u0026txn_ix);\n\n\n//pick accounts from the txn\nlet mut all_accounts: Vec\u003cVec\u003cu8\u003e\u003e = txn_message.account_keys.clone();\n// rw - https://github.com/rpcpool/yellowstone-vixen/blob/5a6788ee5da28d640a002b8d63b93297907ae20d/crates/core/src/instruction.rs#L191\nall_accounts.extend(txn_meta.loaded_writable_addresses.iter().cloned());\nall_accounts.extend(txn_meta.loaded_readonly_addresses.iter().cloned());\nlet account_pubkeys: Vec\u003cPubkey\u003e = all_accounts\n        .iter()\n        .map(|acc| Pubkey::new_from_array(acc.as_slice().try_into().unwrap()))\n        .collect();\n// returns data params and structured accounts but instead of u8, the accounts will be pubkey\nlet data_pks = RaydiumAmmV4Decoder.decode_compiled_instruction_with_accounts(\u0026txn_ix, \u0026account_pubkeys);\n```\nOR\n```rust\n/// .\n/// RAYDIUM\n///\n///\npub fn raydium_amm_v4_handler(txn_ix: CompiledInstruction)  {\n    if let Some(decoded_ix) = RaydiumAmmV4Decoder.decode_compiled_instruction(\u0026txn_ix) {\n        match decoded_ix.compiled_accounts {\n            raydium_amm_v4_decoder::instructions::CompiledInstructionAccounts::SwapBaseIn(\n                swap_base_in_compiled_instruction_accounts,\n            ) =\u003e {\n             \n                    // pool: swap_base_in_compiled_instruction_accounts.amm,\n                    // vault_a: swap_base_in_compiled_instruction_accounts.pool_coin_token_account,\n                    // vault_b: swap_base_in_compiled_instruction_accounts.pool_pc_token_account,\n                    // user_vault_a: swap_base_in_compiled_instruction_accounts.uer_source_token_account,\n                    // user_vault_b: swap_base_in_compiled_instruction_accounts.uer_destination_token_account,\n                    \n            }\n            raydium_amm_v4_decoder::instructions::CompiledInstructionAccounts::SwapBaseOut(\n                swap_base_out_compiled_instruction_accounts,\n            ) =\u003e {\n\n                    // pool: swap_base_out_compiled_instruction_accounts.amm,\n                    // vault_a: swap_base_out_compiled_instruction_accounts.pool_coin_token_account,\n                    // vault_b: swap_base_out_compiled_instruction_accounts.pool_pc_token_account,\n                    // user_vault_a: swap_base_out_compiled_instruction_accounts.uer_source_token_account,\n                    // user_vault_b: swap_base_out_compiled_instruction_accounts.uer_destination_token_account,\n            }\n            _ =\u003e {}\n        }\n    }\n    None\n}\n```\nOR\n```rust\n#[derive(Debug, Clone)]\npub struct SwapEventRouter {\n    pub amm: String,\n    pub input_mint: String,\n    pub output_mint: String,\n    pub input_amount: u64,\n    pub output_amount: u64,\n}\n/// .\n/// JUPITER\n///\n///\npub fn jupiter_v6_handler(inner_ixs: Vec\u003cInnerInstruction\u003e) -\u003e Option\u003cVec\u003cSwapEventRouter\u003e\u003e {\n    let mut swap_events: Vec\u003cSwapEventRouter\u003e = Vec::new();\n    for ix in inner_ixs {\n        if let Some(decoded_event) =\n            JupiterV6Decoder.decode_compiled_instruction_params(\u0026CompiledInstruction {\n                program_id_index: ix.program_id_index,\n                accounts: ix.accounts,\n                data: ix.data,\n            })\n        {\n            match decoded_event {\n                jupiter_v6_decoder::instructions::JupiterV6Instruction::SwapEvent(swap_event) =\u003e {\n                    swap_events.push(SwapEventRouter{\n                        amm: swap_event.amm.to_string(),\n                        input_mint: swap_event.input_mint.to_string(),\n                        output_mint: swap_event.output_mint.to_string(),\n                        input_amount: swap_event.input_amount,\n                        output_amount: swap_event.output_amount,\n                    });\n                },\n                _=\u003e {}\n            }\n        }\n    }\n\n     Some(swap_events)\n}\n```\n## Interactive Mode\n\nRun without arguments for interactive mode:\n\n```bash\ncargo run\n```\n\nThe CLI will prompt you to:\n1. Choose between `parse` or `scaffold`\n2. Select IDL source (file or program address)\n3. Configure output options\n4. Select decoders and data sources (for scaffold)\n\n## Development\n\n### Project Structure\n- `src/main.rs` - CLI entry point and interactive mode\n- `src/commands.rs` - Command definitions and argument parsing\n- `src/handlers/` - Core parsing and generation logic\n- `templates/` - Code generation templates\n- `decoders/` - Pre-built decoder implementations\n\n### Building\n```bash\ncargo build\n```\n\n\n# Copied idl from the site? Do the following:\n1. replace `:` -\u003e `\":\"`\n2. in VsCode, `ctrl+f` in the file and add the following regex: `(\\s[a-zA-Z]+\":)`\n3. replace: `\"$1`\n4. Some fields may have values as follows:\n    ```\n    active: !0,    //  true --\u003e replace\n    disabled: !1   //  false --\u003e replace\n    ```\n\n# Common Errors:\n## Eq, Hash\n1. add impl instead of them:\nExample:\n    ```\n    use std::hash::Hasher;\n    use std::hash::Hash;\n    impl Hash for StubOracleSet {\n        fn hash\u003cH: Hasher\u003e(\u0026self, state: \u0026mut H) {\n            self.price.to_bits().hash(state);\n        }\n    }\n\n    impl Eq for StubOracleSet {}\n    ```        \n2. its its optional: `self.max_staleness_slots.hash(state);`\n\n## Transactions not being parsed\n- Well, the problem is here: https://github.com/PUMPFUN-max/carbon-cli-ys/blob/main/src/accounts.rs#L52\n- So, you gotta go through each instruction in decoder\u003esrc\u003einstructions and add the actual discrimator.\n- Feel free to open a PR if you think you got a better solution thats supported by global idl's.\n\n## Import Errors:\nJust import the packages/files... \n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpumpfun-max%2Fcarbon-cli-ys","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpumpfun-max%2Fcarbon-cli-ys","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpumpfun-max%2Fcarbon-cli-ys/lists"}