Skip to content

useSubscription ​

The useSubscription hook provides a way to subscribe to real-time data from the blockchain using dedot's subscription system.

Import ​

tsx
import { useSubscription } from '@luno-kit/react'

Usage ​

Basic Usage ​

tsx
import { useSubscription } from '@luno-kit/react'

interface AccountData {
  data: {
    free: bigint | string | number;
    reserved: bigint | string | number;
    frozen: bigint | string | number;
  };
}

function BalanceSubscription() {
  const { data: balance, isLoading, error } = useSubscription<[string], AccountData, string>({
    queryKey: '/balance-subscription',
    factory: (api) => api.query.system.account,
    params: ['your-address-here'],
    options: {
      enabled: true,
      transform: (result) => result.data.free.toString()
    }
  })
  
  if (isLoading) {
    return <div>Subscribing to balance...</div>
  }
  
  if (error) {
    return <div>Subscription error: {error.message}</div>
  }
  
  return (
    <div>
      <h3>Live Balance</h3>
      <p>Balance: {balance || 'Loading...'}</p>
    </div>
  )
}
ts
import { createConfig } from '@luno-kit/react'
import { polkadot, kusama } from '@luno-kit/react/chains'
import { polkadotjsConnector } from '@luno-kit/react/connectors'

const config = createConfig({
  appName: 'luno with-vite example',
  chains: [polkadot, kusama],
  connectors: [polkadotjsConnector()],
  autoConnect: true,
});

Multiple Query Subscription ​

tsx
import { useSubscription } from '@luno-kit/react'
import type { AccountBalance } from '@luno-kit/react';

interface AccountData {
  data: {
    free: bigint | string | number;
    reserved: bigint | string | number;
    frozen: bigint | string | number;
  };
}

interface BalanceLock {
  id: string | number;
  amount: bigint | string | number;
  reasons?: string | number;
}

function MultiQuerySubscription() {
  const { data: accountData, isLoading, error } = useSubscription<
    { fn: any, args: any[] }[],
    [AccountData, BalanceLock[]],
    AccountBalance
  >({
    queryKey: '/multi-query',
    factory: (api) => api.queryMulti,
    params: (api) => [
      { fn: api.query.system.account, args: ['address'] },
      { fn: api.query.balances.locks, args: ['address'] }
    ],
    options: {
      enabled: !!address,
      transform: (results) => ({
        balance: results[0].data.free.toString(),
        locks: results[1].map(lock => lock.amount.toString())
      })
    }
  })
  
  if (isLoading) return <div>Loading...</div>
  if (error) return <div>Error: {error.message}</div>
  
  return (
    <div>
      <p>Balance: {accountData?.balance}</p>
      <p>Locks: {accountData?.locks?.length || 0}</p>
    </div>
  )
}
ts
import { createConfig } from '@luno-kit/react'
import { polkadot, kusama } from '@luno-kit/react/chains'
import { polkadotjsConnector } from '@luno-kit/react/connectors'

const config = createConfig({
  appName: 'luno with-vite example',
  chains: [polkadot, kusama],
  connectors: [polkadotjsConnector()],
  autoConnect: true,
});

Parameters ​

The hook takes a configuration object with the following properties:

PropertyTypeDescription
queryKeystring | numberUnique identifier for the subscription
factory(api: LegacyClient) => SubscriptionFnFunction that creates the subscription
paramsTArgs | (api: LegacyClient) => QueryMultiItem[]Parameters for the subscription or function to generate them
optionsUseSubscriptionOptions<TData, TTransformed>Optional configuration options

UseSubscriptionOptions ​

PropertyTypeDescription
enabledbooleanWhether the subscription is enabled (default: true)
transform(data: TData) => TTransformedFunction to transform the subscription data
defaultValueTTransformedDefault value to use before subscription data arrives

QueryMultiItem ​

PropertyTypeDescription
fnGenericStorageQueryThe query function to call
argsany[]Arguments to pass to the query function

Return Value ​

The hook returns an object with the following properties:

PropertyTypeDescription
dataTTransformed | undefinedThe transformed subscription data
errorError | undefinedAny error that occurred during subscription
isLoadingbooleanWhether the subscription is currently loading

TIP

This hook internally manages subscription lifecycle, automatically subscribing when enabled and unsubscribing when the component unmounts or when the query key changes. useSubscription automatically listens for value changes, but only for query-based subscriptions. For RPC-based queries, please refer to the examples in useApi.

Released under the MIT License.