API ยอดคงเหลือโทเค็นของกระเป๋าเงิน: สินทรัพย์ ERC-20 และประวัติการโอน
สร้างหน้าสินทรัพย์ของกระเป๋าเงินด้วยยอดคงเหลือโทเค็น ERC-20 ที่ไม่เป็นศูนย์, ประวัติการโอนโทเค็น และเมทาดาตาแบบแบตช์ ตรวจสอบความครอบคลุมของเชน, แบ่งหน้าผลลัพธ์ และปรับสเกลจำนวนเต็มด้วย decimals
สร้างหน้าสินทรัพย์ของกระเป๋าเงินด้วย API ข้อมูลกระเป๋าเงินบล็อกเชน: ใช้ Token Balances API สำหรับการถือครอง ERC-20 ที่ไม่เป็นศูนย์ และใช้ Token Transfers API สำหรับประวัติของกระเป๋าเงิน ทั้งนักพัฒนาและ AI agent ต่างใช้คำขอที่ผ่านการยืนยันตัวตนแบบเดียวกัน ก่อนสืบค้น ให้อ่าน GET /v1/status และตรวจสอบ data_features และ data_status ของเชนที่เลือก; ความครอบคลุมของยอดคงเหลือจะแตกต่างกันไปตามแต่ละเชน ดูพารามิเตอร์คำขอและสคีมาการตอบกลับได้ใน เอกสารอ้างอิง Data API
งานที่คู่มือนี้จะช่วยคุณดำเนินการ
- อ่านยอดคงเหลือโทเค็นของกระเป๋าเงิน ด้วยคีย์และแบ่งหน้าการถือครอง ERC-20 ที่ไม่เป็นศูนย์
- อ่านประวัติการโอนของกระเป๋าเงิน ภายในหน้าต่างบล็อกที่กำหนด และติดตามเคอร์เซอร์สำหรับแอดเดรสที่เลือก
- เติมข้อมูลเมทาดาตาของโทเค็น เพื่อแสดงชื่อและสัญลักษณ์ควบคู่ไปกับยอดคงเหลือจำนวนเต็มดิบ โดยรักษาฟิลด์ที่ขาดหายไว้
ข้อมูลสามประเภทที่หน้าสินทรัพย์ของกระเป๋าเงินต้องการ
หน้าสินทรัพย์ของกระเป๋าเงินสามารถแสดงยอดคงเหลือโทเค็น ERC-20, ประวัติการโอนโทเค็น และเมทาดาตาของโทเค็นของแอดเดรสได้ โดย Data API มี endpoint สำหรับแต่ละรายการ:
- ยอดคงเหลือ:
GET /{chain}/addresses/{address}/balancesส่งคืนยอดคงเหลือ ERC-20 ที่ไม่เป็นศูนย์ของแอดเดรส เรียงลำดับตามแอดเดรสtokenจากน้อยไปมาก พร้อมทั้งระบุsymbolและdecimalsของโทเค็นหากมีข้อมูล แอดเดรสที่ไม่มีการถือครองโทเค็นจะส่งคืน200พร้อมdata: [] - การโอน:
GET /{chain}/addresses/{address}/transfersส่งคืนการโอนโทเค็นที่เกี่ยวข้องกับแอดเดรสภายในหน้าต่างบล็อกที่จำเป็น เรียงลำดับตาม(block_number, log_index)จากมากไปน้อย - เมทาดาตาของโทเค็น:
GET /{chain}/tokens/{token}อ่านชื่อ, สัญลักษณ์, decimals และอุปทานรวมของหนึ่งโทเค็นตามแอดเดรสสัญญา;POST /{chain}/tokens:batchอ่านเมทาดาตาเดียวกันนี้สำหรับสูงสุด 100 แอดเดรสในคำขอเดียว
ทั้งสามรายการใช้ https://api.blockvectra.com/v1/data เป็น base URL และใช้ส่วนหัวคำขอ x-api-key โดยใช้ robinhood_mainnet เป็นเชนตัวอย่าง ทั้งหมดอยู่ภายใต้ความสามารถ balances, transfers และ token_metadata ตามลำดับ; สำหรับเชนที่ให้บริการแต่ละความสามารถ โปรดดูหน้า เชนที่รองรับ บนเชนที่ไม่มีความสามารถดังกล่าว endpoint จะส่งคืน 422 no_coverage
คำขอที่ 1: ยอดคงเหลือของแอดเดรส
endpoint นี้รับพารามิเตอร์น้อยกว่า จึงเหมาะเป็นคำขอแรกสำหรับหน้าสินทรัพย์:
{chain}(พารามิเตอร์พาธ, จำเป็น): ตัวระบุเชน ซึ่งเป็นค่าchainของรายการในGET /chains(ตัวอย่างเช่นrobinhood_mainnet) การจับคู่จะตรงกันทุกตัวอักษรและคำนึงถึงตัวพิมพ์ใหญ่-เล็ก; ไม่ยอมรับนามแฝงหรือ chain ID แบบตัวเลข{address}(พารามิเตอร์พาธ, จำเป็น): แอดเดรสขนาด 20 ไบต์; คำนำหน้า0xเป็นตัวเลือก และยอมรับตัวพิมพ์ใหญ่หรือเล็กก็ได้limit(พารามิเตอร์แบบสอบถาม, ไม่บังคับ): ขนาดหน้า ค่าเริ่มต้นคือ 50; ค่าที่มากกว่า 500 จะถูกปรับลดลงเหลือ 500; การส่งค่า0หรือไม่ใช่จำนวนเต็มจะส่งคืน400 bad_requestcursor(พารามิเตอร์แบบสอบถาม, ไม่บังคับ):next_cursorของการตอบกลับครั้งก่อนหน้า ซึ่งส่งกลับมาโดยไม่เปลี่ยนแปลงเพื่อดึงข้อมูลหน้าถัดไป โดยเคอร์เซอร์จะใช้ได้เฉพาะกับเชน, endpoint และพารามิเตอร์แบบสอบถามที่ออกเคอร์เซอร์นั้นเท่านั้น; การนำไปใช้ซ้ำที่อื่นจะส่งคืน400 bad_request
การแบ่งหน้าเป็นแบบ keyset: next_cursor จะปรากฏเฉพาะเมื่อมีหน้าถัดไป ในหน้าสุดท้ายคีย์นี้จะไม่มีอยู่เลย โดยไม่เคยเป็น null
export BLOCKVECTRA_API_KEY=rgw_your_api_key
curl -s "https://api.blockvectra.com/v1/data/robinhood_mainnet/addresses/0x1111111111111111111111111111111111111111/balances?limit=50" \
-H "x-api-key: $BLOCKVECTRA_API_KEY"โครงสร้างการตอบกลับคือ AddressBalanceListEnvelope ซึ่งประกอบด้วย data และ meta โดยแต่ละรายการใน data คือ AddressBalance:
| ฟิลด์ | ชนิด | คำอธิบาย |
|---|---|---|
token | string (address) | แอดเดรสสัญญาโทเค็น; รูปแบบมาตรฐานคือ 0x ตามด้วยเลขฐานสิบหกตัวพิมพ์เล็ก 40 หลัก |
balance | string (decimal) | ยอดคงเหลือจำนวนเต็มดิบ ซึ่งอาจเกิน 2^53 โดยส่งคืนเป็นสตริงฐานสิบธรรมดา — ไม่เป็นตัวเลข JSON, สัญกรณ์วิทยาศาสตร์ หรือเลขฐานสิบหก |
symbol | string หรือ null | สัญลักษณ์โทเค็น หรือ null เมื่อไม่มีข้อมูล |
decimals | integer หรือ null | ทศนิยมของโทเค็น 0–255 หรือ null เมื่อไม่มีข้อมูล |
คำขอที่ 2: การโอนของแอดเดรส
endpoint สำหรับการโอนจำเป็นต้องระบุหน้าต่างบล็อกอย่างชัดเจน: ทั้ง from_block และ to_block จำเป็นต้องระบุ และต้องเป็นไปตามเงื่อนไข from_block <= to_block โดยรับพารามิเตอร์เพิ่มเติมอีกสองสามรายการ:
standard(พารามิเตอร์แบบสอบถาม, จำเป็น):erc20หรือerc721คำค้นหาในขอบเขตแอดเดรสไม่ครอบคลุมerc1155; การส่งค่าดังกล่าวจะส่งคืน422 no_coveragedirection(พารามิเตอร์แบบสอบถาม, ไม่บังคับ):in,outหรือany; ค่าเริ่มต้นคือanyและกรองตามทิศทางที่สัมพันธ์กับแอดเดรสtoken(พารามิเตอร์แบบสอบถาม, ไม่บังคับ): จำกัดผลลัพธ์ให้อยู่ในสัญญาโทเค็นเดียวclamp(พารามิเตอร์แบบสอบถาม, ไม่บังคับ): มีเพียงสตริงtrueตรงตัวเท่านั้นที่จะเปิดใช้งาน; ค่าอื่นๆ ทั้งหมดจะถือว่าเป็นfalse
ขอบเขตหน้าต่างและสถานะสิ้นสุด: ค่า to_block ที่ชัดเจนซึ่งสูงกว่า as_of_block จะส่งคืน 409 not_indexed_yet เว้นแต่ว่า clamp=true จะตัดค่าลงมาอยู่ที่ as_of_block; หน้าต่างที่กว้างกว่าขีดจำกัดของเชน (limits.max_window_blocks จาก GET /chains) จะส่งคืน 409 window_too_large เว้นแต่ว่า clamp=true จะตัดทอนจากฝั่งที่เก่ากว่า (เพิ่มค่า from_block และคงค่า to_block ไว้) หาก from_block เองเกิน as_of_block ไปแล้ว จะยังคงส่งคืน 409 อย่างเข้มงวดแม้จะใช้ clamp=true ก็ตาม เมื่อหน้าต่างถูก clamp หรือครอบคลุมเพียงบางส่วน ค่า meta.coverage ในการตอบกลับจะเป็น "partial"; มิฉะนั้นจะเป็น "full"
ในระเบียนการโอน รายการ ERC-20 จะเพิ่ม amount; รายการ ERC-721 จะเพิ่ม token_id โดยทั้งสองจะประกอบด้วย token, standard, from, to, block_number, block_timestamp, tx_hash, tx_index และ log_index
export BLOCKVECTRA_API_KEY=rgw_your_api_key
# 1) Read as_of_block from the balances response.
AS_OF_BLOCK=$(curl -s "https://api.blockvectra.com/v1/data/robinhood_mainnet/addresses/0x1111111111111111111111111111111111111111/balances" \
-H "x-api-key: $BLOCKVECTRA_API_KEY" | grep -o '"as_of_block":[0-9]*' | cut -d: -f2)
# 2) clamp=true truncates a too-wide window, or a to_block above as_of_block, instead of returning 409.
curl -s "https://api.blockvectra.com/v1/data/robinhood_mainnet/addresses/0x1111111111111111111111111111111111111111/transfers?standard=erc20&from_block=0&to_block=$AS_OF_BLOCK&direction=any&clamp=true" \
-H "x-api-key: $BLOCKVECTRA_API_KEY"การแบ่งหน้าเพื่อดึงข้อมูลการโอนทั้งหมด
next_cursor ของ endpoint การโอนของแอดเดรสเป็นแบบคาดการณ์ในแง่ดี: ค่านี้จะปรากฏเฉพาะเมื่อหน้านั้นส่งคืนจำนวนแถวเท่ากับ limit พอดี ดังนั้นหน้าที่มี next_cursor อาจกลายเป็นหน้าสุดท้ายได้ อย่าหยุดทำงานเมื่อพบหน้าที่ว่างเปล่า; ให้ติดตาม next_cursor ไปเรื่อยๆ จนกระทั่งไม่มีคีย์นี้ปรากฏ
โค้ดด้านล่างนี้จะดึงข้อมูลการโอนทุกรายการในหน้าต่างบล็อก:
const address = "0x1111111111111111111111111111111111111111";
const head = await fetch(
`https://api.blockvectra.com/v1/data/robinhood_mainnet/addresses/${address}/balances`,
{ headers: { "x-api-key": process.env.BLOCKVECTRA_API_KEY! } },
).then((r) => r.json());
const asOfBlock = head.meta.as_of_block;
const transfers: unknown[] = [];
let cursor: string | undefined;
do {
const url = new URL(
`https://api.blockvectra.com/v1/data/robinhood_mainnet/addresses/${address}/transfers`,
);
url.searchParams.set("standard", "erc20");
url.searchParams.set("from_block", "0");
url.searchParams.set("to_block", String(asOfBlock));
url.searchParams.set("limit", "500");
// clamp truncates from the older end
url.searchParams.set("clamp", "true");
if (cursor) url.searchParams.set("cursor", cursor);
const res = await fetch(url, {
headers: { "x-api-key": process.env.BLOCKVECTRA_API_KEY! },
});
const page = await res.json();
transfers.push(...page.data);
cursor = page.next_cursor; // absent on the last page
} while (cursor);คำขอที่ 3: เมทาดาตาของโทเค็นและ tokens:batch
อ่านโทเค็นเดี่ยวด้วย GET /{chain}/tokens/{token}; พาธนี้รับเฉพาะ {chain} และ {token} โดยไม่มีการแบ่งหน้า โครงสร้างการตอบกลับคือ TokenEnvelope และ data คือ Token:
| ฟิลด์ | ชนิด | คำอธิบาย |
|---|---|---|
address | string (address) | แอดเดรสสัญญาโทเค็น |
standard | string | erc20, erc721 หรือ unknown |
name | string หรือ null | ชื่อโทเค็น หรือ null เมื่อไม่มีข้อมูล |
symbol | string หรือ null | สัญลักษณ์โทเค็น หรือ null เมื่อไม่มีข้อมูล |
decimals | integer หรือ null | ทศนิยมของโทเค็น 0–255 หรือ null เมื่อไม่มีข้อมูล |
total_supply | string หรือ null | อุปทานรวมดิบ; API ไม่ได้ใช้การปรับสเกล decimals มีค่าเป็น null เมื่อไม่มีข้อมูล |
first_seen_block | integer (int64) | ความสูงของบล็อกที่พบโทเค็นนี้เป็นครั้งแรก |
metadata_updated_at | string (timestamp) | เวลา UTC เมื่อเมทาดาตาได้รับการอัปเดตล่าสุด |
metadata_block | integer (int64) | ความสูงของบล็อกที่มีการอ่านเมทาดาตา |
metadata_status | string | ok, partial หรือ unavailable |
metadata_issues | object | บันทึกปัญหาแยกตามฟิลด์ โดยมีคีย์เป็น name, symbol, decimals, total_supply พร้อมค่า reverted, no_data, invalid_encoding หรือ temporarily_unavailable |
{token} ที่ไม่ใช่แอดเดรสขนาด 20 ไบต์ที่ถูกต้องจะส่งคืน 400 bad_request; {token} ที่ไม่รู้จักจะส่งคืน 404 not_found; {chain} ที่ไม่รู้จักจะส่งคืน 404 unknown_chain
endpoint ยอดคงเหลือมี symbol และ decimals รวมอยู่ด้วยแล้วในกรณีที่มีข้อมูล แต่ทั้งสองค่าอาจเป็น null ได้ หากต้องการเติมชื่อและ decimals สำหรับทุกโทเค็นในกระเป๋าเงิน ให้ใช้ POST /{chain}/tokens:batch:
- เนื้อหาคำขอคือ
{"addresses": [...]}โดยมีแอดเดรสได้สูงสุด 100 แอดเดรสต่อหนึ่งคำขอ; รายการที่มากกว่า 100 รายการ หรือรายการที่ไม่ใช่แอดเดรสขนาด 20 ไบต์ที่ถูกต้อง จะส่งคืน400 bad_request(จะล้มเหลวทันทีที่พบแอดเดรสแรกที่ไม่ถูกต้อง) - แอดเดรสที่ไม่พบจะไม่ทำให้เกิดข้อผิดพลาด; แอดเดรสเหล่านั้นจะแสดงอยู่ใน
data.missingขณะที่data.tokensจะมีเฉพาะโทเค็นที่พบเมทาดาตาเท่านั้น - แอดเดรสที่ซ้ำกันจะถูกขจัดรายการซ้ำออกทั้งใน
tokensและmissingโดยคงลำดับการปรากฏครั้งแรกในคำขอไว้
export BLOCKVECTRA_API_KEY=rgw_your_api_key
# Single token
curl -s "https://api.blockvectra.com/v1/data/robinhood_mainnet/tokens/0x1111111111111111111111111111111111111111" \
-H "x-api-key: $BLOCKVECTRA_API_KEY"
# Batch: up to 100 addresses per request
curl -s -X POST "https://api.blockvectra.com/v1/data/robinhood_mainnet/tokens:batch" \
-H "x-api-key: $BLOCKVECTRA_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"addresses":["0x1111111111111111111111111111111111111111","0x2222222222222222222222222222222222222222"]}'การปรับสเกลจำนวนเงินด้วย decimals
ฟิลด์ยอดคงเหลือ balance และฟิลด์การโอน ERC-20 amount เป็นจำนวนเต็มดิบที่แสดงผลเป็นสตริงฐานสิบ (UInt256String); อุปทานรวม total_supply ของโทเค็นก็เป็นจำนวนเต็มดิบบนเชนโดยไม่ได้ใช้การปรับสเกล decimals เช่นกัน หากต้องการแสดงปริมาณในรูปแบบที่มนุษย์อ่านได้ ให้หารด้วย decimals ของโทเค็นนั้น
decimalsมาจากsymbol/decimalsของรายการยอดคงเหลือเอง หรือมาจากGET /{chain}/tokens/{token}และPOST /{chain}/tokens:batch; โดยสามารถเป็นnullได้- ค่าเหล่านี้อาจเกิน
2^53ดังนั้นอย่าคำนวณเลขคณิตด้วยตัวเลข JSON: ให้ใช้BigIntใน TypeScript และDecimalใน Python โดยแปลงค่าสตริงฐานสิบตามสภาพเดิมเพื่อหลีกเลี่ยงการสูญเสียความแม่นยำ
function toDisplayAmount(raw: string, decimals: number | null): string {
if (decimals === null) return raw; // no decimals metadata: keep the raw integer
const value = BigInt(raw);
const base = 10n ** BigInt(decimals);
const whole = value / base;
const fraction = (value % base)
.toString()
.padStart(decimals, "0")
.replace(/0+$/, "");
return fraction ? `${whole}.${fraction}` : whole.toString();
}
// balance.balance is a raw decimal string; decimals comes from the same item or tokens:batch.
const display = toDisplayAmount(balance.balance, balance.decimals);ความสดใหม่ของข้อมูล
ทุกการตอบกลับที่สำเร็จในระดับเชนจะมี meta รวมอยู่ด้วย:
as_of_block: บล็อกใหม่ล่าสุดของเชนที่เขียนข้อมูลเสร็จสมบูรณ์แล้ว โดย endpoint ในระดับบล็อกจะให้บริการข้อมูลจนถึงความสูงนี้safe_block: เครื่องหมายระบุแท็กบล็อกฉันทามติsafeของโหนด (เป็นnullเมื่อยังไม่ทราบ) ค่านี้จะไม่ต่ำกว่าfinalized_blockและไม่ตัดทอน ปฏิเสธ หรือทำให้การตอบกลับล่าช้าfinalized_block: เครื่องหมายระบุแท็กบล็อกฉันทามติfinalizedของโหนด (เป็นnullเมื่อยังไม่ทราบ) ค่านี้ไม่ตัดทอน ปฏิเสธ หรือทำให้การตอบกลับล่าช้า; ไคลเอนต์สามารถตัดสินใจเลือกระดับความปลอดภัยที่ต้องการจากเครื่องหมายนี้ได้เอง (เช่น สถานะการยืนยัน)coverage:"full"หรือ"partial"endpoint การโอนของแอดเดรสและ endpoint ที่คล้ายกันจะรายงาน"partial"เมื่อclampได้ตัดทอนหน้าต่างที่ให้บริการให้แคบลง หรือเมื่อหน้าต่างเริ่มต้นก่อนบล็อกแรกที่ทำดัชนีของเชนrefreshed_at: เวลาที่ข้อมูลเบื้องหลังการตอบกลับได้รับการอัปเดตล่าสุด (UTC) อาจเป็นnull:nullหมายความว่าไม่ทราบเวลาอัปเดตของข้อมูลนี้และควรได้รับการปฏิบัติเสมือนข้อมูลล้าสมัย; ส่วน endpoint ที่อิงตามบล็อกจะส่งคืนค่าเสมอ- นอกจากนี้ยังระบุซ้ำถึง
chain,chain_slugและchain_external_id
รูปแบบที่ใช้กันทั่วไป: ให้อ่าน meta.as_of_block จากการตอบกลับแรกใดๆ เพื่ออ่านข้อมูลจนถึงบล็อกที่ทำดัชนีใหม่ล่าสุด และตรวจสอบ meta.safe_block / meta.finalized_block หากคุณต้องการแสดงสถานะที่ได้รับการยืนยันแล้ว
ประมาณการ CU สำหรับการโหลดหน้าหนึ่งครั้ง
ทุกเมธอดจะถูกคิดค่าบริการตามค่าน้ำหนัก CU ซึ่งอ่านมาจาก API แผนของแพลตฟอร์ม:
น้ำหนัก CU ต่อการเรียก
| เมธอด | CU ต่อการเรียก |
|---|---|
data.address_balances | 25 |
data.address_transfers | 25 |
data.tokens_batch | 10 |
การโหลดหน้าหนึ่งครั้ง (โดยประมาณ)
คำขอ balances 1 ครั้ง + หน้า transfer 3 หน้า + คำขอ tokens:batch 1 ครั้ง, รวมทั้งหมด 5 การเรียก, ประมาณ 110 CU. การใช้งานจริงขึ้นอยู่กับจำนวนหน้าและโทเค็น
สำหรับการตัดสินใจเกี่ยวกับการเรียกเก็บเงินและการตอบกลับข้อผิดพลาดที่ไม่คิดค่าบริการ โปรดดู กฎการเรียกเก็บเงิน หากสิ่งที่คุณต้องการไม่ใช่ประวัติการโอนที่ทำดัชนีไว้ แต่เป็น log จากบล็อกล่าสุด โปรดอ่าน ข้อมูลโหนดล่าสุดเทียบกับประวัติที่ทำดัชนี ก่อนที่จะตัดสินใจว่าจะเปลี่ยนไปใช้ eth_getLogs หรือไม่
ขั้นตอนถัดไป
- เลือกดูไดเรกทอรีชุดข้อมูล เพื่อดูชุดข้อมูลทั้งหมดที่ BlockVectra จัดทำดัชนี
- ดูแพ็กเกจฟรีและการกำหนดราคา เพื่อตรวจสอบสิทธิประโยชน์ในบัญชีของคุณ
- เข้าสู่ระบบคอนโซล เพื่อสร้าง API key
อัปเดตล่าสุด:
เลือกผู้ให้บริการ RPC
ประเมินต้นทุนของเมธอด RPC, ช่วงของ log, เครดิตฟรี, การจำกัดอัตรา, ความครอบคลุมของเชน, Push และ Data API, การยืนยันตัวตน และการเข้าถึงของ Agent พร้อมการทดสอบภาระงานด้วยตนเอง
Transaction traces
สร้าง Call Tree ของการประมวลผลธุรกรรมขึ้นใหม่: เมธอด JSON-RPC debug_traceTransaction พร้อม Tracer และมาตรการป้องกันที่อนุญาต ตลอดจน Endpoint getTransactionTrace และ getBlockTraces บน Data API พร้อมขอบเขตความครอบคลุม