Skip to content

Soroban Horizon endpoint selection ignores --rpc-url/--network for balance/account/history #1

Description

@Kingvic300

Description

SorobanAdapter has two families of methods: JSON-RPC calls that correctly use self.rpc_url (the URL the user configured via --rpc-url/--network), and REST calls against Stellar's Horizon API that instead go through horizon_url() (cli/src/chains/soroban.rs, lines 20-26):

fn horizon_url(&self) -> &'static str {
    if self.rpc_url.contains("mainnet") {
        "https://horizon.stellar.org"
    } else {
        "https://horizon-testnet.stellar.org"
    }
}

get_balance (84-89), get_account (110-115), and get_history (117-126) all call self.horizon_url() — a hardcoded Horizon endpoint chosen by naive substring-matching on the default rpc_url string — while get_transaction, get_block, and get_gas_price go through call_rpc, which correctly uses the actual self.rpc_url the user configured.

Verified

ChainFactory::get_adapter (cli/src/chains/factory.rs:25) threads the user's --rpc-url straight into SorobanAdapter::with_rpc, so self.rpc_url can be any custom endpoint. If a user runs txio --network mainnet --rpc-url https://my-node.example.com soroban balance GABC..., horizon_url() checks "https://my-node.example.com".contains("mainnet") → false → returns "https://horizon-testnet.stellar.org". The balance/account/history commands then silently query TESTNET Horizon while the user explicitly asked for mainnet via both --network and --rpc-url, while txio soroban block/gas/tx on the same invocation correctly hit the real mainnet endpoint. This also means --network devnet and --network localnet (whose default rpc_urls are futurenet/127.0.0.1 respectively — neither contains "mainnet") both fall through to testnet Horizon for balance/account/history, not a network-appropriate endpoint. The README's own claim — "same flags, same commands, predictable output" — is directly contradicted here: --rpc-url/--network work fully for Sui/Ethereum/Solana/Aptos and for 3 of Soroban's 6 operations, but are silently ignored for Soroban balance/account/history.

Suggested fix

Make horizon_url derived from the actual selected Network passed into with_rpc (already available at construction time) instead of substring-matching the RPC URL, and reject/fall back explicitly (with a warning) for networks that have no known Horizon endpoint (devnet/futurenet, localnet) rather than silently defaulting to testnet:

pub fn with_rpc(rpc_url: Option<String>, network: Network) -> Self {
    ...
    Self { client, rpc_url: url, network }  // store network
}
fn horizon_url(&self) -> Result<&'static str> {
    match self.network {
        Network::Mainnet => Ok("https://horizon.stellar.org"),
        Network::Testnet => Ok("https://horizon-testnet.stellar.org"),
        Network::Devnet | Network::Localnet =>
            Err(anyhow!("no known Horizon endpoint for this network")),
    }
}

Timeframe

Claim window: 96 hours. If this issue is claimed/assigned, please submit a fix within 96 hours of assignment — after that window it may be released back up for grabs.

Community

Questions about this issue or the campaign? Join https://t.me/txioCommunity

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial Campaign | FWC26Campaign: Official Campaign | FWC26Third CampaignCampaign: Third CampaignbugSomething isn't workingpriority:highShould be next

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions