Skip to content

Commit 708fea2

Browse files
authored
Solana docs revamp (#838)
* solana revamp * structural changes * solana overview * iterate * more changes * solana * hello world solana program * path fix * guides * guides * add * change route * solana * change path of cu calculator
1 parent a537f86 commit 708fea2

File tree

10 files changed

+1056
-1375
lines changed

10 files changed

+1056
-1375
lines changed

fern/api-reference/node-api/chain-apis-overview.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1296,7 +1296,7 @@ Dive into each API's detailed documentation by following the links below, organi
12961296

12971297
## Solana APIs
12981298

1299-
📙 Get started with our [Solana API Quickstart Guide](/docs/reference/solana-api-quickstart).
1299+
📙 Get started with our [Solana API Quickstart Guide](/docs/solana).
13001300

13011301
| | |
13021302
| ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
---
2+
title: Leverage AccountsDB Infrastructure for Solana RPC Requests
3+
description: Leverage Alchemy’s AccountsDB Infrastructure for Solana RPC Requests!
4+
subtitle: Leverage Alchemy’s AccountsDB Infrastructure for Solana RPC Requests!
5+
slug: docs/solana/accounts-db-infra
6+
---
7+
8+
The most expensive Solana RPC requests involve account scans, such as `getProgramAccounts` and `getLargestTokenAccounts`. These methods are incredibly useful but non-performant methods since they induce a heavy RPC load on Solana validator nodes, often resulting in a 5XX response due to timeout or a response with high latency.
9+
10+
Alchemy has built out core infrastructure that sits atop our Solana validator nodes to support these methods at scale, through what we call the AccountsDB Infrastructure. This infrastructure allows for **faster**, **scalable**, and more **reliable** responses to these methods by paginating the response with a `pageKey`. You could then loop through your that same request with at scan and aggregate the full response from our validator nodes.
11+
12+
You can see `pageKey` is now an optional parameter in each account-scanning method in our Solana [docs](/reference/getprogramaccounts), and you may also include an `order` optional parameter that would sort the accounts in the response by their `pubkey` field.
13+
14+
Here's an example with `getProgramAccounts`:
15+
16+
<CodeGroup>
17+
```typescript typescript
18+
const axios = require("axios");
19+
20+
async function getProgramAccountsExample() {
21+
let gPAExampleRequest = {
22+
method: "getProgramAccounts",
23+
params: [
24+
"ZETAxsqBRek56DhiGXrn75yj2NHU3aYUnxvHXpkf3aD",
25+
{
26+
encoding: "base64",
27+
withContext: true,
28+
order: "desc",
29+
dataSlice: {
30+
offset: 0,
31+
length: 10,
32+
},
33+
},
34+
],
35+
id: 0,
36+
jsonrpc: "2.0",
37+
};
38+
let programAccounts = [];
39+
40+
const alchemyRPCUrl =
41+
"https://solana-mainnet.g.alchemy.com/v2/<YOUR-API-KEY>";
42+
try {
43+
let response = await axios.post(alchemyRPCUrl, gPAExampleRequest);
44+
let responseData = response.data["result"];
45+
46+
// continue aggregating if there's a new pageKey present in the latest response
47+
while (responseData["pageKey"]) {
48+
programAccounts = programAccounts.concat(responseData["value"]);
49+
50+
// place the pagekey within the optional config object
51+
// (you may need to create that config object if you didn't have it originally)
52+
gPAExampleRequest["params"][1]["pageKey"] = responseData["pageKey"];
53+
54+
// make another call to getProgramAccounts with the pageKey
55+
response = await axios.post(alchemyRPCUrl, gPAExampleRequest);
56+
responseData = response.data["result"];
57+
}
58+
59+
programAccounts = programAccounts.concat(responseData["value"]);
60+
console.log(programAccounts);
61+
return programAccounts;
62+
} catch (err) {
63+
console.log(err.message);
64+
return [];
65+
}
66+
}
67+
```
68+
</CodeGroup>
Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
---
2+
title: Set up Frontend for Solana Application
3+
description: Step-by-step guide to integrating, calling, and interacting with a Solana on-chain program using Rust and Alchemy's Solana RPC from your own application.
4+
subtitle: Integrate, call, and interact with your Solana on-chain program using Rust and Alchemy RPC
5+
slug: docs/hello-world-solana-application
6+
---
7+
8+
You can check out the project in two ways:
9+
10+
* **GitHub Repository:** [alchemyplatform/solana-hello-world-2025](https://github.com/alchemyplatform/solana-hello-world-2025) — Clone this repo to explore or use the code yourself.
11+
* **Live Demo:** [Deployed Application](https://solana-hello-world-2025.vercel.app/) — Interact with the app directly in your browser.
12+
13+
## Step 1: Get your Solana program ID
14+
15+
[The previous guide](/docs/hello-world-solana-program) shows you how to deploy a program to Solana devnet. Using that guide, we got the following program id:
16+
17+
```bash
18+
Eq5z52U3gGZNHVhgR1bgba8deMgtuFkpUNzd8iBsKvwJ
19+
```
20+
21+
You can use this in the examples below, or replace it with your own.
22+
23+
## Step 2: Create a Next.js app
24+
25+
From your terminal, run:
26+
27+
```bash
28+
npx create-next-app@latest solana-hello-frontend \
29+
--typescript \
30+
--eslint \
31+
--app \
32+
--src-dir \
33+
--tailwind \
34+
--import-alias "@/*"
35+
36+
cd solana-hello-frontend
37+
```
38+
39+
This sets up:
40+
41+
* Next.js with the App Router
42+
* TypeScript
43+
* Tailwind (optional, but nice for styling)
44+
45+
***
46+
47+
## Step 3: Install Solana web3.js and set environment variables
48+
49+
Install the Solana SDK:
50+
51+
```bash
52+
npm install @solana/web3.js
53+
```
54+
55+
Create a file called `.env` in the root of `solana-hello-frontend` folder:
56+
57+
```bash
58+
touch .env
59+
```
60+
61+
Add your Alchemy RPC URL and program ID:
62+
63+
```bash
64+
NEXT_PUBLIC_ALCHEMY_RPC_URL="https://solana-devnet.g.alchemy.com/v2/YOUR_ALCHEMY_API_KEY"
65+
NEXT_PUBLIC_PROGRAM_ID="Eq5z52U3gGZNHVhgR1bgba8deMgtuFkpUNzd8iBsKvwJ"
66+
```
67+
68+
> In a real app, replace the example program ID with the one from your own deployment.
69+
70+
## Step 4: Build a minimal client UI that pings your program
71+
72+
We’ll make the homepage (app/page.tsx) a client component that:
73+
74+
* connects a Solana wallet (e.g. Phantom)
75+
76+
* builds a transaction with an instruction calling your program
77+
78+
* sends it via Alchemy RPC
79+
80+
* shows the signature + status
81+
82+
Open `src/app/page.tsx` and replace its contents with:
83+
84+
```typescript
85+
"use client";
86+
87+
import { useState } from "react";
88+
import {
89+
Connection,
90+
PublicKey,
91+
Transaction,
92+
TransactionInstruction,
93+
} from "@solana/web3.js";
94+
95+
const RPC_URL = process.env.NEXT_PUBLIC_ALCHEMY_RPC_URL as string;
96+
const PROGRAM_ID = process.env.NEXT_PUBLIC_PROGRAM_ID as string;
97+
98+
declare global {
99+
interface Window {
100+
solana?: any; // Phantom or compatible wallet
101+
}
102+
}
103+
104+
export default function Home() {
105+
const [walletAddress, setWalletAddress] = useState<string | null>(null);
106+
const [txSignature, setTxSignature] = useState<string | null>(null);
107+
const [status, setStatus] = useState<string | null>(null);
108+
const [loading, setLoading] = useState(false);
109+
110+
const connectWallet = async () => {
111+
try {
112+
if (!window.solana) {
113+
alert("No Solana wallet found. Please install Phantom or a compatible wallet.");
114+
return;
115+
}
116+
117+
const resp = await window.solana.connect();
118+
setWalletAddress(resp.publicKey.toString());
119+
setStatus("Wallet connected.");
120+
} catch (err) {
121+
console.error(err);
122+
setStatus("Failed to connect wallet.");
123+
}
124+
};
125+
126+
const pingProgram = async () => {
127+
if (!walletAddress) {
128+
setStatus("Connect your wallet first.");
129+
return;
130+
}
131+
132+
if (!RPC_URL || !PROGRAM_ID) {
133+
setStatus("Missing RPC URL or PROGRAM_ID env vars.");
134+
return;
135+
}
136+
137+
try {
138+
setLoading(true);
139+
setStatus("Sending transaction...");
140+
setTxSignature(null);
141+
142+
const connection = new Connection(RPC_URL, "confirmed");
143+
const provider = window.solana;
144+
145+
const programId = new PublicKey(PROGRAM_ID);
146+
const userPublicKey = new PublicKey(walletAddress);
147+
148+
// Build an instruction that calls your Hello World program
149+
const instruction = new TransactionInstruction({
150+
programId,
151+
keys: [
152+
{
153+
pubkey: userPublicKey,
154+
isSigner: true,
155+
isWritable: false,
156+
},
157+
],
158+
// Your Hello World program ignores instruction data, so this can be empty
159+
data: Buffer.from([]),
160+
});
161+
162+
const transaction = new Transaction().add(instruction);
163+
164+
// Set fee payer and recent blockhash
165+
transaction.feePayer = userPublicKey;
166+
const latestBlockhash = await connection.getLatestBlockhash();
167+
transaction.recentBlockhash = latestBlockhash.blockhash;
168+
169+
// Ask the wallet to sign the transaction
170+
const signedTx = await provider.signTransaction(transaction);
171+
172+
// Send to the network through Alchemy RPC
173+
const signature = await connection.sendRawTransaction(signedTx.serialize());
174+
setTxSignature(signature);
175+
setStatus("Transaction sent. Waiting for confirmation...");
176+
177+
// Wait for confirmation
178+
await connection.confirmTransaction(
179+
{
180+
signature,
181+
blockhash: latestBlockhash.blockhash,
182+
lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,
183+
},
184+
"confirmed"
185+
);
186+
187+
setStatus("✅ Success! Your program was invoked.");
188+
} catch (err) {
189+
console.error(err);
190+
setStatus("❌ Error sending transaction. Check the browser console for details.");
191+
} finally {
192+
setLoading(false);
193+
}
194+
};
195+
196+
return (
197+
<main className="min-h-screen flex items-center justify-center bg-slate-950 text-slate-100">
198+
<div className="w-full max-w-md rounded-2xl border border-slate-800 bg-slate-900/70 p-6 shadow-xl">
199+
<h1 className="mb-2 text-xl font-semibold">
200+
Solana Hello World 👋
201+
</h1>
202+
<p className="mb-4 text-sm text-slate-400">
203+
Connect your wallet and ping your on-chain Hello World program on{" "}
204+
<span className="font-semibold text-slate-100">devnet</span> using Alchemy RPC.
205+
</p>
206+
207+
{!walletAddress ? (
208+
<button
209+
onClick={connectWallet}
210+
className="mb-3 w-full rounded-xl bg-indigo-500 px-4 py-2 text-sm font-semibold text-white hover:bg-indigo-600 transition"
211+
>
212+
Connect Wallet
213+
</button>
214+
) : (
215+
<>
216+
<div className="mb-3 text-xs text-slate-400 break-all">
217+
Connected:{" "}
218+
<span className="text-slate-100">{walletAddress}</span>
219+
</div>
220+
<button
221+
onClick={pingProgram}
222+
disabled={loading}
223+
className={`mb-3 w-full rounded-xl px-4 py-2 text-sm font-semibold text-white transition ${
224+
loading
225+
? "bg-slate-600 cursor-default"
226+
: "bg-emerald-500 hover:bg-emerald-600"
227+
}`}
228+
>
229+
{loading ? "Sending..." : "Ping Program"}
230+
</button>
231+
</>
232+
)}
233+
234+
{status && (
235+
<p className="mb-2 text-sm text-slate-200">
236+
{status}
237+
</p>
238+
)}
239+
240+
{txSignature && (
241+
<p className="text-xs text-slate-400 break-all">
242+
Tx Signature:{" "}
243+
<a
244+
href={`https://explorer.solana.com/tx/${txSignature}?cluster=devnet`}
245+
target="_blank"
246+
rel="noreferrer"
247+
className="text-sky-400 underline underline-offset-2"
248+
>
249+
View on Solana Explorer
250+
</a>
251+
</p>
252+
)}
253+
</div>
254+
</main>
255+
);
256+
}
257+
```
258+
259+
## Step 5: Run the Next.js app
260+
261+
```bash
262+
npm run dev
263+
```
264+
265+
# 🎉 Success
266+
267+
You now have a working Solana program deployed on Solana devnet!
268+
269+
Check out the next guide on how to:
270+
271+
1. set up a frontend for this program
272+
2. invoke it using Alchemy 🚀

0 commit comments

Comments
 (0)