Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions reference/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ Source: `atomicassets-api src/api/server.ts` (`swagger.setup` mounted at `/docs`

## List endpoints cap limit at 100

The AtomicMarket API (eosio-contract-api) validates the `limit` query parameter on list endpoints such as `/atomicmarket/v1/buyoffers` and `/atomicmarket/v1/sales` against a maximum that defaults to 100; requests above the cap are rejected with HTTP 400 and `{"success": false, "message": "Invalid value for parameter limit"}` rather than being clamped. The cap is an operator-configurable server setting (`limits` in the API config), so the reference deployment at wax.api.atomicassets.io enforces 100. Pagination code must therefore bound `limit` to 100 and use `page`, and counting code must treat a non-2xx response as an error: an HTTP client helper that returns undefined or empty on failure will silently turn an over-limit request into a zero count.
The atomicassets-api validates the `limit` query parameter on list endpoints such as `/atomicmarket/v1/buyoffers` and `/atomicmarket/v1/sales` against a maximum that defaults to 100; requests above the cap are rejected with HTTP 400 and `{"success": false, "message": "Invalid value for parameter limit"}` rather than being clamped. The cap is an operator-configurable server setting (`limits` in the API config), so the reference deployment at wax.api.atomicassets.io enforces 100. Pagination code must therefore bound `limit` to 100 and use `page`, and counting code must treat a non-2xx response as an error: an HTTP client helper that returns undefined or empty on failure will silently turn an over-limit request into a zero count.

## Template buyoffers keep all lifecycle states

AtomicMarket template buyoffers in eosio-contract-api follow a three-state lifecycle: `lognewtbuyo` inserts a row in state 0 (LISTED), `canceltbuyo` flips it to 1 (CANCELED), and `fulfilltbuyo` flips it to 2 (SOLD), setting the seller and inserting the fulfilled asset rows. Rows are never deleted or archived: no maintenance job cleans up CANCELED or SOLD offers, so they persist indefinitely as state markers. The `/v1/template_buyoffers` endpoint applies no state filter by default: without an explicit `state` query parameter it returns offers in all three states, so clients that only want active offers must pass `state=0`. No socket notifications are broadcast for template buyoffers at the pinned commit: the socket handler for new offers exists in the source but is never wired into the atomicmarket namespace, and cancellation and fulfillment have no handler at all (`reference/api-streaming.md`). Poll the endpoint rather than waiting on socket events. The filler and API state enums both encode LISTED=0, CANCELED=1, SOLD=2 and map 1:1.
AtomicMarket template buyoffers in the atomicassets-api follow a three-state lifecycle: `lognewtbuyo` inserts a row in state 0 (LISTED), `canceltbuyo` flips it to 1 (CANCELED), and `fulfilltbuyo` flips it to 2 (SOLD), setting the seller and inserting the fulfilled asset rows. Rows are never deleted or archived: no maintenance job cleans up CANCELED or SOLD offers, so they persist indefinitely as state markers. The `/v1/template_buyoffers` endpoint applies no state filter by default: without an explicit `state` query parameter it returns offers in all three states, so clients that only want active offers must pass `state=0`. No socket notifications are broadcast for template buyoffers at the pinned commit: the socket handler for new offers exists in the source but is never wired into the atomicmarket namespace, and cancellation and fulfillment have no handler at all (`reference/api-streaming.md`). Poll the endpoint rather than waiting on socket events. The filler and API state enums both encode LISTED=0, CANCELED=1, SOLD=2 and map 1:1.

## The `state` field means something different on each listing endpoint

Expand Down
2 changes: 1 addition & 1 deletion reference/atomicassets-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ The AtomicMarket handler's schema setup declares a foreign key from `atomicmarke

## Reader-priority drain gate and queue dedup

The eosio-contract-api filler protects block ingestion with a reader-priority gate on scheduled aggregator drains: drains are deferred while the reader is more than a stop threshold of blocks behind chain head (default 200) and resume only once it falls below a lower resume threshold (default 60); both are environment-tunable. The two thresholds form a hysteresis band so the gate does not flap between defer and resume on every block. The gate is only safe in combination with queue deduplication: unique partial indexes on the sales-filter update queue collapse repeated updates for the same sale, asset, or offer key, so a gated queue grows only to the number of distinct dirty keys rather than with raw event volume. Gating without dedup produces a doom loop: the deferred queue grows without bound, each eventual drain gets more expensive, the reader falls further behind, and the gate never releases.
The atomicassets-api filler protects block ingestion with a reader-priority gate on scheduled aggregator drains: drains are deferred while the reader is more than a stop threshold of blocks behind chain head (default 200) and resume only once it falls below a lower resume threshold (default 60); both are environment-tunable. The two thresholds form a hysteresis band so the gate does not flap between defer and resume on every block. The gate is only safe in combination with queue deduplication: unique partial indexes on the sales-filter update queue collapse repeated updates for the same sale, asset, or offer key, so a gated queue grows only to the number of distinct dirty keys rather than with raw event volume. Gating without dedup produces a doom loop: the deferred queue grows without bound, each eventual drain gets more expensive, the reader falls further behind, and the gate never releases.

## Sales-filter freshness is rest-gap dominated

Expand Down
2 changes: 1 addition & 1 deletion reference/atomicassets/v2-upgrade.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ What changed in the `atomicassets` contract's V2 upgrade, and the indexer/chain

## V2 is an additive in-place upgrade

AtomicAssets V2 is a non-breaking, additive, in-place upgrade of the V1 contract. Every existing table and action keeps its layout (new capabilities live in new tables and actions), so a `setcode`/`setabi` preserves all on-chain state and requires no on-chain migration. The indexer/chain compatibility matrix follows from that: a V2 indexer against a V1 chain is safe (the new code paths stay dormant), a V1 indexer against a V2 chain is degraded but not fatal (it keeps indexing ownership, mints, transfers, and offers while ignoring the new actions and tables; verified empirically by running a stock legacy eosio-contract-api 1.3.x filler against a live V2 testnet chain with zero errors), and full V2 functionality requires the V2 indexer with its database migration applied. There is no flag day: operators can upgrade indexers on their own schedule. The V2 indexer has no exotic database requirement: PostgreSQL 14+ is recommended and existing PostgreSQL 13 installations work.
AtomicAssets V2 is a non-breaking, additive, in-place upgrade of the V1 contract. Every existing table and action keeps its layout (new capabilities live in new tables and actions), so a `setcode`/`setabi` preserves all on-chain state and requires no on-chain migration. The indexer/chain compatibility matrix follows from that: a V2 indexer against a V1 chain is safe (the new code paths stay dormant), a V1 indexer against a V2 chain is degraded but not fatal (it keeps indexing ownership, mints, transfers, and offers while ignoring the new actions and tables; verified empirically by running a stock legacy 1.3.x filler (from the era the project was still named eosio-contract-api) against a live V2 testnet chain with zero errors), and full V2 functionality requires the V2 indexer with its database migration applied. There is no flag day: operators can upgrade indexers on their own schedule. The V2 indexer has no exotic database requirement: PostgreSQL 14+ is recommended and existing PostgreSQL 13 installations work.

## Deployment status

Expand Down