> For the complete documentation index, see [llms.txt](https://docs.xhash.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.xhash.com/staking/staking-api.md).

# 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>
