Repository navigation
feat(rest): add account_history to master, iter_account_fa_transactions, and one cursor rule - #40
Merged
Merged
Conversation
…ctions, and SUPRA layout docs (#36) * feat(rest): add account_history and iter_account_history `account_history` reads `GET /rpc/v3/accounts/{address}/history`: every finalized transaction that concerns an account, once each, with the categories it matched (`sent`, `coin`, `fa`, `da`). It takes `PaginationWithOrder` (`count`, `start`, `ascending`) and an optional `categories` filter, as `AccountHistoryCategory` members or their string values, sent comma separated. It returns the page and the next cursor. The route exists only on nodes from supra_node_v12.0.0, which end a feed by omitting `x-supra-cursor`. The history therefore ends only when the header is absent or empty: an empty page with a cursor continues, since the node filters by category while it scans, and "0" is a cursor (a genesis-block row). `next_cursor` takes `only_missing_header_ends` for this; every other feed keeps its rule. `iter_account_history` follows the cursor until the history ends or the node repeats a cursor. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(rest): add a transaction type filter to account_coin_transactions `account_coin_transactions` and `iter_account_coin_transactions` take an optional `transaction_type` (`TransactionType` or its string value), sent as the node's `type` query parameter. `TransactionType` gains `RECORD` and `SETTLEMENT`; v11.7.x nodes reject `settlement` with HTTP 400. With the filter set, the first request of an ascending read keeps an empty page's cursor "0", which can be the position of a genesis row the filter excluded; the next request continues with `start=0`, and the node's echo of it ends the feed. Without the filter, "0" on an empty page still ends the feed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs: say which method lists SUPRA movements on each layout On a chain created with features 64 and 65 on, such as Devnet, no account has a `CoinStore<SupraCoin>`: SUPRA moves between primary fungible stores, and `coin_transactions` lists none of it. `account_coin_transactions` and its iterator say so and point to `account_fa_transactions` and to `account_history` with the category `fa`. The README gains a section on which method lists an account's SUPRA movements on the coin layout and on the primary-store layout. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(rest): do not send an empty transaction type; correct the layout docs `account_coin_transactions` treats `transaction_type=""` as no filter, as it treats an empty `start`: the parameter is not sent, and "0" on the first empty page ends the feed. Docs: - While feature 64 or 65 is enabled, registering SUPRA creates the primary fungible store instead of a `CoinStore<SupraCoin>`, so the coin layout lasts only for accounts created before either is enabled. The README and the coin transactions docstrings say so. - The zero-cursor rule of `account_coin_transactions` states its exception next to the rule, and that the node answers the following `start=0` request with "0" (v11.7.x) or without a cursor (v12). - `account_history` states that it does not return the `x-supra-history-indexed-from` header, and that an entry's `transaction` is a `TransactionV3` tagged by `txn_type`. The history iterator test reads ascending, where a scan that starts at the genesis row can return an empty page with cursor "0". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…sor rule `iter_account_fa_transactions` takes the arguments of `account_fa_transactions` and follows the cursor until the feed ends or the node repeats one, like the other iterators. `account_fa_transactions` reads its cursor with `paging.next_cursor`; the private copy of the rule in `account.py` is removed. `account_coin_transactions` says that either feature 64 or feature 65 holds SUPRA in primary stores. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…sactions `account_fa_transactions` treats `transaction_type=""` as no filter, as `account_coin_transactions` does: no `type` parameter is sent and "0" on the first empty page ends the feed. Both methods derive the parameter with one helper. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
account_coin_transactions reports the end of the feed as a None cursor, whether the x-supra-cursor header is missing or the node returns "0" on an empty page. The node-backed test now expects ([], None) on a node without a SUPRA CoinStore. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This was referenced Nov 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
#36 was squash-merged into #30's branch (
fix/paging-and-request-params) after #30 had been merged, so its changesare not on
master. This PR applies them tomaster: its first commit is #36's squash commit (0b39ac1),cherry-picked onto
master.The two commits after it do the work that was left over when #30 and #31 were both merged:
account_fa_transactionsreads its cursor withpaging.next_cursor. feat(client): add fungible asset balance, transfer, migration and transaction helpers #31 had a private copy of the same rule inaccount.py, which is removed. The two functions return the same result for every input.iter_account_fa_transactionsis added, like the other iterators.account_fa_transactionsandaccount_coin_transactionstreat an emptytransaction_typethe same way: notypeparameter is sent.
account_coin_transactionssays that feature 64 or feature 65 puts SUPRA in primary stores.Behaviour
From #36 (unchanged; its description has the details):
account_history(account_address, pagination=None, categories=None)anditer_account_historyforGET /rpc/v3/accounts/{address}/history:(entries, cursor). Each entry is{"categories": [...], "transaction": {...}}.categoriestakesAccountHistoryCategorymembers or their names (sent,coin,fa,da). An empty,unknown or comma-joined value raises
ValueErrorbefore any request.x-supra-cursor:"0"is a valid cursor, and an empty page with acursor continues. The iterator also stops on a repeated cursor.
supra_node_v12.0.0. A v11.7.x node answers 404, raised asApiError.x-supra-history-indexed-fromheader.transaction_typeonaccount_coin_transactionsanditer_account_coin_transactions:typequery parameter.TransactionTypegainsRECORDandSETTLEMENT.settlementneedsa v12 node; a v11.7.x node answers 400.
"0"cursor on an empty page, which costs at mostone more request.
paging.next_cursorgains the keywordonly_missing_header_ends(default False), used by the history feed.docstrings point to
account_fa_transactionsandaccount_history.New here:
iter_account_fa_transactions(account_address, pagination=None, metadata_address=0xa, transaction_type=None, *, store_address=None): the arguments ofaccount_fa_transactions. It follows the cursor until the feed ends orthe node repeats one. An invalid address raises
ValueErrorwhen the iteration starts.account_fa_transactionssends notypeparameter for an emptytransaction_type, and then does not applythe
"0"rule for typed ascending reads. Before, it senttype=with an empty value.Checks
account.py(feat(rest): account history, a transaction type filter on coin transactions, and SUPRA layout docs #36'sACCOUNT_HISTORY_ENDPOINTand feat(client): add fungible asset balance, transfer, migration and transaction helpers #31'sACCOUNT_FA_TRANSACTIONS_ENDPOINT); both are kept.paging.pyandtests/unit/test_paging.pyare identical to0b39ac1, and the other files differ from it only by feat(client): add fungible asset balance, transfer, migration and transaction helpers #31's additions.account_coin_transactionsfeed now reports its cursor asNone, not"". CI skips the node-backed tests, somasterdid not show it.make fmt-check,make lint,make typecheck,make test-spec(248 scenarios),make build: pass.make test-unit: 350 tests, OK (26 node-backed skipped). New offline tests coveriter_account_fa_transactionsending on a missing header, continuing past an empty filtered page, and with
store_address; and an emptytransaction_typeonaccount_fa_transactions.supra_node_v12.0.0.rc7localnet:make test-unitwithSUPRA_RPC_URLset: 350 tests, OK, none skipped.account_historylisted the transfer assentandfaand the faucet grant asfa; the receiver's history listed the transfer underfaand nothingunder
coin. Both history iterators read to the end.account_coin_transactionsreturned empty pages withcursor
Nonefor both accounts with every filter,settlementincluded./history, the coin-transaction filters, 400 forsettlement) were not repeated:the code they exercised is unchanged by this PR's later commits.
🤖 Generated with Claude Code