跳到主要內容

Building a Block Explorer with ARC: The UI Starts in AFS

Robert
ARCAFSAUPBlockchainBlock ExplorerEverything is Context

Chain Explorer home with entity counts, recent transactions, and tokens

Chain Explorer in production, October 24, 2026. Cropped to the data browsing area.

Our Block Explorer now runs on ARC. It looks like a familiar blockchain explorer: find a transaction, open an account, inspect a token, and follow its related records. Look at the source, though, and the application itself is mostly AUP declarations.

The interesting part is why that works. ARC exposes ArcBlock chain data as addressable resources in AFS. The Explorer uses AUP to describe how those resources appear and how people browse them. The provider and shared runtime handle the query adaptation and UI machinery, so the application can reuse them.

It is also a concrete answer to a question we hear: has working on ARC pushed blockchain aside? The chain now has a place among ARC's built-in system resources. The Explorer is a complete application using that support.

Put the chain in the filesystem

AFS, the Agentic File System, provides a common path and operation interface across different resource backends. This does not mean downloading the blockchain into local files. The chain service still supplies the data; ARC's OCAP provider turns query results into AFS entries.

The default main and beta networks appear at /dev/chain/main and /dev/chain/beta. Here is the part of one network's resource tree relevant to this walkthrough:

text
/dev/chain/main/
  transactions/{hash}
  accounts/{address}/
    transactions/
    tokens/
  tokens/{address}/
    transactions/
    holders/
  assets/
  factories/
  stakes/
  bridges/

Use list for a collection and read for an individual transaction. Follow paths to an account's transactions or a token's holders. The application uses the same interface throughout. The provider translates pagination and query conditions into OCAP GraphQL requests.

There is a useful boundary here. This implementation is a read-only view of the entities and queries exposed by the provider. It does not imply that every underlying chain datum, signing operation, or broadcast operation is available through AFS. It does cover a substantial part of what an explorer needs to browse.

The mount belongs to the host: the ARC instance running these applications. Explorer does not declare a separate chain connection in its own manifest, and other applications on the same host can use the same paths. Chain access becomes reusable infrastructure.

Explorer declares where to look

AUP, the Agentic UI Protocol, describes interfaces through structured declarations. Nodes specify component types, data sources, properties, and events. A shared runtime presents them to the user.

This excerpt from the Explorer's main page definition captures the idea. Only the relevant fields are shown:

json
{
  "id": "primary-surface",
  "type": "surface",
  "src": "/dev/chain/main",
  "props": {
    "variant": "data-browser",
    "mountRoot": "/dev/chain/main",
    "urlSync": "loc",
    "urlSelect": "loc",
    "urlSyncMode": "push"
  }
}

It points a browsing surface at a data tree and keeps its location synchronized with the URL. The surrounding page adds navigation, search, and a network selector. There is no transaction-specific fetch-and-render function in this declaration.

Site bindings connect a browser URL such as /main/tokens/an-address to /dev/chain/main/tokens/an-address. Switching to beta moves the browsing location into another tree with the same structure. Both networks use the same interface description.

That is how an application with its own URL, navigation, and detail pages can be a declarative blocklet. The runtime and provider still contain implementation code. Explorer avoids maintaining another copy of that machinery.

Follow a transaction to its token

Open a recent transaction from the home page. This example is a Transfer V3. Its hash identifies the transaction, its type describes the operation, and its status reports the execution result. Sender and Receiver identify the parties.

Transfer V3 detail showing status, participants, and execution receipts

Production transaction detail, October 24, 2026. Receipts expose the changes caused by the transaction.

Receipts tell us more than “Success.” In this example they show the token quantity changes for two accounts. The Raw tab provides the underlying data for closer inspection. An individual record becomes a set of relationships the reader can follow.

Click AIGNEP in a receipt to reach its token page. A token is an entity with its own address and state. Its page exposes the identifier, issuer, display precision, and permissions. Transactions and Top Holders lead to related collections.

AIGNEP token detail with its identifier, issuer, decimal precision, and permissions

Production token detail, October 24, 2026. Quantities are a snapshot at capture time.

Precision matters to presentation. Integer quantities from the chain need the token's decimal value to become readable units. A field-format declaration expresses that rule, so each table does not have to implement it again.

Data comes with a description of its view

If the main page only says “browse this tree,” how does the runtime know which fields belong on a token page? The OCAP provider ships AUP recipes: view templates for its entities, alongside the data adapter.

The runtime can read these templates through .aup entries on the mounted tree. Collections have collection views; individual entities have detail views. Explorer can use those descriptions as it moves through the tree. The chain data and the UI descriptions have separate origins: recipes ship with the provider and are not stored on the blockchain.

Here is the core of the holders list in the token detail recipe, with some columns and properties omitted:

json
{
  "id": "tok-tab-holders-list",
  "type": "afs-list",
  "src": "${_parentPath}/holders",
  "props": {
    "layout": "table",
    "columns": [
      { "key": "content.address", "label": "Address", "format": "did" },
      { "key": "content._tokenBalance", "label": "Balance",
        "format": "bignum:@{content._tokenDecimal}",
        "symbol": "@{content._tokenSymbol}" }
    ],
    "pageSize": 10,
    "pagination": "manual"
  }
}

_parentPath is the current token's path. Appending /holders selects its holders collection. The rest declares a table, address and balance fields, token-specific numeric formatting, and pagination.

This is what declarative means in practice. The data source, view composition, and field presentation are readable declarations. The provider still performs queries and necessary data preparation; shared renderers still implement tables and interactions. The application is small because those jobs already have a home.

A dynamic application goes beyond page generation

Much of our website uses Web Device to generate pages suited to publishing and indexing. Explorer shows another use of ARC: the browsing location changes, query conditions change, and the chain data being inspected keeps changing too.

Click a hash and the runtime reads that entity and presents its detail. Switch tabs to read a related collection. Turn a page to request the next batch. These operations do not wait for a website build. The server can render the initial page, while subsequent interactions continue in an AUP session.

Transaction events have a live update path as well. With a subscription-capable data source, the OCAP provider listens for tx.create and emits an AFS append event pointing at transactions/{hash}. UI lists consume these events through the shared runtime.

That path depends on the data source and deployment adapter supporting subscriptions. Reads remain available when a subscription cannot be established. Live transaction notifications also do not make every statistic a per-event stream: chain-level aggregate queries currently have a 30-second cache. Dynamic reads, transaction notifications, and immediate changes to every field are different guarantees.

For the application developer, the useful result is that Explorer does not need its own chain-specific event transport and DOM update implementation. AUP declarations can describe an interactive application over changing data.

People browse pages; agents read the same resources

Explorer also makes a core AFS application principle visible: people and agents are both first-class citizens. A person can understand a transaction through a web page. An agent can work with regular paths and structured fields. Both access the same chain resources.

For the Transfer V3 above, a person opens the detail page to inspect its status, participants, and receipts. An agent can read the corresponding AFS entry directly:

bash
arc afs read /dev/chain/main/transactions/D892B951049B2FA859769D56F236682E3F700830ACE002A44615DD1D321F1274

The entry carries transaction data in content, with consistent entity information supplied by the provider. An agent can read fields such as hash, type, time, and participants, then follow the token or list its holders and transactions. The provider's exposed capabilities determine what is accessible.

Table layout, abbreviated addresses, and the currently selected tab do not change how these resources are addressed. An agent does not have to download the page, parse a complex DOM, and infer which visual column represents the sender. It can keep using data paths when the presentation changes.

People do not have to read JSON either. AUP presents these resources as browsable pages with useful fields and related links. People get a readable interface; agents get a usable data interface. AFS connects these two ways of using the application, treating both people and agents as first-class citizens.

Where to start building a similar view

Try the main or beta network. The former browser entry points at main.abtnetwork.io and beta.abtnetwork.io now redirect to their respective network pages here.

To read the implementation, start with the chain-explorer blocklet. Its manifest defines the site and path bindings; .aup defines the shell and browsing surface. Then open the OCAP provider and compare its data routes with its aup/ recipes. Together they explain the application.

In a local ARC installation with the default chain devices available, you can inspect the data before opening a UI:

bash
arc afs list /dev/chain
arc afs list /dev/chain/main/tokens
arc afs read /dev/chain/main/tokens/z35nQNyuhz8wXi9uZkmLw9HYJLk4DSaJV3hoC

The first command checks the default networks: it should list main and beta. For custom networks, see the Explorer README.

For a similar application, establish which data the provider already exposes. Decide which collections need lists, which entities need detail views, and where a click should take the reader. With an existing provider, most of that work is view definition. A new data source still needs an adapter. Signing and transaction submission need their own authorization and execution handling.

The application definition is the simple part

Explorer makes blockchain support in ARC tangible. Chain data has stable paths. The provider prepares entities and related queries. AUP turns those resources into an application people can browse continuously.

The result still feels like a normal Block Explorer. What changed is how we define it: we compose existing resources into views, using shared data access and UI behavior. Blockchain has a concrete place in ARC, and AUP has a dynamic application working with real chain data every day. People follow the web interface; agents follow AFS paths. The same application treats both as first-class users of those resources.