Stock Ledger Get started
Integration

Reading the registry

Three kinds of consumer, three shapes of the same data: a venue that needs marks and events, a pool or basket that needs allocations, and an interface that needs to tell a user what happened to their position.

Status. The registry is being seeded contract by contract, starting with the nine that have already received an action. The interfaces described here are the published shape of the product: field names and semantics are stable, coverage is not yet complete. Where a page describes behaviour that is not live for a given name, it says so.

There is no endpoint of ours

You do not integrate against a service we run. You point your own client at a public RPC node for chain 4663 and get the same answers we get. That is the whole design: a register nobody can quietly edit is worth more than an API nobody can audit.

Which also means there is nothing to sign up for, nothing to rate limit, and nothing that can go down and take your marks with it. Quickstart is the shortest version: three calls, no dependencies, five minutes.

The whole read surface

Four values and one topic cover everything on this site. Hand-encode them and you are done; a full ABI coder is forty kilobytes of dependency for four calls that take no arguments.

What you needHow to get it
Is this contract realeth_getCode: 283 bytes, beacon inside
The current factoreth_call selector 0xa60bf13d
Every corporate actioneth_getLogs on one topic, no address filter
A holder's raw balanceeth_call selector 0x70a08231
Decimals for the scalingeth_call selector 0x313ce567

The topic is 0x2205df4534432b2f60654a3fdb48737ffdaf3e9edb1a498bd985bc026b15b055, which is keccak256("UIMultiplierUpdated(uint256,uint256,uint256)"). Factors carry 18 decimals.

Resolve the contract before anything else

A ticker is not an identifier on this chain and neither is a name: 1,130 contracts answer to AAPL and four of them wear Apple's name. Identity is bytecode, and the test is two lines:

const code = await rpc('eth_getCode', [address, 'latest']);
const real = (code.length - 2) / 2 === 283 &&
  code.toLowerCase().includes('e10b6f6b275de231345c20d14ab812db62151b00');

When more than one candidate passes, or none does, return nothing rather than a guess. On a chain where 348 contracts copy the naming scheme, an honest empty answer beats a confident wrong one.

A venue

Pull the log for the addresses you list and keep each entry's before and after value. Three things matter, and each of them has already bitten someone on this chain:

  • Do not apply the multiplier twice. The Chainlink feed already includes it. Multiplying the oracle price by uiMultiplier() double counts the dividend.
  • Read absolute values. Take the after figure the event carries, never a running product of deltas. Deltas compound wrongly when an event is emitted twice, and two of the fifteen events on this chain are repeats. Compose them and CRWD comes out at sixteen instead of four.
  • Use the effective time, not the emission block. They differ, sometimes by a lot: the same effective time appears twice in this log, 150,000 blocks apart.

A pool or a basket

A pool holding wrappers accrues value it cannot attribute: the pool contract got richer, and the chain says nothing about whose share of it that was. Take the holder list at the effective block, split the step across it, and settle the remainder by largest remainder rather than by rounding each share on its own. Book that at the moment it applies, instead of discovering the drift against the benchmark at the end of the quarter.

An interface

The smallest useful integration is one line in a position view: the current factor, the last event that moved it, and the date. That single row is the whole product from the user's side.

Conventions

  • Factors and amounts are decimal strings. Do not parse them into floats.
  • Timestamps are UTC. Dates without a time are calendar dates in the listing venue's time zone.
  • Records are versioned and corrections are re-emitted; treat id plus version as the key.
  • balanceOf returns the raw balance and never the UI amount. Scaling is a decision: make it once, deliberately, and never on top of a price that already includes the factor.
  • There are no rate limits and no API keys, because there is no service to rate limit.

Think a figure here is wrong? Reproduce it first: every number on this site comes from a call listed above, and the block it was read at is printed in the footer. If the chain disagrees with us, the chain is right and we are behind.