THE STELLAR CHECK FIELD GUIDE8 min read

Better payments
start with context.

Why we built Stellar Check, the problems it helps you catch, and how to put a useful answer before the signature request.

For builders & curious peopleRelease · v0.1.1
The idea in one sentence

Read public account data, check a supported payment, and explain what needs attention before asking someone to sign.

There’s a gap before “Send”.

A payment form usually starts with an address, an asset and an amount. Those inputs don’t tell the whole story. Some of the sender’s XLM may be reserved. The recipient may not have a trustline for that particular asset. A receiving service may require a memo.

We built Stellar Check to make that context available at the point where it is useful: before the application requests a signature. It gives builders a consistent way to turn supported account-state problems into specific guidance.

The goal is a calmer payment flow. A person should be able to understand what needs to change, who can change it, and when to try again.

What could get in the way?

A balance is not a spending limit.

XLM availability accounts for required reserves, sponsorship, selling liabilities and the planned fee. An issued asset also has its own available balance.

Stellar reference: sponsored reserves ↗

The right asset needs the right trustline.

For issued assets, a matching code alone is not enough. The issuer must match too. The check also considers authorization and the recipient’s remaining capacity.

Stellar reference: verifying trustlines ↗

Small details carry meaning.

The expected network must match the provider. A declared memo requirement needs attention, even when the account and amount otherwise look fine.

Stellar reference: account memo requirements ↗

One missing trustline.
One useful answer.

Imagine sending 1 USD on Testnet. The sender holds the asset and both accounts exist, but the recipient has no trustline for this exact USD issuer.

CONTROLLED EXAMPLENO PAYMENT SENT
SENDER1 USDRECIPIENTTrustline missing
The recipient needs a trustline.

The report identifies the recipient as the affected party and recommends creating a trustline for the exact asset code and issuer.

Status
issues_found
Diagnostic
DESTINATION_TRUSTLINE_MISSING
Who can act?
The recipient
  1. Explain the issue. Show the asset and issuer, so the recipient knows which trustline is needed.
  2. Let the recipient act. They establish the trustline in their wallet, with sufficient reserve and any required issuer authorization.
  3. Read fresh state. Check the payment again. A resolved trustline issue does not prove that every other check will pass.
Try the missing-trustline example

This example uses the project’s controlled fixture. Opening it makes no live network request and sends no funds.

Read. Assess. Explain.

01

Describe the payment

Provide the network, public accounts, asset, amount, fee budget and optional memo.

02

Read & assess

Read public state through Horizon, validate the supported shape, then evaluate the relevant checks.

03

Return a report

Receive a status, diagnostics, exact amounts, coverage and observation metadata.

checkPayment(intent, provider) coordinates fresh reads. assessPayment(intent, snapshot) evaluates supplied observations without network access, which is useful for fixtures and tests.

Three outcomes, deliberately different

No known issues

no_known_issues

Applicable supported checks completed without finding a diagnosed problem. This is an observation, not a promise of execution.

Issues found

issues_found

The checks identified something to address. Each issue includes a stable code, affected party, explanation and suggested action.

Incomplete

incomplete

Input, scope or unavailable observations prevented a complete assessment. Known issues are retained. Always check the status, even when the issues list is empty.

Coverage marks checks as complete, unresolved or not applicable. “Complete” means the check ran; it may still have found an issue.

Make the reasoning inspectable.

The report is grounded in defined rules and observed account data. It does not use an AI guess to decide whether a payment is ready.

  • Exact arithmetic. Amounts are parsed into integer units with seven-decimal precision. Report values remain decimal strings, avoiding floating-point rounding in readiness calculations.
  • Explicit dependencies. A missing or malformed observation produces an incomplete result instead of an assumed zero balance or a silent pass.
  • Network and time context. Reports carry the expected network, per-read observations and available ledger metadata. The reads are explicitly non-atomic.
  • Repeatable verification. The local suite covers reserves, liabilities, trustlines, authorization, capacity, fees, memo behavior and provider failures. The current project has 121 passing tests, including UI theme tests.
Test coverage is evidence, not certification.

The library has not had an independent production audit. Separate reads can become stale, and unassessed transaction conditions can still prevent execution.

Put it before the signature.

Install Stellar Check from npm. The package includes ESM output and TypeScript declarations for Node 22.12 or later and modern browser bundlers. The example below also imports network constants from the Stellar SDK, so install both packages:

IN YOUR APPLICATION
npm install stellar-check @stellar/stellar-sdk

Provide your own sender and recipient public addresses. The example below only reads state:

PAYMENT-CHECK.TS
import { Networks } from '@stellar/stellar-sdk';
import { checkPayment, HorizonProvider }
  from 'stellar-check';

const provider = new HorizonProvider(
  'https://horizon-testnet.stellar.org'
);

const report = await checkPayment({
  networkPassphrase: Networks.TESTNET,
  source: senderPublicAddress,
  destination: recipientPublicAddress,
  asset: { type: 'native' },
  amount: '2.5000000',
  feeBudget: '0.0000100',
}, provider);

console.log(report.status, report.coverage);
for (const issue of report.issues) {
  console.log(issue.code, issue.party, issue.action);
}

feeBudget is the total planned fee in XLM, not stroops. Use decimal strings for amounts. For an issued asset, provide { type: 'credit', code, issuer }; the issuer is part of the asset’s identity.

Start from an unsigned transaction

The Playground can decode transaction XDR locally and preview the payment before loading it into the form. Select the network explicitly: the envelope does not identify its network. Loading selects Live Horizon; public reads begin only when you click Check payment.

In code, use importPaymentXdr(xdr, networkPassphrase). A successful result provides payment for the checker and context with the original sequence and time bounds. These envelope conditions are not assessed. Editing imported values changes the form only, not the original XDR.

The importer accepts one unsigned V1 classic payment in the supported scope. It rejects signed envelopes, fee bumps, legacy envelopes, transaction extensions and extended preconditions. Amounts and fees stay exact; text memos must be valid UTF-8.

Try importing XDR

Follow the issue to its input

Use Review amount, Edit fee budget or Edit memo to jump to the relevant form field. For trustline and authorization issues, Copy asset details provides the exact issuer and affected accounts. Correct what you control, then run a fresh check.

Integrate the decision, not just the call

Branch on report.status, surface the relevant actions, and refresh when payment inputs change or before confirmation. Signing, sequence handling, fee selection and submission remain your application’s responsibility.

Public reads are still network requests.

Live checks disclose the queried public addresses to your configured Horizon provider. The library never needs a secret key or wallet connection.

Useful once. Reusable across apps.

The intended contribution is a shared payment-readiness component that Stellar builders can inspect, test and integrate. It builds on the official SDK and public network data.

For wallet & payment developers

Reusable calculations and stable diagnostic codes can reduce repeated integration work and make payment guidance more consistent.

For people making payments

Specific explanations can make it easier to distinguish an amount problem from a recipient or issuer action.

For maintainers & contributors

Explicit scope, controlled fixtures and an Apache-2.0 license give others a concrete starting point for review and improvement.

These are intended benefits. We do not yet have adoption data, measured support-ticket reductions or maintainer endorsements. Integration feedback and independent review are the next sources of evidence.

Know what the report covers.

Supported in v0.1

  • One classic payment
  • Distinct Stellar G accounts
  • Native XLM or an issued asset
  • The same source and fee payer
  • Supported account-state and memo checks

Outside this release

  • Path payments, batches and fee bumps
  • Soroban and M addresses
  • Self-payments or an asset issuer as a party
  • Signatures and sequence numbers
  • Submission, finality and surge-fee inclusion

A supplied memo establishes presence only. It does not verify the intended customer or prove that the receiving service will credit the deposit correctly. Obtain the actual required memo from that service.

A clean report never guarantees a successful transaction. Unsupported input and unavailable data are reported explicitly, and account state may change immediately after a read.

Go straight to the sources.

Use these primary references to understand the network rules behind the checks. This project is an independent tool, not an official Stellar product.

CONTEXT, MEET PRACTICE.

See what a payment tells you.

Try a sample check