Skip to main content
The @txnlab/use-wallet-solid package provides SolidJS-specific bindings for use-wallet, including a context provider and reactive primitives that enable fine-grained reactivity in Solid applications.

Installation

npm install @txnlab/use-wallet-solid

Setup

Configure wallet provider

Create a WalletManager instance with your desired wallet providers and network configuration, then wrap your app with the WalletProvider component.
import {
  NetworkId,
  WalletId,
  WalletManager,
  WalletProvider
} from '@txnlab/use-wallet-solid'

const walletManager = new WalletManager({
  wallets: [
    WalletId.DEFLY,
    WalletId.PERA,
    WalletId.EXODUS,
    {
      id: WalletId.WALLETCONNECT,
      options: { projectId: 'YOUR_PROJECT_ID' }
    },
    WalletId.KMD
  ],
  defaultNetwork: NetworkId.TESTNET
})

function App() {
  return (
    <WalletProvider manager={walletManager}>
      {/* Your app components */}
    </WalletProvider>
  )
}

Using the wallet hook

The useWallet hook provides reactive access to wallet state and signing methods. All returned values are reactive signals or accessors.

Basic usage

import { useWallet } from '@txnlab/use-wallet-solid'
import { For, Show } from 'solid-js'

function ConnectButton() {
  const { wallets, activeAddress } = useWallet()

  return (
    <div>
      <Show
        when={activeAddress()}
        fallback={
          <For each={wallets}>
            {(wallet) => (
              <button
                onClick={() => wallet.connect()}
                disabled={wallet.isConnected()}
              >
                Connect {wallet.metadata.name}
              </button>
            )}
          </For>
        }
      >
        <p>Connected: {activeAddress()}</p>
      </Show>
    </div>
  )
}

Return values

The useWallet hook returns reactive signals and methods:
interface UseWalletReturn {
  // Wallet state (reactive signals)
  wallets: BaseWallet[]
  isReady: Accessor<boolean>
  activeWallet: Accessor<BaseWallet | null>
  activeWalletAccounts: Accessor<WalletAccount[] | null>
  activeWalletAddresses: Accessor<string[] | null>
  activeAccount: Accessor<WalletAccount | null>
  activeAddress: Accessor<string | null>
  activeWalletId: Accessor<WalletKey | null>
  algodClient: Accessor<algosdk.Algodv2>

  // Helper functions
  isWalletActive: (walletKey: WalletKey) => boolean
  isWalletConnected: (walletKey: WalletKey) => boolean

  // Signing methods
  signTransactions: (txnGroup: Transaction[] | Uint8Array[], indexesToSign?: number[]) => Promise<(Uint8Array | null)[]>
  transactionSigner: (txnGroup: Transaction[], indexesToSign: number[]) => Promise<Uint8Array[]>
  signData: (data: string, metadata: SignMetadata) => Promise<SignDataResponse>
  withPrivateKey: <T>(callback: (secretKey: Uint8Array) => Promise<T>) => Promise<T>
  walletStore: Accessor<Record<WalletKey, WalletState>>
}

Signing transactions

The transactionSigner method is compatible with the Algorand SDK’s AtomicTransactionComposer.
import { useWallet } from '@txnlab/use-wallet-solid'
import algosdk from 'algosdk'
import { createSignal } from 'solid-js'

function SendTransaction() {
  const { activeAddress, algodClient, transactionSigner } = useWallet()
  const [isSending, setIsSending] = createSignal(false)

  const sendTransaction = async () => {
    const sender = activeAddress()
    if (!sender) {
      throw new Error('No active account')
    }

    setIsSending(true)

    try {
      const atc = new algosdk.AtomicTransactionComposer()
      const suggestedParams = await algodClient().getTransactionParams().do()

      const transaction = algosdk.makePaymentTxnWithSuggestedParamsFromObject({
        sender,
        receiver: sender,
        amount: 0,
        suggestedParams
      })

      atc.addTransaction({ txn: transaction, signer: transactionSigner })

      const result = await atc.execute(algodClient(), 4)
      console.log('Transaction sent:', result.txIDs)
    } finally {
      setIsSending(false)
    }
  }

  return (
    <button onClick={sendTransaction} disabled={!activeAddress() || isSending()}>
      {isSending() ? 'Sending...' : 'Send Transaction'}
    </button>
  )
}

Network management

The useNetwork hook provides methods for managing network configuration.
import { useNetwork } from '@txnlab/use-wallet-solid'

function NetworkSelector() {
  const { activeNetwork, setActiveNetwork } = useNetwork()

  return (
    <div>
      <p>Current network: {activeNetwork()}</p>
      <button onClick={() => setActiveNetwork('mainnet')}>
        Switch to MainNet
      </button>
      <button onClick={() => setActiveNetwork('testnet')}>
        Switch to TestNet
      </button>
    </div>
  )
}

Return values

interface UseNetworkReturn {
  activeNetwork: Accessor<string>
  networkConfig: Accessor<Record<string, NetworkConfig>>
  activeNetworkConfig: Accessor<NetworkConfig>
  setActiveNetwork: (networkId: NetworkId | string) => Promise<void>
  updateAlgodConfig: (networkId: string, config: Partial<AlgodConfig>) => void
  resetNetworkConfig: (networkId: string) => void
}

Managing accounts

Switch between accounts for a connected wallet:
import { useWallet } from '@txnlab/use-wallet-solid'
import { Show, For } from 'solid-js'

function AccountSelector() {
  const { activeWallet, isWalletConnected } = useWallet()

  return (
    <Show when={activeWallet() && isWalletConnected(activeWallet()!.id)}>
      <select
        value={activeWallet()!.activeAccount?.address}
        onChange={(e) => activeWallet()!.setActiveAccount(e.target.value)}
      >
        <For each={activeWallet()!.accounts}>
          {(account) => (
            <option value={account.address}>
              {account.address}
            </option>
          )}
        </For>
      </select>
    </Show>
  )
}

Working with multiple wallets

Iterate through wallets and check their connection status:
import { useWallet } from '@txnlab/use-wallet-solid'
import { For, Show } from 'solid-js'

function WalletList() {
  const { wallets, isWalletActive, isWalletConnected } = useWallet()

  return (
    <For each={wallets}>
      {(wallet) => (
        <div class="wallet-group">
          <h4>
            {wallet.metadata.name}
            <Show when={isWalletActive(wallet.id)}>
              <span> [active]</span>
            </Show>
          </h4>
          <button
            onClick={() => wallet.connect()}
            disabled={isWalletConnected(wallet.id)}
          >
            Connect
          </button>
          <button
            onClick={() => wallet.disconnect()}
            disabled={!isWalletConnected(wallet.id)}
          >
            Disconnect
          </button>
          <Show when={!isWalletActive(wallet.id)}>
            <button
              onClick={() => wallet.setActive()}
              disabled={!isWalletConnected(wallet.id)}
            >
              Set Active
            </button>
          </Show>
        </div>
      )}
    </For>
  )
}

Signing arbitrary data

For wallets that support it, you can sign arbitrary data for authentication:
import { useWallet, ScopeType } from '@txnlab/use-wallet-solid'

function AuthButton() {
  const { activeAddress, signData, activeWallet } = useWallet()

  const authenticate = async () => {
    const address = activeAddress()
    const wallet = activeWallet()

    if (!address || !wallet?.canSignData) {
      throw new Error('Wallet does not support data signing')
    }

    const message = { domain: window.location.host, timestamp: Date.now() }
    const data = btoa(JSON.stringify(message))
    const metadata = { scope: ScopeType.AUTH, encoding: 'base64' }

    const response = await signData(data, metadata)
    console.log('Signature:', response)
  }

  return (
    <button
      onClick={authenticate}
      disabled={!activeWallet()?.canSignData}
    >
      Authenticate
    </button>
  )
}

Accessing the wallet manager

For advanced use cases, access the wallet manager directly:
import { useWalletManager } from '@txnlab/use-wallet-solid'

function AdvancedComponent() {
  const manager = useWalletManager()

  // Access manager methods and properties
  console.log('Network config:', manager.networkConfig)
  console.log('All wallets:', manager.wallets)

  return <div>Advanced wallet operations</div>
}

TypeScript support

The package includes full TypeScript definitions. All hooks and components are fully typed:
import type {
  BaseWallet,
  WalletAccount,
  WalletMetadata,
  WalletState,
  SignMetadata,
  SignDataResponse
} from '@txnlab/use-wallet-solid'

Next steps

Configuration

Learn about wallet and network configuration options

Wallets

Explore supported wallet providers and their options

Build docs developers (and LLMs) love