BARU: Helius mengakuisisi Light Protocol
getTransfersByAddress
Blog/Pembaruan

getTransfersByAddress: Riwayat Transfer Solana yang Diurai dalam 1 Panggilan

Produk @ HeliusKiryl Miranovich di XKiryl Miranovich di LinkedIn
Bacaan 5 menit

getTransfersByAddress adalah metode RPC Solana baru yang eksklusif dari Helius dan mengembalikan catatan transfer token serta SOL yang telah diurai dan mudah dibaca untuk sebuah alamat dompet — dengan filter bawaan untuk mint, waktu, jumlah, slot, arah, dan pihak lawan.

Metode ini merupakan pelengkap sempurna untuk getTransactionsForAddress (gTFA). Jika gTFA mengembalikan payload transaksi lengkap, getTransfersByAddress mengembalikan objek transfer yang ringkas: siapa mengirim apa, kepada siapa, kapan, dan berapa banyak.

Mengapa kita memerlukan metode RPC khusus transfer?

Sebagian besar produk dompet, pembayaran, dan portofolio tidak memerlukan seluruh payload transaksi. Produk tersebut memerlukan transfer.

Jadi, apa yang dilakukan masing-masing produk? Setiap tim menulis versi parser transfernya sendiri, dan sayangnya sebagian besar tidak menangani kasus khusus dengan benar.

Sebelumnya, untuk membuat riwayat transfer Solana yang rapi, developer harus:

  1. Mengambil signature dengan getSignaturesForAddress
  2. Mengambil setiap signature dengan getTransaction
  3. Mengurai saldo sebelum/sesudah, saldo token, dan instruksi internal
  4. Merekonstruksi transfer, menangani semantik biaya SPL Token vs Token-2022, dan mengurai derau wrap/unwrap WSOL
  5. Mengulanginya di beberapa halaman, menangani percobaan ulang, dan menyimpan hasil

Meskipun metode getTransactionsForAddress menyatukan langkah 1 dan 2 menjadi satu panggilan, langkah 3–5 masih harus ditangani developer.

Kini, getTransfersByAddress menangani pekerjaan ini untuk Anda dan mengembalikan hasilnya sebagai daftar terstruktur.

Respons getTransfersByAddress

Setiap objek transfer mencakup signature, slot, waktu blok, jenis transfer, pengirim, penerima, mint, jumlah (mentah dan UI), desimal, status konfirmasi, serta indeks instruksi yang tepat sehingga Anda dapat memetakan setiap transfer kembali ke transaksi sumbernya.

Kode
{
  "signature": "<TX_SIGNATURE>",
  "slot": 315073428,
  "blockTime": 1736159420,
  "type": "transfer",
  "fromUserAccount": "<SENDER_WALLET>",
  "toUserAccount": "<RECIPIENT_WALLET>",
  "fromTokenAccount": "<SENDER_TOKEN_ACCOUNT>",
  "toTokenAccount": "<RECIPIENT_TOKEN_ACCOUNT>",
  "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
  "amount": "2500000",
  "decimals": 6,
  "uiAmount": "2.5",
  "confirmationStatus": "finalized",
  "transactionIdx": 35,
  "instructionIdx": 1,
  "innerInstructionIdx": 0
}

Kolom type memberi tahu Anda secara tepat apa yang terjadi — transfer, transferFee, mint, burn, wrap, unwrap, changeAccountOwner, atau withdrawWithheldFee — sehingga Anda tidak perlu menyimpulkan perilaku dari data program mentah.

Mengapa transfer Solana sulit diurai?

Transfer dalam sebuah transaksi Solana bukanlah satu konsep tunggal.

Transfer merupakan kategori yang menyembunyikan sekitar setengah lusin kasus khusus, dan kesalahan pada salah satunya akan merusak data Anda.

SOL vs. WSOL

SOL native dan Wrapped SOL terlihat seperti aset yang sama bagi pengguna, tetapi keduanya berada di bagian transaksi yang berbeda.

SOL native berpindah melalui saldo lamport sebelum/sesudah pada akun sistem. WSOL berpindah melalui saldo token SPL pada akun token.

Pengguna yang melakukan swap di Jupiter dapat melakukan wrap SOL menjadi WSOL, menukar WSOL dengan USDC, lalu tidak pernah melakukan unwrap — sehingga menyisakan akun token WSOL.

Dari sudut pandang pengguna, mereka membelanjakan SOL. Dari sudut pandang jaringan, terjadi tiga transfer dan satu wrap.

Lebih buruk lagi, wrap itu sendiri bukanlah transfer ke pemilik lain — dompet yang sama memindahkan lamport ke akun tokennya sendiri. Menghitungnya sebagai transfer akan menggandakan penghitungan aktivitas pengguna.

Biaya Transfer Token-2022

Token-2022 memperkenalkan TransferCheckedWithFee, yang membuat debit pengirim tidak sama dengan kredit penerima.

Selisihnya ditahan di akun token penerima sebagai biaya, yang nantinya dapat dibayarkan kepada otoritas biaya melalui withdrawWithheldFee.

Parser sederhana melihat satu transfer dan salah menghitung jumlahnya. Parser yang cermat mendeteksi ekstensi biaya, membagi instruksi menjadi transfer dan akumulasi biaya yang ditahan, serta melacak akun biaya secara terpisah.

Mint dan Burn

Token yang dicetak ke sebuah akun tidak memiliki pengirim. Token yang dibakar tidak memiliki penerima. Keduanya terlihat seperti "transfer" dalam delta saldo sebelum/sesudah, tetapi menyamakannya dengan transfer antardompet akan mendistorsi analitik pihak lawan — Anda akan melihat dompet "menerima" dana dari alamat nol dan "mengirim" dana ke ruang kosong.

getTransfersByAddress merepresentasikannya sebagai jenis mint dan burn dengan fromUserAccount atau toUserAccount yang ditetapkan ke null, sehingga Anda dapat menyertakan atau mengecualikannya sesuai produk yang Anda buat.

Manfaat getTransfersByAddress

Metode getTransfersByAddress menerima filter yang sebelumnya mengharuskan Anda mengambil dan mengurai seluruh riwayat transaksi di sisi klien. 

Cari berdasarkan Mint

Hanya kembalikan transfer untuk token tertentu.

Kode
{
  "jsonrpc": "2.0",
  "id": "1",
  "method": "getTransfersByAddress",
  "params": [
    "<WALLET_ADDRESS>",
    { "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" }
  ]
}

Cari berdasarkan Jumlah

Filter berdasarkan jumlah mentah dengan perbandingan gt, gte, lt, lte. Berguna untuk menemukan whale, mengabaikan dust (yaitu akun dengan jumlah token yang tidak signifikan), atau menandai aktivitas yang tidak biasa.

Kode
{
  "params": [
    "<WALLET_ADDRESS>",
    {
      "mint": "So11111111111111111111111111111111111111112",
      "filters": {
        "amount": { "gte": 1000000000, "lt": 10000000000 }
      }
    }
  ]
}

Cari berdasarkan Waktu

Waktu blok didukung sebagai rentang stempel waktu Unix. Rentang slot bekerja dengan cara yang sama untuk kueri dengan presisi slot.

Kode
{
  "params": [
    "<WALLET_ADDRESS>",
    {
      "filters": {
        "blockTime": { "gte": 1735718400, "lt": 1738396800 }
      }
    }
  ]
}

Cari berdasarkan Pihak Lawan

Gabungkan parameter with dan direction untuk mengueri transfer antara dua dompet tertentu, dalam kedua arah.

Kode
{
  "params": [
    "<WALLET_ADDRESS>",
    {
      "with": "<COUNTERPARTY_WALLET>",
      "direction": "in"
    }
  ]
}

Mode SOL

Karena SOL native dan WSOL ditampilkan secara berbeda di Solana tetapi biasanya bermakna sama bagi pengguna, metode getTransfersByAddress menyediakan parameter solMode.

merged (default)

WSOL diperlakukan sebagai SOL native.

Baris wrap dan unwrap dikecualikan, dan kueri berdasarkan mint SOL native mengembalikan transfer SOL native serta WSOL.

separate

Dalam mode ini, WSOL dipertahankan sebagai mint yang berbeda, dan baris siklus hidup wrap dan unwrap disertakan agar dapat diaudit sepenuhnya.

Sebagian besar kasus penggunaan produk biasanya memerlukan merged. Rekonsiliasi, akuntansi, dan analitik tingkat protokol biasanya memerlukan separate.

Paginasi dan Pengurutan

Paginasi standar berbasis kursor melalui paginationToken, hingga 100 catatan per halaman. sortOrder menerima asc dan desc.

Kode
{
  "jsonrpc": "2.0",
  "id": "1",
  "method": "getTransfersByAddress",
  "params": [
    "<WALLET_ADDRESS>",
    { "limit": 50, "paginationToken": "315069220:308:2:1" }
  ]
}

Kapan Harus Menggunakan getTransfersByAddress

getTransfersByAddress dan getTransactionsForAddress serupa, tetapi memiliki tujuan yang berbeda. 

KebutuhanMetode
Transfer token dan SOL yang telah diurai, dengan filtergetTransfersByAddress
Payload transaksi lengkap atau aktivitas non-transfergetTransactionsForAddress
Instruksi yang didekode untuk signature atau alamat apa punParsed Events API
Hanya signaturegetTransactionsForAddress dengan transactionDetails: 'signatures'
Streaming transfer secara real-timeLaserStream

Mulai Gunakan

Metode getTransfersByAddress kini tersedia di semua paket berbayar mulai dari paket Developer. Biayanya 10 kredit per permintaan dan termasuk dalam grup batas laju RPC standar Anda.

Gunakan dengan URL RPC Helius Anda yang sudah ada:

Kode
const response = await fetch("https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    jsonrpc: "2.0",
    id: "1",
    method: "getTransfersByAddress",
    params: ["<WALLET_ADDRESS>"]
  })
});

const data = await response.json();
console.log(data.result.data);

Baca referensi API untuk mengetahui detail lengkap parameter dan respons.

Berlangganan Helius

Ikuti perkembangan terbaru dalam pengembangan Solana dan dapatkan pembaruan saat kami memublikasikan postingan