You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Electron(Node.js 18)应用中Casper(CSPR)余额查询端点测试失败的问题排查及可靠方案咨询

Electron(Node.js 18)应用中Casper(CSPR)余额查询端点测试失败的问题排查及可靠方案咨询

问题描述

我正在构建一个Electron应用(Node.js 18)来查询加密货币余额,其中包括Casper(CSPR)。但在尝试查询CSPR余额时,一直收到**"No working endpoints found"**错误。

错误信息

Testing available endpoints...
Testing endpoint: https://rpc.mainnet.casperlabs.io
Testing endpoint: https://casper-node.services.dev.z7x.org
// ... more endpoints ...
Endpoint https://casper-node.services.dev.z7x.org failed: getaddrinfo ENOTFOUND
Found 0 working endpoints
CSPR balance check failed: Error: No working endpoints found

相关代码

端点测试函数

async function testEndpoint(url) {
    try {
        console.log(`Testing endpoint: ${url}`);
        const response = await axios.post(`${url}/rpc`, {
            jsonrpc: "2.0",
            id: "0",
            method: "info_get_status",
            params: []
        }, {
            timeout: 10000,
            headers: { 'Content-Type': 'application/json' },
            validateStatus: status => status < 500,
            httpsAgent: new require('https').Agent({
                rejectUnauthorized: false,
                timeout: 10000
            })
        });
        
        if (response.data && !response.data.error) {
            console.log(`Endpoint ${url} is working`);
            return true;
        }
        console.log(`Endpoint ${url} returned invalid data:`, response.data);
        return false;
    } catch (error) {
        console.log(`Endpoint ${url} failed:`, error.message);
        return false;
    }
}

余额查询函数

async function getCSPRBalance(key) {
    try {
        const formattedKey = normalizePublicKey(key);
        
        const endpoints = Array.isArray(config.casper.apiUrl) 
            ? config.casper.apiUrl 
            : [config.casper.apiUrl];
        
        // Test endpoints in parallel
        const endpointTests = endpoints.map(endpoint => testEndpoint(endpoint));
        const results = await Promise.allSettled(endpointTests);
        
        const workingEndpoints = endpoints.filter((endpoint, index) => 
            results[index].status === 'fulfilled' && results[index].value === true
        );
        
        if (workingEndpoints.length === 0) {
            throw new Error('No working endpoints found');
        }

        // Try each working endpoint
        for (const baseUrl of workingEndpoints) {
            try {
                const url = `${baseUrl}/rpc`;
                const rpcKey = `01${formattedKey}`;

                const accountResponse = await axios.post(url, {
                    jsonrpc: "2.0",
                    id: "1",
                    method: "state_get_account_info",
                    params: {
                        public_key: rpcKey
                    }
                });

                // ... rest of balance checking logic ...
            } catch (endpointError) {
                // Continue to next endpoint
            }
        }
    } catch (error) {
        return {
            success: false,
            error: error.message || 'Failed to check CSPR balance',
            address: key
        };
    }
}

使用的端点列表

const endpoints = [
    'https://rpc.mainnet.casperlabs.io',
    'https://casper-node.services.dev.z7x.org',
    'https://casper-proxy.liquidstaking.com',
    'https://casper-node-proxy.dev.z7x.org',
    'https://node.casper.network.dev.z7x.org'
];

已尝试的解决方法

  • 使用不同的Casper RPC端点
  • 添加SSL/TLS错误处理
  • 实现超时和重试机制
  • 为测试禁用SSL验证

测试用公钥

0203d9f49b0d76a3f14482ab11926f0d5f792e933f3df824dc1e0b07104474c4c3b3

核心问题

  1. 有没有更可靠的Casper RPC端点可以使用?
  2. 我的端点测试方法是否存在问题?
  3. 从Electron应用向Casper节点发起RPC调用有什么需要特别注意的地方?

环境

  • Electron
  • Node.js 18
  • axios 用于HTTP请求
  • casper-js-sdk 用于密钥处理

问题排查与解决方案

一、更可靠的Casper主网RPC端点

给你几个目前验证过的稳定主网端点,优先推荐官方维护的:

  • https://mainnet.casperlabs.io(官方主节点,稳定性最高)
  • https://api.casperholders.com(社区维护的高可用端点)
  • https://casper-mainnet.public.blastapi.io(第三方提供的分布式节点)
  • https://rpc.casper.network(官方备用节点)

建议把官方端点放在列表最前面,社区端点作为备用。

二、你的端点测试方法的潜在问题

  1. 路径拼接的兼容性问题
    你给每个端点都拼接了/rpc路径,但有些官方端点本身已经包含/rpc后缀(比如https://mainnet.casperlabs.io/rpc),会导致拼接后变成xxx/rpc/rpc,触发404错误。
    建议统一端点格式:要么都使用不带/rpc的基础URL,要么在测试前自动处理路径:

    let rpcUrl = new URL(url);
    if (!rpcUrl.pathname.endsWith('/rpc')) {
        rpcUrl.pathname = rpcUrl.pathname.replace(/\/?$/, '/rpc');
    }
    const fullRpcUrl = rpcUrl.toString();
    
  2. Promise.allSettled的逻辑优化
    你的过滤逻辑没问题,但可以简化为直接判断result.value(因为testEndpoint返回的是布尔值):

    const workingEndpoints = endpoints.filter((endpoint, index) => {
        const result = results[index];
        return result.status === 'fulfilled' && result.value;
    });
    
  3. SSL验证的风险与必要性
    测试时禁用rejectUnauthorized可以临时解决证书问题,但生产环境绝对不建议这么做——这会让请求暴露在中间人攻击的风险下。如果遇到证书错误,优先更换端点,而不是禁用验证。

  4. 重复超时设置的冗余
    你同时在axios配置和httpsAgent里设置了timeout,axios的全局timeout已经足够覆盖请求周期,不需要在Agent里重复设置,避免逻辑混乱。

三、Electron应用调用Casper RPC的特殊注意事项

  1. 网络权限配置
    在Electron的package.json里确保配置了正确的网络权限:

    "permissions": ["network", "https://*/*"]
    

    另外,如果启用了contextIsolation(Electron 12+默认开启),建议把RPC请求放在主进程中处理,通过IPC和渲染进程通信——渲染进程直接发起请求可能会遇到CORS或权限问题。

  2. 系统代理的干扰
    Electron会自动继承系统代理设置,如果用户的代理配置有问题,会导致端点连接失败。可以在axios中显式跳过代理:

    {
        proxy: false
    }
    
  3. Electron网络栈的差异
    Electron的网络栈和Node.js原生有细微差异,比如证书验证逻辑。如果在主进程中请求正常,渲染进程中异常,大概率是CORS或权限问题,建议统一把网络请求放在主进程。

四、优化后的端点测试函数示例

const https = require('https');
const axios = require('axios');

async function testEndpoint(url, retryCount = 1) {
    try {
        // 统一处理RPC路径
        let rpcUrl = new URL(url);
        if (!rpcUrl.pathname.endsWith('/rpc')) {
            rpcUrl.pathname = rpcUrl.pathname.replace(/\/?$/, '/rpc');
        }
        const fullRpcUrl = rpcUrl.toString();
        
        console.log(`Testing endpoint: ${fullRpcUrl}`);
        
        const response = await axios.post(fullRpcUrl, {
            jsonrpc: "2.0",
            id: "0",
            method: "info_get_status",
            params: []
        }, {
            timeout: 10000,
            headers: { 'Content-Type': 'application/json' },
            validateStatus: status => status < 500,
            proxy: false,
            httpsAgent: new https.Agent({
                rejectUnauthorized: true, // 生产环境启用
                timeout: 10000
            })
        });
        
        // 严格验证RPC响应格式
        if (response.data?.jsonrpc === "2.0" && !response.data.error) {
            console.log(`Endpoint ${url} is working`);
            return true;
        }
        console.log(`Endpoint ${url} returned invalid data:`, response.data);
        return false;
    } catch (error) {
        console.log(`Endpoint ${url} failed:`, error.message);
        // 临时错误重试(超时、DNS解析失败)
        if ((error.code === 'ETIMEDOUT' || error.code === 'ENOTFOUND') && retryCount > 0) {
            console.log(`Retrying endpoint: ${url}`);
            return await testEndpoint(url, retryCount - 1);
        }
        return false;
    }
}

五、额外建议

  • 添加端点优先级:把官方稳定端点放在列表最前面,优先测试
  • 缓存工作端点:如果某个端点测试通过,缓存下来,下次启动直接使用,减少重复测试
  • 完善日志:记录每个端点的测试耗时、错误类型,方便后续排查

备注:内容来源于stack exchange,提问作者Jintor

火山引擎 最新活动