Robinhood Chain Testnet RPC başlangıcı: anahtarsız okuma, WebSocket log'ları ve mainnet'e geçiş
Robinhood Chain Testnet RPC ile başlayın: genel RPC URL'si, anahtarsız okumalar, API anahtarı ile WebSocket log'ları, faucet erişimi ve aynı anahtarla mainnet'e geçiş.
BlockVectra, Robinhood Chain Testnet'i (zincir kimliği 46630) JSON-RPC ve WebSocket üzerinden sunar; aynı API anahtarı Robinhood Chain mainnet üzerinde de çalışır. Bu rehber, Robinhood Chain Testnet başlangıcı şablonunu üç adımda takip eder: testnet'i anahtarsız okuma, programatik olarak hesap açıp log akışını başlatma ve ardından aynı anahtarı mainnet'e taşıma. Uç nokta parametreleri, yöntem politikası ve tokenize hisse senedi verileri için Robinhood Chain rehberi sayfasına bakın.
Şablonu çalıştırın
git clone https://github.com/blockvectra/robinhood-testnet-starter
cd robinhood-testnet-starter
npm install
npm run typecheckNode.js 18 veya daha yenisi gereklidir. Üç betik npm run step1, npm run step2 ve npm run step3 şeklindedir. İsteğe bağlı değişkenler (BLOCKVECTRA_API_KEY, WALLET_PRIVATE_KEY) kabuktan okunur; hiçbir şey .env dosyasını otomatik olarak yüklemez.
Adım 1: Testnet'i anahtarsız okuyun
Genel uç nokta https://api.blockvectra.com/v1/robinhood_testnet/public, hesap ve API anahtarı gerektirmeden cüzdan JSON-RPC yöntemlerini sunar. EIP-155 zincir kimliğini doğrudan sorgulayın:
curl -s "https://api.blockvectra.com/v1/robinhood_testnet/public" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}'Yanıt {"jsonrpc":"2.0","id":1,"result":"0xb626"} şeklindedir; 0xb626, ondalık olarak 46630 olan onaltılık zincir kimliğidir.
Şablon, zincir kaydını GET /v1/chains üzerinden okur ve bundan bir viem istemcisi oluşturur; böylece zincir adı ve kimliği koda sabitlenmez. src/shared.ts dosyasından:
import { createPublicClient, defineChain, http, webSocket } from "viem";
export const API_BASE = "https://api.blockvectra.com/v1";
export interface ChainEntry {
chain: string;
name: string;
chain_id: number;
data: boolean;
ws: boolean;
subscriptions: string[];
public?: { url: string };
}
export async function getChain(slug: string): Promise<ChainEntry> {
const res = await fetch(`${API_BASE}/chains`);
if (!res.ok) throw new Error(`GET /v1/chains failed: ${res.status}`);
const { chains } = (await res.json()) as { chains: ChainEntry[] };
const entry = chains.find((c) => c.chain === slug);
if (!entry) throw new Error(`${slug} not found in /v1/chains`);
return entry;
}
export function toViemChain(entry: ChainEntry, rpcUrl: string) {
return defineChain({
id: entry.chain_id,
name: entry.name,
nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
rpcUrls: { default: { http: [rpcUrl] } },
});
}
export function httpClient(entry: ChainEntry, url: string, apiKey?: string) {
return createPublicClient({
chain: toViemChain(entry, url),
transport: http(url, apiKey ? { fetchOptions: { headers: { "x-api-key": apiKey } } } : undefined),
});
}
export function wsClient(entry: ChainEntry, apiKey: string) {
const base = "wss://api.blockvectra.com/v1";
const url = `${base}/${entry.chain}/${apiKey}`;
return createPublicClient({ chain: toViemChain(entry, url), transport: webSocket(url) });
}Bu modül ile src/step1-public-read.ts zincir kimliğini, en son bloğu ve bir adres bakiyesini okur:
import { formatEther, type Address } from "viem";
import { API_BASE, getChain, httpClient } from "./shared.js";
const SLUG = "robinhood_testnet";
// Any address works; override with the first CLI argument.
const address = (process.argv[2] ?? "0x0000000000000000000000000000000000000000") as Address;
const chain = await getChain(SLUG);
const client = httpClient(chain, `${API_BASE}/${SLUG}/public`);
const [chainId, blockNumber, balance] = await Promise.all([
client.getChainId(),
client.getBlockNumber(),
client.getBalance({ address }),
]);
console.log(`chain : ${chain.name} (${SLUG})`);
console.log(`eth_chainId : ${chainId} (0x${chainId.toString(16)})`);
console.log(`block : ${blockNumber}`);
console.log(`balance : ${formatEther(balance)} ETH (${address})`);Adım 2: Programatik olarak hesap açın ve log'lara abone olun
src/step2-key-and-logs.ts, https://console-api.blockvectra.com/v1 adresinde bir cüzdanla (SIWE, EIP-191) oturum açar. İlk oturum açma işlemi hesabı oluşturur; istemci ardından bir API anahtarı oluşturur. Yeni hesaplar kaydolduklarında 30,000,000 CU kazanır — kredi kartı gerekmez.
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
import type { Hex } from "viem";
const CONSOLE_API = "https://console-api.blockvectra.com/v1";
const REF = "gh-robinhood-testnet-starter";
async function post<T>(path: string, body: unknown, token?: string): Promise<T> {
const res = await fetch(`${CONSOLE_API}${path}`, {
method: "POST",
headers: { "Content-Type": "application/json", ...(token ? { Authorization: `Bearer ${token}` } : {}) },
body: JSON.stringify(body),
});
if (!res.ok) throw new Error(`${path} failed: ${res.status} ${await res.text()}`);
return (await res.json()) as T;
}
async function provisionKey(): Promise<string> {
const pk = (process.env.WALLET_PRIVATE_KEY as Hex | undefined) ?? generatePrivateKey();
const account = privateKeyToAccount(pk);
console.log(`wallet: ${account.address}`);
// SIWE: ask for a challenge, sign it verbatim (EIP-191), log in. A first sign-in creates the account.
const { message } = await post<{ message: string }>("/auth/siwe/challenge", {
address: account.address,
purpose: "login",
});
const signature = await account.signMessage({ message });
const login = await post<{ session: { token: string }; account_created: boolean }>("/auth/siwe/login", {
message,
signature,
ref: REF,
});
console.log(`account_created: ${login.account_created}`);
const created = await post<{ api_key: string }>("/keys", { label: "robinhood-testnet-starter" }, login.session.token);
return created.api_key;
}
const apiKey = process.env.BLOCKVECTRA_API_KEY?.trim() || (await provisionKey());Zaten bir anahtarınız varsa, export BLOCKVECTRA_API_KEY=... kaydolma adımını atlar. WALLET_PRIVATE_KEY olmadan betik bellekte tek kullanımlık bir cüzdan oluşturur ve çalışma bittiğinde bunu atar; aynı hesaba tekrar oturum açmak istiyorsanız yerel ortamınızda WALLET_PRIVATE_KEY ayarlayın.
WebSocket URL'si anahtarı yola yerleştirir: wss://api.blockvectra.com/v1/robinhood_testnet/{api_key}. Şablon, abone olmadan önce GET /v1/chains üzerinden canlı ws bayrağını ve subscriptions listesini kontrol eder:
const chain = await getChain("robinhood_testnet");
if (!chain.ws || !chain.subscriptions.includes("logs")) {
throw new Error(`robinhood_testnet does not offer a logs subscription in /v1/chains`);
}
console.log(`subscriptions (from /v1/chains): ${chain.subscriptions.join(", ")}`);
const client = wsClient(chain, apiKey);
const stop = client.watchEvent({
address: "0x1234567890123456789012345678901234567890",
onLogs: (logs) => {
for (const l of logs) console.log(`block ${l.blockNumber} ${l.address} topic0=${l.topics[0]}`);
},
onError: (e) => console.error("subscription error:", e.message),
});Her logs abonelik filtresi bir address veya topic0 içermelidir; örnek adresi izlemek istediğiniz sözleşmeyle değiştirin. Filtre kuralları, kapanış kodları ve yeniden bağlanma için WebSocket abonelikleri rehberi sayfasına bakın.
Adım 3: Aynı anahtarı mainnet'e geçirin
Mainnet tek kelimelik bir değişikliktir: robinhood_mainnet slug'ını ve aynı API anahtarını kullanın. src/step3-mainnet.ts mainnet blok numarasını okur ve Robinhood hisse senedi token'ları için Data API'yi çağırır:
const apiKey = process.env.BLOCKVECTRA_API_KEY?.trim();
if (!apiKey) throw new Error("Set BLOCKVECTRA_API_KEY (run step 2 first, or create a key in the console).");
const mainnet = await getChain("robinhood_mainnet");
// JSON-RPC with the key: the chain slug changes.
const client = httpClient(mainnet, `${API_BASE}/${mainnet.chain}`, apiKey);
console.log(`mainnet block: ${await client.getBlockNumber()}`);
// Data API: Robinhood stock-token leaderboard (see the Robinhood Chain guide).
const res = await fetch(`${API_BASE}/data/${mainnet.chain}/stocks`, { headers: { "x-api-key": apiKey } });
if (!res.ok) throw new Error(`Data API failed: ${res.status} ${await res.text()}`);
console.log(JSON.stringify(await res.json(), null, 2).slice(0, 2000));Curl ile aynı lider tablosu uç noktası:
curl -s -H "x-api-key: $BLOCKVECTRA_API_KEY" \
"https://api.blockvectra.com/v1/data/robinhood_mainnet/stocks"Data API yalnızca mainnet'e özeldir: GET /v1/chains, robinhood_testnet için data: false ve robinhood_mainnet için data: true bildirir. İstek parametreleri ve yanıt zarfları için Tokenize hisse senetleri rehberi sayfasına bakın.
Limitleri ve yetenekleri API üzerinden keşfedin
Canlı jsonrpc, data, ws ve subscriptions bayrakları, izin verilen JSON-RPC yöntemleri, log blok aralıkları, durum saklama ve her zincirin genel uç noktası için GET /v1/chains okuyun. Güncel fiyatlar ve plan limitleri için GET /v1/plans okuyun.
curl -s "https://api.blockvectra.com/v1/chains"İlgili rehberler
- Testnet RPC URL'sini ve limitlerini bulun.
- İşlem göndermeden önce testnet faucet'inden test ETH talep edin.
Sonraki adımlar
Son güncelleme:
Testnet faucet'i
Kendi API anahtarınızla test ETH talep edin: hesap gereksinimleri, talep sınırları, kabul edilen işlemler ve hata yönetimi.
İşlemleri Simüle Etme
eth_simulateV1 kullanarak zincir üzerinde göndermeden önce birden fazla işlemi test edin ve durum değişikliklerini inceleyin. Desteklenen zincir yöntemi politikalarını, yürütme belirtimi istek yüklerini, CU fiyatlandırma ağırlıklarını ve AI Agent MCP entegrasyonunu öğrenin.