Skip to main content

What is Sinker?

Sinker is a two-layer transaction reliability stack for Solana. It combines:
  • A Rust sidecar that tracks every stage of the transaction lifecycle — from bundle submission to on-chain finalization — using a live Yellowstone gRPC stream.
  • An AI agent that makes tip selection, submission timing, and retry decisions grounded in real-time oracle data and historical bundle outcomes.
The TypeScript SDK gives you a clean async interface over the sidecar without dealing with raw HTTP or SSE.
Your App → sinker-sdk → Rust Sidecar → Jito Block Engine → Solana

                         AI Agent (decides when + how much to tip)

Start the stack


Prerequisites

Rust sidecar running

The sidecar must be running at localhost:7777 before the SDK can connect. See the README for setup.

Model API key

Sinker’s AI agent requires a provider key. Set ANTHROPIC_API_KEY, OPENAI_API_KEY, GROQ_API_KEY, or XAI_API_KEY in your environment.

Pre-signed transaction

The SDK never touches your keypair. Sign the transaction yourself and pass the base64-encoded wire bytes to sinker.enqueue().

Install

npm install sinker-sdk

Submit your first transaction

import { Sinker } from 'sinker-sdk';
import { Connection, Keypair, SystemProgram, Transaction, sendAndConfirmTransaction } from '@solana/web3.js';
import bs58 from 'bs58';

// 1. Connect to the running sidecar with your model provider
const sinker = new Sinker({
  model: {
    provider: 'anthropic',
    apiKey: process.env.ANTHROPIC_API_KEY!,
  },
  // sidecarUrl defaults to http://localhost:7777
});

// 2. Sign your transaction externally — Sinker never sees your keypair
const tx = buildAndSignMyTransaction(); // your signing code
const rawTxBase64 = Buffer.from(tx.serialize()).toString('base64');

// 3. Enqueue it
const handle = await sinker.enqueue(rawTxBase64);
console.log('Enqueued:', handle.txId);

// 4. Wait for finalization
const result = await handle.waitFor('finalized');
console.log('Finalized sigs:', result.tx_signatures);

// 5. Clean up
sinker.destroy();
The AI agent fires automatically on the tx_enqueued SSE event. You don’t need to call submit() manually — the agent selects a tip and submits the bundle.

What happens under the hood

1

Enqueue

sinker.enqueue() POSTs your transaction bytes to /tx/enqueue. The sidecar assigns a tx_id, fires a tx_enqueued SSE event, and returns immediately.
2

Agent decides

The AI agent receives the SSE event, checks the live tip oracle, reviews failure history, and selects a tip percentile. It calls POST /internal/submit with tx_ids and tip_lamports.
3

Jito bundle

The sidecar builds a Jito bundle (your tx + tip tx), submits it to the block engine, and starts a background status tracker.
4

SSE confirmation

The Yellowstone gRPC stream fires as each commitment stage is reached. The sidecar broadcasts tx_status_changed SSE events. handle.waitFor() resolves when your target state arrives.