createReactiveStoreWithInitialValueAndSlotTracking

function createReactiveStoreWithInitialValueAndSlotTracking<
    TRpcValue,
    TSubscriptionValue,
    TItem,
>(
    config,
): ReactiveStore<
    Readonly<{
        context: Readonly<{
            slot: Slot;
        }>;
        value: TItem;
    }>
>;

Creates a ReactiveStore that combines an initial RPC fetch with an ongoing subscription to keep its state up to date.

The store uses slot-based comparison to ensure that only the most recent value is kept, regardless of whether it came from the initial RPC response or a subscription notification. This prevents stale data from overwriting newer data when the RPC response and subscription notifications arrive out of order.

Things to note:

  • getState() returns undefined until the first response or notification arrives. Once data arrives, it returns a SolanaRpcResponse containing the value and the slot context at which it was observed.
  • On error from either source, getState() continues to return the last known value and getError() returns the error. Only the first error is captured.
  • When an error occurs, the abort signal is triggered, cancelling both the RPC request and the subscription.
  • Triggering the caller's abort signal disconnects the store from both sources.

Type Parameters

Type Parameter
TRpcValue
TSubscriptionValue
TItem

Parameters

ParameterTypeDescription
configCreateReactiveStoreWithInitialValueAndSlotTrackingConfig<TRpcValue, TSubscriptionValue, TItem>-

Returns

ReactiveStore<Readonly<{ context: Readonly<{ slot: Slot; }>; value: TItem; }>>

Example

import {
    address,
    createReactiveStoreWithInitialValueAndSlotTracking,
    createSolanaRpc,
    createSolanaRpcSubscriptions,
} from '@solana/kit';
 
const rpc = createSolanaRpc('http://127.0.0.1:8899');
const rpcSubscriptions = createSolanaRpcSubscriptions('ws://127.0.0.1:8900');
const myAddress = address('FnHyam9w4NZoWR6mKN1CuGBritdsEWZQa4Z4oawLZGxa');
 
const balanceStore = createReactiveStoreWithInitialValueAndSlotTracking({
    abortSignal: AbortSignal.timeout(60_000),
    rpcRequest: rpc.getBalance(myAddress, { commitment: 'confirmed' }),
    rpcValueMapper: lamports => lamports,
    rpcSubscriptionRequest: rpcSubscriptions.accountNotifications(myAddress),
    rpcSubscriptionValueMapper: ({ lamports }) => lamports,
});
 
const unsubscribe = balanceStore.subscribe(() => {
    const error = balanceStore.getError();
    if (error) console.error('Error:', error);
    else {
        const state = balanceStore.getState();
        if (state) console.log(`Balance at slot ${state.context.slot}:`, state.value);
    }
});

See

ReactiveStore

On this page