Skip to content

Commit dce0b8d

Browse files
committed
make account refetching work
1 parent 4da5caa commit dce0b8d

Some content is hidden

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

44 files changed

+2885
-159
lines changed

.gitignore

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,6 @@ Thumbs.db
3939
coverage/
4040
.nyc_output
4141

42-
# Bun
43-
bun.lockb
44-
4542
# Cache
4643
.eslintcache
4744
.cache/
@@ -51,4 +48,5 @@ bun.lockb
5148
*.temp
5249

5350
.devenv.flake.nix
54-
.devenv/
51+
/nix
52+
/.devenv

CLAUDE.md

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
Grill is a modern Solana development kit monorepo that provides React components and utilities for building Solana applications with automatic account batching and caching. It's built on top of gill-react and integrates with @solana/kit.
8+
9+
## Technology Stack
10+
11+
- **Package Manager**: Bun (v1.2.19)
12+
- **Build System**: Turbo for monorepo orchestration
13+
- **Framework**: React 19 with TypeScript
14+
- **Solana**: @solana/kit, gill, gill-react
15+
- **State Management**: @tanstack/react-query for caching
16+
- **Routing**: @tanstack/react-router (in example-dapp)
17+
- **Styling**: Tailwind CSS v4 with shadcn/ui components
18+
- **Code Quality**: Biome for formatting, ESLint for linting
19+
- **Testing**: Vitest
20+
21+
## Essential Commands
22+
23+
```bash
24+
# Development
25+
bun install # Install all dependencies
26+
bun run build # Build all packages
27+
bun run build:watch # Watch mode for all packages
28+
bun run build:watch:packages # Watch mode for packages only
29+
30+
# Code Quality
31+
bun run lint # Run biome check + eslint
32+
bun run lint:fix # Fix linting issues
33+
biome check --write # Format with biome
34+
35+
# Testing
36+
bun run test # Run all tests
37+
bun test # Run tests directly
38+
39+
# Package Publishing
40+
bun run changeset # Create changeset for version bumps
41+
bun run ci:publish # Publish packages to npm
42+
43+
# Example App Development
44+
cd apps/example-dapp
45+
bun run dev # Start Vite dev server
46+
bun run build # Build the app
47+
```
48+
49+
## Architecture
50+
51+
### Monorepo Structure
52+
53+
The project uses Bun workspaces with packages in two directories:
54+
- `packages/*` - Core library packages
55+
- `apps/*` - Example applications
56+
57+
### Core Packages
58+
59+
1. **@macalinao/grill** - Main package providing React context and hooks
60+
- `GrillProvider`: Creates DataLoader for batching account requests
61+
- `WalletProvider`: Kit wallet integration context
62+
- `useAccount`: Hook for fetching account data with batching
63+
- `useKitWallet`: Access wallet signer and RPC
64+
65+
2. **@macalinao/solana-batch-accounts-loader** - DataLoader implementation for batching Solana account fetches
66+
67+
3. **@macalinao/wallet-adapter-compat** - Compatibility layer between @solana/wallet-adapter and @solana/kit
68+
69+
4. **dataloader-es** - ES module compatible DataLoader implementation
70+
71+
### Provider Hierarchy
72+
73+
When using Grill, providers must be set up in this order:
74+
```tsx
75+
QueryClientProvider
76+
SolanaProvider (gill-react)
77+
ConnectionProvider (@solana/wallet-adapter-react)
78+
WalletProvider (@solana/wallet-adapter-react)
79+
WalletModalProvider
80+
GrillProvider
81+
```
82+
83+
### Account Batching Architecture
84+
85+
The core innovation is automatic batching of concurrent account requests:
86+
- Multiple `useAccount` calls in different components are automatically batched
87+
- Uses DataLoader pattern to coalesce requests within a tick
88+
- Single RPC call instead of multiple, improving performance
89+
- Integrated with React Query for caching
90+
91+
### Kit Wallet Integration
92+
93+
Provides two contexts:
94+
1. Account batching context (GrillProvider)
95+
2. Wallet context for TransactionSendingSigner (WalletProvider from grill)
96+
97+
## Code Style Guidelines
98+
99+
### TypeScript
100+
- Use specific types, avoid `any`
101+
- Prefer interfaces over type aliases for objects
102+
- Use `import type` for type-only imports (enforced by Biome)
103+
- Arrays use shorthand syntax: `string[]` not `Array<string>`
104+
- **Use double quotes for strings** (not single quotes)
105+
- Follow default Prettier settings
106+
107+
### React Components
108+
- Small, focused components
109+
- Use function components with hooks
110+
- Props interfaces should be explicitly defined
111+
- File structure: `components/category/component-name/index.tsx`
112+
113+
### Biome/ESLint Configuration
114+
- No floating promises (must be handled)
115+
- Use const assertions where applicable
116+
- No non-null assertions are allowed
117+
- Simplified logic expressions required
118+
- No double equals (use === instead)
119+
- Imports are auto-organized on save
120+
121+
## Example App (example-dapp)
122+
123+
The example-dapp demonstrates:
124+
- TanStack Router for routing
125+
- shadcn/ui component integration
126+
- Wallet connection with Solana wallet adapter
127+
- Layout system with navigation and sidebar
128+
- Dark mode support
129+
130+
Routes:
131+
- `/` - Home page
132+
- `/dashboard` - Simple dashboard
133+
- `/examples/*` - Examples section with sidebar navigation
134+
135+
## Turborepo Configuration
136+
137+
Tasks are defined in turbo.json:
138+
- `build`: Depends on upstream builds, outputs to `./dist/**`
139+
- `lint`: Depends on upstream builds
140+
- `test`: Depends on build, no caching
141+
- Tasks run in topological order respecting dependencies
142+
143+
## Working with Providers
144+
145+
When creating new features that need account data:
146+
1. Ensure component is wrapped in GrillProvider
147+
2. Use `useAccount` hook for fetching account data
148+
3. Account requests are automatically batched
149+
4. React Query handles caching and refetching
150+
151+
## Vendor Documentation
152+
153+
The repository includes vendor documentation at `/docs/vendor/`:
154+
- `gill.md` - Complete documentation for the gill library (Solana client library)
155+
- Includes transaction builders, token operations, and program clients
156+
- Used as the foundation for Solana operations in Grill
157+
158+
## CI/CD
159+
160+
GitHub Actions workflow runs on push/PR to master:
161+
- Installs dependencies with frozen lockfile
162+
- Builds all packages
163+
- Runs linting (biome + eslint)
164+
- Runs tests
165+
- Checks TypeScript compilation
166+
167+
## Publishing Workflow
168+
169+
1. Create changeset: `bun run changeset`
170+
2. Version packages: `bun run ci:version`
171+
3. Publish to npm: `bun run ci:publish`
172+
4. Changesets handle version bumping and changelog generation

apps/example-dapp/package.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,16 @@
1212
"dependencies": {
1313
"@macalinao/grill": "workspace:*",
1414
"@macalinao/wallet-adapter-compat": "workspace:*",
15+
"@radix-ui/react-dialog": "^1.1.14",
16+
"@radix-ui/react-navigation-menu": "^1.2.13",
17+
"@radix-ui/react-separator": "^1.1.7",
1518
"@radix-ui/react-slot": "^1.2.3",
19+
"@radix-ui/react-tooltip": "^1.2.7",
20+
"@solana-program/system": "^0.7.0",
21+
"@solana-program/token": "^0.5.1",
22+
"@solana-program/token-2022": "^0.4.2",
1623
"@solana/kit": "catalog:",
24+
"@solana/spl-token": "^0.4.13",
1725
"@solana/wallet-adapter-react": "catalog:",
1826
"@solana/wallet-adapter-react-ui": "^0.9.39",
1927
"@solana/wallet-adapter-wallets": "^0.19.37",
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import { Link, Outlet, useLocation } from "@tanstack/react-router";
2+
import { Coins, LayoutDashboard } from "lucide-react";
3+
import type { FC } from "react";
4+
import {
5+
Sidebar,
6+
SidebarContent,
7+
SidebarGroup,
8+
SidebarGroupContent,
9+
SidebarGroupLabel,
10+
SidebarHeader,
11+
SidebarInset,
12+
SidebarMenu,
13+
SidebarMenuButton,
14+
SidebarMenuItem,
15+
SidebarProvider,
16+
} from "@/components/ui/sidebar";
17+
import { cn } from "@/lib/utils";
18+
19+
export interface ExamplesLayoutProps {
20+
className?: string;
21+
}
22+
23+
interface ExampleNavItem {
24+
title: string;
25+
href: string;
26+
icon: React.ComponentType;
27+
}
28+
29+
// Example navigation items - clean and simple for sidebar
30+
const exampleNavItems: ExampleNavItem[] = [
31+
{
32+
title: "Dashboard",
33+
href: "/examples/dashboard",
34+
icon: LayoutDashboard,
35+
},
36+
{
37+
title: "Wrapped SOL",
38+
href: "/examples/wrapped-sol",
39+
icon: Coins,
40+
},
41+
];
42+
43+
export const ExamplesLayout: FC<ExamplesLayoutProps> = ({ className }) => {
44+
const location = useLocation();
45+
46+
return (
47+
<SidebarProvider defaultOpen={true}>
48+
<div className={cn("flex h-[calc(100vh-4rem)] w-full", className)}>
49+
<Sidebar variant="sidebar" collapsible="icon">
50+
<SidebarHeader>
51+
<div className="px-3 py-2">
52+
<h2 className="text-lg font-semibold">Examples</h2>
53+
<p className="text-sm text-muted-foreground group-data-[collapsible=icon]:hidden">
54+
Explore Solana dApp patterns
55+
</p>
56+
</div>
57+
</SidebarHeader>
58+
59+
<SidebarContent>
60+
<SidebarGroup>
61+
<SidebarGroupLabel>Getting Started</SidebarGroupLabel>
62+
<SidebarGroupContent>
63+
<SidebarMenu>
64+
{exampleNavItems.map((item) => {
65+
const Icon = item.icon;
66+
return (
67+
<SidebarMenuItem key={item.href}>
68+
<SidebarMenuButton
69+
asChild
70+
isActive={location.pathname === item.href}
71+
>
72+
<Link to={item.href}>
73+
<Icon />
74+
<span>{item.title}</span>
75+
</Link>
76+
</SidebarMenuButton>
77+
</SidebarMenuItem>
78+
);
79+
})}
80+
</SidebarMenu>
81+
</SidebarGroupContent>
82+
</SidebarGroup>
83+
</SidebarContent>
84+
</Sidebar>
85+
86+
<SidebarInset className="overflow-auto">
87+
<div className="p-6">
88+
<Outlet />
89+
</div>
90+
</SidebarInset>
91+
</div>
92+
</SidebarProvider>
93+
);
94+
};
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { WalletMultiButton } from "@solana/wallet-adapter-react-ui";
2+
import { Link, Outlet } from "@tanstack/react-router";
3+
import type { FC } from "react";
4+
import {
5+
NavigationMenu,
6+
NavigationMenuItem,
7+
NavigationMenuLink,
8+
NavigationMenuList,
9+
} from "@/components/ui/navigation-menu";
10+
import { cn } from "@/lib/utils";
11+
12+
export interface MainLayoutProps {
13+
className?: string;
14+
}
15+
16+
export const MainLayout: FC<MainLayoutProps> = ({ className }) => {
17+
return (
18+
<div className={cn("flex min-h-screen flex-col bg-background", className)}>
19+
<header className="sticky top-0 z-50 flex h-16 w-full border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
20+
<div className="flex flex-1 items-center justify-between px-4 sm:px-6 lg:px-8">
21+
{/* Logo and Navigation */}
22+
<div className="flex items-center gap-6">
23+
<Link
24+
to="/"
25+
className="flex items-center gap-2 text-lg font-semibold"
26+
>
27+
<span className="text-2xl">🍳</span>
28+
<span>Grill</span>
29+
</Link>
30+
31+
<NavigationMenu>
32+
<NavigationMenuList>
33+
<NavigationMenuItem>
34+
<Link to="/examples">
35+
<NavigationMenuLink className="group inline-flex h-9 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground disabled:pointer-events-none disabled:opacity-50">
36+
Examples
37+
</NavigationMenuLink>
38+
</Link>
39+
</NavigationMenuItem>
40+
</NavigationMenuList>
41+
</NavigationMenu>
42+
</div>
43+
44+
{/* Wallet Connection */}
45+
<div className="flex items-center">
46+
<WalletMultiButton />
47+
</div>
48+
</div>
49+
</header>
50+
51+
<div className="flex-1">
52+
<Outlet />
53+
</div>
54+
</div>
55+
);
56+
};

0 commit comments

Comments
 (0)