Skip to main content
The SolanaRpcWebsocket interface provides WebSocket-based subscriptions for real-time updates from Solana. It enables monitoring of account changes, transaction confirmations, and program state updates.

Interface Definition

Package: software.sava.rpc.json.http.ws File: SolanaRpcWebsocket.java:22
public interface SolanaRpcWebsocket extends AutoCloseable

Creating a WebSocket Client

Factory Method

static Builder build()
Returns: Builder instance for configuration Example:
import software.sava.rpc.json.http.ws.SolanaRpcWebsocket;
import software.sava.rpc.json.http.SolanaNetwork;

var ws = SolanaRpcWebsocket.build()
    .uri(SolanaNetwork.MAIN_NET)
    .commitment(Commitment.CONFIRMED)
    .create();

// Connect and start receiving updates
ws.connect().join();
See SolanaRpcWebsocket.java:41-43.

Core Methods

endpoint()

Get the WebSocket endpoint URI.
URI endpoint()

defaultCommitment()

Get the default commitment level for subscriptions.
Commitment defaultCommitment()

connect()

Connect or reconnect the underlying WebSocket.
CompletableFuture<?> connect()
Returns: CompletableFuture that completes when connected, or null if closed Note: Connection attempts are delayed by Timings.reConnectDelay on subsequent attempts. See SolanaRpcWebsocket.java:55-62.

close()

Close the WebSocket connection permanently.
void close()
Note: Once closed, the WebSocket cannot be reused. See SolanaRpcWebsocket.java:238-239.

closed()

Check if the WebSocket has been closed.
boolean closed()

Account Subscriptions

accountSubscribe()

Subscribe to account changes.
boolean accountSubscribe(
    PublicKey key,
    Consumer<AccountInfo<byte[]>> consumer
)
key
PublicKey
required
Account public key to monitor
commitment
Commitment
Optional commitment level (defaults to client’s defaultCommitment)
onSub
Consumer<Subscription<AccountInfo<byte[]>>>
Optional callback when subscription is confirmed
consumer
Consumer<AccountInfo<byte[]>>
required
Callback for account updates
Returns: true if subscription was initiated, false if already subscribed or closed Example:
ws.accountSubscribe(
    tokenAccount,
    accountInfo -> {
        System.out.println("Account updated: " + accountInfo.lamports());
    }
);
See SolanaRpcWebsocket.java:66-84.

accountUnsubscribe()

Unsubscribe from account updates.
boolean accountUnsubscribe(PublicKey key)
key
PublicKey
required
Account to unsubscribe from
commitment
Commitment
Commitment level used in original subscription
See SolanaRpcWebsocket.java:86-88.

Program Subscriptions

programSubscribe()

Subscribe to all accounts owned by a program.
boolean programSubscribe(
    PublicKey program,
    Consumer<AccountInfo<byte[]>> consumer
)
program
PublicKey
required
Program public key
filters
List<Filter>
Optional filters (memcmp, dataSize)
commitment
Commitment
Commitment level
onSub
Consumer<Subscription<AccountInfo<byte[]>>>
Callback when subscription is confirmed
consumer
Consumer<AccountInfo<byte[]>>
required
Callback for account updates
Example:
import software.sava.core.rpc.Filter;
import java.util.List;

// Subscribe to all token accounts for a mint
var filters = List.of(
    Filter.createMemCompFilter(0, tokenMint)  // Filter by mint
);

ws.programSubscribe(
    Commitment.CONFIRMED,
    TokenProgram.PROGRAM_ID,
    filters,
    accountInfo -> {
        System.out.println("Token account updated: " + accountInfo.pubKey());
    }
);
See SolanaRpcWebsocket.java:176-223.

programUnsubscribe()

Unsubscribe from program updates.
boolean programUnsubscribe(PublicKey program)
See SolanaRpcWebsocket.java:225-227.

Transaction Subscriptions

signatureSubscribe()

Subscribe to transaction confirmation.
boolean signatureSubscribe(
    String b58TxSig,
    Consumer<TxResult> consumer
)
b58TxSig
String
required
Transaction signature (base58)
commitment
Commitment
Commitment level for confirmation
enableReceivedNotification
boolean
default:"false"
Enable notification when transaction is received (PROCESSED only)
onSub
Consumer<Subscription<TxResult>>
Callback when subscription is confirmed
consumer
Consumer<TxResult>
required
Callback for transaction result
Example:
// Send transaction and monitor confirmation
String txSig = client.sendTransaction(transaction, feePayer).join();

ws.signatureSubscribe(
    Commitment.FINALIZED,
    txSig,
    result -> {
        if (result.error() == null) {
            System.out.println("Transaction confirmed!");
        } else {
            System.err.println("Transaction failed: " + result.error());
        }
        ws.signatureUnsubscribe(txSig);
    }
);
See SolanaRpcWebsocket.java:111-154.

signatureUnsubscribe()

Unsubscribe from signature updates.
boolean signatureUnsubscribe(String b58TxSig)
See SolanaRpcWebsocket.java:156-158.

Logs Subscriptions

logsSubscribe()

Subscribe to transaction logs mentioning an account.
boolean logsSubscribe(
    PublicKey key,
    Consumer<TxLogs> consumer
)
key
PublicKey
required
Account or program to monitor
commitment
Commitment
Commitment level
onSub
Consumer<Subscription<TxLogs>>
Callback when subscription is confirmed
consumer
Consumer<TxLogs>
required
Callback for transaction logs
Example:
ws.logsSubscribe(
    programId,
    logs -> {
        System.out.println("Transaction: " + logs.signature());
        for (String log : logs.logs()) {
            System.out.println("  " + log);
        }
    }
);
See SolanaRpcWebsocket.java:90-105.

logsUnsubscribe()

Unsubscribe from log updates.
boolean logsUnsubscribe(PublicKey key)
See SolanaRpcWebsocket.java:107-109.

Slot Subscriptions

slotSubscribe()

Subscribe to slot updates.
boolean slotSubscribe(Consumer<ProcessedSlot> consumer)
onSub
Consumer<Subscription<ProcessedSlot>>
Optional callback when subscription is confirmed
consumer
Consumer<ProcessedSlot>
required
Callback for slot updates
Example:
ws.slotSubscribe(slot -> {
    System.out.println("Slot: " + slot.slot());
    System.out.println("Parent: " + slot.parent());
    System.out.println("Root: " + slot.root());
});
See SolanaRpcWebsocket.java:229-233.

slotUnsubscribe()

Unsubscribe from slot updates.
boolean slotUnsubscribe()
See SolanaRpcWebsocket.java:235.

Token Account Subscriptions

subscribeToTokenAccount()

Subscribe to a specific token account.
boolean subscribeToTokenAccount(
    PublicKey tokenMint,
    PublicKey ownerAddress,
    Consumer<AccountInfo<byte[]>> consumer
)
tokenMint
PublicKey
required
Token mint address
ownerAddress
PublicKey
required
Token account owner
commitment
Commitment
Commitment level
consumer
Consumer<AccountInfo<byte[]>>
required
Callback for account updates
See SolanaRpcWebsocket.java:160-167.

subscribeToTokenAccounts()

Subscribe to all token accounts owned by an address.
boolean subscribeToTokenAccounts(
    PublicKey ownerAddress,
    Consumer<AccountInfo<byte[]>> consumer
)
See SolanaRpcWebsocket.java:169-174.

Exception Handling

exceptionSubscribe()

Subscribe to WebSocket exceptions.
void exceptionSubscribe(Consumer<RuntimeException> consumer)
consumer
Consumer<RuntimeException>
required
Callback for exceptions
Example:
ws.exceptionSubscribe(error -> {
    System.err.println("WebSocket error: " + error.getMessage());
    // Optionally reconnect
    ws.connect();
});
See SolanaRpcWebsocket.java:64.

Builder Configuration

The Builder interface provides configuration options:

uri()

Set the WebSocket endpoint.
Builder uri(URI uri)
uri
URI
required
WebSocket endpoint (wss://…)
Variants:
  • uri(String endpoint) - Parse from string
  • uri(SolanaNetwork network) - Use predefined network
See SolanaRpcWebsocket.java:245-253.

webSocketBuilder()

Provide a custom WebSocket builder.
Builder webSocketBuilder(WebSocket.Builder webSocketBuilder)
See SolanaRpcWebsocket.java:255-259.

commitment()

Set default commitment level.
Builder commitment(Commitment commitment)
See SolanaRpcWebsocket.java:277.

Timing Configuration

Builder reConnectDelay(long reConnectDelay)
Builder pingDelay(long pingDelay)
Builder subscriptionAndPingCheckDelay(long subscriptionAndPingCheckDelay)
See SolanaRpcWebsocket.java:261-275.

Lifecycle Callbacks

Builder onOpen(Consumer<SolanaRpcWebsocket> onOpen)
Builder onClose(OnClose onClose)
Builder onError(BiConsumer<SolanaRpcWebsocket, Throwable> onError)
See SolanaRpcWebsocket.java:296-311.

Complete Examples

Monitor Token Account Balance

import software.sava.rpc.json.http.ws.SolanaRpcWebsocket;
import software.sava.rpc.json.http.SolanaNetwork;
import software.sava.rpc.json.http.request.Commitment;

var ws = SolanaRpcWebsocket.build()
    .uri(SolanaNetwork.MAIN_NET)
    .commitment(Commitment.CONFIRMED)
    .create();

ws.connect().join();

ws.accountSubscribe(
    tokenAccount,
    accountInfo -> {
        long lamports = accountInfo.lamports();
        System.out.println("New balance: " + lamports);
    }
);

Track Transaction Confirmation

// Send transaction
String txSig = rpcClient.sendTransaction(transaction, signer).join();
System.out.println("Transaction sent: " + txSig);

// Monitor confirmation with WebSocket
ws.signatureSubscribe(
    Commitment.FINALIZED,
    true,  // Enable received notification
    txSig,
    subscription -> {
        System.out.println("Subscription ID: " + subscription.id());
    },
    result -> {
        if (result.error() == null) {
            System.out.println("Transaction finalized!");
        } else {
            System.err.println("Transaction error: " + result.error());
        }
        ws.signatureUnsubscribe(Commitment.FINALIZED, txSig);
    }
);

Monitor Program Activity

import software.sava.core.rpc.Filter;
import java.util.List;

var ws = SolanaRpcWebsocket.build()
    .uri("wss://api.mainnet-beta.solana.com")
    .commitment(Commitment.CONFIRMED)
    .onError((websocket, error) -> {
        System.err.println("Error: " + error.getMessage());
        websocket.connect(); // Auto-reconnect
    })
    .create();

ws.connect().join();

// Filter for specific account type
var filters = List.of(
    Filter.createDataSizeFilter(165)  // Token account size
);

ws.programSubscribe(
    Commitment.CONFIRMED,
    TokenProgram.PROGRAM_ID,
    filters,
    accountInfo -> {
        System.out.println("Token account updated: " + accountInfo.pubKey());
        // Parse and process token account data
    }
);

Slot Monitoring

var ws = SolanaRpcWebsocket.build()
    .uri(SolanaNetwork.MAIN_NET)
    .create();

ws.connect().join();

ws.slotSubscribe(
    subscription -> {
        System.out.println("Slot subscription active: " + subscription.id());
    },
    slot -> {
        System.out.printf(
            "Slot %d (parent: %d, root: %d)%n",
            slot.slot(),
            slot.parent(),
            slot.root()
        );
    }
);

Best Practices

Connection Management

// Create with auto-reconnect on error
var ws = SolanaRpcWebsocket.build()
    .uri(SolanaNetwork.MAIN_NET)
    .onError((websocket, error) -> {
        System.err.println("Connection error, reconnecting...");
        websocket.connect();
    })
    .create();

// Always connect after creation
ws.connect().join();

// Clean up when done
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
    ws.close();
}));

Subscription Cleanup

// Track subscriptions
Set<PublicKey> subscribedAccounts = new HashSet<>();

// Subscribe
if (ws.accountSubscribe(account, consumer)) {
    subscribedAccounts.add(account);
}

// Clean up on shutdown
for (PublicKey account : subscribedAccounts) {
    ws.accountUnsubscribe(account);
}
ws.close();

Error Recovery

ws.exceptionSubscribe(error -> {
    System.err.println("WebSocket exception: " + error);
    
    // Attempt to reconnect after delay
    CompletableFuture.delayedExecutor(5, TimeUnit.SECONDS)
        .execute(() -> {
            if (!ws.closed()) {
                ws.connect();
            }
        });
});

See Also

Build docs developers (and LLMs) love