Skip to content

Commit a388439

Browse files
authored
Add Solana facilitator guide to docs (#8511)
1 parent 7b873d3 commit a388439

File tree

2 files changed

+177
-0
lines changed

2 files changed

+177
-0
lines changed
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
import { Callout, createMetadata } from "@doc";
2+
3+
export const metadata = createMetadata({
4+
image: {
5+
title: "Solana Facilitator",
6+
icon: "solana",
7+
},
8+
title: "Solana Facilitator",
9+
description: "Verify and settle Solana transactions through your own facilitator wallets.",
10+
});
11+
12+
# Solana Facilitator
13+
14+
Solana is now a supported network for x402 payments. You can gate, verify, and settle Solana transactions through your own facilitator wallets — fully end-to-end.
15+
16+
<Callout variant="info" title="Supported Networks">
17+
We support Solana Mainnet and Devnet. Use the following network identifiers:
18+
19+
- **Mainnet**: `solana:mainnet`
20+
- **Devnet**: `solana:devnet`
21+
</Callout>
22+
23+
This enables you to spin up your own server wallet, prepare payment payloads, and handle verification + settlement directly on Solana (devnet or mainnet). No middle layers. No bloat.
24+
25+
## Features
26+
27+
- **Solana facilitator flow** — create or register a Solana server wallet, quote pricing with `/v1/payments/x402/accepts`, and settle signed transactions with `/v1/payments/x402/settle`.
28+
- **Unified verify path**`/v1/payments/x402/verify` now validates Solana payloads the same way it does for EVM, so you can reuse your middleware checks across chains.
29+
- **End-to-end examples** — refreshed snippets for Node environments that show the exact headers, payloads, and success envelopes you should expect in production.
30+
31+
## Fast Start Guide
32+
33+
### 1. Create a facilitator wallet
34+
35+
First, create a server-side wallet that will act as the facilitator.
36+
37+
```ts
38+
const response = await fetch("https://api.thirdweb.com/v1/solana/wallets", {
39+
method: "POST",
40+
headers: {
41+
"x-secret-key": "YOUR_SECRET_KEY",
42+
"Content-Type": "application/json",
43+
},
44+
body: JSON.stringify({
45+
label: "my-solana-facilitator",
46+
}),
47+
});
48+
49+
const wallet = await response.json();
50+
console.log(wallet.result.address);
51+
```
52+
53+
The returned address is the server-side payer for settles, so double-check that it appears in your project’s server wallet list.
54+
55+
<Callout variant="info">
56+
**Fund the wallet:** Top up SOL for fees on the target cluster (devnet or mainnet-beta).
57+
</Callout>
58+
59+
### 2. Quote access
60+
61+
Use `/v1/payments/x402/accepts` to generate the payment requirements.
62+
63+
```ts
64+
const acceptsResponse = await fetch(
65+
"https://api.thirdweb.com/v1/payments/x402/accepts",
66+
{
67+
method: "POST",
68+
headers: {
69+
"x-secret-key": "YOUR_SECRET_KEY",
70+
"Content-Type": "application/json",
71+
},
72+
body: JSON.stringify({
73+
resourceUrl: "https://example.com/solana-protected",
74+
method: "POST",
75+
network: "solana:devnet",
76+
price: {
77+
amount: "0",
78+
asset: {
79+
address: "So11111111111111111111111111111111111111112",
80+
decimals: 9,
81+
tokenProgram: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
82+
},
83+
},
84+
serverWalletAddress: "YOUR_SOLANA_FACILITATOR_ADDRESS",
85+
}),
86+
}
87+
);
88+
89+
const { accepts } = await acceptsResponse.json();
90+
const paymentRequirements = accepts[0];
91+
```
92+
93+
Keep `paymentRequirements` around—clients will sign against it, and the facilitator will reuse it when settling.
94+
95+
### 3. Verify before you settle
96+
97+
Once you have the signed payment payload from the client, you can verify it.
98+
99+
```ts
100+
const verifyResponse = await fetch(
101+
"https://api.thirdweb.com/v1/payments/x402/verify",
102+
{
103+
method: "POST",
104+
headers: {
105+
"x-secret-key": "YOUR_SECRET_KEY",
106+
"Content-Type": "application/json",
107+
},
108+
body: JSON.stringify({
109+
paymentPayload: SIGNED_PAYMENT_PAYLOAD,
110+
paymentRequirements,
111+
}),
112+
}
113+
);
114+
115+
const verifyData = await verifyResponse.json();
116+
console.log(verifyData.isValid);
117+
```
118+
119+
A truthy `isValid` means the signatures, blockhash, and amounts all check out.
120+
121+
### 4. Settle on-chain
122+
123+
Settle the transaction using your facilitator wallet.
124+
125+
```ts
126+
const settleResponse = await fetch(
127+
"https://api.thirdweb.com/v1/payments/x402/settle",
128+
{
129+
method: "POST",
130+
headers: {
131+
"x-secret-key": "YOUR_SECRET_KEY",
132+
"Content-Type": "application/json",
133+
},
134+
body: JSON.stringify({
135+
paymentPayload: SIGNED_PAYMENT_PAYLOAD,
136+
paymentRequirements,
137+
waitUntil: "submitted",
138+
}),
139+
}
140+
);
141+
142+
const settleData = await settleResponse.json();
143+
console.log(settleData.transaction);
144+
```
145+
146+
<Callout variant="info">
147+
Use `waitUntil: "confirmed"` if you need finality before responding to the client.
148+
</Callout>
149+
150+
Watch your server wallet dashboard or any Solana explorer for the transaction signature the settle endpoint returns.
151+
152+
### Fetch protected resources
153+
154+
Let payers fetch protected resources. If the client hits the protected endpoint first, have it replay the request through `/v1/payments/x402/fetch`. The API will answer with the payload you need for verification and settlement.
155+
156+
```ts
157+
const fetchResponse = await fetch(
158+
"https://api.thirdweb.com/v1/payments/x402/fetch?" +
159+
new URLSearchParams({
160+
url: "https://example.com/solana-protected",
161+
from: "PAYER_SOLANA_ADDRESS",
162+
chainId: "solana:devnet",
163+
}),
164+
{
165+
method: "POST",
166+
headers: {
167+
"x-secret-key": "YOUR_SECRET_KEY",
168+
},
169+
}
170+
);
171+
172+
const fetchData = await fetchResponse.json();
173+
```

apps/portal/src/app/x402/sidebar.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ export const sidebar: SideBar = {
3737
href: `${x402Slug}/facilitator`,
3838
name: "Facilitator",
3939
},
40+
{
41+
href: `${x402Slug}/facilitator/solana`,
42+
name: "Solana",
43+
},
4044
],
4145
name: "Guides",
4246
},

0 commit comments

Comments
 (0)