Package Exports
- @macalinao/grill
Readme
@macalinao/grill
Modern Solana development kit for React applications with automatic account batching, caching, and transaction notifications.
Features
- 🚀 Automatic Account Batching: Coalesces multiple account requests into single RPC calls
- 💾 Smart Caching: Integrated with React Query for intelligent cache management
- 🔔 Transaction Notifications: Built-in toast notifications for transaction status updates via Sonner
- 🔐 Modern Wallet Integration: Full support for @solana/kit wallet standard
- ⚡ Performance Optimized: Reduces RPC calls and improves app responsiveness
- 🎨 Headless Option: Use GrillHeadlessProvider for custom UI implementations
Installation
npm install @macalinao/grill sonner
# or
yarn add @macalinao/grill sonner
# or
bun add @macalinao/grill sonnerQuick Start
1. Set up the provider hierarchy
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { SolanaProvider } from "@gillsdk/react";
import { GrillProvider } from "@macalinao/grill";
import { Toaster } from "sonner";
const queryClient = new QueryClient();
function App() {
return (
<QueryClientProvider client={queryClient}>
<SolanaProvider>
<GrillProvider>{/* Your app components */}</GrillProvider>
<Toaster />
</SolanaProvider>
</QueryClientProvider>
);
}2. Fetch account data with automatic batching
import { useAccount } from "@macalinao/grill";
function TokenBalance({ tokenAccount }: { tokenAccount: string }) {
const { data: account, isLoading } = useAccount(tokenAccount);
if (isLoading) return <div>Loading...</div>;
if (!account) return <div>Account not found</div>;
return <div>Balance: {account.lamports}</div>;
}3. Send transactions with automatic notifications
import { useSendTX } from "@macalinao/grill";
import { getTransferSolInstruction } from "@solana-program/system";
function SendButton() {
const sendTX = useSendTX();
const handleSend = async () => {
const instruction = getTransferSolInstruction({
source: publicKey,
destination: recipientPublicKey,
lamports: 1000000000n, // 1 SOL
});
// Transaction status toasts will automatically appear
const signature = await sendTX("Transfer SOL", [instruction]);
console.log("Transaction sent:", signature);
};
return <button onClick={handleSend}>Send 1 SOL</button>;
}Provider Options
GrillProvider
The main provider with built-in toast notifications:
<GrillProvider
maxBatchSize={99} // Max accounts per batch (default: 99)
batchDurationMs={10} // Batch window in ms (default: 10)
showToasts={true} // Show transaction toasts (default: true)
successToastDuration={5000} // Success toast duration (default: 5000)
errorToastDuration={7000} // Error toast duration (default: 7000)
onTransactionStatusEvent={(event) => {
// Optional: Handle transaction events manually
console.log("Transaction event:", event);
}}
>
{children}
</GrillProvider>GrillHeadlessProvider
For custom UI implementations without built-in toasts:
<GrillHeadlessProvider
maxBatchSize={99}
batchDurationMs={10}
onTransactionStatusEvent={(event) => {
// Handle all transaction events yourself
switch (event.type) {
case "preparing":
console.log("Preparing transaction...");
break;
case "confirmed":
console.log("Transaction confirmed!");
break;
// ... handle other event types
}
}}
>
{children}
</GrillHeadlessProvider>Hooks
useAccount
Fetch account data with automatic batching and caching:
const { data, isLoading, error, refetch } = useAccount(address, options);useSendTX
Send transactions with automatic status notifications:
const sendTX = useSendTX();
// Send a transaction
const signature = await sendTX("Transaction Name", instructions, {
signers: [], // Additional signers
luts: {}, // Address lookup tables
});useKitWallet
Access the wallet signer and connection:
const { signer, publicKey } = useKitWallet();Transaction Status Events
The provider emits the following transaction status events:
error-wallet-not-connected: Wallet is not connectedpreparing: Building the transactionawaiting-wallet-signature: Waiting for user approvalwaiting-for-confirmation: Transaction sent, awaiting confirmationconfirmed: Transaction confirmed on-chainerror-transaction-failed: Transaction failed
How Batching Works
When multiple components request account data simultaneously, Grill automatically:
- Collects all requests within a 10ms window
- Combines them into a single RPC call (up to 99 accounts)
- Distributes results to all requesting components
- Caches results with React Query
This significantly reduces RPC calls and improves performance, especially in data-rich interfaces.
Requirements
- React 18+ or React 19
- @solana/web3.js v2
- @solana/kit
- @tanstack/react-query v5
- sonner (for toast notifications)
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Support
For issues and questions, please visit our GitHub Issues.
License
Copyright (c) 2025 Ian Macalinao. Licensed under the Apache-2.0 License.