Code Examples

Real-world examples for integrating x402Tele

Complete 402 Flow

Full implementation of the HTTP 402 payment handshake:

async function executeCommand(
  botId: string,
  command: string,
  args: any,
  userId: string
) {
  const idempotencyKey = crypto.randomUUID();
  const endpoint = `/api/v1/bots/${botId}/commands/${command}`;

  let response = await fetch(endpoint, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Idempotency-Key': idempotencyKey,
    },
    body: JSON.stringify({ args, user_id: userId }),
  });

  if (response.status === 402) {
    const price = response.headers.get('X-402-Price');
    const currency = response.headers.get('X-402-Currency');
    const nonce = response.headers.get('X-402-Nonce');

    console.log(`Payment required: ${price} ${currency}`);

    // Approve payment (implement your payment logic)
    await approvePayment(nonce, parseFloat(price));

    // Retry with same idempotency key
    response = await fetch(endpoint, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Idempotency-Key': idempotencyKey,
        'X-402-Nonce': nonce,
      },
      body: JSON.stringify({ args, user_id: userId }),
    });
  }

  if (!response.ok) {
    throw new Error(`HTTP ${response.status}: ${await response.text()}`);
  }

  return response.json();
}

Telegram Bot with Error Handling

import { Telegraf } from 'telegraf';

const bot = new Telegraf(process.env.BOT_TOKEN!);

bot.command('analyze', async (ctx) => {
  const symbol = ctx.message.text.split(' ')[1];
  
  if (!symbol) {
    return ctx.reply('Usage: /analyze <symbol>');
  }

  try {
    const result = await executeCommand(
      'mybot',
      'analyze',
      { q: symbol },
      `tg:${ctx.from.id}`
    );

    await ctx.reply(
      `Analysis for ${symbol}:\n${JSON.stringify(result.result, null, 2)}`
    );
  } catch (error) {
    if (error.message.includes('402')) {
      await ctx.reply('Payment required. Please approve payment to continue.');
    } else if (error.message.includes('Insufficient budget')) {
      await ctx.reply('Insufficient budget. Please add funds.');
    } else {
      await ctx.reply('An error occurred. Please try again.');
      console.error('Command error:', error);
    }
  }
});

Batch Processing with Budget

async function processBatch(items: string[], budget: number) {
  let spent = 0;
  const results = [];

  for (const item of items) {
    if (spent >= budget) {
      console.log('Budget exhausted');
      break;
    }

    try {
      const result = await executeCommand('mybot', 'analyze', { q: item }, 'batch:001');
      
      const cost = result.receipt.amount;
      spent += cost;
      
      results.push({
        item,
        result: result.result,
        cost,
      });
      
      console.log(`Processed ${item}: ${cost} USDC (total: ${spent})`);
    } catch (error) {
      console.error(`Failed to process ${item}:`, error);
    }
  }

  return {
    results,
    totalSpent: spent,
    remainingBudget: budget - spent,
  };
}

// Use it
const { results, totalSpent } = await processBatch(
  ['BTC', 'ETH', 'SOL'],
  1.0 // $1 budget
);

Webhook Handler

import express from 'express';
import crypto from 'crypto';

const app = express();
app.use(express.json());

app.post('/webhook', (req, res) => {
  const signature = req.headers['x-webhook-signature'];
  const payload = JSON.stringify(req.body);

  // Verify signature
  const expected = crypto
    .createHmac('sha256', WEBHOOK_SECRET)
    .update(payload)
    .digest('hex');

  if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
    return res.status(401).send('Invalid signature');
  }

  const event = req.body;

  // Handle event
  switch (event.type) {
    case 'payment.succeeded':
      console.log('Payment received:', event.data.receipt);
      // Update user balance, send notification, etc.
      break;
    
    case 'payment.failed':
      console.log('Payment failed:', event.data);
      // Handle failure
      break;
  }

  res.status(200).send('OK');
});

Time-Pass Key Implementation

// Issue a time-pass key
async function issueTimePass(userId: string) {
  const response = await fetch('/api/v1/keys', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      command: 'premium-daily',
      user_id: userId,
    }),
  });

  const key = await response.json();
  console.log(`Key issued: ${key.key}`);
  console.log(`Expires: ${key.expires_at}`);
  
  return key;
}

// Use the key
async function useTimePass(key: string, command: string) {
  const response = await fetch(`/api/v1/commands/${command}`, {
    method: 'POST',
    headers: {
      'X-TimePass-Key': key,
    },
    body: JSON.stringify({ args: {} }),
  });

  return response.json();
}

Full Example Files

Complete Examples

Complete example implementations are available in the examples directory:

  • headless-agent.ts - Autonomous agent with budget management
  • telegram-bot.ts - Full Telegram bot integration