API Reference
Factory & Contracts

Factory & Contracts API

GET /api/factory tells you which community factory is live, which collections it offers, and which characters a token name in each collection may contain. Read it at startup instead of hardcoding a contract address.

All paths are relative to https://api.superhero.com. Reads need no authentication.

Method & pathReturns
GET /api/factoryThe active community factory schema
GET /api/contractsDeprecated. A one-element array naming the factory
GET /api/statsIndexer sync state, uptime and API version

GET /api/factory

curl -s "https://api.superhero.com/api/factory"
FieldTypeMeaning
addressstringct_... of the live CommunityFactory contract
deployed_at_block_heightnumberHeight the factory was deployed at. GET /api/stats reports it as bclBlockNumber
bctsl_aex9_addressstringct_... of the protocol's own AEX-9 token
affiliation_addressstringct_... of the AffiliationTreasury
collectionsobjectMap of full collection id to collection data

Each entry in collections is keyed by its own id:

FieldTypeMeaning
idstringFull collection id, NAME-ak_deployer, the same string as the map key
namestringHuman-readable label, used as the badge on a token
descriptionstringOptional
allowed_name_lengthstringMaximum token name length in this collection. Parse it
allowed_name_charsarray of rule objectsWhich characters a name may contain

The schema is cached in memory for the process lifetime, so the payload is cheap and stable.

Fetch it once and cache it. Pick a collection by id or name rather than by position:

const factorySchema = await fetch('https://api.superhero.com/api/factory').then(r => r.json());
const collection = Object.values(factorySchema.collections).find(c => c.name === 'WORDS');

allowed_name_chars

Each rule is one of exactly two forms: a set of single code points, or an inclusive code point range:

allowedNameChars = SingleChar(int) | CharRangeFromTo(int, int)
[
  { "SingleChar": [45] },
  { "CharRangeFromTo": [48, 57] },
  { "CharRangeFromTo": [65, 90] }
]

That is the English WORDS collection: -, then 0 through 9, then A through Z. Turn it into a validator by mapping each rule to a character-class fragment:

function allowedNameCharsToPattern(rules) {
  return (rules || []).map((rule) => {
    if (rule.SingleChar?.length) {
      return rule.SingleChar.map((c) => String.fromCodePoint(c)).join('');
    }
    if (rule.CharRangeFromTo?.length === 2) {
      const [start, end] = rule.CharRangeFromTo;
      return start > end ? '' : `${String.fromCodePoint(start)}-${String.fromCodePoint(end)}`;
    }
    return '';
  }).join('');
}
// then: new RegExp(`^[${pattern}]+$`, 'u')

Escape -, \, ], ^ and [ before putting them in a character class, and keep the u flag so astral code points count as one character.

Because the rules come from the server, a name written in Chinese, Arabic or Russian is matched to its collection automatically, and a collection added later is picked up with no client change.

Collection metadata on a token

TokenDto carries collection (the id string) and collection_info, a resolved CollectionInfoDto with id, name, description and allowed_name_length. collection_info is null when the token has no collection or the collection is unknown to the factory. See Tokens.

Filter the token list by collection directly:

# Every token in the Chinese collection
curl -s "https://api.superhero.com/api/tokens?collection=CHINESE&limit=20"

collection accepts all (the default), a bare collection name, or a full collection id.

Detecting a factory upgrade

There is no version field and no upgrade notification. Instead:

  1. GET /api/factory returns address. Cache it; a change means a new factory is live.
  2. Every token carries factory_address. Tokens minted by an older factory keep pointing at it, so factory_address on a TokenDto is a reliable record of provenance.
  3. GET /api/tokens?factory_address=ct_... filters the token list to one deployment.

When address changes, re-derive everything you hold that depends on it: the factory address, the collection ids and the AffiliationTreasury address, which is affiliation_address on the same response.

The social posting contract (ct_2Hyt9ZxzXra5NAzhePkRsDPDWppoatVD7CtHnUoHVbuehwR8Nb on mainnet), governance and DEX addresses are not covered by this endpoint; see Contract addresses.

GET /api/contracts

Deprecated. Returns a one-element array naming the current factory:

[{ "contractId": "ct_25cqTw85wkF5cbcozmHHUCuybnfH9WaRZXSgEcNNXG9LsCJWTN",
   "description": "Community Factory" }]

Migrate by replacing contracts[0].contractId with factory.address from GET /api/factory.

GET /api/stats

The indexer's own status page.

curl -s "https://api.superhero.com/api/stats"
FieldTypeMeaning
fullSyncingbooleanThe backward indexer is running
currentBlockNumbernumberThe chain tip height the indexer knows about
bclBlockNumbernumberThe factory's deployed_at_block_height, the floor of interesting history
syncingLatestBlocksbooleanSame value as fullSyncing
lastSyncedBlockNumbernumberHow far down from the tip the backward sync has reached
remainingBlocksToSyncnumberlastSyncedBlockNumber minus 0, because the backward sync targets genesis
apiVersionstringThe deployed package version
mdwConnectedbooleanWhether the middleware WebSocket subscription is up
uptimestringHuman-readable, e.g. 3d 4h 12m 8s
uptimeDurationSecondsnumberThe same as a number

Read mdwConnected and the gap between currentBlockNumber and lastSyncedBlockNumber before trusting that a recent trade is indexed. GET /api/mdw/health gives a more detailed version of the same picture; see Node & Middleware. For platform metrics rather than indexer health, use Analytics.

Related