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

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