ドキュメント

RPC API リファレンス

ノードがウォレットに提供する HTTP インターフェースです。エンドポイントは4つで、ステータスとエラーは JSON、ブロックと支払いはコンパクトなバイナリエンコーディングです。

テストネットワーク:コインに価値はありません

公開テストノードのベース URL は https://node.tint.top です。このインターフェースが鍵や金額を目にすることはありません。ウォレットは完成した支払いを送り、ブロック全体を読み取って、自分で復号します。

エンドポイント

メソッドとパス返すもの
GET /v1/statusチェーンの現状(JSON)。
GET /v1/blocks/{height}確定済みのブロック1つ(ワイヤエンコーディング)。
GET /v1/blocks?from=N高さ N 以降の、支払いを含むブロック(ブロックバッチ)。
POST /v1/transactionsワイヤエンコーディングの支払いを受け取り、その識別子を JSON で返します。

GET /v1/status

request
curl -s https://node.tint.top/v1/status
response (example values)
{
  "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最新の確定済みブロックのハッシュ(16進数)。
genesis最初のブロックのハッシュ(16進数)。2つのテストネットワークが同じ chain_id を持つことがあり、これで区別できます。
queuedブロックを待っている支払い。
pools[].assetプールがネイティブコインと交換するコイン(1 は TUSD)。
pools[].native、pools[].other最新の確定済みブロック時点でプールが保有している量(単位。1 コイン = 100,000,000 単位)。
pools[].fee_bpsプールの手数料(1万分率)。30 は 0.3% です。

GET /v1/blocks/{height}

確定済みのブロック1つを application/octet-stream で返します。確定済みのブロックは変わらないため、レスポンスには Cache-Control: public, max-age=31536000, immutable が付きます。数値でない高さには invalid_height、存在しない高さには not_found を返します。

GET /v1/blocks?from=N

高さ N 以降の、支払いを含むブロックを1つのブロックバッチ(application/octet-stream)として、回答が対象とした最後の高さ(through)とともに返します。追いつこうとしているウォレットは、through の次の高さから再度問い合わせます。回答はチェーンとともに大きくなるため、Cache-Control: no-store を付けて送られます。from は整数でなければなりません。

POST /v1/transactions

完成した支払いを、ワイヤエンコーディングでリクエストボディとして送ります。支払いはウォレットが作成します。フォーマットは tint-core の wire.rs モジュールで定義されており、固定幅のフィールドで、値ごとに有効なエンコーディングは1つ、末尾の余分なバイトはありません。

request
curl -s -X POST https://node.tint.top/v1/transactions \
  -H 'content-type: application/octet-stream' \
  --data-binary @payment.bin
response
{ "txid": "5be1…07af" }

トランザクションは、アセット(u32)、有効期限の高さ(u64)、種類(支払いは 0、スワップは 1)で始まり、その後にバンドルが続きます。バンドルは、フラグ、値の収支、アンカー、アクション数、そして証明付きのアクションです。スワップでは、購入するコイン、支払う額、2つ目のバンドルが加わります。

エラー

エラーは JSON です:{"error":{"code":"...","message":"..."}}。

HTTPcode意味
400malformedボディが支払いではありません。
400invalid_height高さまたは from が整数ではありません。
404not_foundこの高さに確定済みのブロックがないか、そのようなリソースがありません。
409double_spendこの支払いのノートがすでに使用済みです。
409conflict待機中の別の支払いが、同じノートのいずれかを使用しています。
409price_movedプールが、このスワップの要求する額をもう出せません。
413too_large支払いがチェーンの許容サイズを超えています。
422rejected支払いがチェーンのルールに違反しています。メッセージにどのルールかが示されます。
429rate_limitedこのクライアントアドレスがリクエストの割り当てを使い切りました。Retry-After ヘッダーの時間が経ってから再試行してください。
500internalノードが検証またはエンコードできませんでした。
503busy, queue_fullノードが他の支払いを検証中か、キューが満杯です。再試行してください。Retry-After: 1。

レート制限

デフォルトでは、各クライアントアドレスは、持続的に毎秒 50 リクエスト、バーストで 100 リクエストまで送れます。また、全クライアントを通じて、同時に検証される支払いは最大 4 件です。運営者は両方を変更できます。リバースプロキシの背後では、ノードはプロキシが X-Forwarded-For に最後に書き込んだアドレスでクライアントを数え、それより前のエントリは信用しません。

例:チェーンを追跡する

python (server side)
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)

このインターフェースから、ノードの運営者がなお知り得るのは、支払いの送信元のネットワークアドレスです。金額、送信者、受取人は、証明と暗号化されたノートの中にあります。