# Staking API

## Preparation <a href="#preparation" id="preparation"></a>

Before you use API, you need to login the website to create API Key with proper permissions.

You can manage your API Keys [here](https://www.xhash.com/usercenter).

Please remember below information after creation:

* `Access Key`: It is used in API request
* `Private Key`: It is used to generate the signature (<mark style="color:red;">only visible once after creation</mark>)

{% hint style="info" %}
Every user can create at most 10 API Keys，every API Key can bind maximum 10 IP address.
{% endhint %}

## Interface URL

<https://stakingapi.xhash.com:18000>

## Authentication <a href="#id-138a6766" id="id-138a6766"></a>

* All interfaces are requested using the private key signature and public key verification
* The request header contains the following signature information:

```
access_key: The 'accessKey' in your API Key
sign: The value after signed, it uses MD5withRSA, MD5withRSA(requestBody+timestamp), requestBody equal "" if no request param。
timestamp: The time stamp（ms）
```

* All interfaces use **post** requests with **request parameters** placed in requestBody

<pre><code>such as : /api/v1/xhash/getUserDailyIncome
<strong>header：
</strong>"access_key"："50CEA00402A84BFF9B47CF44A947DA0B"
"sign"："sEm3E4qD8fD7mb54SxJLKajf28gItAkHNjk44QJgrjRqh9XQX6xNMdhsKXSAabcfQ77Mpp/PI6i9hW1XPnfkrLKDlAeaTMXKWxQaRKryzB99p782Re0mRoWFW1iZcvaUFzgb3aY3Oj7/xD0Qz6Y+cg/SZGM6KcTC2IL3PosoWPk="
"timestamp"："1666854104527"

<strong>requestBody：
</strong><strong>{
</strong>    "pageNum": 1,
    "pageSetNum": 10
}
</code></pre>

* Response Format

```
  {
      "code": "",
      "data": object,
      "msg": ""
  }
  
  code="200" is success, other is fail
```

## Example

{% tabs %}
{% tab title="Java" %}
{% file src="/files/s9UUXFSxNho5erd79bgE" %}

```
String accessKey = "A95B2CFA7B1940B799EFCE792AD...";
String privateKey = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAMQzb3GI8fTGUUXaZsZxnLBWnihO9iSua4z7v9tY...";
String url = "https://stakingapi.xhash.com:18000/api/v1/xhash/getUserDailyIncome";

Map<String, Object> requestBody = new HashMap<>();
requestBody.put("pageNum", 1);
requestBody.put("pageSetNum", 10);

String content = new GsonBuilder().serializeNulls().create().toJson(requestBody);

long timestamp = System.currentTimeMillis();
System.out.println(content + timestamp);
String sign = RSACoder.sign((content + timestamp).getBytes(), privateKey);

HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("access_key",accessKey);
httpHeaders.add("timestamp",timestamp + "");
httpHeaders.add("sign",sign);

HttpEntity<String> httpEntity = new HttpEntity<>(content, httpHeaders);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> result = restTemplate.postForEntity(url, httpEntity, String.class);
System.out.println(result);
```

{% endtab %}

{% tab title="Python" %}

```
import requests
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import MD5
import base64
import time
import calendar

url = "https://stakingapi.xhash.com:18000/api/v1/xhash/getUserDailyIncome"
accessKey = "0EDF9F7653344B10808972B287832727..."
privatekey="MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAN7ALyd..."
datajson = '{"pageNum":1,"pageSetNum":10}'
timestamp = str(int(round(calendar.timegm(time.gmtime())*1000)))
data = datajson + (timestamp)

private_keyBytes = base64.b64decode(privatekey)
prikey = RSA.importKey(private_keyBytes)
signer = PKCS1_v1_5.new(prikey)
hash_obj = MD5.new(data.encode('utf-8'))
signtrue = base64.b64encode(signer.sign(hash_obj))
sign = str(signtrue)[2:-1]

headers = {
  'access_key': accessKey,
  'sign': sign,
  'timestamp': timestamp
}
result = requests.post(url, headers=headers, data=datajson)
print(result.text)
```

{% endtab %}

{% tab title="Node" %}

```
const https = require('https');
const crypto = require('crypto');
const accessKey = "0EDF9F7653344B10808972B28C..."
const privateKey = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAN7ALyd8Bkx..."

const signer = (json) => {
    const privateKeys = "-----BEGIN PRIVATE KEY-----\n" + privateKey + "\n-----END PRIVATE KEY-----"
    const sign = crypto.createSign('md5');
    sign.update(json);
    return sign.sign(privateKeys, 'base64');
}

const postData = JSON.stringify({
    "pageNum": 1,
    "pageSetNum": 10
})

const timestamp = new Date().valueOf()
const dataJsonStr = `${postData}${timestamp}`
const sign = signer(dataJsonStr)
const options = {
    method: 'POST',
    host: 'stakingapi.xhash.com',
    port: 18000,
    path: '/api/v1/xhash/getUserDailyIncome',
    headers: {
        'access_key': accessKey,
        'sign': sign,
        'timestamp': timestamp
    }
};

var req = https.request(options, (res) => {
    res.setEncoding('utf8');
    res.on('data', (chunk) => {
        console.log(`${chunk}`);
    });
});

req.write(postData);
req.end();
```

{% endtab %}
{% endtabs %}

## Interface details

### Get user balance and unpaid amount

**HTTP Request**

`POST /api/v1/xhash/getUserStatus`

**RequestBody**

No param

**Response**

<table><thead><tr><th></th><th width="108"></th><th width="252"></th><th></th></tr></thead><tbody><tr><td><strong>Parameter</strong></td><td><strong>Data Type</strong></td><td><strong>Description</strong></td><td><strong>remark</strong></td></tr><tr><td>clBalance</td><td>int</td><td>balance of consensus-layer</td><td>Gwei</td></tr><tr><td>waitPayment</td><td>float</td><td>balance of execution-layer</td><td>Gwei</td></tr></tbody></table>

**Example**

```
{
  "code": "200",
  "data": {
    "clBalance": 1446286721091,
    "waitPayment": 1596525011
  },
  "msg": "Success"
}
```

### Get user detail status

**HTTP request**

`POST /api/v1/xhash/getUserDetailStatus`

**RequestBody**\
No param

**Response**

<table><thead><tr><th width="241"></th><th width="108"></th><th width="252"></th><th></th></tr></thead><tbody><tr><td><strong>Parameter</strong></td><td><strong>Data Type</strong></td><td><strong>Description</strong></td><td><strong>remark</strong></td></tr><tr><td>validatorsOnline</td><td>int</td><td>validators num online</td><td></td></tr><tr><td>validatorsOffline</td><td>int</td><td>validators num offline</td><td></td></tr><tr><td>totalBalance</td><td>string</td><td>balance of consensus-layer</td><td>Gwei</td></tr><tr><td>totalChange</td><td>string</td><td>total reward (Execution+consensus)</td><td>Gwei</td></tr><tr><td>hoursIncome24</td><td>string</td><td><p>24 hour reward</p><p>(Execution+consensus)</p></td><td>Gwei</td></tr><tr><td>partailWithdrawalsAmount</td><td>number</td><td>consensus withdrawals amount</td><td>Gwei</td></tr><tr><td>waitPayment</td><td>string</td><td>execution-layer wait payment</td><td>Gwei</td></tr><tr><td>pendingPayment</td><td>string</td><td>execution-layer pending payment</td><td>Gwei</td></tr><tr><td>paid</td><td>string</td><td>execution-layer paid</td><td>Gwei</td></tr><tr><td>avgRealApr</td><td>float</td><td>average apr of all validators</td><td></td></tr></tbody></table>

**Example**

```
{
    "code": "200",
    "data": {
        "validatorsOnline": 45,
        "validatorsOffline": 0,
        "totalBalance": "1440081374281",
        "totalChange": "48615375055.435027176",
        "hoursIncome24": "236051566.84745468",
        "partailWithdrawalsAmount": 35685091263,
        "waitPayment": "400428103.199571345",
        "pendingPayment": "0",
        "paid": "13441757945.295420862",
        "avgRealApr": 0.05681605041
    },
    "msg": "Success"
}
```

###

### Get user daily Income

**HTTP Request**

`POST /api/v1/xhash/getUserDailyIncome`

**RequestBody**

<table><thead><tr><th width="149"></th><th width="124"></th><th></th><th width="117"></th><th width="192"></th></tr></thead><tbody><tr><td><strong>Parameter</strong></td><td><strong>Data Type</strong></td><td><strong>Required</strong></td><td><strong>Default</strong></td><td><strong>Description</strong></td></tr><tr><td>pageNum</td><td>int</td><td>true</td><td>-</td><td>Number of pages [1,...]</td></tr><tr><td>pageSetNum</td><td>int</td><td>true</td><td>-</td><td>Number each page [10,100]</td></tr></tbody></table>

**Response**

<table><thead><tr><th></th><th width="116"></th><th width="296"></th><th></th></tr></thead><tbody><tr><td><strong>Parameter</strong></td><td><strong>Data Type</strong></td><td><strong>Description</strong></td><td><strong>remark</strong></td></tr><tr><td>userId</td><td>int</td><td>user ID</td><td></td></tr><tr><td>totalReward</td><td>float</td><td>total reward</td><td>Eth</td></tr><tr><td>clReward</td><td>float</td><td>consensus-layer reward</td><td>Eth</td></tr><tr><td>elReward</td><td>float</td><td>execution-layer reward</td><td>Eth</td></tr><tr><td>mevReward</td><td>float</td><td>mev reward of execution-layer</td><td>Eth</td></tr><tr><td>txReward</td><td>float</td><td>txfee reward of execution-layer</td><td>Eth</td></tr><tr><td>rewardDay</td><td>int</td><td>timestamp of reward day</td><td>second</td></tr><tr><td>validatorNum</td><td>int</td><td>number of validators generating revenue that day</td><td></td></tr><tr><td>total</td><td>int</td><td>number of all rewards</td><td></td></tr></tbody></table>

**Example**

```
{
  "code": "200",
  "data": {
    "pageNum": 1,
    "pageData": [
      {
        "userId": 123456,
        "totalReward": 0.15852195658793655,
        "clReward": 0.142707974,
        "elReward": 0.01581398258793658,
        "mevReward": 0.001352162267224239,
        "txReward": 0.014461820320712356,
        "rewardDay": 1666569600,
        "validatorNum": 2
      },
      ...
      ...
    ],
    "total": 27
  },
  "msg": "Success"
}
```

### Get user payment history

**HTTP Request**

`POST /api/v1/xhash/getUserPaymentHistory`

**RequestBody**

<table><thead><tr><th width="149"></th><th width="124"></th><th></th><th width="117"></th><th width="192"></th></tr></thead><tbody><tr><td><strong>Parameter</strong></td><td><strong>Data Type</strong></td><td><strong>Required</strong></td><td><strong>Default</strong></td><td><strong>Description</strong></td></tr><tr><td>pageNum</td><td>int</td><td>true</td><td>-</td><td>Number of pages [1,...]</td></tr><tr><td>pageSetNum</td><td>int</td><td>true</td><td>-</td><td>Number each page [10,100]</td></tr></tbody></table>

**Response**

<table><thead><tr><th></th><th width="116"></th><th width="296"></th><th></th></tr></thead><tbody><tr><td><strong>Parameter</strong></td><td><strong>Data Type</strong></td><td><strong>Description</strong></td><td><strong>remark</strong></td></tr><tr><td>userId</td><td>int</td><td>user ID</td><td></td></tr><tr><td>realAmount</td><td>float</td><td>payment amount</td><td>Eth</td></tr><tr><td>chainAmount</td><td>float</td><td>execution-layer amount on chain</td><td>Eth</td></tr><tr><td>withHoldTxFee</td><td>float</td><td>tx fee withholding</td><td>Eth</td></tr><tr><td>realTxFee</td><td>float</td><td>tx fee on chain</td><td>Eth</td></tr><tr><td>retained</td><td>float</td><td>tx feen retained</td><td>Eth</td></tr><tr><td>txHash</td><td>string</td><td>tx hash on chain</td><td></td></tr><tr><td>status</td><td>int</td><td>payment status</td><td>0:paying, 1:finished</td></tr><tr><td>chainTime</td><td>int </td><td>the time on chain</td><td></td></tr><tr><td>updateTime</td><td>int </td><td>payment update time</td><td></td></tr><tr><td>total</td><td>int</td><td>number of all rewards</td><td></td></tr></tbody></table>

**Example**

```
{
  "code": "200",
  "data": {
    "pageNum": 1,
    "pageData": [
      {
        "userId": 123456,
        "realAmount": 0.148897612,
        "chainAmount": 0,
        "withHoldTxFee": 0.148897612,
        "realTxFee": 0,
        "retained": 0,
        "txHash": "",
        "status": 0,
        "chainTime": 0,
        "updateTime": 1666842847
      }
    ],
    "total": 1
  },
  "msg": "Success"
}
```

### Get user validator list

**HTTP Request**

`POST /api/v1/xhash/getUserValidatorList`

**RequestBody**

<table><thead><tr><th width="149"></th><th width="124"></th><th></th><th width="103"></th><th width="192"></th></tr></thead><tbody><tr><td><strong>Parameter</strong></td><td><strong>Data Type</strong></td><td><strong>Required</strong></td><td><strong>Default</strong></td><td><strong>Description</strong></td></tr><tr><td>pageNum</td><td>int</td><td>true</td><td>-</td><td>Number of pages [1,...]</td></tr><tr><td>pageSetNum</td><td>int</td><td>true</td><td>-</td><td>Number each page [10,100]</td></tr></tbody></table>

**Response**

<table><thead><tr><th width="211"></th><th width="116"></th><th width="296"></th><th></th></tr></thead><tbody><tr><td><strong>Parameter</strong></td><td><strong>Data Type</strong></td><td><strong>Description</strong></td><td><strong>remark</strong></td></tr><tr><td>id</td><td>int</td><td>sequence id</td><td></td></tr><tr><td>userId</td><td>int</td><td>user ID</td><td></td></tr><tr><td>validatorIndex</td><td>int</td><td>validator index</td><td></td></tr><tr><td>validatorPublicKey</td><td>string</td><td>validator publicKey</td><td></td></tr><tr><td>totalIncome</td><td>int</td><td>consensus-layer income</td><td>Gwei</td></tr><tr><td>effectiveBalance</td><td>int</td><td>consensus-layer effective balance</td><td>Gwei</td></tr><tr><td>finalizedBalance</td><td>int</td><td>consensus-layer finalized balance </td><td>Gwei</td></tr><tr><td>currentBalance</td><td>int</td><td>consensus-layer balance </td><td>Gwei</td></tr><tr><td>currentEffectiveness</td><td>string</td><td>effectiveness</td><td></td></tr><tr><td>apr</td><td>float</td><td>apr by 7 day</td><td></td></tr><tr><td>node_status</td><td>string</td><td>validator status in xhash</td><td></td></tr><tr><td>chain_status</td><td>string</td><td>consensus-layer status</td><td></td></tr><tr><td>created_time</td><td></td><td>timestamp in xhash</td><td>second</td></tr><tr><td>total</td><td>int</td><td>number of all rewards</td><td></td></tr></tbody></table>

**Example**

```
{
  "code": "200",
  "data": {
    "pageNum": 1,
    "pageData": [
      {
        "id": 45,
        "userId": 123456,
        "validatorIndex": 429489,
        "validatorPublicKey": "0x827b58e886b0024022120a549a7a50bc2b44b51e0d09663d5f543c17fba3f2ec3faf30126979241d0fd1297838de74d8",
        "totalIncome": 118681206,
        "effectiveBalance": 32000000000,
        "finalizedBalance": 32118648446,
        "currentBalance": 32118648446,
        "currentEffectiveness": 99.01,
        "apr": 0.03623521,
        "node_status": "Active",
        "chain_status": "Active",
        "created_time": 1663310642
      },
      ...
      ...
    ],
    "total": 45
  },
  "msg": "Success"
}
```

### Get consensus-layer withdrawals

**HTTP Request**

`POST /api/v1/xhash/getUserPartailWithdrawals`

**RequestBody**

<table><thead><tr><th width="149"></th><th width="124"></th><th></th><th width="103"></th><th width="192"></th></tr></thead><tbody><tr><td><strong>Parameter</strong></td><td><strong>Data Type</strong></td><td><strong>Required</strong></td><td><strong>Default</strong></td><td><strong>Description</strong></td></tr><tr><td>pageNum</td><td>int</td><td>true</td><td>-</td><td>Number of pages [1,...]</td></tr><tr><td>pageSetNum</td><td>int</td><td>true</td><td>-</td><td>Number each page [10,100]</td></tr></tbody></table>

**Response**

<table><thead><tr><th width="211"></th><th width="116"></th><th width="296"></th><th></th></tr></thead><tbody><tr><td><strong>Parameter</strong></td><td><strong>Data Type</strong></td><td><strong>Description</strong></td><td><strong>remark</strong></td></tr><tr><td>id</td><td>int</td><td>sequence id</td><td></td></tr><tr><td>userId</td><td>int</td><td>userId</td><td></td></tr><tr><td>validatorIndex</td><td>int</td><td>validator index</td><td></td></tr><tr><td>validatorPublicKey</td><td>string</td><td>validator publicKey</td><td></td></tr><tr><td>blockSlot</td><td>int</td><td>slot</td><td></td></tr><tr><td>withdrawalIndex</td><td>int</td><td>withdrawal Index</td><td></td></tr><tr><td>address</td><td>string</td><td>withdrawal address</td><td></td></tr><tr><td>amount</td><td>float</td><td>withdrawal amount</td><td>eth</td></tr><tr><td>createdTime</td><td>long</td><td>timestamp,second</td><td></td></tr></tbody></table>

**Example**

```
{
    "code": "200",
    "data": {
        "pageNum": 1,
        "pageData": [
            {
                "id": 0,
                "userId": 101527,
                "validatorIndex": 429481,
                "validatorPublicKey": "0xac34188ca2c6ec29e40534229698d38fc733908c34eeecd77df0f477481344b10fcebbabbb9cc233a09390d1afb6121d",
                "blockSlot": 6281691,
                "withdrawalIndex": 1122084,
                "address": "0x0708f87a089a91c65d48721aa941084648562287",
                "amount": "0.012279707",
                "createdTime": 1682204315
            },
            ...
            ...
        ],
        "total": 135
    },
    "msg": "Success"
}
```

##

## Error Code

<table><thead><tr><th width="284"></th><th></th></tr></thead><tbody><tr><td><strong>code</strong></td><td><strong>message</strong></td></tr><tr><td>200</td><td>success</td></tr><tr><td>400</td><td>Param error</td></tr><tr><td>401</td><td>Authentication failed</td></tr><tr><td>403</td><td>Ip not on whitelist</td></tr><tr><td>404</td><td>Path Not Found</td></tr><tr><td>405</td><td>Request timestamp expire</td></tr><tr><td>429</td><td>Requests has exceeded the per second limit</td></tr><tr><td>500</td><td>Server error</td></tr><tr><td>4001</td><td>Select user balance failed</td></tr><tr><td>4002</td><td>Page invalid</td></tr><tr><td>4003</td><td>Select user reward failed</td></tr><tr><td>4004</td><td>Select user payments history failed</td></tr><tr><td>4005</td><td>Select validator list failed</td></tr></tbody></table>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.xhash.com/staking/staking-api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
