React
iso-filecoin-react
provides React hooks and context to easily integrate Filecoin wallet interactions into your React applications. It works seamlessly with the wallet adapters from iso-filecoin-wallets
.
Installation
Section titled “Installation”First, you need to install the necessary packages. You’ll typically need iso-filecoin-react
, iso-filecoin
(as a peer dependency), and at least one wallet adapter from iso-filecoin-wallets
. You might also need @tanstack/react-query
if you haven’t installed it already, as it’s a peer dependency for hooks.
# Using pnpm (recommended for this monorepo)pnpm add iso-filecoin-react iso-filecoin iso-filecoin-wallets @tanstack/react-query
Setup: The FilecoinProvider
Section titled “Setup: The FilecoinProvider”Wrap your application (or the relevant part of it) with the FilecoinProvider
. This component initializes the context and makes the wallet state and hooks available throughout your app.
You need to pass an array of instantiated wallet adapters to the adapters
prop.
// Import the actual provider nameimport { FilecoinProvider } from 'iso-filecoin-react';import { WalletAdapterHd, WalletAdapterLedger,} from 'iso-filecoin-wallets'import TransportWebUSB from '@ledgerhq/hw-transport-webusb'// Need QueryClientProvider for TanStack Query hooksimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';import { StrictMode } from 'react'import { createRoot } from 'react-dom/client'import App from './App';
// Instantiate the wallet adapters you want to supportconst adapters = [ new WalletAdapterLedger({ transport: TransportWebUSB, }), new WalletAdapterHd(),]
const queryClient = new QueryClient();
createRoot(document.getElementById('root')!).render( <StrictMode> {/* Wrap with QueryClientProvider */} <QueryClientProvider client={queryClient}> {/* Use FilecoinProvider and the correct prop names */} <FilecoinProvider adapters={adapters} reconnectOnMount={true}> <App /> </FilecoinProvider> </QueryClientProvider> </StrictMode>,);
// @filename: App.tsxexport default function App() { return <div>My Filecoin App</div>;}
Props for FilecoinProvider
:
adapters
: (WalletAdapter[]
, Required) An array of initialized wallet adapter instances (e.g.,new WalletAdapterHD()
).network
: (Network
, Optional) The initial network to use (‘mainnet’ or ‘testnet’). Defaults to'mainnet'
.rpcs
: (Record<Network, RPC>
, Optional) An object mapping network names to initializedRPC
client instances fromiso-filecoin/rpc
. If not provided, defaults are used for mainnet and testnet.reconnectOnMount
: (boolean
, Optional) Iftrue
, tries to automatically connect to the last used wallet adapter stored in local storage upon mounting. Defaults totrue
.children
: (React.ReactNode
, Required) Your application components.
Basic Usage: Accessing Wallet State
Section titled “Basic Usage: Accessing Wallet State”Once the provider is set up, you can use the hooks provided by iso-filecoin-react
within any child component.
useAdapter
Section titled “useAdapter”Provides access to the currently selected adapter instance, loading/reconnecting states, errors, and the current network.
import { function useAdapter(): Pick<FilecoinContextType, "adapter" | "error" | "loading" | "network" | "reconnecting">
Hook to access the current wallet adapter and its state
useAdapter } from 'iso-filecoin-react';
export function function WalletInfo(): React.JSX.Element
WalletInfo() { const { const adapter: WalletAdapter | undefined
Currently selected wallet adapter
adapter, const loading: boolean
Provider is checking adapters support
loading, const error: Error | undefined
Last error that occurred on the selected adapter
error, const network: Network
Current network (mainnet or testnet)
network, const reconnecting: boolean
Provider is reconnecting to the last selected adapter
reconnecting } = function useAdapter(): Pick<FilecoinContextType, "adapter" | "error" | "loading" | "network" | "reconnecting">
Hook to access the current wallet adapter and its state
useAdapter();
// loading is true only during initial provider setup/adapter check if (const loading: boolean
Provider is checking adapters support
loading) return <React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>Checking adapter support...</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>; // reconnecting is true if reconnectOnMount is true and it's trying to connect if (const reconnecting: boolean
Provider is reconnecting to the last selected adapter
reconnecting) return <React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>Reconnecting wallet...</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>; if (const error: Error | undefined
Last error that occurred on the selected adapter
error) return <React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>Error: {const error: Error
Last error that occurred on the selected adapter
error.Error.message: string
message}</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>; // adapter can be undefined if no wallet is selected/connected yet if (!const adapter: WalletAdapter | undefined
Currently selected wallet adapter
adapter) return <React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>No wallet adapter selected.</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>;
return ( <React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div> <React.JSX.IntrinsicElements.p: React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p>Selected Adapter: {const adapter: WalletAdapter
Currently selected wallet adapter
adapter.WalletAdapter.name: string
Human readable wallet name
name}</React.JSX.IntrinsicElements.p: React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p> {/* adapter.connected and adapter.connecting reflect the *adapter's* state */} <React.JSX.IntrinsicElements.p: React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p>Is Connected: {const adapter: WalletAdapter
Currently selected wallet adapter
adapter.WalletAdapter.connected: boolean
Whether the wallet is currently connected
connected ? 'Yes' : 'No'}</React.JSX.IntrinsicElements.p: React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p> <React.JSX.IntrinsicElements.p: React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p>Is Connecting: {const adapter: WalletAdapter
Currently selected wallet adapter
adapter.WalletAdapter.connecting: boolean
Whether the wallet is in the process of connecting
connecting ? 'Yes' : 'No'}</React.JSX.IntrinsicElements.p: React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p> <React.JSX.IntrinsicElements.p: React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p>Network: {const network: Network
Current network (mainnet or testnet)
network}</React.JSX.IntrinsicElements.p: React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p> {/* 'mainnet' or 'testnet' - reflects provider state */} </React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div> );}
Return value of useAdapter
:
adapter
: (WalletAdapter | undefined
) The currently selected wallet adapter instance, orundefined
if none is selected/connected.loading
: (boolean
)true
while the provider checks adapter support on initial mount.error
: (Error | undefined
) The last error encountered related to the adapter or provider state.network
: (Network
) The current network (‘mainnet’ or ‘testnet’) set in the provider state.reconnecting
: (boolean
)true
if the provider is attempting to auto-connect viareconnectOnMount
.
useAccount
Section titled “useAccount”Provides access to the connected account details (IAccount
), the active adapter instance, network/chain information, the derived connection state, and the address string.
import { function useAccount(): UseAccountReturnType
Hook to access the current account and its state
useAccount } from 'iso-filecoin-react';import type { type ConnectionState = "connected" | "disconnected" | "connecting" | "reconnecting"
ConnectionState } from 'iso-filecoin-react'; // Import type if needed
export function function AccountDisplay(): React.JSX.Element
AccountDisplay() { // address is returned directly for convenience const { const account: IAccount | undefined
Currently connected account
account, const address: string
Current address
address, const adapter: WalletAdapter | undefined
Currently selected wallet adapter
adapter, const network: Network
Current network (mainnet or testnet)
network, const chain: Chain
Current chain
chain, const state: ConnectionState
Current connection state
state } = function useAccount(): UseAccountReturnType
Hook to access the current account and its state
useAccount();
// State provides a string representation: 'disconnected', 'connecting', 'connected', 'reconnecting' const const displayState: ConnectionState
displayState: type ConnectionState = "connected" | "disconnected" | "connecting" | "reconnecting"
ConnectionState = const state: ConnectionState
Current connection state
state;
if (const displayState: ConnectionState
displayState === 'connecting' || const displayState: "connected" | "disconnected" | "reconnecting"
displayState === 'reconnecting') { return <React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>Status: {const displayState: "connecting" | "reconnecting"
displayState}...</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>; }
if (const displayState: "connected" | "disconnected"
displayState === 'disconnected' || !const account: IAccount | undefined
Currently connected account
account) { return <React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>Status: Disconnected. Please connect a wallet.</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>; }
// State is 'connected' here return ( <React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div> <React.JSX.IntrinsicElements.h2: React.DetailedHTMLProps<React.HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>
h2>Connected Account</React.JSX.IntrinsicElements.h2: React.DetailedHTMLProps<React.HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>
h2> {/* Use the direct address string */} <React.JSX.IntrinsicElements.p: React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p>Address: {const address: string
Current address
address}</React.JSX.IntrinsicElements.p: React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p> <React.JSX.IntrinsicElements.p: React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p>Type: {const account: IAccount
Currently connected account
account.IAccount.type: "SECP256K1" | "BLS"
type}</React.JSX.IntrinsicElements.p: React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p> {/* 'SECP256K1' or 'BLS' */} <React.JSX.IntrinsicElements.p: React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p>Network: {const network: Network
Current network (mainnet or testnet)
network}</React.JSX.IntrinsicElements.p: React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p> {/* 'mainnet' or 'testnet' */} <React.JSX.IntrinsicElements.p: React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p>Chain ID: {const chain: Chain
Current chain
chain.Chain.id: string | number
id}</React.JSX.IntrinsicElements.p: React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p> {/* e.g., 314 for mainnet */} <React.JSX.IntrinsicElements.p: React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p>Adapter: {const adapter: WalletAdapter | undefined
Currently selected wallet adapter
adapter?.WalletAdapter.name: string | undefined
Human readable wallet name
name}</React.JSX.IntrinsicElements.p: React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p> <React.JSX.IntrinsicElements.p: React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p>State: {const displayState: "connected"
displayState}</React.JSX.IntrinsicElements.p: React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p> </React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div> );}
Return value of useAccount
:
account
: (IAccount | undefined
) The currently connected account object, orundefined
if not connected. Containsaddress
(asIAddress
object) andtype
.address
: (string | undefined
) The string representation of the connected account’s address, orundefined
.adapter
: (WalletAdapter | undefined
) The currently selected and connected wallet adapter instance.chain
: (Chain
) An object representing the current Filecoin chain based on the provider’snetwork
state (e.g.,{ id: 314, name: 'Filecoin Mainnet' }
).network
: (Network
) The current network (‘mainnet’ or ‘testnet’) from the provider state.state
: (ConnectionState
) The derived connection status string:'disconnected'
,'connecting'
,'connected'
, or'reconnecting'
.
Other Core Hooks
Section titled “Other Core Hooks”These hooks provide mutation functions (leveraging @tanstack/react-query
), query results, or access context state for performing common wallet actions:
useConnect
: Returns theconnect
mutation function to initiate connection to a selected wallet adapter. Also provides the list of availableadapters
, the currently selectedadapter
(if any), and the provider’s initialloading
state.useDisconnect
: Returns thedisconnect
mutation function to disconnect the currently connected wallet adapter.useChangeNetwork
: Returns thechangeNetwork
mutation function to switch the provider’s and potentially the adapter’s active network (between ‘mainnet’ and ‘testnet’).useDeriveAccount
: Returns thederiveAccount
mutation function to derive a new account from the current adapter at a specific index (if supported by the adapter).useBalance
: Returns a TanStack Query query result object ({ data, isLoading, error, ... }
) for fetching the FIL balance ({ value: Token, symbol: string }
|undefined
) of the connected account. Requires RPC client configuration.useAddresses
: Takes an optional address string and returns TanStack Query query result objects for resolving its corresponding ID address (addressId: { data, ... }
) and f4/0x address (address0x: { data, ... }
) using the configured RPC client.useEstimateGas
: Takes message parameters (to
,value
,maxFee
) and returns a TanStack Query query result object ({ data, ... }
) containing the estimated gas cost ({ gas: bigint, total: bigint, symbol: string }
|undefined
) for sending the message from the currently connected account. Requires RPC client configuration.useSendMessage
: Returns thesendMessage
mutation function. Takes a partial message object, prepares it using the RPC client (getting nonce, gas estimation), signs it using the adapter, and pushes it to the network via the RPC client. Returns the message CID ({ '/': string }
).useSign
: Returns thesign
mutation function. Takes a rawUint8Array
message and requests a signature from the connected adapter using the adapter’s genericsign
method. (Note: This is different fromuseSignMessage
which prepares and signs a specific Filecoin message structure).
Playground
Section titled “Playground”Play with all the hooks in this StackBlitz example:
Check the source code here.
Next Steps
Section titled “Next Steps”- Explore the API Reference for detailed information on all hooks and types.
- See the guide on Using Wallet Adapters for more on specific adapters.
- Check out the examples folder in the repository for practical examples.