Antes de Empezar
1
Registrate en pan
Visita app.pan.tech y crea tu cuenta. El plan gratuito incluye:
- 100 wallets
- 100 créditos de API
- Acceso a testnets
No necesitas tarjeta de crédito para comenzar.
2
Obtiene tu API Key
Una vez registrado, navega a Settings > API Keys y copia tu API key.Tu API key tiene el formato:
pan_sk_ seguido de 64 caracteres hexadecimales.pan_sk_a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456
Nunca expongas tu API key en código del lado del cliente, repositorios publicos, o logs. Tratala como una contrasena.
3
Configura tu entorno
Guarda tu API key como variable de entorno:
export PAN_API_KEY="pan_sk_tu_api_key_aqui"
$env:PAN_API_KEY="pan_sk_tu_api_key_aqui"
PAN_API_KEY=pan_sk_tu_api_key_aqui
Tu Primera Llamada API
1. Crea una Wallet
Las wallets son la base de pan. Cada wallet representa un usuario en tu aplicación y soporta automáticamente todas las blockchains.curl -X POST https://api.pan.tech/v1/wallets \
-H "Authorization: Bearer $PAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"userId": "mi_primer_usuario",
"metadata": {
"nombre": "Usuario de Prueba",
"app": "mi-app"
}
}'
const response = await fetch('https://api.pan.tech/v1/wallets', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.PAN_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
userId: 'mi_primer_usuario',
metadata: {
nombre: 'Usuario de Prueba',
app: 'mi-app'
}
})
});
const wallet = await response.json();
console.log('Wallet creada:', wallet);
import os
import requests
response = requests.post(
'https://api.pan.tech/v1/wallets',
headers={
'Authorization': f"Bearer {os.getenv('PAN_API_KEY')}",
'Content-Type': 'application/json'
},
json={
'userId': 'mi_primer_usuario',
'metadata': {
'nombre': 'Usuario de Prueba',
'app': 'mi-app'
}
}
)
wallet = response.json()
print('Wallet creada:', wallet)
import { Pan } from '@pan/sdk';
const pan = new Pan({ apiKey: process.env.PAN_API_KEY });
const wallet = await pan.wallet.create({
userId: 'mi_primer_usuario',
metadata: {
nombre: 'Usuario de Prueba',
app: 'mi-app'
}
});
console.log('Wallet creada:', wallet);
{
"id": "pan_wallet_a1b2c3d4e5f6",
"userId": "mi_primer_usuario",
"address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"chainType": "ethereum",
"chains": [
"ethereum-sepolia",
"arbitrum-sepolia",
"base-sepolia"
],
"metadata": {
"nombre": "Usuario de Prueba",
"app": "mi-app"
},
"createdAt": "2024-01-15T10:30:00Z"
}
Guarda el
id de la wallet (pan_wallet_...). Lo necesitaras para todas las operaciones posteriores.2. Fondea la Wallet (Testnet)
Para probar en testnet, necesitas obtener tokens de prueba. pan ofrece un endpoint de demo para fondear wallets en testnet:curl -X POST https://api.pan.tech/v1/demo/fund \
-H "Authorization: Bearer $PAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"walletId": "pan_wallet_a1b2c3d4e5f6"
}'
const response = await fetch('https://api.pan.tech/v1/demo/fund', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.PAN_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
walletId: 'pan_wallet_a1b2c3d4e5f6'
})
});
const result = await response.json();
console.log('Fondeo:', result);
El endpoint demo/fund siempre envia 1 USDC en arbitrum-sepolia. No se puede configurar cantidad ni chain.
Tambien puedes usar faucets externos para obtener tokens de testnet:
3. Consulta el Balance
Verifica que los fondos llegaron consultando el balance de la wallet:curl -X GET "https://api.pan.tech/v1/balances/pan_wallet_a1b2c3d4e5f6" \
-H "Authorization: Bearer $PAN_API_KEY"
const response = await fetch(
'https://api.pan.tech/v1/balances/pan_wallet_a1b2c3d4e5f6',
{
headers: {
'Authorization': `Bearer ${process.env.PAN_API_KEY}`
}
}
);
const balances = await response.json();
console.log('Balances:', JSON.stringify(balances, null, 2));
const balances = await pan.wallet.getBalances('pan_wallet_a1b2c3d4e5f6');
console.log('Balances:', balances);
{
"walletId": "pan_wallet_a1b2c3d4e5f6",
"address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"chains": [
{
"chain": "arbitrum-sepolia",
"tokens": [
{
"asset": "USDC",
"balance": "1000000",
"balanceFormatted": "1.00",
"decimals": 6,
"valueUsd": 1.00
}
]
},
{
"chain": "base-sepolia",
"tokens": []
},
{
"chain": "ethereum-sepolia",
"tokens": []
}
],
"totalValueUsd": 1.00
}
4. Consulta los Mejores Yields
Antes de prestar, veamos donde conviene depositar:curl -X GET "https://api.pan.tech/v1/yields" \
-H "Authorization: Bearer $PAN_API_KEY"
const response = await fetch('https://api.pan.tech/v1/yields', {
headers: {
'Authorization': `Bearer ${process.env.PAN_API_KEY}`
}
});
const yields = await response.json();
console.log('Yields disponibles:');
yields.rates.forEach(y => {
console.log(` ${y.chain}: ${y.apy}% APY en ${y.protocol}`);
});
{
"rates": [
{
"chain": "base-sepolia",
"protocol": "aave",
"asset": "USDC",
"apy": 8.52
},
{
"chain": "arbitrum-sepolia",
"protocol": "aave",
"asset": "USDC",
"apy": 7.23
},
{
"chain": "ethereum-sepolia",
"protocol": "aave",
"asset": "USDC",
"apy": 5.15
}
],
"best": {
"chain": "base-sepolia",
"asset": "USDC",
"apy": 8.52,
"reasoning": "Highest APY available"
}
}
5. Ejecuta tu Primer Intent
Ahora viene la magia. Crea un intent de lending y pan se encargara de todo:curl -X POST https://api.pan.tech/v1/intents \
-H "Authorization: Bearer $PAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"walletId": "pan_wallet_a1b2c3d4e5f6",
"action": "lend",
"amount": 1000,
"asset": "USDC"
}'
const response = await fetch('https://api.pan.tech/v1/intents', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.PAN_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
walletId: 'pan_wallet_a1b2c3d4e5f6',
action: 'lend',
amount: 1000,
asset: 'USDC'
})
});
const intent = await response.json();
console.log('Intent creado:', intent.id);
console.log('Estado:', intent.status);
console.log('Plan de ejecución:', JSON.stringify(intent.executionPlan, null, 2));
const intent = await pan.lend({
walletId: 'pan_wallet_a1b2c3d4e5f6',
amount: 1000,
asset: 'USDC'
});
console.log('Intent creado:', intent.id);
console.log('Estado:', intent.status);
{
"id": "intent_xyz789abc123",
"walletId": "pan_wallet_a1b2c3d4e5f6",
"status": "planning",
"action": "lend",
"amount": 1,
"asset": "USDC",
"executionPlan": {
"strategy": "direct-deposit",
"steps": [
{
"type": "deposit",
"chain": "arbitrum-sepolia",
"protocol": "aave",
"asset": "USDC",
"amount": 1
}
],
"reasoning": "Direct deposit on arbitrum-sepolia with 7.23% APY"
},
"createdAt": "2024-01-15T10:40:00Z"
}
Observa el plan de ejecución: pan analiza los balances disponibles y los APYs en cada chain para determinar la estrategia optima. En este caso, como los fondos ya están en arbitrum-sepolia, usa
direct-deposit.6. Monitorea la Ejecución
Los intents se ejecutan de forma asincrona. Consulta el estado periodicamente:curl -X GET "https://api.pan.tech/v1/intents/intent_xyz789abc123" \
-H "Authorization: Bearer $PAN_API_KEY"
async function monitorearIntent(intentId) {
const maxIntentos = 60; // 5 minutos con intervalos de 5 segundos
let intentos = 0;
while (intentos < maxIntentos) {
const response = await fetch(
`https://api.pan.tech/v1/intents/${intentId}`,
{
headers: {
'Authorization': `Bearer ${process.env.PAN_API_KEY}`
}
}
);
const intent = await response.json();
console.log(`Estado: ${intent.status}`);
if (intent.status === 'completed') {
console.log('Intent completado exitosamente!');
console.log('Resultados:', JSON.stringify(intent.results, null, 2));
return intent;
}
if (intent.status === 'failed') {
console.error('Intent fallido:', intent.error);
throw new Error(intent.error.message);
}
// Mostrar progreso si está ejecutando
if (intent.status === 'executing' && intent.executionPlan) {
const completados = intent.results?.completedSteps || 0;
const total = intent.executionPlan.steps.length;
console.log(` Progreso: ${completados}/${total} pasos`);
}
// Esperar 5 segundos
await new Promise(resolve => setTimeout(resolve, 5000));
intentos++;
}
throw new Error('Timeout: el intent tardo demasiado');
}
// Usar
await monitorearIntent('intent_xyz789abc123');
// El SDK incluye helpers para monitorear
const completedIntent = await pan.waitForIntent('intent_xyz789abc123', {
pollingInterval: 5000, // 5 segundos
timeout: 300000 // 5 minutos
});
console.log('Completado:', completedIntent);
{
"id": "intent_xyz789abc123",
"walletId": "pan_wallet_a1b2c3d4e5f6",
"status": "completed",
"action": "lend",
"amount": 1,
"asset": "USDC",
"executionPlan": {
"strategy": "direct-deposit",
"steps": [...]
},
"results": {
"completedSteps": 1,
"transactions": [
{
"type": "deposit",
"txHash": "0x456def...",
"chain": "arbitrum-sepolia",
"gasUsed": "200000",
"gasCostUsd": 0.05
}
],
"totalGasUsed": "200000",
"totalGasCostUsd": 0.05,
"finalAmount": "1.00",
"apy": 7.23
},
"createdAt": "2024-01-15T10:40:00Z",
"completedAt": "2024-01-15T10:41:30Z"
}
Resumen del Flujo Completo
1. POST /v1/wallets → Crear wallet para el usuario
2. POST /v1/demo/fund → Fondear wallet (solo testnet)
3. GET /v1/balances/:id → Verificar que llegaron los fondos
4. GET /v1/yields → Ver mejores oportunidades
5. POST /v1/intents → Crear intent de lending
6. GET /v1/intents/:id → Monitorear hasta completar
Código Completo
Aqui tienes un script completo que puedes copiar y ejecutar:import 'dotenv/config';
const API_KEY = process.env.PAN_API_KEY;
const BASE_URL = 'https://api.pan.tech/v1';
async function request(method, endpoint, body = null) {
const options = {
method,
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
}
};
if (body) {
options.body = JSON.stringify(body);
}
const response = await fetch(`${BASE_URL}${endpoint}`, options);
return response.json();
}
async function main() {
console.log('=== pan API - Inicio Rápido ===\n');
// 1. Crear wallet
console.log('1. Creando wallet...');
const wallet = await request('POST', '/wallets', {
userId: `usuario_${Date.now()}`,
metadata: { app: 'inicio-rapido' }
});
console.log(` Wallet: ${wallet.id}`);
console.log(` Address: ${wallet.address}\n`);
// 2. Fondear (solo testnet)
console.log('2. Fondeando wallet...');
await request('POST', '/demo/fund', {
walletId: wallet.id
});
console.log(' Fondeo iniciado (1 USDC en arbitrum-sepolia)\n');
// Esperar un poco para que lleguen los fondos
await new Promise(r => setTimeout(r, 10000));
// 3. Consultar balance
console.log('3. Consultando balance...');
const balances = await request('GET', `/balances/${wallet.id}`);
console.log(` Total USD: $${balances.totalValueUsd}\n`);
// 4. Ver yields
console.log('4. Consultando yields...');
const yields = await request('GET', '/yields');
console.log(` Mejor APY: ${yields.best.apy}% en ${yields.best.chain}\n`);
// 5. Crear intent
console.log('5. Creando intent de lending...');
const intent = await request('POST', '/intents', {
walletId: wallet.id,
action: 'lend',
amount: 1000,
asset: 'USDC'
});
console.log(` Intent: ${intent.id}`);
console.log(` Estrategia: ${intent.executionPlan?.strategy}\n`);
// 6. Monitorear
console.log('6. Monitoreando ejecución...');
let status = intent.status;
while (status !== 'completed' && status !== 'failed') {
await new Promise(r => setTimeout(r, 5000));
const updated = await request('GET', `/intents/${intent.id}`);
status = updated.status;
console.log(` Estado: ${status}`);
}
console.log('\n=== Completado! ===');
}
main().catch(console.error);
import os
import time
import requests
API_KEY = os.environ.get('PAN_API_KEY')
BASE_URL = 'https://api.pan.tech/v1'
def request(method, endpoint, body=None):
headers = {
'Authorization': f'Bearer {API_KEY}',
'Content-Type': 'application/json'
}
if method == 'GET':
response = requests.get(f'{BASE_URL}{endpoint}', headers=headers)
else:
response = requests.post(f'{BASE_URL}{endpoint}', headers=headers, json=body)
return response.json()
def main():
print('=== pan API - Inicio Rápido ===\n')
# 1. Crear wallet
print('1. Creando wallet...')
wallet = request('POST', '/wallets', {
'userId': f'usuario_{int(time.time())}',
'metadata': {'app': 'inicio-rapido'}
})
print(f" Wallet: {wallet['id']}")
print(f" Address: {wallet['address']}\n")
# 2. Fondear
print('2. Fondeando wallet...')
request('POST', '/demo/fund', {
'walletId': wallet['id']
})
print(' Fondeo iniciado (1 USDC en arbitrum-sepolia)\n')
time.sleep(10)
# 3. Balance
print('3. Consultando balance...')
balances = request('GET', f"/balances/{wallet['id']}")
print(f" Total USD: ${balances['totalValueUsd']}\n")
# 4. Yields
print('4. Consultando yields...')
yields = request('GET', '/yields')
best = yields['best']
print(f" Mejor APY: {best['apy']}% en {best['chain']}\n")
# 5. Intent
print('5. Creando intent de lending...')
intent = request('POST', '/intents', {
'walletId': wallet['id'],
'action': 'lend',
'amount': 1000,
'asset': 'USDC'
})
print(f" Intent: {intent['id']}")
print(f" Estrategia: {intent.get('executionPlan', {}).get('strategy')}\n")
# 6. Monitorear
print('6. Monitoreando ejecución...')
status = intent['status']
while status not in ['completed', 'failed']:
time.sleep(5)
updated = request('GET', f"/intents/{intent['id']}")
status = updated['status']
print(f' Estado: {status}')
print('\n=== Completado! ===')
if __name__ == '__main__':
main()
Próximos Pasos
Autenticación
Aprende sobre API keys, X402, y mejores prácticas de seguridad
Conceptos Clave
Entiende a fondo wallets, intents y planes de ejecución
SDK de JavaScript
Usa el SDK oficial para una integración más simple
Referencia API
Documentación completa de todos los endpoints
Tokens de testnet: Recuerda que pan actualmente opera en testnets. Obtiene tokens gratuitos de los faucets para experimentar con la API.
