Subgraph Examples
This document provides a number of usable examples that you can use to obtain any information from the SSVNetwork smart contract using the subgraph.
The examples are provided in GraphQL to be used directly on the subgraph, Javascript to be used within code, or Curl to be used in any terminal.
These can be used on one of the official Subgraphs deployed, Ethereum Mainnet
Explorer for Hoodi will be available soon.
In the below Javascript and Curl examples we are using the Hoodi end point, to use the same queries on the Mainnet subgraph please use this endpoint:
https://api.studio.thegraph.com/query/71118/ssv-network-ethereum/version/latest
Account Nonce
Returns the nonce of an account.
- GraphQL
- JavaScript
- cURL
query AccountNonceQuery {
account(id: "0x09cef28c35a5fab6f5fdbf45603b8eaac7b8b797") {
nonce
}
}
const url = "https://api.studio.thegraph.com/query/71118/ssv-network-hoodi/version/latest";
const query = `
query AccountNonceQuery {
account(id: "0x09cef28c35a5fab6f5fdbf45603b8eaac7b8b797") {
nonce
}
}`;
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ query })
});
const responseData = await response.json();
console.log(responseData);
curl -X POST "https://api.studio.thegraph.com/query/71118/ssv-network-hoodi/version/latest" \
-H "Content-Type: application/json" \
-d '{
"query": "query AccountNonceQuery { account(id: \"0x09cef28c35a5fab6f5fdbf45603b8eaac7b8b797\") { nonce }}"
}'
Output:
{
"data": {
"account": {
"nonce": "0"
}
}
}
Cluster Snapshot
Returns the Cluster Snapshot needed in many smart contracts functions, like registering a validator.
Note: the cluster's id
is generated by concatenating the owner address and the operator IDs using a dash (-
) separator.
- GraphQL
- JavaScript
- cURL
query ClusterSnapshot {
cluster(id: "0x0f1651507bdd33d3d18a5732c22d4713020cd100-5-6-7-8") {
validatorCount
networkFeeIndex
index
active
balance
}
}
const url = "https://api.studio.thegraph.com/query/71118/ssv-network-hoodi/version/latest";
const query = `
query ClusterSnapshot {
cluster(id: "0x0f1651507bdd33d3d18a5732c22d4713020cd100-5-6-7-8") {
validatorCount
networkFeeIndex
index
active
balance
}
}`;
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ query })
});
const responseData = await response.json();
console.log(responseData);
curl -X POST "https://api.studio.thegraph.com/query/71118/ssv-network-hoodi/version/latest" \
-H "Content-Type: application/json" \
-d '{
"query": "query ClusterSnapshot { cluster(id: \"0x0f1651507bdd33d3d18a5732c22d4713020cd100-5-6-7-8\") { active balance index lastUpdateBlockNumber networkFeeIndex validatorCount }}"
}'
Output
{
"data": {
"cluster": {
"active": true,
"balance": "5353643967300000000",
"index": "34520824200",
"lastUpdateBlockNumber": "232527",
"networkFeeIndex": "0",
"validatorCount": "3"
}
}
}
DAO constants and protocol network fee index
Returns the value of important values set by the DAO (such as Minimum Liquidation Collatera, and Liquidation Threshold Period), as well as the protocol-wide Network Fee Index, needed to calculate the balance of clusters and verify their risk of liquidation.
Note: the id
of daovalues
is the address of the SSVNetwork smart contract deployed on the current chain. So in the case of Hoodi it's 0x58410Bef803ECd7E63B23664C586A6DB72DAf59c
- GraphQL
- JavaScript
- cURL
query daoValues {
daovalues(id: "0x58410Bef803ECd7E63B23664C586A6DB72DAf59c") {
declareOperatorFeePeriod
executeOperatorFeePeriod
liquidationThreshold
minimumLiquidationCollateral
networkFee
networkFeeIndex
networkFeeIndexBlockNumber
operatorFeeIncreaseLimit
operatorMaximumFee
}
}
const url = "https://api.studio.thegraph.com/query/71118/ssv-network-hoodi/version/latest";
const query = `
query daoValues {
daovalues(id: "0x58410Bef803ECd7E63B23664C586A6DB72DAf59c") {
declareOperatorFeePeriod
executeOperatorFeePeriod
liquidationThreshold
minimumLiquidationCollateral
networkFee
networkFeeIndex
networkFeeIndexBlockNumber
operatorFeeIncreaseLimit
operatorMaximumFee
}
}`;
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ query })
});
const responseData = await response.json();
console.log(responseData);
curl -X POST "https://api.studio.thegraph.com/query/71118/ssv-network-hoodi/version/latest" \
-H "Content-Type: application/json" \
-d '{
"query": "query daoValues { daovalues(id: \"0x58410Bef803ECd7E63B23664C586A6DB72DAf59c\") { declareOperatorFeePeriod executeOperatorFeePeriod liquidationThreshold minimumLiquidationCollateral networkFee networkFeeIndex networkFeeIndexBlockNumber operatorFeeIncreaseLimit operatorMaximumFee }}"
}'
Output
{
"data": {
"daovalues": {
"declareOperatorFeePeriod": "604800",
"executeOperatorFeePeriod": "60480",
"liquidationThreshold": "214800",
"minimumLiquidationCollateral": "1000000000000000000",
"networkFee": "382640000000",
"networkFeeIndex": "215784140000000",
"networkFeeIndexBlockNumber": "131572",
"operatorFeeIncreaseLimit": "1000",
"operatorMaximumFee": "76528650000000"
}
}
}
Cluster Balance Values
Returns all necessary data needed to compute the Cluster Balance.
- GraphQL
- JavaScript
- cURL
query clusterBalanceValues {
_meta {
block {
number
}
}
daovalues(id: " 0x58410Bef803ECd7E63B23664C586A6DB72DAf59c") {
networkFee
networkFeeIndex
networkFeeIndexBlockNumber
}
operators(where: {id_in: ["5", "6", "7", "8"]}) {
fee
feeIndex
feeIndexBlockNumber
}
cluster(id: "0x0f1651507bdd33d3d18a5732c22d4713020cd100-5-6-7-8") {
validatorCount
networkFeeIndex
index
balance
}
}
const url = "https://api.studio.thegraph.com/query/71118/ssv-network-hoodi/version/latest";
const query = `
query clusterBalanceValues {
_meta {
block {
number
}
}
daovalues(id: " 0x58410Bef803ECd7E63B23664C586A6DB72DAf59c") {
networkFee
networkFeeIndex
networkFeeIndexBlockNumber
}
operators(where: {id_in: ["5", "6", "7", "8"]}) {
fee
feeIndex
feeIndexBlockNumber
}
cluster(id: "0x0f1651507bdd33d3d18a5732c22d4713020cd100-5-6-7-8") {
validatorCount
networkFeeIndex
index
balance
}
}`;
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ query })
});
const responseData = await response.json();
console.log(responseData);
curl -X POST "https://api.studio.thegraph.com/query/71118/ssv-network-hoodi/version/latest" \
-H "Content-Type: application/json" \
-d '{
"query": "query clusterBalanceValues { _meta { block { number }} daovalues(id: \"0x58410Bef803ECd7E63B23664C586A6DB72DAf59c\") { networkFee networkFeeIndex networkFeeIndexBlockNumber } operators(where: {id_in: [\"5\", \"6\", \"7\", \"8\"]}) { fee feeIndex feeIndexBlockNumber } cluster(id: \"0x0f1651507bdd33d3d18a5732c22d4713020cd100-5-6-7-8\") { validatorCount networkFeeIndex index balance }}"
}'
Output
{
"data": {
"daovalues": {
"networkFee": "382640000000",
"networkFeeIndex": "215784140000000",
"networkFeeIndexBlockNumber": "131572"
},
"operators": [
{
"fee": "956600000000",
"feeIndex": "0",
"feeIndexBlockNumber": "20761"
},
{
"fee": "956600000000",
"feeIndex": "0",
"feeIndexBlockNumber": "20762"
},
{
"fee": "956600000000",
"feeIndex": "0",
"feeIndexBlockNumber": "20763"
},
{
"fee": "956600000000",
"feeIndex": "0",
"feeIndexBlockNumber": "20764"
}
],
"cluster": {
"validatorCount": "3",
"networkFeeIndex": "0",
"index": "34520824200",
"balance": "5353643967300000000"
},
"_meta": {
"block": {
"number": 239528
}
}
}
}
List of Validators for an owner
Returns a list of validators for an owner and displays whether they are active or not. Queries the first
5 validators owned by this address.
Note: it's always best to limit the query, to avoid flooding the API, reduce performance issues, and in case of production API, spend too many credits.
- GraphQL
- JavaScript
- cURL
query ListOfValidatorsPerOwner {
validators(
where: {owner: "0x0f1651507bdd33d3d18a5732c22d4713020cd100"}
first: 5
) {
id
owner {
id
}
active
}
}
const url = "https://api.studio.thegraph.com/query/71118/ssv-network-hoodi/version/latest";
const query = `
query ListOfValidatorsPerOwner {
validators(
where: {owner: "0x0f1651507bdd33d3d18a5732c22d4713020cd100"}
first: 5
) {
id
owner {
id
}
active
}
}`;
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ query })
});
const responseData = await response.json();
console.log(responseData);
curl -X POST "https://api.studio.thegraph.com/query/71118/ssv-network-hoodi/version/latest" \
-H "Content-Type: application/json" \
-d '{
"query": "query ListOfValidatorsPerOwner { validators(where: {owner: \"0x0f1651507bdd33d3d18a5732c22d4713020cd100\"}) { id owner { id }}}"
}'
Output
{
"data": {
"validators": [
{
"id": "0x82808139fefab04eec339d1e4137b0e7d05eb75ec5eacdfe0b6f8d1cf2151b9f46ff3854e3ac5f44467fdc86bdbca345",
"owner": {
"id": "0x0f1651507bdd33d3d18a5732c22d4713020cd100"
}
},
{
"id": "0x86825ffcf382b1202e9280ec91d32f9d81cb38281438091839da60a2e9429af09fc9b643f8f4bcd81361bd0a53de5789",
"owner": {
"id": "0x0f1651507bdd33d3d18a5732c22d4713020cd100"
}
},
{
"id": "0x8bd2ecade0c1569802ef23fcde281ea27c7b3a005840808addcfa33d838d599b518ac189f10591d76f74d67190ffe460",
"owner": {
"id": "0x0f1651507bdd33d3d18a5732c22d4713020cd100"
}
}
]
}
}
Validator Data by ID (Active status and Operator IDs)
Returns operator IDs and active status for a validator.
- GraphQL
- JavaScript
- cURL
query ValidatorData {
validator(
id: "0x80033d71f582fb41315ed3e697d7012b8101fb2e9153a9cd3dc3bf9ff3da240c92848fba366c619bdb2aca3e4b0367ef"
) {
removed
operators(first: 10) {
operatorId
}
}
}
const url = "https://api.studio.thegraph.com/query/71118/ssv-network-hoodi/version/latest";
const query = `
query ValidatorData {
validator(
id: "0x80033d71f582fb41315ed3e697d7012b8101fb2e9153a9cd3dc3bf9ff3da240c92848fba366c619bdb2aca3e4b0367ef"
) {
removed
operators(first: 10) {
operatorId
}
}
}`;
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ query })
});
const responseData = await response.json();
console.log(responseData);
curl -X POST "https://api.studio.thegraph.com/query/71118/ssv-network-hoodi/version/latest" \
-H "Content-Type: application/json" \
-d '{
"query": "query ValidatorData { validator(id: \"0x80033d71f582fb41315ed3e697d7012b8101fb2e9153a9cd3dc3bf9ff3da240c92848fba366c619bdb2aca3e4b0367ef\") { removed operators(first: 10) { operatorId }}}"
}'
Output
{
"data": {
"validator": {
"removed": false,
"operators": [
{
"operatorId": "108"
},
{
"operatorId": "111"
},
{
"operatorId": "74"
},
{
"operatorId": "88"
}
]
}
}
}
Cluster Data by ID (Balance, Active status and Operator IDs)
Returns balance, active status and operator IDs for a cluster.
Note: the cluster's id
is generated by concatenating the owner address and the operator IDs using a dash (-
) separator.
- GraphQL
- JavaScript
- cURL
query ClusterData {
cluster(id: "0x0f1651507bdd33d3d18a5732c22d4713020cd100-5-6-7-8") {
active
validators {
id
owner {
id
}
}
validatorCount
}
}
const url = "https://api.studio.thegraph.com/query/71118/ssv-network-hoodi/version/latest";
const query = `
query ClusterData {
cluster(id: "0x0f1651507bdd33d3d18a5732c22d4713020cd100-5-6-7-8") {
active
validators {
id
owner {
id
}
}
validatorCount
}
}`;
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ query })
});
const responseData = await response.json();
console.log(responseData);
curl -X POST "https://api.studio.thegraph.com/query/71118/ssv-network-hoodi/version/latest" \
-H "Content-Type: application/json" \
-d '{
"query": "query ClusterData { cluster(id: \"0x0f1651507bdd33d3d18a5732c22d4713020cd100-5-6-7-8\") { active validators { id owner { id } } validatorCount }}"
}'
Output:
{
"data": {
"cluster": {
"active": true,
"validators": [
{
"id": "0x82808139fefab04eec339d1e4137b0e7d05eb75ec5eacdfe0b6f8d1cf2151b9f46ff3854e3ac5f44467fdc86bdbca345",
"owner": {
"id": "0x0f1651507bdd33d3d18a5732c22d4713020cd100"
}
},
{
"id": "0x86825ffcf382b1202e9280ec91d32f9d81cb38281438091839da60a2e9429af09fc9b643f8f4bcd81361bd0a53de5789",
"owner": {
"id": "0x0f1651507bdd33d3d18a5732c22d4713020cd100"
}
},
{
"id": "0x8bd2ecade0c1569802ef23fcde281ea27c7b3a005840808addcfa33d838d599b518ac189f10591d76f74d67190ffe460",
"owner": {
"id": "0x0f1651507bdd33d3d18a5732c22d4713020cd100"
}
}
],
"validatorCount": "3"
}
}
}
Operator data by ID (Validator count, Fee, private and active status)
Returns validator count, fee, and active status.
- GraphQL
- JavaScript
- cURL
query ValidatorCountPerOperator {
operator(id: "7") {
fee
removed
totalWithdrawn
isPrivate
validatorCount
whitelisted {
id
}
}
}
const url = "https://api.studio.thegraph.com/query/71118/ssv-network-hoodi/version/latest";
const query = `
query ValidatorCountPerOperator {
operator(id: "7") {
fee
removed
totalWithdrawn
isPrivate
validatorCount
whitelisted {
id
}
}
}`;
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ query })
});
const responseData = await response.json();
console.log(responseData);
curl -X POST "https://api.studio.thegraph.com/query/71118/ssv-network-hoodi/version/latest" \
-H "Content-Type: application/json" \
-d '{
"query": "query ValidatorCountPerOperator { operator(id: \"7\") { fee removed totalWithdrawn validatorCount isPrivate whitelisted { id } }}"
}'
Output:
{
"data": {
"operator": {
"fee": "956600000000",
"removed": false,
"totalWithdrawn": "0",
"validatorCount": "318",
"isPrivate": false,
"whitelisted": []
}
}
}
10 most recent clusters with a validator count of 4
Returns data on the 10 most recent clusters, we get this by the last updated blocks and using orderBy: lastUpdateBlockNumber
and sort it by descending using orderDirection: desc
- GraphQL
- JavaScript
- cURL
query ClusterQuery {
clusters(
first: 10
where: {validatorCount: "4"}
orderBy: lastUpdateBlockNumber
orderDirection: desc
) {
validatorCount
lastUpdateBlockNumber
id
}
}
const url = "https://api.studio.thegraph.com/query/71118/ssv-network-hoodi/version/latest";
const query = `
query ClusterQuery {
clusters(
first: 10
where: {validatorCount: "4"}
orderBy: lastUpdateBlockNumber
orderDirection: desc
) {
validatorCount
lastUpdateBlockNumber
id
}
}`;
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ query })
});
const responseData = await response.json();
console.log(responseData);
curl -X POST "https://api.studio.thegraph.com/query/71118/ssv-network-hoodi/version/latest" \
-H "Content-Type: application/json" \
-d '{
"query": "query ClusterQuery { clusters(first: 10 where: {validatorCount: \"4\"} orderBy: lastUpdateBlockNumber orderDirection: desc) { validatorCount lastUpdateBlockNumber id }}"
}'
Output:
{
"data": {
"clusters": [
{
"validatorCount": "4",
"lastUpdateBlockNumber": "239598",
"id": "0xd5822eeeb87c2dcd41b307a741ce993d62baf21b-5-6-7-8"
}
]
}
}