Skip to content

Issue #2: Implement Stellar Network Client with Connection Management #17

@wheval

Description

@wheval

Implement Stellar Network Client

Description:
Build a Stellar network client that handles connections to testnet/mainnet, implements retry logic, and provides an API for querying accounts, balances, and submitting transactions.

Context:
The extension wallet needs reliable communication with the Stellar network. This client will be the foundation for all blockchain interactions. It should use the Stellar RPC server for Soroban compatibility and handle network failures gracefully with exponential backoff retry logic.

Requirements:

  • Create StellarClient class using StellarRpc.Server from Stellar SDK
  • Support network configuration (testnet/mainnet with correct RPC URLs)
  • Implement withRetry helper with exponential backoff (1s, 2s, 4s delays)
  • Add getAccount(publicKey) method
  • Add getBalances(publicKey) method
  • Implement submitTransaction(transaction) method
  • Add fundWithFriendbot(publicKey) for testnet (optional)
  • Create custom error types (NetworkError, AccountNotFoundError)
  • Add network passphrase configuration per network
  • Unit tests with mocked RPC server responses (>85% coverage)
  • Integration tests against live testnet

Implementation Guide:

The client should use @stellar/stellar-sdk's RPC server for Soroban compatibility:

import * as StellarSdk from "@stellar/stellar-sdk";
import { rpc as StellarRpc } from "@stellar/stellar-sdk";

class StellarClient {
  private server: StellarRpc.Server;
  private networkPassphrase: string;
  private maxRetries: number = 3;

  constructor(network: 'testnet' | 'mainnet') {
    const config = this.getNetworkConfig(network);
    this.server = new StellarRpc.Server(config.rpcUrl);
    this.networkPassphrase = config.networkPassphrase;
  }

  private getNetworkConfig(network: string) {
    switch (network) {
      case 'testnet':
        return {
          rpcUrl: 'https://soroban-testnet.stellar.org',
          networkPassphrase: StellarSdk.Networks.TESTNET
        };
      case 'mainnet':
        return {
          rpcUrl: 'https://soroban-mainnet.stellar.org',
          networkPassphrase: StellarSdk.Networks.PUBLIC
        };
    }
  }

  // Retry wrapper with exponential backoff
  private async withRetry<T>(
    operation: () => Promise<T>,
    operationName: string
  ): Promise<T> {
    let lastError: Error;
    
    for (let attempt = 0; attempt < this.maxRetries; attempt++) {
      try {
        return await operation();
      } catch (error) {
        lastError = error as Error;
        if (attempt < this.maxRetries - 1) {
          const delay = 1000 * Math.pow(2, attempt); // Exponential backoff
          await new Promise(r => setTimeout(r, delay));
        }
      }
    }
    throw new Error(`${operationName} failed after ${this.maxRetries} attempts`);
  }

  // Get account info
  async getAccount(publicKey: string) {
    return this.withRetry(
      () => this.server.loadAccount(publicKey),
      `getAccount(${publicKey})`
    );
  }

  // Get balances
  async getBalances(publicKey: string) {
    return this.withRetry(
      async () => {
        const account = await this.server.loadAccount(publicKey);
        return account.balances;
      },
      `getBalances(${publicKey})`
    );
  }

  // Submit transaction
  async submitTransaction(transaction: StellarSdk.Transaction) {
    return this.withRetry(
      () => this.server.submitTransaction(transaction),
      'submitTransaction'
    );
  }
}

Usage:

import { StellarClient } from '@ancore/stellar';

// Initialize for testnet
const client = new StellarClient('testnet');

// Get account
const account = await client.getAccount('GABC...');

// Get balances
const balances = await client.getBalances('GABC...');

// Submit transaction
const result = await client.submitTransaction(signedTx);

Files to Create:

  • packages/stellar/src/client.ts (main implementation with retry logic)
  • packages/stellar/src/network-config.ts (RPC URLs and network passphrases)
  • packages/stellar/src/errors.ts (custom error types)
  • packages/stellar/src/__tests__/client.test.ts (unit tests)
  • packages/stellar/src/__tests__/integration.test.ts (testnet integration tests)
  • packages/stellar/README.md (usage examples)

Dependencies:

  • @stellar/stellar-sdk (^12.0.0 or latest)
  • @ancore/types

Note: The retry logic should be built-in (no need for external retry library). Use exponential backoff: 1s, 2s, 4s delays.

Success Criteria:

  • Client connects to testnet and mainnet
  • Error handling with helpful messages
  • Integration tests pass against testnet
  • Recovers from network failures

Definition of Done:

  • All requirements implemented
  • Unit tests >85% coverage
  • Integration tests pass against testnet
  • Error handling tested
  • Documentation with troubleshooting guide

Labels: stellar, sdk, foundation, help wanted
Complexity: 200 points (High)
Estimated Effort: 3-4 days
Priority: Critical


Questions or need help? Join our Telegram community

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions