Skip to content

Instantly share code, notes, and snippets.

@harishkotra
Created April 12, 2026 05:47
Show Gist options
  • Select an option

  • Save harishkotra/81311273b7fef7624c3157c7364f97e6 to your computer and use it in GitHub Desktop.

Select an option

Save harishkotra/81311273b7fef7624c3157c7364f97e6 to your computer and use it in GitHub Desktop.
Ultra low-latency SOL PnL solver using getTransactionsForAddress (RPC-only, no indexing)
/**
* SOL PnL Ultra Solver (single-file submission)
* RPC-only, no indexing, optimized for low latency on getTransactionsForAddress.
*
* Run:
* RPC_ENDPOINTS="https://rpc1,https://rpc2" \
* TARGET_ADDRESS="wallet_pubkey" \
* START_SLOT=0 \
* END_SLOT=350000000 \
* PROBE_CONCURRENCY=24 \
* FULL_CONCURRENCY=32 \
* SEED_BUCKETS=96 \
* MIN_PROBE_SPAN=2048 \
* MAX_PROBE_DEPTH=24 \
* node --experimental-strip-types sol_pnl_ultra_single.ts
*/
type JsonRpcRequest = {
jsonrpc: "2.0";
id: number;
method: string;
params: unknown[];
};
type JsonRpcSuccess<T> = {
jsonrpc: "2.0";
id: number;
result: T;
};
type JsonRpcFailure = {
jsonrpc: "2.0";
id: number;
error: { code: number; message: string; data?: unknown };
};
type SignatureTx = {
slot: number;
signature: string;
};
type FullTx = {
slot: number;
signature: string;
transaction?: {
message?: {
accountKeys?: Array<string | { pubkey: string }>;
};
};
meta?: {
preBalances?: number[];
postBalances?: number[];
err?: unknown;
};
};
type GtfaResult<T> = {
data?: T[];
paginationToken?: string | null;
};
type SlotRange = {
startSlot: number;
endSlot: number;
depth: number;
};
type EndpointState = {
url: string;
inflight: number;
ewmaMs: number;
};
class RpcPool {
private nextId = 1;
private readonly endpoints: EndpointState[];
constructor(rawEndpoints: string[]) {
const urls = rawEndpoints.map((x) => x.trim()).filter(Boolean);
if (!urls.length) throw new Error("No RPC endpoints provided");
this.endpoints = urls.map((url) => ({ url, inflight: 0, ewmaMs: 300 }));
}
private chooseEndpoint(exclude?: Set<string>): EndpointState {
let best: EndpointState | undefined;
let bestScore = Number.POSITIVE_INFINITY;
for (const ep of this.endpoints) {
if (exclude?.has(ep.url)) continue;
const score = ep.ewmaMs * (ep.inflight + 1);
if (score < bestScore) {
bestScore = score;
best = ep;
}
}
if (!best) throw new Error("No endpoint available");
return best;
}
private async post<T>(ep: EndpointState, body: unknown): Promise<T> {
const t0 = performance.now();
ep.inflight += 1;
try {
const res = await fetch(ep.url, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify(body),
});
const json = (await res.json()) as T;
const dt = performance.now() - t0;
ep.ewmaMs = ep.ewmaMs * 0.8 + dt * 0.2;
return json;
} finally {
ep.inflight -= 1;
}
}
async call<T>(method: string, params: unknown[], attempts = 3): Promise<T> {
const tried = new Set<string>();
let lastErr: unknown;
for (let i = 0; i < attempts; i++) {
const ep = this.chooseEndpoint(tried);
tried.add(ep.url);
const req: JsonRpcRequest = {
jsonrpc: "2.0",
id: this.nextId++,
method,
params,
};
try {
const json = await this.post<JsonRpcSuccess<T> | JsonRpcFailure>(ep, req);
if ("error" in json) throw new Error(`${json.error.code}: ${json.error.message}`);
return json.result;
} catch (err) {
lastErr = err;
}
}
throw lastErr instanceof Error ? lastErr : new Error(String(lastErr));
}
async callBatch<T>(calls: Array<{ method: string; params: unknown[] }>, attempts = 3): Promise<T[]> {
const tried = new Set<string>();
let lastErr: unknown;
for (let i = 0; i < attempts; i++) {
const ep = this.chooseEndpoint(tried);
tried.add(ep.url);
const batch: JsonRpcRequest[] = calls.map((c) => ({
jsonrpc: "2.0",
id: this.nextId++,
method: c.method,
params: c.params,
}));
try {
const json = await this.post<Array<JsonRpcSuccess<T> | JsonRpcFailure>>(ep, batch);
const byId = new Map<number, JsonRpcSuccess<T> | JsonRpcFailure>();
for (const r of json) byId.set(r.id, r);
return batch.map((req) => {
const item = byId.get(req.id);
if (!item) throw new Error(`Missing batch response for id=${req.id}`);
if ("error" in item) throw new Error(`${item.error.code}: ${item.error.message}`);
return item.result;
});
} catch (err) {
lastErr = err;
}
}
throw lastErr instanceof Error ? lastErr : new Error(String(lastErr));
}
}
class SolPnlUltraSolver {
private readonly rpc: RpcPool;
private readonly address: string;
private readonly startSlot: number;
private readonly endSlot: number;
private readonly probeConcurrency: number;
private readonly fullConcurrency: number;
private readonly probeLimit: number;
private readonly fullLimit: number;
private readonly minProbeSpan: number;
private readonly maxProbeDepth: number;
private readonly seedBuckets: number;
constructor(
rpc: RpcPool,
address: string,
cfg: {
startSlot: number;
endSlot: number;
probeConcurrency: number;
fullConcurrency: number;
probeLimit: number;
fullLimit: number;
minProbeSpan: number;
maxProbeDepth: number;
seedBuckets: number;
}
) {
this.rpc = rpc;
this.address = address;
this.startSlot = cfg.startSlot;
this.endSlot = cfg.endSlot;
this.probeConcurrency = cfg.probeConcurrency;
this.fullConcurrency = cfg.fullConcurrency;
this.probeLimit = cfg.probeLimit;
this.fullLimit = cfg.fullLimit;
this.minProbeSpan = cfg.minProbeSpan;
this.maxProbeDepth = cfg.maxProbeDepth;
this.seedBuckets = cfg.seedBuckets;
}
private signaturesQuery(range: SlotRange, sortOrder: "asc" | "desc") {
return {
transactionDetails: "signatures",
sortOrder,
limit: this.probeLimit,
filters: { slot: { gte: range.startSlot, lte: range.endSlot } },
};
}
private fullQuery(range: SlotRange, paginationToken?: string) {
return {
transactionDetails: "full",
sortOrder: "asc",
limit: this.fullLimit,
encoding: "json",
maxSupportedTransactionVersion: 0,
filters: { slot: { gte: range.startSlot, lte: range.endSlot } },
...(paginationToken ? { paginationToken } : {}),
};
}
private static splitRange(range: SlotRange, parts: 2 | 4): SlotRange[] {
if (parts === 2) {
const mid = Math.floor((range.startSlot + range.endSlot) / 2);
return [
{ startSlot: range.startSlot, endSlot: mid, depth: range.depth + 1 },
{ startSlot: mid + 1, endSlot: range.endSlot, depth: range.depth + 1 },
];
}
const span = range.endSlot - range.startSlot + 1;
const q = Math.max(1, Math.floor(span / 4));
const a = range.startSlot;
const b = Math.min(range.endSlot, a + q - 1);
const c = Math.min(range.endSlot, b + q);
const d = Math.min(range.endSlot, c + q);
return [
{ startSlot: a, endSlot: b, depth: range.depth + 1 },
{ startSlot: b + 1, endSlot: c, depth: range.depth + 1 },
{ startSlot: c + 1, endSlot: d, depth: range.depth + 1 },
{ startSlot: d + 1, endSlot: range.endSlot, depth: range.depth + 1 },
].filter((r) => r.startSlot <= r.endSlot);
}
private async findActiveWindow(): Promise<{ activeStart: number; activeEnd: number } | null> {
const range: SlotRange = { startSlot: this.startSlot, endSlot: this.endSlot, depth: 0 };
const [first, last] = await Promise.all([
this.rpc.call<GtfaResult<SignatureTx>>("getTransactionsForAddress", [
this.address,
{ ...this.signaturesQuery(range, "asc"), limit: 1 },
]),
this.rpc.call<GtfaResult<SignatureTx>>("getTransactionsForAddress", [
this.address,
{ ...this.signaturesQuery(range, "desc"), limit: 1 },
]),
]);
const firstSlot = first.data?.[0]?.slot;
const lastSlot = last.data?.[0]?.slot;
if (typeof firstSlot !== "number" || typeof lastSlot !== "number") return null;
return { activeStart: firstSlot, activeEnd: lastSlot };
}
private initialRanges(activeStart: number, activeEnd: number): SlotRange[] {
const total = activeEnd - activeStart + 1;
const size = Math.max(1, Math.floor(total / Math.max(1, this.seedBuckets)));
const out: SlotRange[] = [];
for (let s = activeStart; s <= activeEnd; ) {
const e = Math.min(activeEnd, s + size - 1);
out.push({ startSlot: s, endSlot: e, depth: 0 });
s = e + 1;
}
return out;
}
private async partition(activeStart: number, activeEnd: number): Promise<{ leaves: SlotRange[]; probeCalls: number }> {
const queue = this.initialRanges(activeStart, activeEnd);
const leaves: SlotRange[] = [];
let probeCalls = 0;
while (queue.length) {
const batch = queue.splice(0, this.probeConcurrency);
const calls = batch.map((r) => ({
method: "getTransactionsForAddress",
params: [this.address, this.signaturesQuery(r, "asc")],
}));
const res = await this.rpc.callBatch<GtfaResult<SignatureTx>>(calls);
probeCalls += batch.length;
for (let i = 0; i < batch.length; i++) {
const range = batch[i];
const rr = res[i];
const count = rr.data?.length ?? 0;
const saturated = count >= this.probeLimit || !!rr.paginationToken;
const span = range.endSlot - range.startSlot + 1;
if (!saturated) {
if (count > 0) leaves.push(range);
continue;
}
if (range.depth >= this.maxProbeDepth || span <= this.minProbeSpan) {
leaves.push(range);
continue;
}
const parts: 2 | 4 = span > this.minProbeSpan * 8 ? 4 : 2;
queue.push(...SolPnlUltraSolver.splitRange(range, parts));
}
}
return { leaves, probeCalls };
}
private async fetchRangeFull(range: SlotRange): Promise<{ txs: FullTx[]; calls: number }> {
const out: FullTx[] = [];
let calls = 0;
let token: string | undefined;
while (true) {
const page = await this.rpc.call<GtfaResult<FullTx>>("getTransactionsForAddress", [
this.address,
this.fullQuery(range, token),
]);
calls += 1;
const data = page.data ?? [];
if (!data.length) break;
out.push(...data);
if (!page.paginationToken) break;
token = page.paginationToken;
}
return { txs: out, calls };
}
private async fetchAll(leaves: SlotRange[]): Promise<{ txs: FullTx[]; fullCalls: number }> {
const queue = [...leaves];
const out: FullTx[] = [];
let fullCalls = 0;
const workers = Array.from({ length: Math.max(1, this.fullConcurrency) }, async () => {
while (true) {
const range = queue.pop();
if (!range) break;
const r = await this.fetchRangeFull(range);
out.push(...r.txs);
fullCalls += r.calls;
}
});
await Promise.all(workers);
return { txs: out, fullCalls };
}
private computePnlLamports(txs: FullTx[]): { pnlLamports: bigint; successCount: number; failedCount: number } {
let pnlLamports = 0n;
let successCount = 0;
let failedCount = 0;
for (const tx of txs) {
const keys = tx.transaction?.message?.accountKeys ?? [];
const idx = keys.findIndex((k) => (typeof k === "string" ? k : k?.pubkey) === this.address);
if (idx < 0) continue;
const pre = tx.meta?.preBalances?.[idx];
const post = tx.meta?.postBalances?.[idx];
if (typeof pre !== "number" || typeof post !== "number") continue;
pnlLamports += BigInt(post - pre);
if (tx.meta?.err) failedCount++;
else successCount++;
}
return { pnlLamports, successCount, failedCount };
}
async run() {
const t0 = performance.now();
const active = await this.findActiveWindow();
if (!active) {
return {
address: this.address,
slotWindow: { requestedStart: this.startSlot, requestedEnd: this.endSlot, activeStart: null, activeEnd: null },
txCount: 0,
pnlLamports: "0",
pnlSOL: 0,
successCount: 0,
failedCount: 0,
perf: { totalMs: Number((performance.now() - t0).toFixed(2)), probeCalls: 2, fullCalls: 0, totalCalls: 2 },
};
}
const { leaves, probeCalls } = await this.partition(active.activeStart, active.activeEnd);
const { txs, fullCalls } = await this.fetchAll(leaves);
const seen = new Set<string>();
const uniq: FullTx[] = [];
for (const tx of txs) {
if (!seen.has(tx.signature)) {
seen.add(tx.signature);
uniq.push(tx);
}
}
uniq.sort((a, b) => a.slot - b.slot);
const pnl = this.computePnlLamports(uniq);
const totalMs = performance.now() - t0;
return {
address: this.address,
slotWindow: {
requestedStart: this.startSlot,
requestedEnd: this.endSlot,
activeStart: active.activeStart,
activeEnd: active.activeEnd,
},
shardCount: leaves.length,
txCount: uniq.length,
pnlLamports: pnl.pnlLamports.toString(),
pnlSOL: Number((Number(pnl.pnlLamports) / 1_000_000_000).toFixed(9)),
successCount: pnl.successCount,
failedCount: pnl.failedCount,
perf: {
totalMs: Number(totalMs.toFixed(2)),
probeCalls,
fullCalls,
totalCalls: probeCalls + fullCalls + 2,
txPerSec: Number(((uniq.length / totalMs) * 1000).toFixed(2)),
},
};
}
}
function intEnv(name: string, fallback: number): number {
const v = Number(process.env[name] ?? String(fallback));
if (!Number.isFinite(v)) throw new Error(`Invalid number for ${name}`);
return Math.floor(v);
}
async function main() {
const endpoints = (process.env.RPC_ENDPOINTS ?? process.env.RPC_ENDPOINT ?? "")
.split(",")
.map((x) => x.trim())
.filter(Boolean);
const address = process.env.TARGET_ADDRESS ?? "";
if (!endpoints.length || !address) {
console.error("Need RPC_ENDPOINT(S) and TARGET_ADDRESS");
process.exit(1);
}
const startSlot = intEnv("START_SLOT", 0);
const endSlot = intEnv("END_SLOT", 350_000_000);
if (startSlot > endSlot) {
console.error("START_SLOT must be <= END_SLOT");
process.exit(1);
}
const solver = new SolPnlUltraSolver(new RpcPool(endpoints), address, {
startSlot,
endSlot,
probeConcurrency: intEnv("PROBE_CONCURRENCY", 24),
fullConcurrency: intEnv("FULL_CONCURRENCY", 32),
probeLimit: Math.min(1000, intEnv("PROBE_LIMIT", 1000)),
fullLimit: Math.min(100, intEnv("FULL_LIMIT", 100)),
minProbeSpan: intEnv("MIN_PROBE_SPAN", 2048),
maxProbeDepth: intEnv("MAX_PROBE_DEPTH", 24),
seedBuckets: intEnv("SEED_BUCKETS", 96),
});
const out = await solver.run();
console.log(JSON.stringify(out, null, 2));
}
main().catch((err) => {
console.error(err);
process.exit(1);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment