Skip to content

身份验证 ​

所有对TRXUp API的请求都需要使用Bearer令牌和签名进行身份验证。这确保了您的API请求的安全性和完整性。

获取API凭据 ​

要开始使用TRXUp API,您需要从控制面板获取API凭据:

  1. 登录 TRXUp 客户面板
  2. 在侧边栏的账户下打开 API 访问
  3. 点击创建凭据

令牌和签名密钥只在创建的那一刻显示一次。密钥此后不再显示——既不会显示片段,也不会再出现在该页面。若丢失,请重新签发一对。

API 访问页面

在同一页面上,您可以把这对凭据限制到自己服务器发起调用的 IP 地址。限制之后,即使签名正确,来自其他地址的请求也会被拒绝。

TIP

请确保您的API凭据安全,永远不要公开分享它们。您的API密钥应像密码一样对待。

必需的请求头 ​

请求头描述
Authorization: Bearer YOUR_API_TOKEN您的API令牌
X-Signature: YOUR_SIGNATURE请求签名
Content-Type: application/json内容类型必须为JSON

签名计算 ​

签名通过请求体与您的API密钥连接后的SHA256哈希值计算。

bash
signature=$(echo -n "$requestBody$apiSecret" | sha256sum | cut -d' ' -f1)

不同语言的示例 ​

bash
#!/bin/bash
API_TOKEN="your_api_token"
API_SECRET="your_api_secret"
REQUEST_BODY='{"service":"energy","params":{"address":"TRX_ADDRESS","energy_amount":65000,"duration":1}}'

# 计算签名
SIGNATURE=$(echo -n "${REQUEST_BODY}${API_SECRET}" | sha256sum | cut -d' ' -f1)

# 发送API请求
curl -X POST "https://api.trxup.com/v1/transaction/new" \
  -H "Authorization: Bearer ${API_TOKEN}" \
  -H "X-Signature: ${SIGNATURE}" \
  -H "Content-Type: application/json" \
  -d "${REQUEST_BODY}"
javascript
const crypto = require('crypto');
const axios = require('axios');

const apiToken = 'your_api_token';
const apiSecret = 'your_api_secret';
const requestBody = JSON.stringify({
  service: 'energy',
  params: {
    address: 'TRX_ADDRESS',
    energy_amount: 65000,
    duration: 1
  }
});

// 计算签名
const signature = crypto
  .createHash('sha256')
  .update(requestBody + apiSecret)
  .digest('hex');

// 发送API请求
axios({
  method: 'post',
  url: 'https://api.trxup.com/v1/transaction/new',
  headers: {
    'Authorization': `Bearer ${apiToken}`,
    'X-Signature': signature,
    'Content-Type': 'application/json'
  },
  data: requestBody
})
.then(response => console.log(response.data))
.catch(error => console.error(error));
php
<?php
$apiToken = 'your_api_token';
$apiSecret = 'your_api_secret';
$requestBody = json_encode([
  'service' => 'energy',
  'params' => [
    'address' => 'TRX_ADDRESS',
    'energy_amount' => 65000,
    'duration' => 1
  ]
]);

// 计算签名
$signature = hash('sha256', $requestBody . $apiSecret);

// 发送API请求
$ch = curl_init('https://api.trxup.com/v1/transaction/new');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $requestBody);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
  'Authorization: Bearer ' . $apiToken,
  'X-Signature: ' . $signature,
  'Content-Type: application/json'
]);

$response = curl_exec($ch);
curl_close($ch);

echo $response;
?>
python
import hashlib
import json
import requests

api_token = 'your_api_token'
api_secret = 'your_api_secret'
request_body = json.dumps({
  'service': 'energy',
  'params': {
    'address': 'TRX_ADDRESS',
    'energy_amount': 65000,
    'duration': 1
  }
})

# 计算签名
signature = hashlib.sha256((request_body + api_secret).encode()).hexdigest()

# 发送API请求
headers = {
  'Authorization': f'Bearer {api_token}',
  'X-Signature': signature,
  'Content-Type': 'application/json'
}

response = requests.post(
  'https://api.trxup.com/v1/transaction/new',
  headers=headers,
  data=request_body
)

print(response.json())

签名版本2(可选) ​

签名版本2是对同样的请求进行签名的一种可选的、更安全的方式。按请求启用:在请求中发送X-Signature-Version: 2请求头即可。没有该请求头或带有X-Signature-Version: 1的请求,仍完全按照上文所述进行校验,因此现有集成无需任何改动。版本1将继续可用,切换没有截止日期;对于新的集成,我们建议使用版本2。

版本2新增的保护:

  • 签名与端点绑定。 方法和路径也参与签名,因此为/v1/subscription/check签名的请求无法被重放到/v1/subscription/stop。
  • 5分钟后过期。 签名中的时间戳与服务器时钟的偏差不得超过300秒。
  • 每个已签名的请求只会被接受一次。 已签名的nonce不能重复使用,因此被截获的请求无法被重放。

必需的请求头(版本2) ​

请求头描述
Authorization: Bearer YOUR_API_TOKEN您的API令牌,与版本1相同
X-Signature-Version: 2为此请求选择签名版本2
X-Timestamp: 1761040800当前Unix时间(秒),十进制整数
X-Nonce: 7f3c9a12b4e8d05c每个请求唯一的值:由A–Z a–z 0–9 . _ ~ -组成的8–128个字符(UUID或16个以上随机十六进制字符均可)。切勿重复使用nonce
X-Signature: YOUR_SIGNATURE请求签名,计算方法见下文
Content-Type: application/json内容类型必须为JSON

签名计算(版本2) ​

X-Signature是以您的API密钥为key、对以下字符串计算的HMAC-SHA256,以小写十六进制表示:

text
METHOD + "\n" + PATH + "\n" + X-Timestamp + "\n" + X-Nonce + "\n" + BODY
  • METHOD为POST(所有/v1端点均使用POST)。
  • PATH为与实际发送完全一致的请求路径,不含主机名,也不含查询字符串,例如/v1/transaction/new。
  • X-Timestamp和X-Nonce与您发送的请求头的值完全一致。
  • BODY为请求体的原始字节,须完全一致(请求体为空时为空字符串)。请对实际发送的字节签名:如果签名后再次序列化JSON,签名将无法匹配。
  • "\n"为单个换行符(0x0A)。请求体之后没有换行符。

服务器先校验签名,然后校验X-Timestamp与服务器自身时钟的偏差在任一方向上不超过300秒(5分钟),最后校验您的账户此前未使用过该nonce(nonce会被记住约11分钟)。请使用NTP同步您服务器的时钟。重试即是一个新请求:需要新的时间戳、新的nonce和新的签名。

测试向量 ​

调用API之前,请先用以下数值检查您的代码:

输入值
API密钥your_api_secret
方法POST
路径/v1/transaction/new
X-Timestamp1761040800
X-Nonce7f3c9a12b4e8d05c
请求体{"service":"energy","params":{"address":"TRX_ADDRESS","energy_amount":65000,"duration":1}}

待签名字符串(共五行,最后一行之后没有换行符):

text
POST
/v1/transaction/new
1761040800
7f3c9a12b4e8d05c
{"service":"energy","params":{"address":"TRX_ADDRESS","energy_amount":65000,"duration":1}}

预期的X-Signature:

text
56576e1faecaca2b2533bee6124e7ece2b023665addb2f2e79b8ac83bf8104e8

错误(版本2) ​

校验失败时返回与版本1相同的HTTP 401响应,"code": 1。签名、时间戳或nonce错误或缺失,以及X-Signature-Version不是1或2时,返回常见的Incorrect token or signature。只有在签名有效之后,才可能出现以下两条更具体的消息:

  • X-Timestamp is N seconds from this server's clock; at most 300 either way is accepted —— 您的时钟有偏差:请使用NTP同步。
  • This X-Nonce was already used; every request needs a new one —— 请为每个请求(包括重试)生成新的nonce。

版本2在不同语言中的示例 ​

bash
#!/bin/bash
API_TOKEN="your_api_token"
API_SECRET="your_api_secret"
REQUEST_PATH="/v1/transaction/new"
REQUEST_BODY='{"service":"energy","params":{"address":"TRX_ADDRESS","energy_amount":65000,"duration":1}}'

# A new timestamp and nonce for every request
TIMESTAMP=$(date +%s)
NONCE=$(openssl rand -hex 16)

# Calculate signature: METHOD\nPATH\nTIMESTAMP\nNONCE\nBODY, no trailing newline
SIGNATURE=$(printf '%s\n%s\n%s\n%s\n%s' "POST" "$REQUEST_PATH" "$TIMESTAMP" "$NONCE" "$REQUEST_BODY" \
  | openssl dgst -sha256 -hmac "$API_SECRET" | awk '{print $NF}')

# Make API request
curl -X POST "https://api.trxup.com${REQUEST_PATH}" \
  -H "Authorization: Bearer ${API_TOKEN}" \
  -H "X-Signature-Version: 2" \
  -H "X-Timestamp: ${TIMESTAMP}" \
  -H "X-Nonce: ${NONCE}" \
  -H "X-Signature: ${SIGNATURE}" \
  -H "Content-Type: application/json" \
  -d "${REQUEST_BODY}"
javascript
const crypto = require('crypto');
const axios = require('axios');

const apiToken = 'your_api_token';
const apiSecret = 'your_api_secret';
const requestPath = '/v1/transaction/new';
const requestBody = JSON.stringify({
  service: 'energy',
  params: {
    address: 'TRX_ADDRESS',
    energy_amount: 65000,
    duration: 1
  }
});

// A new timestamp and nonce for every request
const timestamp = Math.floor(Date.now() / 1000).toString();
const nonce = crypto.randomUUID();

// Calculate signature: METHOD\nPATH\nTIMESTAMP\nNONCE\nBODY
const payload = ['POST', requestPath, timestamp, nonce, requestBody].join('\n');
const signature = crypto
  .createHmac('sha256', apiSecret)
  .update(payload)
  .digest('hex');

// Make API request (send exactly the body that was signed)
axios({
  method: 'post',
  url: 'https://api.trxup.com' + requestPath,
  headers: {
    'Authorization': `Bearer ${apiToken}`,
    'X-Signature-Version': '2',
    'X-Timestamp': timestamp,
    'X-Nonce': nonce,
    'X-Signature': signature,
    'Content-Type': 'application/json'
  },
  data: requestBody
})
.then(response => console.log(response.data))
.catch(error => console.error(error));
php
<?php
$apiToken = 'your_api_token';
$apiSecret = 'your_api_secret';
$requestPath = '/v1/transaction/new';
$requestBody = json_encode([
  'service' => 'energy',
  'params' => [
    'address' => 'TRX_ADDRESS',
    'energy_amount' => 65000,
    'duration' => 1
  ]
]);

// A new timestamp and nonce for every request
$timestamp = (string) time();
$nonce = bin2hex(random_bytes(16));

// Calculate signature: METHOD\nPATH\nTIMESTAMP\nNONCE\nBODY
$payload = implode("\n", ['POST', $requestPath, $timestamp, $nonce, $requestBody]);
$signature = hash_hmac('sha256', $payload, $apiSecret);

// Make API request (send exactly the body that was signed)
$ch = curl_init('https://api.trxup.com' . $requestPath);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $requestBody);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
  'Authorization: Bearer ' . $apiToken,
  'X-Signature-Version: 2',
  'X-Timestamp: ' . $timestamp,
  'X-Nonce: ' . $nonce,
  'X-Signature: ' . $signature,
  'Content-Type: application/json'
]);

$response = curl_exec($ch);
curl_close($ch);

echo $response;
?>
python
import hashlib
import hmac
import json
import time
import uuid
import requests

api_token = 'your_api_token'
api_secret = 'your_api_secret'
request_path = '/v1/transaction/new'
# Compact separators: the same bytes as the test vector and the other examples
request_body = json.dumps({
  'service': 'energy',
  'params': {
    'address': 'TRX_ADDRESS',
    'energy_amount': 65000,
    'duration': 1
  }
}, separators=(',', ':'))

# A new timestamp and nonce for every request
timestamp = str(int(time.time()))
nonce = uuid.uuid4().hex

# Calculate signature: METHOD\nPATH\nTIMESTAMP\nNONCE\nBODY
payload = '\n'.join(['POST', request_path, timestamp, nonce, request_body])
signature = hmac.new(api_secret.encode(), payload.encode(), hashlib.sha256).hexdigest()

# Make API request (send exactly the bytes that were signed)
headers = {
  'Authorization': f'Bearer {api_token}',
  'X-Signature-Version': '2',
  'X-Timestamp': timestamp,
  'X-Nonce': nonce,
  'X-Signature': signature,
  'Content-Type': 'application/json'
}

response = requests.post(
  'https://api.trxup.com' + request_path,
  headers=headers,
  data=request_body.encode()
)

print(response.json())

Tron Energy API Documentation