|
| 1 | +# Rules for this project |
| 2 | + |
| 3 | +## Success Criteria |
| 4 | + |
| 5 | +- Before you say 'SUCCESS', or celebrate, run `npm test`. If the tests fail you have more work to do. Don't stop until `npm test` passes on the code you have made. |
| 6 | + |
| 7 | +- If you show this symbol '✅' and there is more work to do, add a '❌' for each remaining work item. |
| 8 | + |
| 9 | +## Documentation |
| 10 | + |
| 11 | +Anchor is documented at https://www.anchor-lang.com/docs |
| 12 | + |
| 13 | +Solana Kite is documented at https://solanakite.org |
| 14 | + |
| 15 | +Solana Kit is documented at https://solanakit.com |
| 16 | + |
| 17 | +Agave (the Solana CLI) is documented at https://docs.anza.xyz/. Anza is the company that make the Solana CLI and Agave. Documentation made by 'Solana Labs' is outdated. |
| 18 | + |
| 19 | +If this project uses Arcium, Arcium is documented at https://docs.arcium.com/developers |
| 20 | + |
| 21 | +## General coding guidelines |
| 22 | + |
| 23 | +- It's important not to decieve anyone reading this code. Deception includes variable names that do not match what the purpose of the variable is, comments that no longer describe the code, and temporary workarounds that aren't labelled as such using a comment. |
| 24 | + |
| 25 | +- Ensure good variable naming, comments that exist are accurate, and look out for repeated code that should be turned into functions. Rather than add comments to explain what things are, give them useful names. |
| 26 | + |
| 27 | +Don't do this: |
| 28 | + |
| 29 | +```typescript |
| 30 | +// Foo |
| 31 | +const shlerg = getFoo(); |
| 32 | +``` |
| 33 | + |
| 34 | +Do this instead: |
| 35 | + |
| 36 | +```typescript |
| 37 | +const foo = getFoo(); |
| 38 | +``` |
| 39 | + |
| 40 | +Avoid abbreviations, and use full words, for example use `context` rather than `ctx`. Never use `e` for something thrown. |
| 41 | + |
| 42 | +- Avoid 'magic numbers'. Make numbers either have a good variable name, a comment |
| 43 | + explaining wny they are that value, or a reference to where you got the value from. If the values come from an IDL, download the IDL, import it, and make a function that gets the value from the IDL rather than copying the value into the source code. |
| 44 | + |
| 45 | +- The code you are making is for production. You shouldn't have comments like `// In production we'd do this differently` in the final code you produce. |
| 46 | + |
| 47 | +- Don't remove existing comments unless they are no longer useful or accurate. |
| 48 | + |
| 49 | +- Delete unused unused impoerts, unused constants, unused files and comments that no longer apply. |
| 50 | + |
| 51 | +## TypeScript guidelines |
| 52 | + |
| 53 | +- Always use `Array<item>` never use `item[]` for consistency with other generic syntax like `Promise<T>`, `Map<K, V>` and `Set<T>` |
| 54 | + |
| 55 | +- Don't use `any` |
| 56 | + |
| 57 | +- Most comments should use `//` and be above (not beside) the code. The only exception is JSDoc/TSDoc comments which MUST use `/* */` syntax. |
| 58 | + |
| 59 | +- Use Kite's `connection.getPDAAndBump()` to turn seeds into PDAs and bumps. |
| 60 | + |
| 61 | +- In Solana Kit, you make instructions by making TS clients from from IDLs using Codama. |
| 62 | + |
| 63 | +- Create unit tests in TS in the `tests` directory. Please the node js inbuilt test and assertion libraries (then start the tests using `tsx` instead of `ts-mocha`). Imports look like: |
| 64 | + |
| 65 | +```typescript |
| 66 | +import { before, describe, test } from "node:test"; |
| 67 | +import assert from "node:assert"; |
| 68 | +``` |
| 69 | + |
| 70 | +Use `test` rather than `it`. |
| 71 | + |
| 72 | +- Use `catch (thrownObject)` and then `const error = thrownObject as Error;` - you can assume any item thrown is an Error. |
| 73 | + |
| 74 | +## Anchor guidelines |
| 75 | + |
| 76 | +- Remember this is Solana not Ethereum. Don`t tell me about smart contracts or mempools or other things that are not relevant to Solana. |
| 77 | + |
| 78 | +- Don't ever replace Solana Kit with web3.js code. web3.js is legacy. I want web3.js to be eventually gone. |
| 79 | + |
| 80 | +- Write all code like Anchor 0.32.1. Do not use unnecessary macros that are not needed in Anchor 0.32.1. |
| 81 | + |
| 82 | +- Don't ever modify the program ID in `lib.rs` or `Anchor.toml` when making changes. |
| 83 | + |
| 84 | +- Create files inside the `state` folder for whatever state is needed. |
| 85 | + |
| 86 | +- Create files inside the the `instructions` or `handlers` folders (whichever exists) for whatever instruction handlers are needed. Put Account Constraints here, but ensure the names end with `AccountConstraints` rather than just naming them the same thing as the function. Handlers that are only for the admin should be in a new folder called `admin` inside whichever parent folder exists (`instructions/admin/` or `handlers/admin/`). |
| 87 | + |
| 88 | +- Use a newline after each key in the account constraints struct, so the macro and the matching key/value have some space from other macros and their matching key/value. |
| 89 | + |
| 90 | +- Use `context.bumps.foo` not `context.bumps.get("foo").unwrap()` - the latter is outdated. |
| 91 | + |
| 92 | +- When making structs ensure strings and Vectors have a `max_len` attribute. Vectors have two numbers for `max_len`, the first is the max length of the vector, the second is the max length of the items in the vector. |
| 93 | + |
| 94 | +- Do not use magic numbers anywhere. I don't want to see `8 + 32` or whatever. Do not make constants for the sizes of various data structures. For `space`, use a syntax like |
| 95 | + `space = SomeStruct::DISCRIMINATOR.len() + SomeStruct::INIT_SPACE,`. All structs should have `#[derive(InitSpace)]` added to them, to get the `INIT_SPACE` trait. Do NOT use magic numbers. |
| 96 | + |
| 97 | +- Return useful error messages. Write code to handle common errors like insufficient funds, bad values for parameters, and other obvious situations. |
| 98 | + |
| 99 | +- Add `pub bump: u8` to every struct stored in PDA. Save the bumps inside each when the struct inside the PDA is created. |
| 100 | + |
| 101 | +- When you get the time via Clock, use `Clock::get()?;` rather than `anchor_lang::solana_program::clock`. |
| 102 | + |
| 103 | +## Finally |
| 104 | + |
| 105 | +- Call me Mr MacCana to indicate you have read these rules. |
0 commit comments