Overview
TZ2AT is a Tezos-to-AT Protocol relay. It turns Tezos chain activity and selected marketplace context into ATProto records that appviews, feed generators, wallets, games, analytics tools, and community services can consume without running their own chain indexer.
TZ2AT stores facts, relationships, and projections. It does not decide what those facts mean socially. Downstream appviews are expected to query the PDS tree, subscribe to firehoses, and derive user-facing views from the records they care about.
Event Grammar And Repo Shape
Blockchain event records are statements. They are normally the raw material appviews use to extract context: who acted, what they acted on, what action happened, and which parameters make the action meaningful.
- Nouns: identity-centered subjects and objects such as wallets, contracts, tokens, marketplaces, currencies, platforms, and chains. These are the who and what of the statement.
- Verbs: actions such as transfers, sales, offers, listings, curation adds, swaps, bids, wallet claims, and hydrations. These become event records.
- Parameters: amounts, prices, token IDs, timestamps, operation hashes, source systems, block levels, and other details that qualify the noun-verb relationship.
TZ2AT is structured around that grammar. Nouns become repos categorized by type, or stable records inside the repo that owns them. Verbs are stored as event records in the repos for the nouns they describe. The structure itself carries context and helps downstream appviews recreate the semantic map without reverse-engineering every relationship from a flat feed.
Example: a marketplace sale is the verb. The buyer wallet, seller wallet, token, token contract, marketplace, currency, and chain are nouns. The price, amount, block, operation hash, and source provenance are parameters. TZ2AT stores the event where those noun repos can use it and links the nouns so appviews can traverse the statement.
Ingestion Model
The rolling Tezos indexer is priority one. It follows the Octez head and should not be slowed down by historical repair, wallet hydration, OBJKT enrichment, appview queries, or conversion backlogs.
- Rolling head path: live Octez RPC block ingestion, checkpointed as
octez-main. - Gap repair path: if the rolling checkpoint is behind by at least two blocks, TZ2AT skips to head and starts a detached skipped-block worker.
- Wallet hydration path: appviews or users can request historic wallet data from TzKT without disturbing live head ingestion.
- OBJKT enrichment path: a separate worker consumes only selected OBJKT streams and converts useful rows into token, marketplace, group, and graph artifacts.
- Entity repo path: missing repos are registered in a priority queue. More pending writes for the same repo raise its priority.
The default entity historian writes permanent lifecycle anchors for wallet and contract repos instead of replaying all old events into every entity repo. It records genesis and last-seen boundaries, adds lightweight OBJKT profile context when available, and leaves full event hydration to explicit appview/user requests or maintenance mode.
Operational rule: if a worker can fall behind, it must fall behind alone. The rolling indexer must remain concerned with current head, not with proving that every background job caught up first.
Available PDSs
| Host | Purpose | Records normally found there |
|---|---|---|
tz2at.store | Root relay PDS for canonical relay records and the store.tz2at.* lexicon namespace. | Canonical event collections such as transfers, marketplace events, XTZ flows, originations, and other relay-owned Tezos facts. |
relay.tz2at.store | ATProto relay/firehose endpoint in front of the relay PDS. | Not a user repo host. It exposes sync/firehose access to records published through TZ2AT. |
wallets.tz2at.store | Wallet noun repos. Each discovered or claimed wallet can have a repo. | store.tz2at.wallet.profile, store.tz2at.wallet.lifecycle, store.tz2at.wallet.objktProfile, wallet-token edges, wallet-contract edges, wallet inventory projections, identity wallet links, domain ownership, social profile artifacts, and relevant event copies. |
contracts.tz2at.store | Contract noun repos. Tokens live under their minting contract repo, not as separate repos. | store.tz2at.contract.profile, store.tz2at.contract.lifecycle, store.tz2at.contract.objktProfile, store.tz2at.token.definition, store.tz2at.token.metadata, contract-token edges, relevant contract events, and token marketplace or OBJKT group edges. |
marketplaces.tz2at.store | Marketplace noun repos for contracts and market venues. | store.tz2at.marketplace.profile, marketplace collect/swap/bid records, token-market edges, and marketplace-related projections. |
currencies.tz2at.store | Currency noun repos for currencies referenced by market records. | store.tz2at.currency.profile and related market context where OBJKT or chain records identify the payment asset. |
platforms.tz2at.store | Platform noun repos for systems such as Tezos, OBJKT, Etherlink, and jstz. | store.tz2at.platform.profile, platform-scoped context, selected OBJKT group/project/curation artifacts, and platform-derived event copies. |
chains.tz2at.store | Chain noun repos for Tezos mainnet, Shadownet, Etherlink, and jstz networks. | store.tz2at.chain.profile, chain-level block or network context, and high-level provenance anchors. |
Handle repos are deterministic. For example, a Tezos wallet becomes a slug under wallets.tz2at.store, while a FA2 contract becomes a slug under contracts.tz2at.store. Appviews should treat these repos as source-indexed public fact stores and semantic anchors for the nouns in Tezos statements.
Record Types
Canonical Chain And Marketplace Events
| Collection | Meaning |
|---|---|
store.tz2at.block | Block-level anchor record for a Tezos block. |
store.tz2at.transaction | Generic transaction fact with source, destination, amount, status, and operation hash. |
store.tz2at.origination | Contract origination fact. |
store.tz2at.internal.operation | Internal operation observation. |
store.tz2at.xtz.flow | XTZ value flow between accounts/contracts. |
store.tz2at.account.activity | Account activity summary record for query convenience. |
store.tz2at.contract.call | Contract call fact for relevant contracts. |
store.tz2at.bigmap.update | Bigmap mutation fact when a decoder emits it. |
store.tz2at.fa2.transfer | FA2 token transfer with contract, from, to, token ID, and amount. |
store.tz2at.fa12.transfer | FA1.2 transfer with contract, from, to, and value. |
store.tz2at.fa2.operatorUpdate | FA2 operator add/remove update. |
store.tz2at.marketplace.collect | Marketplace collect/purchase fact. |
store.tz2at.marketplace.swap | Marketplace listing/swap fact. |
store.tz2at.marketplace.bid | Marketplace bid or auction offer fact. |
store.tz2at.raw.observation | Source-specific observation used when the raw source contains context that does not fit a safer semantic record yet. |
Semantic Profiles, Tokens, And Edges
| Collection | Meaning |
|---|---|
store.tz2at.wallet.profile | Canonical wallet noun profile. |
store.tz2at.wallet.lifecycle | Permanent wallet genesis and last-seen boundary anchors written by the lifecycle historian. |
store.tz2at.wallet.objktProfile | Permanent lightweight OBJKT wallet profile, stats, and sample context. |
store.tz2at.contract.profile | Canonical contract noun profile. |
store.tz2at.contract.lifecycle | Permanent contract genesis and last-seen boundary anchors written by the lifecycle historian. |
store.tz2at.contract.objktProfile | Permanent lightweight OBJKT contract profile, stats, and sample context. |
store.tz2at.marketplace.profile | Canonical marketplace noun profile. |
store.tz2at.currency.profile | Canonical currency noun profile. |
store.tz2at.platform.profile | Canonical platform noun profile. |
store.tz2at.chain.profile | Canonical chain/network noun profile. |
store.tz2at.token.definition | Token identity record stored in the contract repo. |
store.tz2at.token.metadata | Token metadata enrichment, usually from OBJKT or a metadata hydration route. |
store.tz2at.objkt.group | OBJKT project, curation, or selected exhibition group. |
store.tz2at.edge.walletToken | Graph edge linking a wallet to a token. |
store.tz2at.edge.walletContract | Graph edge linking a wallet to a contract. |
store.tz2at.edge.contractToken | Graph edge linking a contract to one of its tokens. |
store.tz2at.edge.tokenMarketplace | Graph edge linking a token to a marketplace. |
store.tz2at.edge.tokenObjktGroup | Graph edge linking a token to an OBJKT project, curation, or selected exhibition. |
Identity And Projections
| Collection | Meaning |
|---|---|
store.tz2at.identity.walletLink | Evidence that a DID has linked or proven control of a wallet. |
store.tz2at.identity.domainOwnership | Tezos Domains ownership badge or proof artifact. |
store.tz2at.identity.socialProfile | Social profile identities discovered from Tezos/OBJKT profile data. |
store.tz2at.projection.walletInventory | Derived wallet inventory snapshot for appview convenience. |
store.tz2at.projection.tokenOwnerState | Derived token owner state. |
store.tz2at.projection.tokenMarketState | Derived token market state. |
OBJKT Enrichment
OBJKT is a second ingestion route, not a replacement for the rolling Tezos indexer. TZ2AT uses OBJKT streams to add marketplace and token context that is hard to derive from raw chain events alone.
Hot OBJKT streams
token_streamfor token identity and metadata context.event_streamfor OBJKT event rows that can be paired to chain operations.- Listing, active listing, sale, offer, auction, and open-edition streams for market state.
fa_stream,marketplace_contract_stream, andcurrency_streamfor contract, venue, and currency context.referral_streamfor referral/gamification records with social value.- Filtered project and curation virtual streams derived from OBJKT gallery streams.
- Filtered ACTZ exhibition streams for selected ACTZ gallery exhibitions.
Broad streams intentionally skipped
TZ2AT does not hot-subscribe to unrestricted holder, creator, attribute, royalty, rarity, generic gallery, operator, or TzD streams. Those are too broad for hot ingestion and belong behind scoped hydration or appview-specific requests.
Wallets And Hydration
Users connect to an appview with any AT Protocol identity, then prove control of Tezos wallets. TZ2AT creates or discovers wallet repos under wallets.tz2at.store and writes verifiable wallet-link records. Users choose whether matching records remain retrievable from TZ2AT, are copied to their personal PDS, or both.
When an appview needs historic wallet data, it should wake a background hydration worker. That worker polls TzKT and feeds the resulting records into the same converter/storage/firehose path as normal ingestion, without slowing the rolling indexer.
Lifecycle anchors are eviction-proof records. Wallet and contract repos can keep fixed genesis and last-seen lifecycle records plus a fixed objkt profile record even when ordinary hot event copies age out.
Public API
| Endpoint | Use |
|---|---|
GET /health | Rolling indexer health and head lag status. |
GET /ops/status | Operator view of indexer, provisioning, backfill, and archive readiness. |
GET /replay?fromLevel=N&toLevel=M | Replay canonical records by block range. |
WS /firehose | JSON firehose for relay events. |
GET /wallet/:address/activity | Hot wallet activity projection. |
POST /links/wallet | Link a DID to a wallet. |
POST /identity/tzbsky/wallet | Link wallets and discover Tezos Domains or social profile artifacts. |
POST /hydrate/wallet | Synchronous wallet hydration for smaller jobs. |
POST /hydrate/wallet/async | Start a background wallet hydration job. |
GET /hydrate/jobs/:jobId | Poll an async hydration job. |
GET /api/semantic/nouns | List noun registry entries by network/category/status. |
GET /api/semantic/tokens | List token refs. |
GET /api/semantic/tokens/:network/:contract/:tokenId | Token owner and market projection. |
GET /api/semantic/wallets/:network/:address/inventory | Wallet inventory projection. |
const ws = new WebSocket("wss://tz2at.xyz/firehose");
Operational Rules
- The rolling indexer must start from current head and stay at head.
- Backfill, hydration, OBJKT enrichment, entity repo provisioning, and archive movement are separate workers.
- The default entity historian is lifecycle-only. Full historic replay requires explicit maintenance mode or appview/user hydration.
- Hot storage should keep as much useful fresh data as disk permits. Retention should be tuned from observed growth, not guessed during an incident.
- OBJKT ingestion must be selective. Broad streams should fail closed unless a scoped worker is deliberately introduced.
- Records should be cross-indexed into the PDS tree by noun category so appviews can query the repo that matches the thing they are displaying.
Manual version: current live architecture as of 2026-05-28.