문서
RPC API 레퍼런스
노드가 지갑에 제공하는 HTTP 인터페이스입니다. 엔드포인트 네 개이며, 상태와 오류는 JSON, 블록과 결제는 간결한 바이너리 인코딩을 사용합니다.
테스트 네트워크: 코인에는 가치가 없습니다
공개 테스트 노드의 기본 URL은 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 | 확정된 최신 블록의 해시(16진수)입니다. |
genesis | 첫 블록의 해시(16진수)입니다. 테스트 네트워크 두 곳이 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}
확정된 블록 하나를 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
완성된 결제를 와이어 인코딩으로 요청 본문에 담아 보냅니다. 결제는 지갑이 만들며, 형식은 tint-core의 wire.rs 모듈에 정의되어 있습니다. 고정 폭 필드, 값마다 유효한 인코딩 하나, 뒤따르는 바이트 없음입니다.
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)노드 운영자가 이 인터페이스에서 여전히 알 수 있는 것은 결제가 들어온 네트워크 주소입니다. 금액, 보낸 사람, 받는 사람은 증명과 암호화된 노트 안에 있습니다.