Skip to content

Commit a878db4

Browse files
authored
Merge pull request #89 from solana-developers/add-table-of-contents
README fixes
2 parents 936a368 + 7567800 commit a878db4

File tree

2 files changed

+231
-27
lines changed

2 files changed

+231
-27
lines changed

README.md

Lines changed: 179 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,189 @@
11
# Program Examples
22

3-
### Onchain program examples for :anchor: Anchor :crab: Native Rust and :snake: Python
3+
## Onchain program examples for :anchor: Anchor :crab: Native Rust, and :snake: Python
44

5-
## Navigating this Repo
5+
This repo contains Solana onchain programs (referred to as 'Smart Contracts' in other blockchains).
66

7-
:file_folder: Each example contains four folders:
7+
> [!NOTE]
8+
> If you're new to Solana, you don't need to create your own programs to perform basic things like making accounts, creating tokens, sending tokens, or minting NFTs. These common tasks are handled with existing programs, for example the System Program (for making account or transferring SOL) or the token program (for creating tokens and NFTs). See the [Solana Developer site](https://solana.com/developers) to learn more.
89
9-
- `anchor` - Written using Anchor's `anchor_lang` Rust crate and the associated Anchor framework to build & deploy.
10-
- `native` - Written using Solana's native Rust crates and vanilla Rust.
11-
- `seahorse` - Written using the Python framework Seahorse, which converts your Python code to Anchor Rust.
10+
## Using this repo
1211

13-
:wrench: How to build & run:
12+
Each folder includes examples for one or more of the following
1413

15-
- Before running anything in any folder make sure you pull in the dependencies with `yarn install`.
16-
- `anchor` - Use `anchor build && anchor deploy` to build & deploy the program. Run `anchor run test` to test it.
17-
- `native` - Use `cicd.sh` to build & deploy the program. Run `yarn run test` to test it.
18-
- `seahorse` - Use `seahorse build && anchor deploy` to build & deploy the program. Run `anchor run test` to test it.
14+
- `anchor` - Written using [Anchor](https://www.anchor-lang.com/), the most popular framework for Solana Development, which uses Rust. Use `anchor build && anchor deploy` to build & deploy the program. Run `anchor run test` to test it.
15+
- `native` - Written using Solana's native Rust crates and vanilla Rust. Use `cicd.sh` to build & deploy the program. Run `yarn run test` to test it.
16+
- `seahorse` - Written using the [Seahorse framework](https://seahorse-lang.org/), which converts your Python code to Anchor Rust. Use `seahorse build && anchor deploy` to build & deploy the program. Run `anchor run test` to test it.
17+
18+
If a given example is missing, please add it!
19+
20+
## The example projects!
21+
22+
### basics
23+
24+
#### account-data
25+
26+
[anchor](./basics/account-data/anchor), [native](./basics/account-data/native)
27+
28+
#### checking-accounts
29+
30+
[anchor](./basics/checking-accounts/anchor), [native](./basics/checking-accounts/native)
31+
32+
#### close-account
33+
34+
[anchor](./basics/close-account/anchor), [native](./basics/close-account/native)
35+
36+
#### counter
37+
38+
[anchor](./basics/counter/anchor), [native](./basics/counter/native), [seahorse](./basics/counter/seahorse)
39+
40+
#### create-account
41+
42+
[anchor](./basics/create-account/anchor), [native](./basics/create-account/native)
43+
44+
#### cross-program-invocation
45+
46+
[anchor](./basics/cross-program-invocation/anchor), [native](./basics/cross-program-invocation/native)
47+
48+
#### favorites
49+
50+
[anchor](./basics/favorites/anchor)
51+
52+
#### hello-solana
53+
54+
[anchor](./basics/hello-solana/anchor), [native](./basics/hello-solana/native), [seahorse](./basics/hello-solana/seahorse)
55+
56+
#### pda-rent-payer
57+
58+
[anchor](./basics/pda-rent-payer/anchor), [native](./basics/pda-rent-payer/native)
59+
60+
#### processing-instructions
61+
62+
[anchor](./basics/processing-instructions/anchor), [native](./basics/processing-instructions/native)
63+
64+
#### program-derived-addresses
65+
66+
[anchor](./basics/program-derived-addresses/anchor), [native](./basics/program-derived-addresses/native)
67+
68+
#### realloc
69+
70+
[anchor](./basics/realloc/anchor), [native](./basics/realloc/native)
71+
72+
#### rent
73+
74+
[anchor](./basics/rent/anchor), [native](./basics/rent/native)
75+
76+
#### repository-layout
77+
78+
[anchor](./basics/repository-layout/anchor), [native](./basics/repository-layout/native)
79+
80+
#### transfer-sol
81+
82+
[anchor](./basics/transfer-sol/anchor), [native](./basics/transfer-sol/native), [seahorse](./basics/transfer-sol/seahorse)
83+
84+
### tokens
85+
86+
#### create-token
87+
88+
[anchor](./tokens/create-token/anchor), [native](./tokens/create-token/native)
89+
90+
#### escrow
91+
92+
[anchor](./tokens/escrow/anchor)
93+
94+
#### nft-minter
95+
96+
[anchor](./tokens/nft-minter/anchor), [native](./tokens/nft-minter/native)
97+
98+
#### pda-mint-authority
99+
100+
[anchor](./tokens/pda-mint-authority/anchor), [native](./tokens/pda-mint-authority/native)
101+
102+
#### spl-token-minter
103+
104+
[anchor](./tokens/spl-token-minter/anchor), [native](./tokens/spl-token-minter/native)
105+
106+
#### token-swap
107+
108+
[anchor](./tokens/token-swap/anchor)
109+
110+
#### transfer-tokens
111+
112+
[anchor](./tokens/transfer-tokens/anchor), [native](./tokens/transfer-tokens/native), [seahorse](./tokens/transfer-tokens/seahorse)
113+
114+
### tokens/token-2022
115+
116+
#### basics
117+
118+
[anchor](./tokens/token-2022/basics/anchor)
119+
120+
#### cpi-guard
121+
122+
[anchor](./tokens/token-2022/cpi-guard/anchor)
123+
124+
#### default-account-state
125+
126+
[anchor](./tokens/token-2022/default-account-state/anchor), [native](./tokens/token-2022/default-account-state/native)
127+
128+
#### group
129+
130+
[anchor](./tokens/token-2022/group/anchor)
131+
132+
#### immutable-owner
133+
134+
[anchor](./tokens/token-2022/immutable-owner/anchor)
135+
136+
#### interest-bearing
137+
138+
[anchor](./tokens/token-2022/interest-bearing/anchor)
139+
140+
#### memo-transfer
141+
142+
[anchor](./tokens/token-2022/memo-transfer/anchor)
143+
144+
#### metadata
145+
146+
[anchor](./tokens/token-2022/metadata/anchor)
147+
148+
#### mint-close-authority
149+
150+
[anchor](./tokens/token-2022/mint-close-authority/anchor), [native](./tokens/token-2022/mint-close-authority/native)
151+
152+
#### multiple-extensions
153+
154+
[native](./tokens/token-2022/multiple-extensions/native)
155+
156+
#### non-transferable
157+
158+
[anchor](./tokens/token-2022/non-transferable/anchor), [native](./tokens/token-2022/non-transferable/native)
159+
160+
#### permanent-delegate
161+
162+
[anchor](./tokens/token-2022/permanent-delegate/anchor)
163+
164+
#### transfer-fee
165+
166+
[anchor](./tokens/token-2022/transfer-fee/anchor), [native](./tokens/token-2022/transfer-fee/native)
167+
168+
### compression
169+
170+
#### cnft-burn
171+
172+
[anchor](./compression/cnft-burn/anchor)
173+
174+
#### cnft-vault
175+
176+
[anchor](./compression/cnft-vault/anchor)
177+
178+
#### cutils
179+
180+
[anchor](./compression/cutils/anchor)
181+
182+
### oracles
183+
184+
#### pyth
185+
186+
[anchor](./oracles/pyth/anchor), [seahorse](./oracles/pyth/seahorse)
19187

20188
## Examples We'd Love to See!
21189

@@ -38,19 +206,3 @@
38206
- Merkle trees (compression)
39207

40208
---
41-
42-
## If You're New To Solana Please Read
43-
44-
Most system-level operations on Solana involve already-existing Solana programs.
45-
46-
For example, to create a **system account** you use the **system program** and to create a **token mint** you use the **token program**.
47-
48-
So, you'll notice that these operations are in fact conducting what's called a **cross-program invocation** - which is a fancy way of saying it calls other Solana programs to do business. You can see this in action whenever you see `invoke` or `invoke_signed` in the `native` examples, or `CpiContext` in the `anchor` examples.
49-
50-
Deciding when to use cross-program invocation instead of invoking the programs directly from the client is completely up to you as the builder. It depends on how your application is designed.
51-
52-
- Maybe you want to add some checks - such as minimum balance required, allowed ownership, etc.
53-
- Maybe you want to assert that an account has a certain data type.
54-
- Perhaps you want to send only one instruction from your client for a handful of sequential operations.
55-
- The list goes on.
56-
Regardless of what you may want to add on top of existing Solana programs, the number one use case for writing your own program is for using accounts with a **Program Derived Address (PDA)**. Crack open the `pdas` folder to see why.

make-table-of-contents.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Usage: esrun make-table-of-contents.ts
2+
import { readdir } from 'node:fs/promises';
3+
const log = console.log;
4+
5+
// A serial async map function (because we like do things in order and performance doesn't matter)
6+
const asyncMap = async (array, asyncFunction) => {
7+
for (const item of array) {
8+
await asyncFunction(item);
9+
}
10+
};
11+
12+
const PROJECT_TYPES = ['anchor', 'native', 'seahorse', 'solidity'];
13+
const CATEGORIES = ['basics', 'tokens', 'tokens/token-2022', 'compression', 'oracles'];
14+
15+
interface LinkMap {
16+
[key: string]: boolean;
17+
}
18+
19+
// Loop through the folders in CATEGORIES
20+
await asyncMap(CATEGORIES, async (category) => {
21+
const path = `./${category}`;
22+
const exampleFolders = (await readdir(path, { withFileTypes: true })).filter((item) => item.isDirectory()).map((dir) => dir.name);
23+
log(`\n\n### ${category}`);
24+
await asyncMap(exampleFolders, async (exampleFolder) => {
25+
// Check if the folder has a subfolder that matches a project type ('anchor', 'native' etc...)
26+
const projectTypeFolders = (await readdir(`./${category}/${exampleFolder}`, { withFileTypes: true }))
27+
.filter((item) => item.isDirectory())
28+
.filter((dir) => PROJECT_TYPES.includes(dir.name));
29+
30+
// If there are no subfolders that match a project type, we can skip this folder - it's not example code
31+
if (projectTypeFolders.length === 0) {
32+
return;
33+
}
34+
log(`\n#### ${exampleFolder}`);
35+
36+
// We can now create a map of the project types that are present in the example folder
37+
const linkMap: LinkMap = {};
38+
PROJECT_TYPES.forEach((projectType) => {
39+
linkMap[projectType] = projectTypeFolders.some((dir) => dir.name === projectType);
40+
});
41+
42+
const links: Array<string> = [];
43+
// Go through the link map add a string link to the folder if the linkmap value is true
44+
for (const [projectType, exists] of Object.entries(linkMap)) {
45+
const link = `./${category}/${exampleFolder}/${projectType}`;
46+
if (exists) {
47+
links.push(`[${projectType}](${link})`);
48+
}
49+
}
50+
log(links.join(', '));
51+
});
52+
});

0 commit comments

Comments
 (0)