Subgraph: Query stake.link Data with GraphQL
stake.link publishes a public subgraph that indexes the protocol’s Ethereum contracts. Query it with GraphQL to get reward history, total staked and holder balances without running your own indexer.
Endpoint
Section titled “Endpoint”https://graph-readonly.linkpool.pro/subgraphs/name/stakedotlink-ethereum-mainnet- Network: Ethereum mainnet
- Method:
POSTwith a JSON body{"query": "..."} - Authentication: none
- CORS: open to all origins, so you can call it directly from a browser
Quick start
Section titled “Quick start”curl -s https://graph-readonly.linkpool.pro/subgraphs/name/stakedotlink-ethereum-mainnet \ -H 'Content-Type: application/json' \ -d '{"query":"{ _meta { block { number timestamp } hasIndexingErrors } }"}'The _meta query returns the last indexed block. Use it to check that the data is up to date.
From JavaScript:
const SUBGRAPH = 'https://graph-readonly.linkpool.pro/subgraphs/name/stakedotlink-ethereum-mainnet';
async function querySubgraph(query, variables = {}) { const res = await fetch(SUBGRAPH, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query, variables }), }); const { data, errors } = await res.json(); if (errors) throw new Error(errors[0].message); return data;}Example queries
Section titled “Example queries”Latest stLINK reward distributions
Section titled “Latest stLINK reward distributions”Each rebase of the LINK StakingPool creates a LinkStakingDistribution entry.
{ linkStakingDistributions(first: 5, orderBy: ts, orderDirection: desc) { ts reward_rate reward_amount total_staked fee_percentage fees time_since_last_distribution tx_hash }}| Field | Meaning |
|---|---|
ts |
Unix timestamp of the distribution, in seconds |
reward_rate |
Annualized net reward rate (after fees) since the previous distribution, in percent |
reward_amount |
Gross rewards earned in this rebase, including fees, in wei (18 decimals) |
total_staked |
Total LINK staked, in wei |
fee_percentage |
Share of rewards taken as protocol fees, in percent |
fees |
Fees taken, in wei |
time_since_last_distribution |
Seconds since the previous distribution |
stPOL and stESP reward distributions
Section titled “stPOL and stESP reward distributions”polStakingDistributions and espStakingDistributions have the same core fields:
{ polStakingDistributions(first: 1, orderBy: ts, orderDirection: desc) { ts reward_rate total_staked } espStakingDistributions(first: 1, orderBy: ts, orderDirection: desc) { ts reward_rate total_staked }}Balances and rewards for an address
Section titled “Balances and rewards for an address”tokenHolder returns an address’s LST balances and the rewards it has earned. The id is the address in lowercase.
query Holder($id: ID!) { tokenHolder(id: $id) { stLinkBalance wstLinkBalance stLinkAllRewardsEarned stPolBalance stPolAllRewardsEarned stEspBalance stEspAllRewardsEarned sdlBalance }}Pass the address as a variable, for example {"id": "0x911d86c72155c33993d594b0ec7e6206b4c803da"}.
Largest stLINK holders
Section titled “Largest stLINK holders”{ tokenHolders(first: 10, orderBy: stLinkBalance, orderDirection: desc) { id stLinkBalance }}The largest holders include protocol contracts, such as the Priority Pool and the wstLINK wrapper. Compare against the contract addresses to filter them out.
Working with the data
Section titled “Working with the data”- Amounts are strings in wei. Token amounts are 18-decimal integers returned as strings. Divide by 1018 with a big-number library, not with JavaScript
Number. - Addresses are lowercase. Use lowercase addresses in
idandwherefilters. - Pagination: each query returns at most 1,000 items. Page with
firstandskip, or filter ontsfor long histories. - Explore the schema: every entity and field is available through GraphQL introspection. Open the endpoint in a GraphQL client such as Altair or Postman to browse it.