Документация
Справочник RPC API
HTTP-интерфейс, который узел отдаёт кошелькам: четыре метода, JSON для состояния и ошибок и компактное двоичное кодирование блоков и платежей.
Тестовая сеть: монеты ничего не стоят
Адрес публичного тестового узла — https://node.tint.top. Интерфейс никогда не видит ключей и сумм: кошелёк отправляет готовые платежи и читает целые блоки, которые расшифровывает сам.
Методы
| Метод и путь | Что отвечает |
|---|---|
GET /v1/status | Где сейчас цепочка, в JSON. |
GET /v1/blocks/{height} | Один финализированный блок в проводном кодировании. |
GET /v1/blocks?from=N | Блоки с платежами начиная с высоты N, пачкой блоков. |
POST /v1/transactions | Принимает платёж в проводном кодировании; отвечает его идентификатором в JSON. |
GET /v1/status
curl -s https://node.tint.top/v1/status{
"chain_id": 6073471695170043905,
"height": 128431,
"tip": "9f3c…e21a",
"genesis": "04b7…c9d0",
"queued": 0,
"pools": [
{ "asset": 1, "native": 20000000000000, "other": 10000000000000, "fee_bps": 30 }
]
}| Поле | Смысл |
|---|---|
chain_id | Идентификатор сети, вшитый в каждую подпись и хеш блока. |
height | Высота последнего финализированного блока. |
tip | Хеш последнего финализированного блока, hex. |
genesis | Хеш первого блока, hex. У двух тестовых сетей может быть один chain_id; по этому хешу их различают. |
queued | Платежей, ожидающих блока. |
pools[].asset | Монета, которую пул обменивает на родную (1 — TUSD). |
pools[].native, pools[].other | Что держит пул, в единицах (1 монета = 100 000 000 единиц), на последнем финализированном блоке. |
pools[].fee_bps | Комиссия пула в десятитысячных долях; 30 — это 0,3 %. |
GET /v1/blocks/{height}
Возвращает один финализированный блок как application/octet-stream. Финализированный блок не меняется, поэтому в ответе Cache-Control: public, max-age=31536000, immutable. Нечисловая высота даёт invalid_height, неизвестная — not_found.
GET /v1/blocks?from=N
Возвращает блоки с платежами начиная с высоты N одной пачкой (application/octet-stream) вместе с последней высотой, за которую ответ отвечает (through). Догоняющий кошелёк спрашивает снова с высоты после through. Ответ растёт вместе с цепочкой, поэтому он идёт с Cache-Control: no-store. from — целое число.
POST /v1/transactions
Отправьте готовый платёж в проводном кодировании как тело запроса. Собирает его кошелёк; формат описан в модуле wire.rs крейта tint-core: поля фиксированной ширины, у каждого значения одно допустимое кодирование, лишних байтов в конце нет.
curl -s -X POST https://node.tint.top/v1/transactions \
-H 'content-type: application/octet-stream' \
--data-binary @payment.bin{ "txid": "5be1…07af" }Транзакция начинается с актива (u32), высоты срока действия (u64) и вида (0 — платёж, 1 — обмен), затем идёт пачка: флаги, баланс значений, якорь, число действий и сами действия с доказательством. У обмена добавляются купленная монета, внесённая сумма и вторая пачка.
Ошибки
Ошибки приходят в JSON: {"error":{"code":"...","message":"..."}}.
| HTTP | code | Смысл |
|---|---|---|
| 400 | malformed | Тело — не платёж. |
| 400 | invalid_height | Высота или from — не целое число. |
| 404 | not_found | Нет финализированного блока такой высоты или нет такого ресурса. |
| 409 | double_spend | Запись этого платежа уже потрачена. |
| 409 | conflict | Другой ожидающий платёж тратит одну из тех же записей. |
| 409 | price_moved | Пул больше не даёт того, что просит этот обмен. |
| 413 | too_large | Платёж больше, чем допускает цепочка. |
| 422 | rejected | Платёж нарушает правило цепочки; в сообщении сказано, какое. |
| 429 | rate_limited | Этот клиентский адрес исчерпал свой запас запросов. Повторите после времени из заголовка Retry-After. |
| 500 | internal | Узел не смог проверить или закодировать. |
| 503 | busy, queue_full | Узел проверяет другие платежи или его очередь полна. Повторите; Retry-After: 1. |
Лимиты запросов
По умолчанию каждому клиентскому адресу можно 50 запросов в секунду постоянно, с всплеском в 100, и одновременно проверяются не больше 4 платежей на всех клиентов. Операторы могут менять оба числа. За обратным прокси узел считает клиентов по последнему адресу, который прокси записал в X-Forwarded-For; более ранним записям он не верит.
Пример: следить за цепочкой
import json, time, urllib.request
BASE = "https://node.tint.top"
while True:
with urllib.request.urlopen(f"{BASE}/v1/status", timeout=10) as r:
status = json.load(r)
print(status["height"], status["queued"])
time.sleep(5)Оператор узла по этому интерфейсу может узнать только сетевой адрес, с которого пришёл платёж. Суммы, отправители и получатели — внутри доказательства и зашифрованных записей.