Solana Processor

The SolanaPaymentProcessor handles all Solana blockchain operations for X402 payments.

Overview

The processor handles:

  • Creating payment transactions

  • Signing and broadcasting transactions

  • Verifying payments on-chain

  • Getting token balances

  • Managing associated token accounts

Creating a Processor

import { SolanaPaymentProcessor } from '@shade402/core';
import { Keypair } from '@solana/web3.js';

const processor = new SolanaPaymentProcessor(
  'https://api.devnet.solana.com',
  walletKeypair, // Optional: for signing
  {
    defaultDecimals: 6, // Default token decimals
    memo: 'X402 payment', // Optional memo
  }
);

Creating Payment Transactions

const transaction = await processor.createPaymentTransaction(
  paymentRequest,
  '0.01', // Amount to pay
  payerKeypair,
  6, // Token decimals (optional, uses default if not provided)
  {
    memo: 'Custom memo', // Optional memo
  }
);

The processor:

  • Validates the payment request

  • Checks expiration

  • Validates amount doesn't exceed maximum

  • Creates associated token accounts if needed

  • Creates transfer instruction

  • Adds memo instruction if provided

Signing and Broadcasting

const txHash = await processor.signAndSendTransaction(
  transaction,
  keypair
);

console.log('Transaction hash:', txHash);

Verifying Payments

Verify that a payment transaction exists and is valid on-chain:

const isValid = await processor.verifyPayment(
  paymentRequest,
  authorization
);

if (!isValid) {
  throw new Error('Payment verification failed');
}

Verification checks:

  • Transaction exists on blockchain

  • Transaction signature is valid

  • Transaction is confirmed

  • Payment details match

Getting Token Balance

const balance = await processor.getTokenBalance(
  walletPublicKey,
  tokenMint
);

console.log('Balance:', balance); // Returns balance as number

Associated Token Accounts

The processor automatically handles associated token accounts:

  • Creates payer's token account if it doesn't exist

  • Creates recipient's token account if it doesn't exist

  • Pays for account creation fees

Complete Example

import { SolanaPaymentProcessor } from '@shade402/core';
import { Keypair } from '@solana/web3.js';

async function makePayment(
  paymentRequest: PaymentRequest,
  amount: string,
  wallet: Keypair
) {
  const processor = new SolanaPaymentProcessor(
    process.env.SOLANA_RPC_URL!,
    wallet,
    {
      defaultDecimals: 6,
      memo: 'X402 payment',
    }
  );

  try {
    // Check balance
    const balance = await processor.getTokenBalance(
      wallet.publicKey,
      paymentRequest.assetAddress
    );
    
    if (balance < parseFloat(amount)) {
      throw new Error('Insufficient balance');
    }

    // Create transaction
    const transaction = await processor.createPaymentTransaction(
      paymentRequest,
      amount,
      wallet
    );

    // Sign and broadcast
    const txHash = await processor.signAndSendTransaction(
      transaction,
      wallet
    );

    console.log('Payment successful:', txHash);
    return txHash;
  } finally {
    await processor.close();
  }
}

Error Handling

The processor throws specific errors:

import {
  InvalidPaymentRequestError,
  TransactionBroadcastError,
  PaymentVerificationError,
} from '@shade402/core';

try {
  const tx = await processor.createPaymentTransaction(request, amount, wallet);
} catch (error) {
  if (error instanceof InvalidPaymentRequestError) {
    console.error('Invalid payment request:', error.message);
  } else if (error instanceof TransactionBroadcastError) {
    console.error('Transaction broadcast failed:', error.message);
  }
}

Configuration Options

interface SolanaPaymentProcessorOptions {
  defaultDecimals?: number; // Default token decimals (default: 6)
  memo?: string;            // Optional memo text
}

Cleanup

Always close the processor to cleanup connections:

try {
  // Use processor
} finally {
  await processor.close();
}

Best Practices

  1. Reuse processor instance for multiple transactions

  2. Always close processor when done

  3. Handle errors appropriately

  4. Check balance before creating transaction

  5. Use appropriate RPC endpoint for network

  6. Monitor transaction status

  7. Retry failed transactions

Next Steps

Last updated