INIT COMMIT
Build, Test, and Push CFDM Docker Image / test (push) Failing after 1m51s
Build, Test, and Push CFDM Docker Image / build-and-push (push) Has been skipped
Build, Test, and Push CFDM Docker Image / update-wiki (push) Has been skipped
Build, Test, and Push CFDM Docker Image / create-release (push) Has been skipped
Build, Test, and Push CFDM Docker Image / test (push) Failing after 1m51s
Build, Test, and Push CFDM Docker Image / build-and-push (push) Has been skipped
Build, Test, and Push CFDM Docker Image / update-wiki (push) Has been skipped
Build, Test, and Push CFDM Docker Image / create-release (push) Has been skipped
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
---
|
||||
description: "Rust best practices for Solana smart contract development using Anchor framework and Solana SDK"
|
||||
globs: programs/**/*.rs, src/**/*.rs, tests/**/*.ts
|
||||
alwaysApply: false
|
||||
---
|
||||
# Rust + Solana (Anchor) Best Practices
|
||||
|
||||
## Program Structure
|
||||
- Structure Solana programs using `Anchor` framework standards
|
||||
- Place program entrypoint logic in `lib.rs`, not `main.rs`
|
||||
- Organize handlers into modules (e.g., `initialize`, `update`, `close`)
|
||||
- Separate state definitions, errors, instructions, and utils
|
||||
- Group reusable logic under a `utils` module (e.g., account validation)
|
||||
- Use `declare_id!()` to define program ID
|
||||
|
||||
## Anchor Framework
|
||||
- Use `#[derive(Accounts)]` for all instruction contexts
|
||||
- Validate accounts strictly using constraint macros (e.g., `#[account(mut)]`, `seeds`, `bump]`)
|
||||
- Define all state structs with `#[account]` and `#[derive(AnchorSerialize, AnchorDeserialize)]`
|
||||
- Prefer `Init`, `Close`, `Realloc`, `Mut`, and constraint macros to avoid manual deserialization
|
||||
- Use `ctx.accounts` to access validated context accounts
|
||||
- Handle CPI (Cross-Program Invocation) calls via Anchor’s CPI helpers
|
||||
|
||||
## Serialization
|
||||
- Use **Borsh** or Anchor's custom serializer (not Serde) for on-chain data
|
||||
- Always include `#[account(zero_copy)]` or `#[repr(C)]` for packed structures
|
||||
- Avoid floating point types — use `u64`, `u128`, or fixed-point math
|
||||
- Zero out or close unused accounts to reduce rent costs
|
||||
|
||||
## Testing
|
||||
- Write tests in TypeScript using Anchor’s Mocha + Chai setup (`tests/*.ts`)
|
||||
- Use `anchor.workspace.MyProgram` to load deployed contracts
|
||||
- Use `provider.simulate()` to inspect failed txs
|
||||
- Spin up a local validator (`anchor test`) and reset between tests
|
||||
- Airdrop SOL to wallets with `provider.connection.requestAirdrop(...)`
|
||||
- Validate program logs using `tx.confirmation.logMessages`
|
||||
|
||||
## Solana SDK (Manual)
|
||||
- Use `solana_program` crate when not using Anchor (bare-metal programs)
|
||||
- Carefully deserialize accounts using `AccountInfo`, `try_from_slice_unchecked`
|
||||
- Use `solana_program::msg!` for lightweight debugging logs
|
||||
- Verify accounts via `is_signer`, `is_writable`, `key == expected`
|
||||
- Never panic! Use `ProgramError::Custom(u32)` or `ErrorCode` enums
|
||||
|
||||
## Security Patterns
|
||||
- Always validate `msg.sender`/signer with `account_info.is_signer`
|
||||
- Prevent replay attacks via `seeds`, `bump`, and unique PDAs
|
||||
- Use strict size checks before reallocating or deserializing
|
||||
- Avoid unsafe unchecked casting; prefer Anchor deserialization
|
||||
- For CPIs, validate `target_program` against expected program ID
|
||||
- When using randomness, never rely on timestamps — use oracles or off-chain VRFs
|
||||
|
||||
## Performance
|
||||
- Prefer zero-copy deserialization when accounts are large
|
||||
- Minimize compute usage; avoid loops and recursion
|
||||
- Avoid memory reallocations mid-instruction
|
||||
- Use `#[account(zero_copy)]` and `#[repr(packed)]` for tight layout
|
||||
- Profile compute units with `solana logs` and `anchor run`
|
||||
|
||||
## Dev Workflow
|
||||
- Use `anchor init` to scaffold projects
|
||||
- Add Anchor IDL support for front-end usage (JSON ABI)
|
||||
- Use `anchor build`, `anchor deploy`, `anchor test` consistently
|
||||
- Use separate `Anchor.toml` environments for devnet/mainnet/localnet
|
||||
- Format all Rust code with `cargo fmt`, lint with `cargo clippy`
|
||||
- Keep `Cargo.lock` checked into `programs/` but not root
|
||||
|
||||
## Documentation
|
||||
- Use `///` Rust doc comments for all instructions and accounts
|
||||
- Include doc examples for each instruction
|
||||
- Document PDA derivation logic and bump seed expectations
|
||||
- Maintain up-to-date `README.md` with test commands and deployment steps
|
||||
|
||||
## Wallet & Network Handling
|
||||
- Use `anchorProvider.wallet.publicKey` for signer verification in tests
|
||||
- Do not hardcode keypairs — use env-based loading (`process.env.ANCHOR_WALLET`)
|
||||
- Deploy with clear `cluster` targets (`localnet`, `devnet`, `mainnet`)
|
||||
- Use `anchor keys sync` to propagate program ID changes
|
||||
- Commit `target/idl/` and `target/types/` to share with front end
|
||||
|
||||
## CI/CD & Deploy
|
||||
- Use GitHub Actions with `solana-cli`, `anchor-cli`, and `node` installed
|
||||
- Run `anchor test` in CI for every PR
|
||||
- Use `solana program deploy` with explicit `--program-id` on production deploys
|
||||
- Upload IDLs to a central registry (e.g., GitHub, IPFS, or `anchor.cloud`)
|
||||
Reference in New Issue
Block a user