서비스, OFAC 데이터셋, 응답의 서명은 어떻게 모니터링합니까?
오류, 한도, 신뢰 · 프로세스 가동 상태, 제재 목록의 경과 시간과 개수, 서비스 자체의 예산 — 그리고 서명하는 배포가 모든 응답에 덧붙이는 Ed25519 증명(attestation)
- API 가이드
- 7분
- 중급
- 개발자
- GET /health
- /ready
- /v1/sanctions
- /v1/stats/slo
- POST /v1/verify-attestation
체인이 아니라 서비스를 감시하는 조회가 네 가지 있습니다. /health와 /ready는 프로세스 가동 상태 — 실행 중이며 데이터베이스가 응답함 — 이며, 인덱싱에 대해서는 아무것도 말하지 않습니다. GET /v1/sanctions는 OFAC 데이터셋입니다. 생태계별 개수(2026-10-24에 주소 385개: EVM 120, 트론 261, 솔라나 4)와 updated_at이 있습니다. GET /v1/stats/slo?chain=은 서비스의 지연 시간 예산과 배치 기준점 — OFAC 목록, 주간 그래프 배치 — 의 경과 시간입니다. 그리고 응답에 서명하는 배포는 응답에 attestation 객체를 덧붙입니다. POST /v1/verify-attestation은 본문을 그것과 대조해 확인하며, 무료이고 독립적입니다. 이 배포는 현재 서명하지 않으며, /.well-known/jwks.json은 비어 있습니다.
가동 상태
curl -s https://stablescan.achivx.com/health # {"status": "ok"}
curl -s https://stablescan.achivx.com/ready # {"status": "ready"}, or 503 not_ready둘 다 no-store입니다. 프로세스가 실행 중이고 데이터베이스가 응답한다고 답합니다. 둘 다 예라고 답하는 동안에도 네트워크는 몇 시간 뒤처져 있을 수 있습니다. 최신성은 네트워크별 /v1/sync/status?chain=이며, 데이터가 최신인가에 맞는 확인 수단입니다.
제재 데이터셋
curl -s https://stablescan.achivx.com/v1/sanctions{
"source": "ofac_sdn",
"evm_count": 120,
"solana_count": 4,
"tron_count": 261,
"total": 385,
"updated_at": "2026-10-24T04:00:04Z",
"note": "OFAC SDN digital-currency addresses (public, 0xB10C list). Heuristic exposure only — not legal advice; verify against the official SDN list."
}updated_at은 모든 판정이 sanctions_list_as_of로 반복하는 날짜입니다. 목록이 7일보다 오래되면 깨끗한 판정이 ofac_list_stale과 함께 unknown으로 읽힙니다. 주소 목록 내보내기는 없습니다. 등재 여부는 주소 개요의 sanctioned입니다. max-age=300이며, ETag로 재검증됩니다.
서비스 자체의 예산
curl -s 'https://stablescan.achivx.com/v1/stats/slo?chain=1'{
"chain_id": 1, "chain_source": "explicit",
"latency": [
{"class": "verify_attestation", "budget_ms": 50, "observed_p95_ms": 0, "samples": 0, "within_budget": true},
{"class": "ego_graph", "budget_ms": 800, "observed_p95_ms": 4707, "samples": 148, "within_budget": false},
{"class": "cached_aggregate", "budget_ms": 300, "…": "…"}
],
"freshness": [
{"anchor": "ofac_sanctions", "scope": "global", "known": true, "age_seconds": 24519, "budget_seconds": 86400, "within_slo": true, "last_refresh": "2026-10-24T04:00:04Z"},
{"anchor": "graph_batch", "scope": "chain", "known": true, "age_seconds": 530664, "budget_seconds": 691200, "within_slo": true, "last_refresh": "2026-10-18T07:24:18Z"}
],
"signal_firing": [{"detector": "wash", "scope": "chain", "known": true, "count": 0}, {"detector": "inflation", "…": "…"}, "…"],
"as_of": "2026-10-24T10:48:43Z"
}latency[]는 경로 유형별 최근 프로세스 내 p95를 공개된 예산과 비교한 것입니다(samples: 0 = 아직 관측되지 않음). 그날 아침 에고 그래프는 p95 4.7초로 800 ms 예산을 초과했으며, 무거운 주소에서의 202 building이 여기서는 이렇게 보입니다. freshness[]는 각 배치 기준점의 경과 시간입니다. OFAC 목록(전역, 하루 예산)과 주간 그래프 배치(체인별, 8일 예산 — 최근 주간 실행보다 오래된 last_refresh는 해당 체인의 실행이 반영되지 않았다는 뜻)입니다. 한 체인에 대해 응답합니다. chain을 넘기거나, 그렇지 않으면 chain_source: "default"가 베이스(Base)임을 알려 줍니다. no-store: 모든 조회는 실시간입니다.
첫 번째 요청의 헬퍼 세 개로 한 같은 호출:
Python
slo = scan("/v1/stats/slo", chain=1)
late = [l["class"] for l in slo["latency"] if l["samples"] and not l["within_budget"]]
stale = [f["anchor"] for f in slo["freshness"] if not f["within_slo"]]
sanctions = scan("/v1/sanctions")
print("over budget:", late, "| stale anchors:", stale, "| OFAC list:", sanctions["total"], "addresses as of", sanctions["updated_at"])Go
var slo struct {
Latency []struct {
Class string `json:"class"`
Samples int `json:"samples"`
WithinBudget bool `json:"within_budget"`
} `json:"latency"`
Freshness []struct {
Anchor string `json:"anchor"`
AgeSeconds int `json:"age_seconds"`
WithinSLO bool `json:"within_slo"`
} `json:"freshness"`
}
if err := get("/v1/stats/slo", url.Values{"chain": {"1"}}, &slo); err != nil {
return err
}TypeScript
type Slo = {
chain_id: number; chain_source: "explicit" | "default";
latency: { class: string; budget_ms: number; observed_p95_ms: number; samples: number; within_budget: boolean }[];
freshness: { anchor: string; scope: "global" | "chain"; known: boolean; age_seconds: number; budget_seconds: number; within_slo: boolean; last_refresh: string }[];
as_of: string;
};
const slo = await scan<Slo>("/v1/stats/slo", { chain: 1 });
const sanctions = await scan<{ total: number; updated_at: string }>("/v1/sanctions");증명: 서명된 응답
서명하는 배포는 모든 주소 응답에 attestation 객체를 덧붙입니다. OpenAPI 스키마는 개요, risk, exposure, approvals, balances, heuristics에서 이를 설명합니다: an Ed25519 signature over the JCS-canonical body without this field(이 필드를 제외한 JCS 정규화 본문에 대한 Ed25519 서명). alg, kid, method, observed_hash, ruleset_version, data_vintage, signed_at, sig가 있습니다. 확인 방법은 두 가지입니다.
/.well-known/jwks.json의 공개 키로 오프라인 확인 — 본문을 정규화하고(RFC 8785,attestation제외), 해시한 뒤,kid가 가리키는 키로sig를 검증합니다.- 또는 본문과 그 증명을
POST /v1/verify-attestation으로 보냅니다. 서버가 해시를 다시 계산해{"valid": true|false, "alg", "kid", "observed_hash"}로 응답하며,valid가 false이면reason을 덧붙입니다 — false is an answer, not an error: the body was altered, the signature does not verify, or the algorithm is not Ed25519. HTTP stays 200.(false는 오류가 아니라 답입니다: 본문이 변경되었거나, 서명이 검증되지 않거나, 알고리즘이 Ed25519가 아닙니다. HTTP는 200으로 유지됩니다.) 자신의 키로 확인하려면public_key(base64url 원시 Ed25519 키)를 넘기십시오.
이 배포는 현재 서명하지 않습니다. 2026-10-24에 어떤 주소 응답에도 attestation이 없었고, /v1/methodology에도 없었으며, /.well-known/jwks.json은 {"keys": []}로 응답했고, 본문과 증명을 넣은 POST /v1/verify-attestation은 400 no_key로 응답했습니다 — no public_key supplied and this deployment has no signing key(public_key가 제공되지 않았고 이 배포에는 서명 키가 없습니다). 잘못된 형식의 키는 400 invalid_public_key, 두 부분이 없는 본문은 400 invalid_body(body and attestation are required)입니다. attestation이 없는 응답을 무효가 아니라 서명 없음으로 처리하도록 확인 코드를 작성하면, 키가 설정되는 날에도 올바르게 동작합니다.
def attested(answer):
'''None when the deployment does not sign; True/False from the server's check otherwise'''
att = answer.get("attestation")
if not att:
return None
body = {k: v for k, v in answer.items() if k != "attestation"}
req = urllib.request.Request(BASE + "/v1/verify-attestation", method="POST", data=json.dumps({"body": body, "attestation": att}).encode(),
headers={"Content-Type": "application/json", "Accept": "application/json"})
with urllib.request.urlopen(req, timeout=30) as r:
return json.load(r)["valid"]무엇에 대해 알림을 보낼 것인가
/ready가 1분 동안200이 아님: 데이터가 아니라 서비스 문제입니다.- 의존하는 네트워크에서
/v1/sync/status의freshness_seconds가 임계값을 넘음: 데이터 문제입니다. /v1/sanctions의updated_at이 하루보다 오래됨: OFAC 기준점(/v1/stats/slo의ofac_sanctions행에서within_slo: false와 같습니다).graph_batch가 예산 초과: 거래 상대 그래프가 오래되고 있습니다./graph응답에snapshot_age_seconds로 나타납니다.
Stablecoin scanner ACHIVX에서
- /health, /ready, /v1/sanctions, /v1/stats/slo?chain=1, /.well-known/jwks.json.
- 사이트에 표시되는 OFAC 상태: 등재된 주소의 빨간 배너, /ethereum/address/0x098B…2f96.
출처
- REST 인터페이스의 OpenAPI 3.1 명세(API 1.4.0)
- 에이전트 매뉴얼 — agents.md(버전 2026-10-05)
- GET /v1/stats/slo?chain=1(2026-10-24 조회)
- GET /v1/sanctions(2026-10-24 조회)
더 알아보기
관련 질문
오류, 한도, 신뢰 · GET /health · /ready · /v1/sanctions · /v1/stats/slo · POST /v1/verify-attestation · 2026-10-24 작성, openapi.json, agents.md 및 당일 실제 호출 기반. 구조는 인용한 것이며, 수치는 날짜 기준이고 인덱스에 따라 바뀝니다.
이 페이지는 ACHIVX Academy 영어 원문을 한국어로 옮긴 것입니다. 번역과 원문이 다르면 영어 원문이 기준입니다.