Cüzdan token bakiyeleri API'si: ERC-20 varlıkları ve transfer geçmişi
Sıfır olmayan ERC-20 token bakiyeleri, token transfer geçmişi ve toplu meta verilerle bir cüzdan varlıkları sayfası oluşturun. Zincir kapsamını kontrol edin, sonuçları sayfalandırın ve tam sayı tutarları decimals değerine göre ölçekleyin.
Blokzincir cüzdan veri API'si ile bir cüzdan varlıkları sayfası oluşturun: sıfır olmayan ERC-20 varlıkları için Token Bakiyeleri API'sini ve cüzdan geçmişi için Token Transferleri API'sini kullanın. Geliştiriciler ve AI Agent'lar aynı kimliği doğrulanmış istekleri kullanır. Sorgulamadan önce GET /v1/status yanıtını okuyun ve seçilen zincirin data_features ile data_status alanlarını kontrol edin; bakiye kapsamı zincire göre değişir. İstek parametreleri ve yanıt şemaları Data API referansında yer almaktadır.
Bu rehberin tamamlamanıza yardımcı olduğu görevler
- Bir key ile cüzdan token bakiyelerini okuyun ve sıfır olmayan ERC-20 varlıklarını sayfalandırın.
- Sabit bir blok penceresinde cüzdan transfer geçmişini okuyun ve seçilen adres için imleçleri (cursor) takip edin.
- Ham tam sayı bakiyelerinin yanında adları ve sembolleri görüntülemek için token meta verilerini tamamlayın; eksik alanları koruyun.
Bir cüzdan varlıkları sayfasının ihtiyaç duyduğu üç tür veri
Bir cüzdan varlıkları sayfası bir adresin ERC-20 token bakiyelerini, token transfer geçmişini ve token meta verilerini gösterebilir. Data API her biri için ayrı bir uç nokta sunar:
- Bakiyeler:
GET /{chain}/addresses/{address}/balances, adresin sıfır olmayan ERC-20 bakiyelerinitokenadresine göre artan sırada döndürür; mevcut olduğunda tokensymbolvedecimalsbilgileri eklenir. Bakiyesi olmayan bir adresdata: []ile200döndürür. - Transferler:
GET /{chain}/addresses/{address}/transfers, zorunlu bir blok penceresi içinde adresle ilişkili token transferlerini(block_number, log_index)azalan sırasında döndürür. - Token meta verileri:
GET /{chain}/tokens/{token}, sözleşme adresine göre tek bir token'ın adını, sembolünü, ondalık basamaklarını (decimals) ve toplam arzını okur;POST /{chain}/tokens:batch, tek bir istekte 100 adrese kadar aynı meta verileri okur.
Her üçü de temel URL olarak https://api.blockvectra.com/v1/data adresini ve x-api-key istek başlığını kullanır; örnek zincir olarak robinhood_mainnet kullanılır. Sırasıyla balances, transfers ve token_metadata yeteneklerine aittirler; her yeteneği sunan zincirler için Desteklenen Zincirler sayfasına bakın. Bu yeteneğe sahip olmayan bir zincirde uç nokta 422 no_coverage döndürür.
İstek 1: adres bakiyeleri
Bu uç nokta daha az parametre alır, bu da onu bir sayfa için iyi bir ilk istek yapar:
{chain}(yol parametresi, zorunlu): zincir tanımlayıcısı,GET /chainsiçindeki bir girdininchaindeğeri (örneğinrobinhood_mainnet). Eşleme tam ve büyük/küçük harfe duyarlıdır; takma adlar ve sayısal Chain ID'ler kabul edilmez.{address}(yol parametresi, zorunlu): 20 baytlık adres;0xöneki isteğe bağlıdır ve her iki harf durumu da kabul edilir.limit(sorgu parametresi, isteğe bağlı): sayfa boyutu. Varsayılan değer 50'dir; 500'ün üzerindeki değerler 500'e kırpılır;0veya tam sayı olmayan bir değer400 bad_requestdöndürür.cursor(sorgu parametresi, isteğe bağlı): sonraki sayfayı getirmek için değiştirilmeden geri iletilen, önceki yanıtınnext_cursordeğeri. Bir imleç yalnızca onu oluşturan zincir, uç nokta ve sorgu parametreleri için geçerlidir; başka bir yerde yeniden kullanılması400 bad_requestdöndürür.
Keyset sayfalandırmalıdır: next_cursor yalnızca başka bir sayfa olduğunda görünür. Son sayfada anahtar hiçbir zaman null olmaz, tamamen mevcut değildir.
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"Yanıt zarfı (envelope), data ve meta içeren AddressBalanceListEnvelope biçimindedir. data içindeki her öğe bir AddressBalance nesnesidir:
| Alan | Tür | Açıklama |
|---|---|---|
token | string (address) | Token sözleşme adresi; kanonik biçim 0x ve ardından 40 küçük harfli onaltılık basamaktır. |
balance | string (decimal) | 2^53 değerini aşabilen ham tam sayı bakiye, düz bir ondalık dize olarak döndürülür — hiçbir zaman bir JSON sayısı, bilimsel gösterim veya onaltılık değildir. |
symbol | string veya null | Token sembolü veya mevcut olmadığında null. |
decimals | integer veya null | Token ondalık basamak sayısı, 0–255 veya mevcut olmadığında null. |
İstek 2: adres transferleri
Transferler uç noktası açık bir blok penceresi gerektirir: from_block ve to_block zorunludur ve from_block <= to_block koşulunu sağlamalıdır. Birkaç parametre daha alır:
standard(sorgu parametresi, zorunlu):erc20veyaerc721. Adres kapsamlı sorgularerc1155standardını kapsamaz; bunun iletilmesi422 no_coveragedöndürür.direction(sorgu parametresi, isteğe bağlı):in,outveyaany; varsayılananydeğeridir ve adrese göre yöne göre filtreler.token(sorgu parametresi, isteğe bağlı): sonuçları tek bir token sözleşmesiyle sınırlandırır.clamp(sorgu parametresi, isteğe bağlı): yalnızca"true"dize sabiti etkinleştirir; diğer tüm değerlerfalseolarak değerlendirilir.
Pencere sınırları ve kesinlik (finality): as_of_block üzerinde açık bir to_block belirtilmesi, clamp=true değeri onu as_of_block seviyesine kırpmadığı sürece 409 not_indexed_yet döndürür; zincirin sınırından (GET /chains üzerinden limits.max_window_blocks) daha geniş bir pencere, clamp=true değeri eski uçtan kırpmadığı sürece (from_block yükseltilir ve to_block sabit tutulur) 409 window_too_large döndürür. from_block değerinin kendisi zaten as_of_block değerini geçmişse, clamp=true olsa bile kesin 409 olarak kalır. Pencere kırpıldığında veya kısmen kapsandığında, yanıttaki meta.coverage değeri "partial" olur; aksi takdirde "full" değeridir.
Transfer kayıtlarında ERC-20 öğelerine amount; ERC-721 öğelerine ise token_id eklenir. Her ikisi de token, standard, from, to, block_number, block_timestamp, tx_hash, tx_index ve log_index alanlarını içerir.
export BLOCKVECTRA_API_KEY=rgw_your_api_key
# 1) balances yanıtından as_of_block değerini okuyun.
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, 409 döndürmek yerine çok geniş bir pencereyi veya as_of_block üzerindeki bir to_block değerini kırpar.
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"Tüm transferler arasında sayfalandırma yapma
Adres transferleri uç noktasının next_cursor değeri iyimserdir (optimistic): yalnızca sayfa tam olarak limit sayıda satır döndürdüğünde görünür; dolayısıyla bir sayfa next_cursor taşısa bile son sayfa olduğu ortaya çıkabilir. Bir sayfa boş olduğunda durmayın; anahtar mevcut olmayana kadar next_cursor değerini izleyin.
Aşağıdaki kod penceredeki her transferi getirir:
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 daha eski taraftan kırpar
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; // son sayfada bulunmaz
} while (cursor);İstek 3: token meta verileri ve tokens:batch
GET /{chain}/tokens/{token} ile tek bir token okuyun; yol yalnızca {chain} ve {token} alır, sayfalandırma içermez. Yanıt zarfı TokenEnvelope biçimindedir ve data bir Token nesnesidir:
| Alan | Tür | Açıklama |
|---|---|---|
address | string (address) | Token sözleşme adresi. |
standard | string | erc20, erc721 veya unknown. |
name | string veya null | Token adı veya mevcut olmadığında null. |
symbol | string veya null | Token sembolü veya mevcut olmadığında null. |
decimals | integer veya null | Token ondalık basamak sayısı, 0–255 veya mevcut olmadığında null. |
total_supply | string veya null | Ham toplam arz; API decimals ölçeklemesi uygulamaz. Mevcut olmadığında null. |
first_seen_block | integer (int64) | Token'ın ilk görüldüğü blok yüksekliği. |
metadata_updated_at | string (timestamp) | Meta verilerin son güncellendiği UTC zamanı. |
metadata_block | integer (int64) | Meta verilerin okunduğu blok yüksekliği. |
metadata_status | string | ok, partial veya unavailable. |
metadata_issues | object | name, symbol, decimals, total_supply anahtarlarıyla alan bazında sorun kayıtları; değerler reverted, no_data, invalid_encoding veya temporarily_unavailable. |
Geçerli bir 20 baytlık adres olmayan bir {token} 400 bad_request döndürür; bilinmeyen bir {token} 404 not_found döndürür; bilinmeyen bir {chain} 404 unknown_chain döndürür.
Bakiyeler uç noktası mevcut olduğunda zaten symbol ve decimals içerir, ancak her ikisi de null olabilir. Bir cüzdandaki her token için adı ve ondalık basamakları tamamlamak üzere POST /{chain}/tokens:batch kullanın:
- İstek gövdesi, istek başına en fazla 100 adres içeren
{"addresses": [...]}biçimindedir; 100'den fazla girdi veya geçerli bir 20 baytlık adres olmayan bir girdi400 bad_requestdöndürür (karşılaştığı ilk geçersiz adreste başarısız olur). - Bulunamayan adresler bir hatayı tetiklemez;
data.missingiçinde listelenirken,data.tokensyalnızca meta verileri bulunan token'ları içerir. - Yinelenen adresler hem
tokenshem demissingiçinde, her birinde ilk görülme istek sırasına göre tekilleştirilir.
export BLOCKVECTRA_API_KEY=rgw_your_api_key
# Tek token
curl -s "https://api.blockvectra.com/v1/data/robinhood_mainnet/tokens/0x1111111111111111111111111111111111111111" \
-H "x-api-key: $BLOCKVECTRA_API_KEY"
# Batch: istek başına en fazla 100 adres
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"]}'Tutarları decimals değerine göre ölçekleme
Bakiye alanı balance ve ERC-20 transfer alanı amount, ondalık dize (UInt256String) olarak oluşturulmuş ham tam sayılardır; bir token'ın total_supply değeri de decimals ölçeklemesi uygulanmamış ham bir zincir üstü tam sayıdır. İnsan tarafından okunabilir bir miktar göstermek için, o token'ın decimals değerine bölün.
decimals, bakiye öğesinin kendisymbol/decimalsdeğerinden veyaGET /{chain}/tokens/{token}ilePOST /{chain}/tokens:batchyanıtlarından gelir;nullolabilir.- Bu değerler
2^53sınırını aşabilir, bu nedenle aritmetik işlemleri bir JSON sayısı ile yapmayın: duyarlık kaybını önlemek için TypeScript'teBigIntve Python'daDecimalkullanarak ondalık dizeyi olduğu gibi ayrıştırın.
function toDisplayAmount(raw: string, decimals: number | null): string {
if (decimals === null) return raw; // decimals meta verisi yok: ham tam sayıyı koru
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 ham bir ondalık dizedir; decimals aynı öğeden veya tokens:batch'ten gelir.
const display = toDisplayAmount(balance.balance, balance.decimals);Veri güncelliği
Zincir kapsamındaki her başarılı yanıt meta taşır:
as_of_block: zincirin en yeni tamamen yazılmış bloğu. Blok kapsamlı uç noktalar bu yüksekliğe kadar veri sunar.safe_block: düğümün konsensüssafeblok etiketini gösteren bir işaretçi (bilinmediğindenull). Aslafinalized_blockaltında değildir ve yanıtları kırpmaz, reddetmez veya geciktirmez.finalized_block: düğümün konsensüsfinalizedblok etiketini gösteren bir işaretçi (bilinmediğindenull). Yanıtları kırpmaz, reddetmez veya geciktirmez; istemciler bu işaretçiden ne tür bir güvenliğe ihtiyaç duyduklarına (onay durumu gibi) kendileri karar verir.coverage:"full"veya"partial". Adres transferleri ve benzer uç noktalar,clampsunulan pencereyi daralttığında veya pencere zincirin ilk indekslenen bloğundan önce başladığında"partial"bildirir.refreshed_at: yanıtın arkasındaki verilerin en son güncellendiği zaman (UTC).nullolabilir:null, verilerin güncelleme zamanının bilinmediği ve güncelliğini yitirmiş (stale) olarak değerlendirilmesi gerektiği anlamına gelir; blok tabanlı uç noktalar her zaman bir değer döndürür.- Ayrıca
chain,chain_slugvechain_external_idalanlarını yineler.
Yaygın bir model: en yeni indekslenmiş bloğa kadar okumak için herhangi bir ilk yanıttan meta.as_of_block değerini okuyun ve onaylanmış durumu görüntülemek istiyorsanız meta.safe_block / meta.finalized_block değerlerini kontrol edin.
Tek bir sayfa yüklemesi için CU tahmini
Her yöntem, platform planları API'sinden okunan CU ağırlığına göre faturalandırılır:
Çağrı başına CU ağırlığı
| Yöntem | Çağrı başına CU |
|---|---|
data.address_balances | 25 |
data.address_transfers | 25 |
data.tokens_batch | 10 |
Bir sayfa yüklemesi (tahmini)
1 balances isteği + 3 transfer sayfası + 1 tokens:batch isteği, toplam 5 çağrı, yaklaşık 110 CU. Gerçek kullanım, sayfa ve token sayısına bağlıdır.
Faturalandırma kararları ve faturalandırılmayan hata yanıtları için faturalandırma kurallarına bakın. İhtiyacınız olan şey indekslenmiş transfer geçmişi değil de en son bloklardaki loglarsa, eth_getLogs yöntemine geçip geçmeyeceğinize karar vermeden önce En son düğüm verileri ve indekslenmiş geçmiş rehberini okuyun.
Sonraki adımlar
- BlockVectra'nın indekslediği tüm veri kümelerini görmek için veri kümeleri dizinine göz atın.
- Hesabınızın neleri içerdiğini kontrol etmek için ücretsiz planı ve fiyatlandırmayı inceleyin.
- Bir API key oluşturmak için konsolda oturum açın.
Son güncelleme:
İşlem izleri
Bir işlem için yürütme çağrı ağaçlarını yeniden yapılandırın: İzin verilen tracer'ları ve korumalarıyla JSON-RPC debug_traceTransaction yöntemi ile kapsam sınırlarıyla Data API getTransactionTrace ve getBlockTraces uç noktaları.
Cüzdan Özel RPC
MetaMask veya Rabby'ye bir BlockVectra RPC URL'si ekleyin. Chain ID'leri ve yerel sembolleri bulun, yolda API key yapılandırın ve özel bir cüzdan anahtarı yönetin.