가이드
토큰 스캔 후 기다리기
스캔을 시작하고, 무리 없는 간격으로 폴링해 완성된 리포트를 받아요.
가장 흔한 흐름이에요. 어딘가에서 컨트랙트 주소를 얻었고, 매매하기 전에 Holder Score를 확인해야 하는 상황이죠. 스캔을 시작한 다음, 완료될 때까지 간격을 점점 늘려 가며 리포트를 폴링하세요.
POST /scans요청은 바로 응답하고, 스캔은 백그라운드에서 진행돼요.- 폴링 간격을 점점 늘리고, 429 응답을 받으면
retryAfter값을 지키세요. DONE또는ERROR상태가 되거나 직접 정한 제한 시간이 지나면 멈추세요.
코드#
const BASE = "https://app.xca.fun/api/v1";
const headers = {
Authorization: `Bearer ${process.env.XCA_API_KEY}`,
"Content-Type": "application/json",
};
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
async function scanAndWait(address, { timeoutMs = 180_000 } = {}) {
const start = await fetch(`${BASE}/scans`, {
method: "POST",
headers,
body: JSON.stringify({ chain: "solana", address }),
});
if (!start.ok) throw new Error((await start.json()).error.message);
const deadline = Date.now() + timeoutMs;
let delay = 2000;
while (Date.now() < deadline) {
const res = await fetch(`${BASE}/tokens/solana/${address}`, { headers });
if (res.status === 429) {
const { error } = await res.json();
await sleep((error.retryAfter ?? 5) * 1000);
continue;
}
const report = await res.json();
if (report.status === "DONE") return report;
if (report.status === "ERROR") throw new Error(report.errorMessage ?? "Scan failed");
console.log(`${report.step ?? "queued"} ${report.progress}%`);
await sleep(delay);
delay = Math.min(delay * 1.5, 8000);
}
throw new Error("Timed out waiting for the scan");
}
const report = await scanAndWait("DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263");
console.log(report.symbol, report.holderScore, report.riskLevel);