Update Verify Trustlines guide to use RPC instead of Horizon - #2760
Update Verify Trustlines guide to use RPC instead of Horizon#2760wmendes wants to merge 2 commits into
Conversation
Removes the Horizon section and rebuilds the RPC section around the modern JS SDK helpers. - Delete "Checking a Trustline through the Horizon API" entirely, matching the sibling migrations (#1769, #1779, #1784, #1786, #1793). - Split the RPC section in two: `getAssetBalance` for existence and authorization, `getLedgerEntries` for the trustline limit (which `getAssetBalance` does not surface). - Use the public `getLedgerEntries` instead of the private `_getLedgerEntries`, which also drops the manual `xdr.LedgerEntryData.fromXDR` step since `entries[].val` is already decoded. - Fix a correctness bug: trustline flags are a bitfield, so `flags() !== 1` wrongly reported an authorized, clawback-enabled trustline (flags = 5) as unauthorized. Now checks `flags() & 1`. - Replace the hardcoded receiver, which 404s on Testnet after a reset, with a placeholder plus guidance on creating one. - SAC section: `authorized` does not return false for a missing trustline — the simulation fails with Error(Contract, #13) — so document which branch handles which case. Also point the bindings command at ./sac so the generated package name matches the `import { Client } from "sac"` below it, and drop a leftover commented-out transfer block. - Link to the official Migrate from Horizon to RPC page, which documents that RPC does not return trustlines alongside accounts. All snippets were run against Testnet with @stellar/stellar-sdk 16.2.0, covering the missing-trustline, authorized, and insufficient-limit paths. Fixes #1743 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Updates the “Verify Trustlines” guide to use Stellar RPC-first patterns (including getAssetBalance and getLedgerEntries) and clarifies how to check existence, authorization, and limits for trustlines and SAC authorization.
Changes:
- Replaces older trustline-check examples with RPC-focused approaches (
getAssetBalance,getLedgerEntries) and adds guidance on when to use each. - Adds a dedicated section on checking trustline limits and improves the trustline-flags authorization logic.
- Clarifies SAC
authorizedbehavior, especially the “missing trustline” simulation failure case.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
Preview is available here: |
- Keep trustline limit arithmetic in BigInt stroops. Converting int64 amounts through Number loses precision above 2^53-1, and trustline limits routinely sit at the int64 maximum (922,337,203,685.4775807). The old Number path falsely rejected valid payments: with a limit at the maximum and 1000 stroops of headroom, sending 0.0001 was reported as exceeding the limit. Adds a `toStroops` helper so the amount to send is converted without going through a float, and links the Amount precision reference. - Drop the same Number conversion from the getAssetBalance snippet and report `amount` as the stroops string the SDK returns. - Stop reporting every getAssetBalance failure as "trustline not found". The SDK's getTrustline swallows the underlying error and always throws the same "not found" message, so an unreachable RPC endpoint is indistinguishable from a genuinely missing trustline. The example now rethrows the original error and says "could not confirm", and a warning documents the caveat and points at getLedgerEntries, which returns an empty entries array for a missing trustline and only rejects on a transport error. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Worked through the Copilot review. Two comments were correct and are now fixed, one was correct in spirit but not fixable as suggested, one was wrong, and one was a false premise. Everything was checked against Testnet rather than reasoned about. Fixed — int64 precision ( Fixed differently — error conflation on Not a bug — Not applicable — " Re-verified after the changes: |
|
Preview is available here: |
Fixes #1743 (child of #1529).
Removes the Horizon section and rebuilds the RPC section around the modern JS SDK helpers.
What changed
## Checking a Trustline through the Horizon API. Matches @ElliotFriend's note on the issue and the sibling migrations (Update Fee-bump transactions to use rpc instead of horizon #1769, Update sponsored reserve examples to use RPC in both languages #1779, commit for claimable balance rework to use RPC in the docs #1784, Update "Create Account" tutorial to use RPC #1786, Update clawback docs to use RPC instead of horizon #1793), which all stripped Horizon code rather than demoting it. The only remaining mention of Horizon is a prose link to the official Migrate from Horizon to RPC page, whoseGET /accounts/{address}row documents exactly the gap this guide fills: "RPC will not provide trust line information associated with the account directly, as Horizon does. You will need to derive this from ledger entries."getAssetBalanceis the quick path for "does this trustline exist and is it authorized";getLedgerEntriesis only needed for the trustline limit, whichBalanceResponsedoesn't surface.Bugs fixed along the way
The RPC section already existed, but it wasn't in shape to be promoted as the primary path:
rpc._getLedgerEntries(key)and therefore hand-decodedxdr.LedgerEntryData.fromXDR(entry.xdr, "base64"). The publicgetLedgerEntriesreturnsentries[].valalready decoded.if (trustlineData.flags() !== 1)is wrong — trustline flags are a bitfield. An authorized and clawback-enabled trustline hasflags() === 5and was falsely reported "not authorized". Now!(flags() & 1), which is what the SDK itself does.GCLNZP3W…returns 404 on Testnet — wiped by a reset, so the snippet threw at step 1 for anyone copy-pasting. Replaced with a"G..."placeholder plus a comment on creating one, so it can't go stale again.authorizeddoesn't returnfalsefor a missing trustline. The simulation fails withError(Contract, #13)(trustline entry is missing for account) instead, so the prose now says which branch handles which case.--output-dir=./bindings(package namebindings) while the snippet didimport { Client } from "sac"— that import cannot resolve. Command now points at./sac.xlmClient.transfer({...})block referencing undefined variables, and fixed "conver" / "addresss" / "cient" / "Now we defined".Testing
Every snippet was run against Testnet with
@stellar/stellar-sdk@16.2.0:getAssetBalance, trustline presentauthorized: true, balance 1252.7872975getAssetBalance, no trustlineTrustline for USDC:… not found— hence try/catch, notif (!balanceEntry)getLedgerEntries→entries[0].val.trustLine()flags() === 1, limit and balance read correctlygetLedgerEntries, no trustlineentries: [], no throwchangeTrustlimit0.5; thelimit - balance < sendingAmountbranch firesauthorized, trustline presenttrueauthorized, no trustlineError(Contract, #13)sacand buildspnpm buildandpnpm check:mdxboth pass.🤖 Generated with Claude Code