跳转到主要内容

参数

pubkey
string
必填
接收空投的账户公钥(base-58 编码)
lamports
number
必填
请求的 lamports 数量(1 SOL = 1,000,000,000 lamports)
config
object
包含以下内容的配置对象:
commitment
string
Commitment 级别(processed、confirmed、finalized)

响应

result
string
空投的交易签名(base-58 编码)

代码示例

基本请求

curl https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY -X POST -H "Content-Type: application/json" -d '{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "requestAirdrop",
  "params": [
    "83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri",
    1000000000
  ]
}'

使用 web3.js

import { Connection, PublicKey } from '@solana/web3.js';

const connection = new Connection('https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY');

// Request airdrop
const signature = await connection.requestAirdrop(
  new PublicKey('83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri'),
  1000000000 // 1 SOL
);
console.log('Airdrop signature:', signature);

// Request airdrop with confirmation
async function requestAirdropWithConfirmation(
  pubkey: string,
  lamports: number,
  config: { commitment?: string }
) {
  const signature = await connection.requestAirdrop(
    new PublicKey(pubkey),
    lamports,
    config
  );
  
  // Wait for confirmation
  const confirmation = await connection.confirmTransaction(signature);
  
  return {
    signature,
    confirmation: {
      status: confirmation.value.err ? 'failed' : 'success',
      slot: confirmation.context.slot
    },
    request: {
      pubkey,
      lamports,
      formatted: lamports / 1e9 + ' SOL'
    },
    metadata: {
      timestamp: Date.now(),
      commitment: config.commitment
    }
  };
}

注意事项

  1. 向 Solana 账户请求空投 SOL
  2. 仅在测试网络(devnet、testnet)上可用
  3. 响应是交易签名
  4. 交易必须被确认后资金才可用
  5. 金额根据网络配置有限制

最佳实践

  1. 根据需求使用适当的 commitment 级别
  2. 在继续之前等待交易确认
  3. 处理速率限制和网络错误
  4. 考虑使用水龙头服务获取更大金额
  5. 监控交易状态以检测失败

常见错误

错误码消息解决方案
-32601Method not found验证是否连接到测试网络
-32602Invalid params检查公钥格式和 lamports 数量
-32003Transaction simulation failed金额可能超出限制或账户可能无效

用例

  1. 空投管理
    interface AirdropRequest {
      request: {
        pubkey: string;
        lamports: number;
        formatted: string;
      };
      transaction: {
        signature: string;
        status: 'pending' | 'success' | 'failed';
        confirmations: number;
      };
      metadata: {
        timestamp: number;
        network: string;
        commitment?: string;
      };
    }
    
    class AirdropManager {
      private readonly maxRetries = 3;
      private readonly confirmationTimeout = 30000; // 30 seconds
      
      async requestAirdrop(
        pubkey: string,
        lamports: number,
        config: { commitment?: string }
      ): Promise<AirdropRequest> {
        let retries = 0;
        let signature: string;
        
        while (retries < this.maxRetries) {
          try {
            signature = await connection.requestAirdrop(
              new PublicKey(pubkey),
              lamports,
              config
            );
            
            // Wait for confirmation
            const confirmation = await connection.confirmTransaction(signature, config.commitment);
            
            if (!confirmation.value.err) {
              return {
                request: {
                  pubkey,
                  lamports,
                  formatted: lamports / 1e9 + ' SOL'
                },
                transaction: {
                  signature,
                  status: 'success',
                  confirmations: 1
                },
                metadata: {
                  timestamp: Date.now(),
                  network: connection.rpcEndpoint,
                  commitment: config.commitment
                }
              };
            }
          } catch (error) {
            retries++;
            if (retries === this.maxRetries) {
              throw error;
            }
            await new Promise(resolve => setTimeout(resolve, 1000));
          }
        }
      }
    }
    
  2. 空投监控
    interface AirdropStatus {
      request: {
        pubkey: string;
        lamports: number;
      };
      status: {
        signature: string;
        confirmations: number;
        slot: number;
      };
      history: Array<{
        timestamp: number;
        status: string;
        confirmations: number;
      }>;
    }
    
    class AirdropMonitor {
      private requests: Map<string, AirdropStatus> = new Map();
      
      async monitorAirdrop(
        signature: string,
        request: {
          pubkey: string;
          lamports: number;
        }
      ): Promise<AirdropStatus> {
        let status = this.requests.get(signature);
        const now = Date.now();
        
        const confirmation = await connection.getSignatureStatus(signature);
        
        if (!status) {
          status = {
            request,
            status: {
              signature,
              confirmations: confirmation?.confirmations || 0,
              slot: confirmation?.slot || 0
            },
            history: [{
              timestamp: now,
              status: confirmation ? 'confirmed' : 'pending',
              confirmations: confirmation?.confirmations || 0
            }]
          };
        } else {
          status.status.confirmations = confirmation?.confirmations || 0;
          status.status.slot = confirmation?.slot || 0;
          status.history.push({
            timestamp: now,
            status: confirmation ? 'confirmed' : 'pending',
            confirmations: confirmation?.confirmations || 0
          });
        }
        
        this.requests.set(signature, status);
        return status;
      }
    }
    
  3. 空投规划
    interface AirdropPlan {
      request: {
        pubkey: string;
        lamports: number;
        formatted: string;
      };
      recommendations: Array<{
        type: 'proceed' | 'split' | 'abort';
        reason: string;
      }>;
      metadata: {
        timestamp: number;
      };
    }
    
    class AirdropPlanner {
      private readonly maxAirdrop = 2000000000; // 2 SOL
      private readonly minAirdrop = 100000; // 0.0001 SOL
      
      async planAirdrop(
        pubkey: string,
        lamports: number
      ): Promise<AirdropPlan> {
        const recommendations: Array<{
          type: 'proceed' | 'split' | 'abort';
          reason: string;
        }> = [];
        
        if (lamports > this.maxAirdrop) {
          recommendations.push({
            type: 'split',
            reason: `Amount ${lamports} exceeds maximum airdrop of ${this.maxAirdrop}`
          });
        } else if (lamports < this.minAirdrop) {
          recommendations.push({
            type: 'abort',
            reason: `Amount ${lamports} is below minimum airdrop of ${this.minAirdrop}`
          });
        } else {
          recommendations.push({
            type: 'proceed',
            reason: 'Amount is within valid range'
          });
        }
        
        return {
          request: {
            pubkey,
            lamports,
            formatted: lamports / 1e9 + ' SOL'
          },
          recommendations,
          metadata: {
            timestamp: Date.now()
          }
        };
      }
      
      async splitAirdrop(
        pubkey: string,
        totalLamports: number
      ): Promise<Array<{
        lamports: number;
        delay: number;
      }>> {
        const chunks: Array<{
          lamports: number;
          delay: number;
        }> = [];
        
        let remaining = totalLamports;
        let delay = 0;
        
        while (remaining > 0) {
          const chunk = Math.min(remaining, this.maxAirdrop);
          chunks.push({
            lamports: chunk,
            delay
          });
          
          remaining -= chunk;
          delay += 2000; // 2 seconds between requests
        }
        
        return chunks;
      }
    }