Skip to content

feat(payments): add Stellar payment flow and safeguards#52

Open
thesumedh wants to merge 2 commits intoStellar-Tools:mainfrom
thesumedh:feat/payment-flow-safeguards
Open

feat(payments): add Stellar payment flow and safeguards#52
thesumedh wants to merge 2 commits intoStellar-Tools:mainfrom
thesumedh:feat/payment-flow-safeguards

Conversation

@thesumedh
Copy link
Copy Markdown

@thesumedh thesumedh commented Apr 10, 2026

Summary

  • add reusable Stellar payment support for native XLM and issued assets
  • validate destination trustlines for issued-asset payments
  • fall back to createAccount when funding an unfunded address with native XLM
  • add memo support and mainnet safety gating in the payment tool
  • expose the payment flow through AgentClient and document it in the README

Validation

  • npm run build
  • npm test (64/64 passing)

Summary by cubic

Add a reusable Stellar payment flow for native XLM and issued assets with trustline checks, safe account funding, and stricter asset validation. Exposes payments via AgentClient.sendPayment and the stellar_send_payment tool, with memo support and mainnet safety gating.

  • New Features

    • lib/payments.sendPayment() sends XLM or issued assets; checks destination trustlines; auto-creates accounts for native to unfunded addresses; validates amount precision and 28-byte text memos; returns tx hash and metadata.
    • AgentClient.sendPayment(...) wrapper and README examples.
    • stellar_send_payment tool forwards asset, memo, and Horizon overrides; blocks mainnet unless allowMainnet is true.
  • Bug Fixes

    • Tightened native asset detection in lib/assets.ts to only accept { type: "native" }, preventing malformed issued assets from being treated as native; added tests.

Written for commit fe241a1. 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.

1 issue found across 9 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="lib/assets.ts">

<violation number="1" location="lib/assets.ts:10">
P2: Native asset type guard is too broad (`"type" in asset`) and can misclassify malformed issued-asset inputs as native, bypassing issued-asset validation/control-flow checks.</violation>
</file>

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

Comment thread lib/assets.ts Outdated
@thesumedh
Copy link
Copy Markdown
Author

Checked this and the issue was valid.

Root cause: isNativeAssetInput() was using a broad presence check ("type" in asset), so malformed runtime payloads with a non-native type field could get classified as native and skip issued-asset validation.

Fix pushed in fe241a1:

  • tighten the guard to require type === "native"
  • add regression coverage in tests/unit/lib/assets.test.ts
  • re-run npm run build and focused asset/dex/payment tests successfully

@cubic-dev-ai re-run review.

@cubic-dev-ai
Copy link
Copy Markdown

cubic-dev-ai Bot commented Apr 10, 2026

Checked this and the issue was valid.

Root cause: isNativeAssetInput() was using a broad presence check ("type" in asset), so malformed runtime payloads with a non-native type field could get classified as native and skip issued-asset validation.

Fix pushed in fe241a1:
...

@thesumedh I have started the AI code review. It will take a few minutes to complete.

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.

2 issues found across 10 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/stellar.ts">

<violation number="1" location="tools/stellar.ts:30">
P2: Memo schema validates character length instead of UTF-8 byte length, mismatching downstream Stellar memo byte-limit enforcement.</violation>

<violation number="2" location="tools/stellar.ts:78">
P1: User-supplied `horizonUrl` is used as an outbound Horizon endpoint without allowlisting, creating an SSRF/internal network access surface.</violation>
</file>

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

Comment thread tools/stellar.ts
{
network: selectedNetwork,
horizonUrl:
horizonUrl ??
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot Apr 10, 2026

Choose a reason for hiding this comment

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

P1: User-supplied horizonUrl is used as an outbound Horizon endpoint without allowlisting, creating an SSRF/internal network access surface.

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

<comment>User-supplied `horizonUrl` is used as an outbound Horizon endpoint without allowlisting, creating an SSRF/internal network access surface.</comment>

<file context>
@@ -1,67 +1,94 @@
+      {
+        network: selectedNetwork,
+        horizonUrl:
+          horizonUrl ??
+          (selectedNetwork === "mainnet"
+            ? "https://horizon.stellar.org"
</file context>
Fix with Cubic

Comment thread tools/stellar.ts
.describe("Optional asset descriptor. Omit to send native XLM."),
memo: z
.string()
.max(28)
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot Apr 10, 2026

Choose a reason for hiding this comment

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

P2: Memo schema validates character length instead of UTF-8 byte length, mismatching downstream Stellar memo byte-limit enforcement.

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

<comment>Memo schema validates character length instead of UTF-8 byte length, mismatching downstream Stellar memo byte-limit enforcement.</comment>

<file context>
@@ -1,67 +1,94 @@
+      .describe("Optional asset descriptor. Omit to send native XLM."),
+    memo: z
+      .string()
+      .max(28)
+      .optional()
+      .describe("Optional text memo up to 28 bytes"),
</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