AURA Transaction Service
High-performance Solana transaction service with MEV protection.
Endpoints and Tip Address
Direct Endpoints (HTTP — lowest latency)
| Region | Endpoint | Status |
|---|---|---|
| Frankfurt (FRA) |
http://64.130.32.177:5000
|
✅ Available |
| Amsterdam (AMS) |
http://198.13.134.177:5000
|
✅ Available |
| New York (NYC) |
http://45.63.11.162:5000
|
✅ Available |
Recommended: Use HTTP/2 long connection (Keep Alive)
Tip Address
To ensure your transaction is processed, include a tip of at least 0.001 SOL to one of our tip wallets (7 available). You may randomly select an address from the list for your transfer, which helps distribute the load and improves system efficiency.
aura2NHPnnLkPWPXkcqeHkRisDT2b8vy76eMgXH6TsL
auraMDpDVVWxwrJDtBz3Nhog4WGtbrGK2v8y3Pda7ei
auraMkDXGTE678N8LX6cqSV5JJKDpgavVcubPudaVrs
auraSRE5x8CMKbPKto1AkWjLaH4SowAJeAfGqAtdmDC
aurahN2ezg2Ktb2vrDVWqe9yunSZJajzPNTevECSGV4
aurajDJ4Eoq7L6AW36frV8PrrSjf6WMfDjEraU5iFPC
aurarguyidxqBCVtDdoi1FiKrFr3CyyNELGPaU2MWLy
Tip Floor
| Minimum Tip |
|---|
| 0.001 SOL |
Transaction Submission
Endpoint
POST /aura?api-key=YOUR_API_KEY
Base64 Format (JSON-RPC)
Request (`sendTransaction`):
{
"jsonrpc": "2.0",
"id": 1,
"method": "sendTransaction",
"params": [
"BASE64_ENCODED_TRANSACTION",
{
"skipPreflight": true,
"encoding": "base64"
}
]
}
Request (`sendBundle`):
Submit up to 4 transactions together. Works out-of-the-box with
the same anti-MEV protection endpoints.
{
"jsonrpc": "2.0",
"id": 1,
"method": "sendBundle",
"params": [
[
"BASE64_ENCODED_TRANSACTION_1",
"BASE64_ENCODED_TRANSACTION_2"
]
]
}
}
Request (`sendTransactionBatch`):
Send up to 10 transactions in a single request. Each transaction is processed independently — they're not atomic like bundles.
{
"jsonrpc": "2.0",
"id": 1,
"method": "sendTransactionBatch",
"params": [
"<base64-tx-1>",
"<base64-tx-2>",
"<base64-tx-3>"
]
}
Note: unlike sendBundle, the transactions go directly in params (no inner array).
Response (`sendTransactionBatch`):
{
"jsonrpc": "2.0",
"id": 1,
"result": ["sig1...", "sig2...", "sig3..."]
}
Returns an array of signatures for the transactions that were accepted.
Response (`sendTransaction` & `sendBundle`):
{
"jsonrpc": "2.0",
"id": 1,
"result": "TRANSACTION_SIGNATURE"
}
Binary Format (Raw Bytes)
Send raw transaction bytes directly. Fastest option.
curl -X POST "http://64.130.32.177:5000/aura?api-key=YOUR_KEY" \
--data-binary @transaction.bin
Response:
TRANSACTION_SIGNATURE
QUIC
Send transactions over QUIC for the lowest possible latency. Raw transaction bytes over a persistent connection — no JSON, no base64.
Connection
| Port | 5001 |
| ALPN | solana-tpu |
| TLS | self-signed (skip verification) |
| Idle timeout | 30s |
| Keep-alive | 10s |
QUIC Regions
| Region | Endpoint |
|---|---|
| Frankfurt |
64.130.32.177:5001
|
| Amsterdam |
198.13.134.177:5001
|
| New York |
45.63.11.162:5001
|
Authentication
The first unidirectional stream on every new connection must contain your API key (36-byte UUID, e.g. 9fd631cf-8c7d-432f-8eb6-4ab17af6ea93). The server validates it and authorizes the connection — all subsequent streams are authenticated with zero overhead.
If the key is invalid or inactive, the server closes the connection immediately.
Sending Transactions
Transactions are raw bincode bytes — bincode::serialize(&versioned_transaction) in Rust, or bytes(transaction) in Python with solders. Valid size: 65–1232 bytes.
Fire-and-forget (fastest)
Open a unidirectional stream, write the bytes, done.
let mut stream = conn.open_uni().await?;
stream.write_all(&tx_bytes).await?;
stream.finish()?;
With confirmation
Open a bidirectional stream, write the bytes, read back the signature.
let (mut send, mut recv) = conn.open_bi().await?;
send.write_all(&tx_bytes).await?;
send.finish()?;
let response = recv.read_to_end(256).await?;
let sig = String::from_utf8(response)?;
// "5KtPn1..." or "ERR:invalid_tx"
Dedup
Duplicate transactions are dropped silently. Only the first copy gets forwarded.
Limitations
- No bundle support — use HTTP
sendBundlefor atomic bundles - Tip requirement still applies (min 0.001 SOL to an Aura tip account)
Code Examples
Rust (Base64)
use solana_sdk::{signature::{Keypair, Signer}, system_instruction, transaction::Transaction};
use base64::Engine;
let tip_account = "auraT1eZF4qTFQbWL6rjHXvh7ciLey6kAhbdLzFEJom".parse()?;
let blockhash = rpc.get_latest_blockhash()?;
let tx = Transaction::new_signed_with_payer(
&[
// Your instruction here
system_instruction::transfer(&payer.pubkey(), &tip_account, 1_000_000),
],
Some(&payer.pubkey()),
&[&payer],
blockhash,
);
let tx_base64 = base64::engine::general_purpose::STANDARD.encode(bincode::serialize(&tx)?);
let body = serde_json::json!({
"jsonrpc": "2.0",
"id": 1,
"method": "sendTransaction",
"params": [tx_base64, {"skipPreflight": true, "encoding": "base64"}]
});
let response = client
.post("http://64.130.32.177:5000/aura?api-key=YOUR_KEY")
.json(&body)
.send()
.await?;
Rust (Binary)
let tx_bytes = bincode::serialize(&tx)?;
let response = client
.post("http://64.130.32.177:5000/aura?api-key=YOUR_KEY")
.body(tx_bytes)
.send()
.await?;
TypeScript (Base64)
import { Connection, Keypair, SystemProgram, Transaction, PublicKey, LAMPORTS_PER_SOL } from '@solana/web3.js';
const tipAccount = new PublicKey('auraT1eZF4qTFQbWL6rjHXvh7ciLey6kAhbdLzFEJom');
const blockhash = await connection.getLatestBlockhash();
const tx = new Transaction({
recentBlockhash: blockhash.blockhash,
feePayer: payer.publicKey,
});
// Add your instruction
tx.add(SystemProgram.transfer({
fromPubkey: payer.publicKey,
toPubkey: tipAccount,
lamports: 0.001 * LAMPORTS_PER_SOL,
}));
tx.sign(payer);
const txBase64 = Buffer.from(tx.serialize()).toString('base64');
const response = await fetch('http://64.130.32.177:5000/aura?api-key=YOUR_KEY', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
jsonrpc: '2.0',
id: 1,
method: 'sendTransaction',
params: [txBase64, { skipPreflight: true, encoding: 'base64' }],
}),
});
TypeScript (Binary)
const txBytes = tx.serialize();
const response = await fetch('http://64.130.32.177:5000/aura?api-key=YOUR_KEY', {
method: 'POST',
body: txBytes,
});
Rust (QUIC — using aura-quic-client)
Use the aura-quic-client library — handles TLS, auth, reconnection.
View on GitHub[dependencies]
aura-quic-client = { git = "https://github.com/aurabooster/aura-quic-client" }
use aura_quic_client::AuraQuicClient;
let client = AuraQuicClient::connect("64.130.32.177:5001", "your-api-key").await?;
// fire-and-forget
client.send_transaction(&tx_bytes).await?;
// or with confirmation
let sig = client.send_transaction_confirmed(&tx_bytes).await?;
The client reconnects automatically if the connection drops.
Rust (QUIC — raw quinn)
If you prefer no dependencies:
use quinn::{ClientConfig, Endpoint};
use std::sync::Arc;
let mut crypto = rustls::ClientConfig::builder()
.dangerous()
.with_custom_certificate_verifier(Arc::new(SkipVerification))
.with_no_client_auth();
crypto.alpn_protocols = vec![b"solana-tpu".to_vec()];
let config = ClientConfig::new(Arc::new(
quinn::crypto::rustls::QuicClientConfig::try_from(crypto)?
));
let mut endpoint = Endpoint::client("0.0.0.0:0".parse()?)?;
endpoint.set_default_client_config(config);
let conn = endpoint.connect("64.130.32.177:5001".parse()?, "localhost")?.await?;
// authenticate — first stream must be your API key
let mut auth = conn.open_uni().await?;
auth.write_all(b"your-api-key-uuid-here").await?;
auth.finish()?;
// send transactions on subsequent streams
let tx_bytes = bincode::serialize(&my_transaction)?;
let mut stream = conn.open_uni().await?;
stream.write_all(&tx_bytes).await?;
stream.finish()?;
Python (QUIC)
import asyncio
from aioquic.asyncio import connect
from aioquic.quic.configuration import QuicConfiguration
API_KEY = "your-api-key-uuid-here"
config = QuicConfiguration(is_client=True, alpn_protocols=["solana-tpu"])
config.verify_mode = False
async with connect("64.130.32.177", 5001, configuration=config) as protocol:
quic = protocol._quic
# authenticate — first stream must be your API key
auth_stream = quic.get_next_available_stream_id(is_unidirectional=True)
quic.send_stream_data(auth_stream, API_KEY.encode(), end_stream=True)
await asyncio.sleep(0.05) # let server validate
# send transaction
tx_bytes = bytes(my_transaction) # solders VersionedTransaction
stream_id = quic.get_next_available_stream_id(is_unidirectional=True)
quic.send_stream_data(stream_id, tx_bytes, end_stream=True)
TypeScript (HTTP fallback)
There's no mature QUIC library for Node.js/browser yet. Use HTTP — it's still fast with HTTP/2 keep-alive:
const resp = await fetch("http://64.130.32.177:5000/aura?api-key=YOUR_KEY", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
jsonrpc: "2.0", id: 1,
method: "sendTransaction",
params: [base64EncodedTx]
})
});
Keep Alive
getHealth
Check service status. No API key required.
curl -X POST "http://64.130.32.177:5000/aura" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"getHealth"}'
Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": "ok"
}
Error Codes
| Code | Message |
|---|---|
| -32001 | API key required |
| -32002 | Invalid API key |
| -32003 | Rate limit exceeded |
| -32004 | Tip required |
| -32005 | Tip too low |
MEV Protection
Include this account in your transaction to enable MEV protection:
auradontfront111111111111111111111111111123
Contact Us
- Telegram: @aurauntouched
- Discord: discord.gg/Dn3fUaucVH