Skip to content

feat: add Stellar balance check tools#45

Open
wolf1276 wants to merge 1 commit intoStellar-Tools:mainfrom
wolf1276:feature/balance-check-tools
Open

feat: add Stellar balance check tools#45
wolf1276 wants to merge 1 commit intoStellar-Tools:mainfrom
wolf1276:feature/balance-check-tools

Conversation

@wolf1276
Copy link
Copy Markdown

@wolf1276 wolf1276 commented Mar 30, 2026

Description

This PR adds new tools for checking Stellar account balances directly through the SDK and AgentClient.

Changes

  • Added : A tool to fetch the balance of a specific account for a given asset (defaults to XLM).
  • Added : A tool to retrieve all asset balances for an account.
  • Exported new tools in array in .
  • Added and methods to class in for consistent developer experience.
  • Added comprehensive unit tests in (mocking Stellar SDK for testability).

Impact

This allows developers and AI agents to verify account state before and after DeFi operations without needing to implement their own balance logic.


Summary by cubic

Adds two Stellar balance tools and AgentClient wrappers to fetch XLM/specified asset balances or list all balances, making it easy to verify account state around DeFi operations.

  • New Features
    • New tools: stellar_get_balance and stellar_get_all_balances (XLM and credit assets; address validation; uses STELLAR_NETWORK with testnet default).
    • Exported in stellarTools via index.ts.
    • AgentClient: getBalance({ address, assetCode?, assetIssuer? }) and getAllBalances(address).
    • Unit tests added with mocked @stellar/stellar-sdk.

Written for commit 1da0059. Summary will update on new commits.

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5 issues found across 4 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="tools/balance.ts">

<violation number="1" location="tools/balance.ts:20">
P1: Network parsing is too strict; non-`mainnet` but valid project conventions (e.g., `stellar-mainnet`) silently route balance checks to testnet Horizon.</violation>

<violation number="2" location="tools/balance.ts:36">
P2: Non-XLM balance lookup is ambiguous when `assetIssuer` is omitted, allowing wrong-issuer asset matches by code alone.</violation>

<violation number="3" location="tools/balance.ts:74">
P2: Non-native balance lines are force-cast to `BalanceLineAsset`, causing malformed all-balance output for non-asset variants (e.g., liquidity pool shares).</violation>
</file>

<file name="agent.ts">

<violation number="1" location="agent.ts:143">
P2: Balance wrapper methods ignore AgentClient network/rpc configuration, so balance reads may target a different network than the configured client.</violation>
</file>

<file name="tests/unit/tools/balance.test.ts">

<violation number="1" location="tests/unit/tools/balance.test.ts:12">
P2: Tests do not verify that `loadAccount` receives the provided `address`, so wrong-account wiring bugs can pass undetected.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread tools/balance.ts
}

const network = typeof process !== 'undefined' ? process.env.STELLAR_NETWORK || "testnet" : "testnet";
const horizonUrl = network === "mainnet"
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Network parsing is too strict; non-mainnet but valid project conventions (e.g., stellar-mainnet) silently route balance checks to testnet Horizon.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At tools/balance.ts, line 20:

<comment>Network parsing is too strict; non-`mainnet` but valid project conventions (e.g., `stellar-mainnet`) silently route balance checks to testnet Horizon.</comment>

<file context>
@@ -0,0 +1,87 @@
+      }
+
+      const network = typeof process !== 'undefined' ? process.env.STELLAR_NETWORK || "testnet" : "testnet";
+      const horizonUrl = network === "mainnet" 
+        ? "https://horizon.stellar.org" 
+        : "https://horizon-testnet.stellar.org";
</file context>
Fix with Cubic

Comment thread tools/balance.ts
if (b.asset_type === "native") {
return `XLM: ${b.balance}`;
}
return `${(b as Horizon.BalanceLineAsset).asset_code} (${(b as Horizon.BalanceLineAsset).asset_issuer}): ${b.balance}`;
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Non-native balance lines are force-cast to BalanceLineAsset, causing malformed all-balance output for non-asset variants (e.g., liquidity pool shares).

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At tools/balance.ts, line 74:

<comment>Non-native balance lines are force-cast to `BalanceLineAsset`, causing malformed all-balance output for non-asset variants (e.g., liquidity pool shares).</comment>

<file context>
@@ -0,0 +1,87 @@
+        if (b.asset_type === "native") {
+          return `XLM: ${b.balance}`;
+        }
+        return `${(b as Horizon.BalanceLineAsset).asset_code} (${(b as Horizon.BalanceLineAsset).asset_issuer}): ${b.balance}`;
+      });
+
</file context>
Fix with Cubic

Comment thread tools/balance.ts

const assetBalance = balances.find((b: Horizon.BalanceLine) => {
if (b.asset_type === "native") return false;
return b.asset_code === assetCode && (!assetIssuer || b.asset_issuer === assetIssuer);
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Non-XLM balance lookup is ambiguous when assetIssuer is omitted, allowing wrong-issuer asset matches by code alone.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At tools/balance.ts, line 36:

<comment>Non-XLM balance lookup is ambiguous when `assetIssuer` is omitted, allowing wrong-issuer asset matches by code alone.</comment>

<file context>
@@ -0,0 +1,87 @@
+
+      const assetBalance = balances.find((b: Horizon.BalanceLine) => {
+        if (b.asset_type === "native") return false;
+        return b.asset_code === assetCode && (!assetIssuer || b.asset_issuer === assetIssuer);
+      });
+
</file context>
Fix with Cubic

Comment thread agent.ts
assetCode?: string;
assetIssuer?: string;
}) {
return await stellarGetBalanceTool.func(params);
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Balance wrapper methods ignore AgentClient network/rpc configuration, so balance reads may target a different network than the configured client.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At agent.ts, line 143:

<comment>Balance wrapper methods ignore AgentClient network/rpc configuration, so balance reads may target a different network than the configured client.</comment>

<file context>
@@ -130,6 +131,26 @@ export class AgentClient {
+    assetCode?: string;
+    assetIssuer?: string;
+  }) {
+    return await stellarGetBalanceTool.func(params);
+  }
+
</file context>
Fix with Cubic

...original,
Horizon: {
Server: vi.fn().mockImplementation(() => ({
loadAccount: vi.fn().mockResolvedValue({
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Tests do not verify that loadAccount receives the provided address, so wrong-account wiring bugs can pass undetected.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At tests/unit/tools/balance.test.ts, line 12:

<comment>Tests do not verify that `loadAccount` receives the provided `address`, so wrong-account wiring bugs can pass undetected.</comment>

<file context>
@@ -0,0 +1,64 @@
+    ...original,
+    Horizon: {
+      Server: vi.fn().mockImplementation(() => ({
+        loadAccount: vi.fn().mockResolvedValue({
+          balances: [
+            { asset_type: 'native', balance: '100.0000000' },
</file context>
Fix with Cubic

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant