Skip to content

Commit 3c4744f

Browse files
authored
Merge pull request #7 from macalinao/igm/codama-renderer
Add codama-renderers-markdown
2 parents 56ce89a + 2402d3c commit 3c4744f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+6640
-139
lines changed

.changeset/sweet-webs-relate.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
"@macalinao/codama-renderers-markdown": patch
3+
"@macalinao/clients-token-metadata": patch
4+
"@macalinao/clients-quarry": patch
5+
"@macalinao/coda": patch
6+
"coda-docs": patch
7+
---
8+
9+
Add codama-renderers-markdown

apps/docs/CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This documentation site is built usig Fumadocs. Documentation can be found here: https://fumadocs.dev/llms.txt

apps/docs/content/docs/configuration.mdx

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ This creates a `coda.config.mjs` file with helpful comments and examples.
2727
- **Default**: `"./src/generated"`
2828
- **Description**: Directory where generated TypeScript files will be placed
2929

30+
### `docs`
31+
- **Type**: `{ path?: string, npmPackageName?: string }`
32+
- **Default**: `{}`
33+
- **Description**: Documentation-specific options
34+
- `path`: Directory where generated markdown documentation will be placed (default: `"./docs"`)
35+
- `npmPackageName`: NPM package name to display badge and link in documentation
36+
3037
### `visitors`
3138
- **Type**: `Visitor[] | (context) => Visitor[]`
3239
- **Default**: `[]`
@@ -239,19 +246,36 @@ export default defineConfig({
239246
});
240247
```
241248

242-
## Command Line Override
249+
## Command Line Arguments
243250

244251
Configuration file settings can be overridden via command line:
245252

253+
### Generate Command
254+
246255
```bash
247256
# Override IDL path
248257
coda generate --idl ./other/idl.json
258+
coda generate -i ./other/idl.json
249259

250260
# Override output directory
251261
coda generate --output ./other/output
262+
coda generate -o ./other/output
252263

253264
# Use different config file
254265
coda generate --config ./custom.config.mjs
266+
coda generate -c ./custom.config.mjs
267+
```
268+
269+
### Docs Command
270+
271+
```bash
272+
# Override IDL path
273+
coda docs --idl ./other/idl.json
274+
coda docs -i ./other/idl.json
275+
276+
# Use different config file
277+
coda docs --config ./custom.config.mjs
278+
coda docs -c ./custom.config.mjs
255279
```
256280

257281
## Priority Order
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
---
2+
title: Generating TypeScript Clients
3+
description: Generate type-safe TypeScript clients for your Solana programs
4+
---
5+
6+
Coda's primary feature is generating fully type-safe TypeScript clients from your Anchor IDLs. These clients provide a modern, ergonomic API for interacting with your Solana programs.
7+
8+
## Basic Usage
9+
10+
To generate a TypeScript client for your program:
11+
12+
```bash
13+
coda generate
14+
```
15+
16+
This command will:
17+
1. Look for IDL files in `./idls/*.json` (or use your configured path)
18+
2. Generate TypeScript code to `./src/generated/` directory
19+
3. Create a complete client with types, instructions, accounts, and more
20+
21+
## What Gets Generated
22+
23+
Coda generates a comprehensive TypeScript client that includes:
24+
25+
### 1. **Programs**
26+
Program constants and metadata:
27+
```typescript
28+
export const MY_PROGRAM_PROGRAM_ADDRESS =
29+
"11111111111111111111111111111111" as Address<"11111111111111111111111111111111">;
30+
```
31+
32+
### 2. **Instructions**
33+
Type-safe instruction builders:
34+
```typescript
35+
import { createTransferInstruction } from "./generated";
36+
37+
const instruction = createTransferInstruction({
38+
source: sourceAddress,
39+
destination: destAddress,
40+
authority: authorityAddress,
41+
amount: 1000n,
42+
});
43+
```
44+
45+
### 3. **Accounts**
46+
Account decoders and fetchers:
47+
```typescript
48+
import { fetchMintAccount, decodeMintAccount } from "./generated";
49+
50+
// Fetch and decode in one call
51+
const mint = await fetchMintAccount(rpc, mintAddress);
52+
53+
// Or decode manually
54+
const accountInfo = await rpc.getAccountInfo(mintAddress);
55+
const mint = decodeMintAccount(accountInfo.data);
56+
```
57+
58+
### 4. **Types**
59+
All TypeScript types from your IDL:
60+
```typescript
61+
import type { TokenMetadata, Creator } from "./generated";
62+
63+
const metadata: TokenMetadata = {
64+
name: "My NFT",
65+
symbol: "NFT",
66+
uri: "https://example.com/metadata.json",
67+
creators: [],
68+
};
69+
```
70+
71+
### 5. **PDAs (Program Derived Addresses)**
72+
Helper functions for deriving PDAs:
73+
```typescript
74+
import { findMetadataPda } from "./generated";
75+
76+
const [metadataAddress, bump] = await findMetadataPda({
77+
mint: mintAddress,
78+
});
79+
```
80+
81+
### 6. **Errors**
82+
Typed error enums and handlers:
83+
```typescript
84+
import { MyProgramError, isMyProgramError } from "./generated";
85+
86+
try {
87+
// ... program interaction
88+
} catch (error) {
89+
if (isMyProgramError(error, MyProgramError.InsufficientFunds)) {
90+
console.log("Not enough funds!");
91+
}
92+
}
93+
```
94+
95+
## Configuration
96+
97+
Client generation can be customized through `coda.config.mjs`. See the [Configuration](/docs/configuration) page for detailed options including:
98+
- Custom IDL paths and output directories
99+
- Working with multiple programs
100+
- Adding custom PDAs with visitors
101+
- Handling naming conflicts between programs
102+
103+
For a real-world example with multiple programs, see the [Quarry configuration](https://github.com/macalinao/coda/blob/master/clients/quarry/coda.config.mjs).
104+
105+
## ES Modules Support
106+
107+
All generated code uses proper ES modules with `.js` extensions:
108+
109+
```typescript
110+
// All imports use .js extensions
111+
import { something } from "./types/index.js";
112+
```
113+
114+
This ensures compatibility with modern TypeScript and Node.js configurations using `"type": "module"`.
115+
116+
## Command Options
117+
118+
The `coda generate` command accepts several options. See the [Configuration](/docs/configuration#generate-command) page for all available command-line arguments.
119+
120+
## Integration Example
121+
122+
Here's a complete example of using a generated client:
123+
124+
```typescript
125+
import {
126+
createMintInstruction,
127+
createTransferInstruction,
128+
fetchTokenAccount,
129+
findAssociatedTokenAddress,
130+
} from "./generated";
131+
import { generateKeyPair, createSolanaRpc } from "@solana/web3.js";
132+
133+
// Setup
134+
const rpc = createSolanaRpc("https://api.mainnet-beta.solana.com");
135+
const authority = await generateKeyPair();
136+
137+
// Find PDA
138+
const [ataAddress] = await findAssociatedTokenAddress({
139+
owner: authority.address,
140+
mint: mintAddress,
141+
});
142+
143+
// Create instruction
144+
const mintIx = createMintInstruction({
145+
mint: mintAddress,
146+
destination: ataAddress,
147+
authority: authority.address,
148+
amount: 1000n,
149+
});
150+
151+
// Send transaction
152+
const signature = await rpc.sendTransaction({
153+
instructions: [mintIx],
154+
signers: [authority],
155+
});
156+
157+
// Fetch account
158+
const tokenAccount = await fetchTokenAccount(rpc, ataAddress);
159+
console.log("Balance:", tokenAccount.amount);
160+
```
161+
162+
## Advanced Features
163+
164+
### Custom Visitors
165+
166+
Coda uses the Codama visitor pattern for AST transformations. You can:
167+
- Rename types and instructions
168+
- Add custom PDAs
169+
- Modify account structures
170+
- Transform field types
171+
- And much more
172+
173+
### Discriminator Handling
174+
175+
Coda automatically handles Anchor's 8-byte discriminators for accounts and instructions, so you don't need to worry about them in your client code.
176+
177+
### BigInt Support
178+
179+
All `u64` and `i64` values are automatically converted to JavaScript `bigint` for proper handling of large numbers:
180+
181+
```typescript
182+
const amount = 1_000_000_000n; // 1 billion lamports
183+
```
184+
185+
## Best Practices
186+
187+
1. **Version Control**: Commit your `coda.config.mjs` but consider gitignoring generated files
188+
2. **CI/CD**: Regenerate clients in CI to ensure they're always up-to-date
189+
3. **Type Checking**: Use TypeScript strict mode for maximum type safety
190+
4. **Custom Types**: Define custom types in separate files that import from generated code
191+
5. **Testing**: Write tests against the generated client interfaces
192+
193+
## Troubleshooting
194+
195+
### Common Issues
196+
197+
**IDL not found**
198+
```bash
199+
Error: IDL file not found at ./idls/*.json
200+
```
201+
Solution: Ensure your Anchor program is built (`anchor build`)
202+
203+
**TypeScript errors**
204+
```bash
205+
Cannot find module './types/index.js'
206+
```
207+
Solution: Make sure your `tsconfig.json` has proper module resolution settings
208+
209+
**Import errors**
210+
```bash
211+
ERR_MODULE_NOT_FOUND
212+
```
213+
Solution: Ensure your `package.json` has `"type": "module"` set

0 commit comments

Comments
 (0)