Skip to content

Repository files navigation

Solana Donation Blink

Una demo pequeña y didáctica para entender cómo funcionan Solana Actions + Blinks sin comenzar desde un scaffold enorme ni desplegar un programa personalizado.

La aplicación crea una Action que prepara una transferencia de 0.001 SOL en Devnet. El usuario revisa la transacción, la firma con Phantom y la envía a Solana.

Esta demo fue preparada para el trayecto de incubación de WayLearn.

¿Qué estamos construyendo?

El proyecto tiene tres piezas principales:

  1. Una Solana Action que responde con metadata mediante GET.
  2. Un endpoint POST que construye una transferencia de SOL sin firmar.
  3. Una página /donate que funciona como cliente sencillo para conectar Phantom, firmar y enviar la transacción.

El flujo completo es:

Usuario abre /donate
        ↓
GET /api/actions/donate
        ↓
Se muestra la metadata de la Action
        ↓
Usuario presiona "Donate 0.001 SOL"
        ↓
POST /api/actions/donate
        ↓
El backend construye una transacción sin firmar
        ↓
Phantom muestra el preview y solicita autorización
        ↓
El usuario firma y la transacción se envía a Devnet

Demo desplegada

¿Necesitamos un smart contract?

No para esta demo.

La transferencia utiliza SystemProgram.transfer, una instrucción del System Program nativo de Solana. Nuestro backend solamente construye la transacción; Phantom conserva la private key, solicita la firma y envía la operación.

Esto permite concentrarnos primero en el ciclo de vida de Actions y Blinks:

GET → metadata
POST → transacción
Wallet → firma
Devnet → ejecución

Requisitos

Antes de comenzar necesitas:

  • Node.js 20.9 o superior.
  • npm.
  • Git.
  • Phantom instalado en el navegador.
  • Testnet Mode activado en Phantom.
  • Un poco de SOL de Devnet en la wallet que firmará.
  • Una dirección pública de Solana que recibirá la donación.

No agregues una seed phrase ni una private key al proyecto. DONATION_WALLET contiene únicamente una dirección pública.

Clonar y ejecutar el proyecto

Clona el repositorio:

git clone <URL-DE-ESTE-REPOSITORIO>
cd solana-donation-blink

Instala las dependencias:

npm install

Crea el archivo de variables locales:

cp .env.example .env.local

Edita .env.local:

DONATION_WALLET=PEGA_AQUI_LA_DIRECCION_PUBLICA_RECEPTORA

Inicia el servidor:

npm run dev

Abre en el navegador:

http://localhost:3000/donate

Archivo .env.example

El repositorio debería incluir un archivo .env.example como este:

DONATION_WALLET=REPLACE_WITH_A_DEVNET_PUBLIC_ADDRESS

La dirección receptora puede pertenecer a Phantom, Solana Playground o cualquier otra wallet de Solana. Para ver claramente el movimiento de fondos, conviene que sea distinta de la wallet que firmará.

Rutas importantes

Ruta Propósito
/donate Cliente web para probar la donación con Phantom
/api/actions/donate Endpoint GET y POST de la Solana Action
/actions.json Mapea una URL normal hacia la Action
/donation.svg Imagen utilizada por la metadata de la Action

Probar el GET

El GET devuelve la información necesaria para que un cliente Blink construya su interfaz:

curl -i http://localhost:3000/api/actions/donate

La respuesta debe incluir datos similares a:

{
  "type": "action",
  "icon": "http://localhost:3000/donation.svg",
  "title": "Support the WayLearn demo",
  "description": "Donate 0.001 devnet SOL and see how a Solana Action becomes a Blink.",
  "label": "Donate 0.001 SOL"
}

En esta etapa todavía no se ha construido ni enviado ninguna transacción.

Probar CORS y OPTIONS

Los clientes Blink pueden enviar una petición OPTIONS antes de consumir la Action:

curl -i -X OPTIONS \
  http://localhost:3000/api/actions/donate

También puedes revisar actions.json:

curl -i http://localhost:3000/actions.json

Busca un header como este:

Access-Control-Allow-Origin: *

Probar manualmente el POST

Define la dirección pública de la wallet que actuaría como sender:

export SENDER_WALLET="PEGA_AQUI_LA_DIRECCION_PUBLICA"

Ejecuta el POST:

curl -i \
  -X POST \
  http://localhost:3000/api/actions/donate \
  -H "Content-Type: application/json" \
  --data "{\"type\":\"transaction\",\"account\":\"$SENDER_WALLET\"}"

La respuesta incluirá una transacción serializada:

{
  "type": "transaction",
  "transaction": "AQAAAAAAAAAAAAAAAA...",
  "message": "Thanks! You are donating 0.001 devnet SOL."
}

Esto no envía la donación. El endpoint solamente construye la transacción. Todavía falta que una wallet la revise, firme y envíe.

Probar la donación con Phantom

  1. Abre Phantom.
  2. Entra a Settings.
  3. Abre Developer Settings.
  4. Activa Testnet Mode.
  5. Confirma que la cuenta tenga SOL de Devnet.
  6. Abre http://localhost:3000/donate.
  7. Presiona Donate 0.001 SOL.
  8. Conecta Phantom.
  9. Revisa el preview de la transacción.
  10. Aprueba la firma.

Al terminar, la página mostrará un enlace hacia Solana Explorer usando cluster=devnet.

La wallet que firma necesita saldo suficiente para:

  • Transferir 0.001 SOL.
  • Pagar la comisión de red.

Conseguir SOL de Devnet

Puedes usar el faucet oficial:

https://faucet.solana.com

Con Solana CLI también puedes solicitar un airdrop:

solana airdrop 2 TU_DIRECCION_PUBLICA --url devnet

El SOL de Devnet no tiene valor real y se utiliza únicamente para desarrollo y pruebas.

Validar el build

Antes de desplegar, ejecuta:

npm run build

Si el build termina correctamente, el proyecto está listo para desplegarse.

Desplegar en Vercel

Instala o ejecuta la CLI de Vercel:

npx vercel login

Vincula la carpeta con un proyecto de Vercel:

npx vercel link

Agrega la dirección receptora al ambiente de producción:

npx vercel env add DONATION_WALLET production

Cuando la CLI lo solicite, pega únicamente la dirección pública.

Despliega a producción:

npx vercel --prod

Cada cambio en una variable de entorno requiere un deployment nuevo para que se aplique:

npx vercel --prod

También puedes conectar el repositorio a Vercel y dejar que cada push a la rama principal genere un deployment automáticamente.

Probar con Blink Inspector

El Inspector permite comprobar:

  • La existencia y estructura de actions.json.
  • Los headers CORS.
  • El código HTTP.
  • El mapeo desde /donate hacia la Action.
  • La respuesta del GET.
  • La respuesta del POST.
  • Los botones y parámetros declarados por la Action.

Actualmente el Inspector puede ejecutarse localmente desde su repositorio:

git clone https://github.com/solana-developers/blinks-xyz.git
cd blinks-xyz
npm install
npm run dev

Abre:

http://localhost:3000/inspector

Pega una de estas URLs:

https://solana-donation-blink.vercel.app/donate

o la Action directa:

https://solana-donation-blink.vercel.app/api/actions/donate

Usar /donate también comprueba que actions.json pueda detectar la página y mapearla hacia /api/actions/donate.

Ejecutar la aplicación y el Inspector localmente

Si la aplicación ya usa el puerto 3000, inicia el Inspector en el puerto 3001:

npm run dev -- -p 3001

Después abre:

http://localhost:3001/inspector

Y prueba:

http://localhost:3000/donate

El Inspector valida la especificación y permite probar las respuestas de la API. La firma real sigue requiriendo un cliente con integración de wallet, como la página /donate incluida en este proyecto.

¿Qué hace actions.json?

Un navegador común entiende esta URL:

https://example.com/donate

Pero un cliente Blink necesita saber cuál es el endpoint de la Action. actions.json crea el mapeo:

/donate → /api/actions/donate

También incluye una regla idempotente para reconocer directamente las rutas bajo:

/api/actions/**

El archivo debe estar disponible en la raíz del dominio:

https://example.com/actions.json

y responder con headers CORS tanto para GET como para OPTIONS.

Estructura principal

solana-donation-blink/
├── public/
│   └── donation.svg
├── src/
│   └── app/
│       ├── actions.json/
│       │   └── route.ts
│       ├── api/
│       │   └── actions/
│       │       └── donate/
│       │           └── route.ts
│       ├── donate/
│       │   └── page.tsx
│       └── page.tsx
├── .env.example
└── README.md

Problemas comunes

DONATION_WALLET is not configured

Crea .env.local o agrega la variable en Vercel:

npx vercel env add DONATION_WALLET production
npx vercel --prod

Phantom no aparece

Comprueba que:

  • La extensión esté instalada y habilitada.
  • La página se abra desde localhost o mediante HTTPS.
  • Phantom no esté bloqueado para ese sitio.

Phantom muestra Mainnet

Activa Testnet Mode desde las opciones de desarrollador de Phantom.

Insufficient funds

La wallet sender necesita SOL de Devnet para la cantidad enviada y la comisión.

El Inspector marca error de CORS

Revisa:

curl -i -X OPTIONS \
  https://TU-DOMINIO/api/actions/donate

y:

curl -i \
  https://TU-DOMINIO/actions.json

Ambos deben permitir peticiones cross-origin.

La imagen no aparece

Abre directamente:

https://TU-DOMINIO/donation.svg

El valor de icon en el GET debe ser una URL absoluta.

La transacción expiró

Vuelve a presionar el botón. El backend generará una transacción nueva con un blockhash reciente.

Sender y recipient muestran el mismo balance

Usa dos direcciones distintas para que el cambio sea fácil de observar durante la demo.

Ideas para continuar

Una vez entendido este ejemplo, se puede extender para:

  • Elegir la cantidad de SOL.
  • Donar un token SPL.
  • Agregar varias acciones o botones.
  • Recibir parámetros del usuario.
  • Registrar una donación mediante un programa de Anchor.
  • Votar por un proyecto incubado.
  • Reclamar una insignia on-chain.
  • Encadenar varias Actions.

Recursos

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages