Tips Mode
Tips Mode Integration Guide. The Tips model is a pay-per-use on-chain bidding mechanism — include a SOL transfer as a tip in your transaction, only charged when successfully confirmed on-chain.
How It Works
Add a SOL transfer to ZAN's tip account in your transaction instructions.
Tip amount determines priority — higher bids = higher priority.
Tip is only deducted when the transaction successfully reaches the chain — failed acceleration incurs no charges.
Key Information
| Item | Description |
|---|---|
| Tip Account | 7HkiWXe5deJvzn4D6kgMUFCADwX9Z4DMrdjNSSxN6bPp |
| Minimum Tip | 0.0003 SOL (300,000 lamports) |
| Billing Logic | Only charged upon successful on-chain confirmation; no charges for failures |
| Priority | Proportional to tip amount |
Tip Strategy
| Scenario | Recommended Tip Amount | Explanation |
|---|---|---|
| Standard Acceleration | 0.0003 SOL (minimum) | Baseline priority suitable for most transactions |
| Moderate Congestion | 0.001 – 0.005 SOL | Higher priority during network congestion |
| High-value/Time-sensitive | 0.005 – 0.01+ SOL | Maximum priority for critical transactions |
Note:Tip Floor API — an API returning real-time recommended minimum tip amounts (similar to Jito's tip floor) is planned but not yet available.
Endpoints
Enable MEV Protection: Append ?anti-mev=true, see MEV Protection .
Client Code Examples
TypeScript (@solana/web3.js)
import {
Connection,
Keypair,
SystemProgram,
Transaction,
PublicKey,
LAMPORTS_PER_SOL,
TransactionMessage,
VersionedTransaction,
TransactionInstruction,
ComputeBudgetProgram,
} from '@solana/web3.js';
import * as fs from 'fs';
import * as path from 'path';
// Endpoint configuration
const ZAN_BOOST_ENDPOINT = 'http://booster-sg.zan.top/node/v1/solana/mainnet/<YOUR_API_KEY>/tips';
const READ_RPC = 'https://api.zan.top/node/v1/solana/mainnet/<YOUR_API_KEY>';
// ZAN Tip Account — only charged upon successful on-chain confirmation
const TIP_ACCOUNT = new PublicKey('7HkiWXe5deJvzn4D6kgMUFCADwX9Z4DMrdjNSSxN6bPp');
const MIN_TIP_LAMPORTS = 300_000; // 0.0003 SOL
// Compute Budget configuration
const COMPUTE_UNIT_LIMIT = 200_000;
const PRIORITY_FEE_MICRO_LAMPORTS = 100_000; // Priority fee per compute unit (micro-lamports)
async function sendBoostedTransaction() {
const readConnection = new Connection(READ_RPC, 'confirmed');
const boostConnection = new Connection(ZAN_BOOST_ENDPOINT, 'confirmed');
// Read private key file
const secretPath = path.join(__dirname, 'guideSecret.json');
const secretKey = JSON.parse(fs.readFileSync(secretPath, 'utf-8'));
const wallet = Keypair.fromSecretKey(new Uint8Array(secretKey));
// <RECIPIENT_ADDRESS>
const recipientAddress = new PublicKey('<RECIPIENT_ADDRESS>');
console.log('Wallet Address:', wallet.publicKey.toBase58());
console.log('Recipient Address:', recipientAddress.toBase58());
// Get latest blockhash
const blockhashResponse = await readConnection.getLatestBlockhashAndContext('confirmed');
const blockhash = blockhashResponse.value.blockhash;
const lastValidBlockHeight = blockhashResponse.value.lastValidBlockHeight;
console.log('Latest Blockhash:', blockhash);
// Build instruction array
const instructions: TransactionInstruction[] = [];
// 1. Set Compute Budget
instructions.push(ComputeBudgetProgram.setComputeUnitLimit({ units: COMPUTE_UNIT_LIMIT }));
instructions.push(ComputeBudgetProgram.setComputeUnitPrice({ microLamports: PRIORITY_FEE_MICRO_LAMPORTS }));
// 2. Business instruction (example: transfer 0.01 SOL)
instructions.push(
SystemProgram.transfer({
fromPubkey: wallet.publicKey,
toPubkey: recipientAddress,
lamports: 0.01 * LAMPORTS_PER_SOL,
})
);
// 3. Tip instruction (>= 0.0003 SOL)
instructions.push(
SystemProgram.transfer({
fromPubkey: wallet.publicKey,
toPubkey: TIP_ACCOUNT,
lamports: MIN_TIP_LAMPORTS,
})
);
// Create V0 transaction
const messageV0 = new TransactionMessage({
payerKey: wallet.publicKey,
recentBlockhash: blockhash,
instructions: instructions,
}).compileToV0Message();
const transaction = new VersionedTransaction(messageV0);
transaction.sign([wallet]);
console.log('Transaction signed, preparing to send...');
// Send transaction
const txid = await boostConnection.sendRawTransaction(transaction.serialize(), {
skipPreflight: true,
maxRetries: 0,
});
const sendTime = new Date().getTime();
console.log(`Transaction sent: ${txid}`);
console.log(`Send time: ${sendTime}`);
console.log(`Explorer: https://solscan.io/tx/${txid}`);
}
sendBoostedTransaction().catch(console.error);Advanced: Multi-region Broadcast + Smart Retry (TypeScript)
import {
Connection,
Keypair,
SystemProgram,
PublicKey,
LAMPORTS_PER_SOL,
TransactionMessage,
VersionedTransaction,
TransactionInstruction,
ComputeBudgetProgram,
} from '@solana/web3.js';
import * as fs from 'fs';
import * as path from 'path';
/**
* Solana Transaction Accelerator - Concurrent multi-endpoint sending example
* Functionality: Concurrently send transactions to multiple Booster endpoints, automatically selecting the fastest responding endpoint
*/
// ========================================
// Configuration Area - Modify based on your needs
// ========================================
const BOOST_ENDPOINTS = [
'http://booster-sg.zan.top/node/v1/solana/mainnet/<YOUR_API_KEY>/tips',
'http://booster-us.zan.top/node/v1/solana/mainnet/<YOUR_API_KEY>/tips',
'http://booster-de.zan.top/node/v1/solana/mainnet/<YOUR_API_KEY>/tips',
'http://booster-hk.zan.top/node/v1/solana/mainnet/<YOUR_API_KEY>/tips',
];
const READ_RPC = 'https://api.zan.top/node/v1/solana/mainnet/<YOUR_API_KEY>';
const TIP_ACCOUNT = new PublicKey('7HkiWXe5deJvzn4D6kgMUFCADwX9Z4DMrdjNSSxN6bPp');
const RECIPIENT_ADDRESS = new PublicKey('<RECIPIENT_ADDRESS>');
// Transaction parameters
const MIN_TIP_LAMPORTS = 300_000; // Tip fee (0.0003 SOL)
const TRANSFER_AMOUNT_SOL = 0.01; // Transfer amount
const COMPUTE_UNIT_LIMIT = 200_000; // Compute unit limit
const PRIORITY_FEE = 100_000; // Priority fee (micro-lamports)
// Retry configuration
const MAX_RETRIES = 3;
const RETRY_INTERVAL_MS = 1000;
const CONFIRMATION_INTERVAL_MS = 2000;
// ========================================
// Utility Functions
// ========================================
const sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms));
async function sendToEndpoint(
endpoint: string,
serializedTransaction: Buffer
): Promise<{ endpoint: string; txid: string }> {
const connection = new Connection(endpoint, 'confirmed');
const txid = await connection.sendRawTransaction(serializedTransaction, {
skipPreflight: true,
maxRetries: 0,
});
return { endpoint, txid };
}
// ========================================
// Main Flow
// ========================================
async function sendBoostedTransactionParallel() {
const startTime = Date.now();
let readConnection: Connection;
// 1. Initialize connection
try {
readConnection = new Connection(READ_RPC, 'confirmed');
} catch (error) {
throw new Error(`RPC connection failed: ${READ_RPC} - ${error instanceof Error ? error.message : error}`);
}
// 2. Load wallet
console.log('[Step 1] Loading wallet');
const secretPath = path.join(__dirname, 'guideSecret.json');
if (!fs.existsSync(secretPath)) {
throw new Error(`Private key file not found: ${secretPath}`);
}
let wallet: Keypair;
try {
const secretKey = JSON.parse(fs.readFileSync(secretPath, 'utf-8'));
wallet = Keypair.fromSecretKey(new Uint8Array(secretKey));
console.log(`✓ Wallet: ${wallet.publicKey.toBase58()}`);
console.log(`✓ Recipient: ${RECIPIENT_ADDRESS.toBase58()}`);
} catch (error) {
throw new Error(`Private key file format error: ${error instanceof Error ? error.message : error}`);
}
// 3. Get blockhash
console.log('\n[Step 2] Getting blockhash');
let blockhash: string;
let lastValidBlockHeight: number;
try {
const blockhashResponse = await readConnection.getLatestBlockhashAndContext('confirmed');
blockhash = blockhashResponse.value.blockhash;
lastValidBlockHeight = blockhashResponse.value.lastValidBlockHeight;
console.log(`✓ Blockhash: ${blockhash.slice(0, 20)}...`);
} catch (error) {
throw new Error(`Failed to get blockhash: ${error instanceof Error ? error.message : error} (RPC: ${READ_RPC})`);
}
// 4. Build transaction
console.log('\n[Step 3] Building transaction');
let transaction: VersionedTransaction;
try {
const instructions: TransactionInstruction[] = [
ComputeBudgetProgram.setComputeUnitLimit({ units: COMPUTE_UNIT_LIMIT }),
ComputeBudgetProgram.setComputeUnitPrice({ microLamports: PRIORITY_FEE }),
SystemProgram.transfer({
fromPubkey: wallet.publicKey,
toPubkey: RECIPIENT_ADDRESS,
lamports: TRANSFER_AMOUNT_SOL * LAMPORTS_PER_SOL,
}),
SystemProgram.transfer({
fromPubkey: wallet.publicKey,
toPubkey: TIP_ACCOUNT,
lamports: MIN_TIP_LAMPORTS,
}),
];
transaction = new VersionedTransaction(
new TransactionMessage({
payerKey: wallet.publicKey,
recentBlockhash: blockhash,
instructions,
}).compileToV0Message()
);
transaction.sign([wallet]);
console.log(`✓ Transaction built successfully (transfer ${TRANSFER_AMOUNT_SOL} SOL + Tip ${MIN_TIP_LAMPORTS / LAMPORTS_PER_SOL} SOL)`);
} catch (error) {
throw new Error(`Transaction build failed: ${error instanceof Error ? error.message : error}`);
}
// 5. Concurrent transaction sending
console.log('\n[Step 4] Concurrently sending transaction');
const serializedTransaction = Buffer.from(transaction.serialize());
let txid = '';
let winningEndpoint = '';
let lastError: Error | null = null;
for (let retry = 1; retry <= MAX_RETRIES; retry++) {
console.log(`\nAttempt ${retry}/${MAX_RETRIES}...`);
try {
const sendPromises = BOOST_ENDPOINTS.map((endpoint) =>
sendToEndpoint(endpoint, serializedTransaction)
.then((result) => {
console.log(` ✓ ${endpoint}`);
return result;
})
.catch((error) => {
console.error(` ✗ ${endpoint}: ${error.message}`);
throw error;
})
);
const raceResult = await Promise.race(sendPromises);
txid = raceResult.txid;
winningEndpoint = raceResult.endpoint;
console.log(`\n✓ Transaction sent: ${txid}`);
console.log(`✓ Winning endpoint: ${winningEndpoint}`);
console.log(` Explorer: https://solscan.io/tx/${txid}`);
break;
} catch (error) {
lastError = error instanceof Error ? error : new Error(String(error));
if (retry >= MAX_RETRIES) {
throw new Error(`All endpoints failed (retried ${MAX_RETRIES} times): ${lastError.message}`);
}
console.log(` Waiting to retry...`);
await sleep(RETRY_INTERVAL_MS);
}
}
}
async function main() {
try {
await sendBoostedTransactionParallel();
} catch (error) {
console.error(`\n❌ Failed: ${error instanceof Error ? error.message : error}`);
process.exit(1);
}
}
main();Python
#!/usr/bin/env python3
"""
Solana Transaction Accelerator - Single endpoint sending example
"""
import json
from pathlib import Path
from solders.keypair import Keypair
from solders.pubkey import Pubkey
from solders.transaction import VersionedTransaction
from solders.message import MessageV0
from solana.rpc.api import Client
from solana.rpc.commitment import Confirmed
from solders.system_program import transfer as system_transfer, TransferParams as SystemTransferParams
from solders.compute_budget import set_compute_unit_limit, set_compute_unit_price
# ========================================
# Configuration Area - Modify based on your needs
# ========================================
ZAN_BOOST_ENDPOINT = 'http://booster-sg.zan.top/node/v1/solana/mainnet/<YOUR_API_KEY>/tips'
READ_RPC = 'https://api.zan.top/node/v1/solana/mainnet/<YOUR_API_KEY>'
# ZAN Tip Account
TIP_ACCOUNT = Pubkey.from_string('7HkiWXe5deJvzn4D6kgMUFCADwX9Z4DMrdjNSSxN6bPp')
MIN_TIP_LAMPORTS = 300_000 # 0.0003 SOL
# Compute Budget configuration
COMPUTE_UNIT_LIMIT = 200_000
PRIORITY_FEE_MICRO_LAMPORTS = 100_000
LAMPORTS_PER_SOL = 1_000_000_000
def send_boosted_transaction():
"""Send accelerated transaction"""
# Initialize connections
try:
read_client = Client(READ_RPC)
boost_client = Client(ZAN_BOOST_ENDPOINT)
except Exception as error:
raise Exception(f'RPC connection failed: {error}')
# Load wallet
secret_path = Path(__file__).parent / 'guideSecret.json'
if not secret_path.exists():
raise Exception(f'Private key file not found: {secret_path}')
try:
with open(secret_path, 'r') as f:
secret_key = json.load(f)
wallet = Keypair.from_bytes(bytes(secret_key))
recipient_address = Pubkey.from_string('<RECIPIENT_ADDRESS>')
print(f'Wallet: {wallet.pubkey()} -> Recipient: {recipient_address}')
except Exception as error:
raise Exception(f'Private key file format error: {error}')
# Get blockhash
try:
blockhash_response = boost_client.get_latest_blockhash(Confirmed)
blockhash = blockhash_response.value.blockhash
print(f'Blockhash: {blockhash}')
except Exception as error:
raise Exception(f'Failed to get blockhash: {error}')
# Build transaction
try:
instructions = [
set_compute_unit_limit(COMPUTE_UNIT_LIMIT),
set_compute_unit_price(PRIORITY_FEE_MICRO_LAMPORTS),
system_transfer(SystemTransferParams(
from_pubkey=wallet.pubkey(),
to_pubkey=recipient_address,
lamports=int(0.01 * LAMPORTS_PER_SOL)
)),
system_transfer(SystemTransferParams(
from_pubkey=wallet.pubkey(),
to_pubkey=TIP_ACCOUNT,
lamports=MIN_TIP_LAMPORTS
))
]
message = MessageV0.try_compile(
payer=wallet.pubkey(),
instructions=instructions,
address_lookup_table_accounts=[],
recent_blockhash=blockhash
)
transaction = VersionedTransaction(message, [wallet])
print(f'Transaction built successfully: Transfer 0.01 SOL + Tip {MIN_TIP_LAMPORTS / LAMPORTS_PER_SOL} SOL')
except Exception as error:
raise Exception(f'Transaction build failed: {error}')
# Send transaction
try:
from solana.rpc.types import TxOpts
txid = boost_client.send_raw_transaction(
bytes(transaction),
opts=TxOpts(skip_preflight=True)
).value
print(f'✓ Transaction sent: {txid}')
print(f' Solscan: https://solscan.io/tx/{txid}')
except Exception as error:
raise Exception(f'Transaction send failed: {error}')
def main():
"""Main function"""
try:
send_boosted_transaction()
except Exception as error:
print(f'\n❌ Failed: {error}')
exit(1)
if __name__ == '__main__':
main()Rust
use anyhow::{Context, Result};
use solana_client::rpc_client::RpcClient;
use solana_sdk::{
compute_budget::ComputeBudgetInstruction,
instruction::Instruction,
message::Message,
pubkey::Pubkey,
signature::{Keypair, Signer},
system_instruction,
transaction::Transaction,
};
use std::fs;
use std::str::FromStr;
use base64::{Engine as _, engine::general_purpose::STANDARD as BASE64};
use serde_json::json;
const ZAN_BOOST_ENDPOINT: &str = "http://booster-sg.zan.top/node/v1/solana/mainnet/<YOUR_API_KEY>/tips";
const READ_RPC: &str = "https://api.zan.top/node/v1/solana/mainnet/<YOUR_API_KEY>";
const TIP_ACCOUNT: &str = "7HkiWXe5deJvzn4D6kgMUFCADwX9Z4DMrdjNSSxN6bPp";
#[tokio::main]
async fn main() -> Result<()> {
// 1. Load wallet
let wallet = Keypair::from_bytes(&serde_json::from_str::<Vec<u8>>(&fs::read_to_string("guideSecret.json")?)?)
.context("❌Private key parsing failed")?;
println!("✅Wallet: {}", wallet.pubkey());
// 2. Get latest blockhash
let blockhash = RpcClient::new(READ_RPC).get_latest_blockhash().context("❌Failed to get blockhash")?;
println!("✅Blockhash: {}", blockhash);
// 3. Build instructions: Compute Budget + Transfer + Tip
let recipient = Pubkey::from_str("<RECIPIENT_ADDRESS>")?;
let instructions: Vec<Instruction> = vec![
ComputeBudgetInstruction::set_compute_unit_limit(200_000),
ComputeBudgetInstruction::set_compute_unit_price(100_000),
system_instruction::transfer(&wallet.pubkey(), &recipient, 10_000_000), // 0.01 SOL
system_instruction::transfer(&wallet.pubkey(), &Pubkey::from_str(TIP_ACCOUNT)?, 300_000), // 0.0003 SOL tip
];
// 4. Sign transaction
let mut tx = Transaction::new_unsigned(Message::new_with_blockhash(&instructions, Some(&wallet.pubkey()), &blockhash));
tx.sign(&[&wallet], blockhash);
println!("✅Transaction signed");
// 5. Send to Booster endpoint
let tx_base64 = BASE64.encode(&bincode::serialize(&tx)?);
let resp = reqwest::Client::new()
.post(ZAN_BOOST_ENDPOINT)
.json(&json!({"jsonrpc":"2.0","id":1,"method":"sendTransaction","params":[tx_base64,{"encoding":"base64","skipPreflight":true}]}))
.send().await.context("❌HTTP request failed")?
.text().await.context("❌Failed to read response")?;
let resp_json = serde_json::from_str::<serde_json::Value>(&resp)?;
let txid = resp_json["result"].as_str().context("❌No transaction signature in response")?;
println!("✅Transaction sent successfully: {}", txid);
println!("🔍Explorer: https://solscan.io/tx/{}", txid);
Ok(())
}cURL
# Example 1: Minimal configuration (recommended)
curl -X POST 'http://booster-sg.zan.top/node/v1/solana/mainnet/<YOUR_API_KEY>/tips' \
-H 'Content-Type: application/json' \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "sendTransaction",
"params": [
"<BASE64_ENCODED_SIGNED_TRANSACTION>",
{ "encoding": "base64", "skipPreflight": true }
]
}'
# Example 2: Full configuration (includes all optional parameters)
curl -X POST 'http://booster-sg.zan.top/node/v1/solana/mainnet/<YOUR_API_KEY>/tips' \
-H 'Content-Type: application/json' \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "sendTransaction",
"params": [
"<BASE64_ENCODED_SIGNED_TRANSACTION>",
{ "encoding": "base64", "skipPreflight": true, "preflightCommitment": "confirmed", "maxRetries": 3 }
]
}'
Note:Keep-alive must be maintained before sending transactions. For details, see the Keep-Alive.
Best Practices
- Use HTTP for Backend, HTTPS for Frontend — HTTP avoids TLS handshake, faster
- Separate Read/Write Operations — Use standard RPC for reads, Boost endpoints for writes
- Enable Keep-Alive — Reuse connections, eliminate repeated handshake overhead
- Optimize Compute Units — Simulate to get actual CU, explicitly set limits
- Incremental Tip Retry — Start with minimum tip, increase 50% on each retry
- Set skipPreflight: true — Skip preflight checks to reduce latency
- Set maxRetries: 0 — Trading Boost handles retries internally
- Broadcast Concurrently to Multiple Regions — Accelerate chain inclusion
Updated 17 days ago
