Actions (the spec)
Standardized HTTP endpoints that produce Solana transactions for wallets and Blinks.
Search across all documentation pages
Standardized HTTP endpoints that produce Solana transactions for wallets and Blinks.
GET /action-info → metadata (title, icon, description)
POST /action-execute → transaction for connected accountWhen to reach for this:
import { NextResponse } from "next/server";
export async function GET() {
return NextResponse.json({
type: "action",
icon: "https://example.com/icon.png",
title: "Vote on Proposal 1",
description: "Cast your governance vote",
label: "Vote",
});
}
export async function POST(req: Request) {
const { account } = await req.json();
if (!account) return NextResponse.json({ error: "missing account" }, { status: 400 });
// build and return { transaction: "<base64>" }
return NextResponse.json({ transaction: "BASE64_TX" });
}What this demonstrates:
| Field | Purpose |
|---|---|
| title | Card headline |
| icon | HTTPS image URL |
| label | Button text |
| transaction | Base64 wire tx |
| Alternative | Use When | Don't Use When |
|---|---|---|
| Deep link only | Single wallet integration | Cross-platform Blinks |
| In-app browser dApp | Full UX control | Viral share campaigns |
Providers in client layout.tsx; pages mix server + client components.
Server env only for keypairs; NEXT_PUBLIC_ for RPC URLs.
All examples use @solana/kit, not web3.js v1.
Signing only in client components.
Revalidate on-chain reads carefully - chain is source of truth.
HTTPS endpoints returning Solana Actions JSON.
Separate React Native app with MWA.
Surfpool for integration; mock RPC in unit tests.
Separate env files and program IDs.
Decode simulation logs for user-facing messages.
Stack versions: This page was written for Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0, and LiteSVM 0.6.x.
Reviewed by Chris St. John·Last updated Jul 19, 2026