This repository contains the backend server for the Rubix Network decentralized explorer Rubix Explorer. It tracks DIDs, tokens, and real-time network transactions.
- Real-Time Data: Integrates an IPFS node to subscribe to the
rubix_txnsPubSub topic for live transactions updates. - Dynamic Processing: Utilizes a highly concurrent processor that dynamically scales worker count based on system load.
- RESTful API: Exposes endpoints for real-time network statistics (total tokens, DIDs, SCs), specific token/transaction retrieval, and DID holding balances.
The explorer operates as a real-time reactive system, processing high volumes of decentralized network events through a highly concurrent pipeline.
graph TD
A[Rubix Network] -- PubSub: rubix_txns --> B[IPFS PubSub Client]
B -- Raw JSON/Base64 --> C[processor.TxnCallBack]
C -- EventTransaction --> D[processor.HandleIncomingTxn]
D -- Enqueue --> E[Dynamic Worker Pool]
E -- ProcessDBTransaction --> F[Database Persistence]
subgraph "Persistence Layer (database/operations)"
F --> G[SaveEventTransaction]
F --> H[SaveTransactionDetails]
F --> I[ProcessTransactionAssets]
I --> J[Update Tokens Table]
I --> K[Update TokenChain/Provenance]
I --> L[Update DIDBalances/Analytics]
end
- PubSub Ingestion: The server subscribes to the
rubix_txnstopic. Incoming messages are decoded (Base64/JSON) and unmarshaled into theEventTransactionmodel. - Validation:
HandleIncomingTxnperforms strict regex-based validation on all DIDs and TokenIDs before any database interaction occurs. - Dynamic Worker Pool: Validated transactions are enqueued into a worker pool that dynamically scales based on the current workload, ensuring the system remains responsive during traffic spikes.
- Atomic Transactions: All asset updates (Tokens, Provenance, and Balances) are performed within a single database transaction to ensure data integrity.
- Flattening: The complex, nested transaction payload is simplified into a flattened
TransactionInfostructure for fast frontend filtering and search. - Provenance Handling: The
TokenChainandTokenChainArraytables work together to maintain a logically sequenced history of every token's movement across the network. - Real-Time Analytics: The
DIDBalancestable is updated incrementally (increments/decrements) during each transaction, allowing for instant "Top Holders" lookups without expensive full-table scans.
Configure your .env (see .env.example).
MainNet (Default)
go run .TestNet
go run . -testnetCustom Network (Private)
go run . -swarmkey config/custom_swarm.keyBuild the executable first:
go build -o explorer.exe .MainNet (Default)
./explorer.exeTestNet
./explorer.exe -testnetCustom Network (Private)
./explorer.exe -swarmkey config/custom_swarm.keyAll requests follow standard REST principles. Pagination parameters limit (default 10) and page (default 1) are supported on all list endpoints.
GET /api/get-info?id=<id>- Input Sample (DID):
/api/get-info?id=bafybm... - Input Sample (Token):
/api/get-info?id=Qm... - Input Sample (Transaction):
/api/get-info?id=txn_...(or IPFS hash) - Parameters:
id(string, required) - Response Model:
api.SearchResult(polymorphic)
- Input Sample (DID):
All count APIs take no inputs and return a JSON object with a single key-value pair.
GET /api/get-rbt-count->{"all_rbt_count": 1250}GET /api/get-ft-count->{"all_ft_count": 5400}GET /api/get-nft-count->{"all_nft_count": 320}GET /api/get-sc-count->{"all_sc_count": 45}GET /api/get-txn-count->{"all_transaction_count": 89000}GET /api/get-did-count->{"all_did_count": 1200}
List endpoints return a plain JSON array of objects. All support limit and page query parameters. Returns an empty array [] if no records found.
-
GET /api/get-latest-transactions- Input Sample:
/api/get-latest-transactions?limit=10&page=1 - Response Model:
[]models.TransactionInfo - Fields:
transaction_id,initiator,owner,epoch,network,tokens,committedTokens,quorums,memo,created_at.
- Input Sample:
-
GET /api/get-did-with-most-rbts- Input Sample:
/api/get-did-with-most-rbts?limit=5 - Response Model:
[]models.DIDBalance - Fields:
did,asset_type,token_name,balance,last_update.
- Input Sample:
-
GET /api/get-rbt-list,GET /api/get-nft-list,GET /api/get-sc-list- Input Sample:
/api/get-rbt-list?limit=10 - Response Model:
[]models.Token - Fields:
token_id,parent_token_id,token_value,token_status,did,transaction_id,token_type,data,created_at,updated_at.
- Input Sample:
-
GET /api/get-ft-group-list- Input Sample:
/api/get-ft-group-list - Response Model:
[]model.FTGroup - Fields:
ftName,count,creatorDID.
- Input Sample:
Returns simple ID/Name lists for frontend address bar suggestions.
-
GET /api/search-rbt-suggestions?query=<prefix>&limit=10- Input Sample:
/api/search-rbt-suggestions?query=1_&limit=5 - Response Model:
[]model.RBTSuggestion
- Input Sample:
-
GET /api/search-ft-suggestions?query=<prefix>&limit=10- Input Sample:
/api/search-ft-suggestions?query=app - Response Model:
[]model.FTSuggestion
- Input Sample:
-
GET /api/get-rbt-info?tokenId=<id>- Response Model:
model.RBTInfo(TokenID, OwnerDID, TokenValue)
- Response Model:
-
GET /api/get-ft-info?ftName=<name>&creatorDID=<did>- Response Model:
model.FTInfo(FTName, CreatorDID, TotalAmount, CreatedTime)
- Response Model:
-
GET /api/get-ft-top-holders?ftName=<name>&creatorDID=<did>- Response Model:
model.FTTopHoldersResponse(Holders array, TotalCount, Page/Limit)
- Response Model:
Supports the network graph view by providing ancestor linkages.
-
GET /api/dagtxns- Description: Returns the latest 1000 transactions for the global graph view.
- Response Model:
[]models.TransactionInfo
-
GET /api/dagtxn/{txnID}?depth=100- Description: Returns the specific transaction and its ancestors up to
depthlevels, following theTokenChain. - Response Model:
model.DAGResponse(Transactions array + Edges array)
- Description: Returns the specific transaction and its ancestors up to
-
GET /api/get-transaction-info?transactionID=<id>- Input Sample:
/api/get-transaction-info?transactionID=txn_123 - Response Model:
models.TransactionInfo
- Input Sample:
-
GET /api/get-token-info?tokenID=<id>- Input Sample:
/api/get-token-info?tokenID=Qm... - Response Model:
models.Token
- Input Sample:
-
GET /api/get-transaction-info-list?tokenID=<id>- Input Sample:
/api/get-transaction-info-list?tokenID=Qm...&limit=5 - Response Model:
[]models.TransactionInfo
- Input Sample:
-
GET /api/get-transaction-id-list?tokenID=<id>- Input Sample:
/api/get-transaction-id-list?tokenID=Qm... - Response Model:
[]models.TokenChain - Fields:
id,token_id,transaction_id,role,previous_transaction_id,created_at.
- Input Sample: