Runtime Node Configuration

Starting with v4.0.0, use-wallet provides methods to update Algod node configurations at runtime. This feature gives users the freedom to connect to their preferred nodes while maintaining your application's default configuration as a fallback option.

Common use cases include:

  • Users running their own private Algod nodes

  • Teams working with custom network configurations

  • Connecting to fallback nodes (like Nodely's backup endpoints) when the primary node is unavailable

Basic Usage

The useNetwork hook/composable provides two methods for managing node configurations:

  • updateAlgodConfig - Update a network's node configuration

  • resetNetworkConfig - Reset a network's configuration to defaults

import { useNetwork } from '@txnlab/use-wallet-react'

function NodeConfig() {
  const { updateAlgodConfig, resetNetworkConfig } = useNetwork()

  const handleNodeChange = () => {
    // Update node configuration for MainNet
    updateAlgodConfig('mainnet', {
      baseServer: 'https://secondary-node.com',
      port: '443',
      token: ''
    })
  }

  const handleReset = () => {
    // Reset MainNet back to default configuration
    resetNetworkConfig('mainnet')
  }

  return (
    <div>
      <button onClick={handleNodeChange}>
        Use Secondary Node
      </button>
      <button onClick={handleReset}>
        Reset Node
      </button>
    </div>
  )
}

Configuration Persistence

Node configurations are automatically saved to local storage. This means:

  • Custom configurations persist across page reloads

  • Each network's configuration can be customized independently

  • Resetting a network only affects that specific network's configuration

Configuration Options

When updating node configurations, you can provide any of these settings:

interface AlgodConfig {
  // API token or authentication header
  token: string | algosdk.AlgodTokenHeader | algosdk.CustomTokenHeader

  // Base URL of the node
  baseServer: string

  // Port number (optional)
  port?: string | number

  // Custom headers (optional)
  headers?: Record<string, string>
}

Automatic Updates

When updating the configuration for the active network, use-wallet automatically:

  1. Creates a new Algod client with the updated configuration

  2. Updates all components that depend on the Algod client

  3. Saves the configuration to local storage

No additional steps are needed to start using the new node.

Example Form

Here's a complete example showing how to implement a node configuration form:

import { useState } from 'react'
import { useNetwork } from '@txnlab/use-wallet-react'

function NodeConfigForm() {
  const {
    activeNetwork,
    activeNetworkConfig,
    updateAlgodConfig,
    resetNetworkConfig
  } = useNetwork()
  
  const [formData, setFormData] = useState({
    baseServer: activeNetworkConfig.algod.baseServer,
    port: activeNetworkConfig.algod.port || '',
    token: ''
  })
  const [error, setError] = useState('')

  const handleSubmit = async ((e): React.FormEvent) => {
    e.preventDefault()
    setError('')

    try {
      await updateAlgodConfig(activeNetwork, {
        baseServer: formData.baseServer,
        port: formData.port || undefined,
        token: formData.token || ''
      })
    } catch (error: any) {
      setError(error.message)
    }
  }

  return (
    <form onSubmit={handleSubmit}>
      <h3>Configure {activeNetwork} Node</h3>
      
      <div>
        <label>Server URL:</label>
        <input
          type="url"
          value={formData.baseServer}
          onChange={(e) => setFormData((d) => ({ ...d, baseServer: e.target.value }))}
          required
        />
      </div>

      <div>
        <label>Port:</label>
        <input
          type="text"
          value={formData.port}
          onChange={(e) => setFormData((d) => ({ ...d, port: e.target.value }))}
          placeholder="Optional"
        />
      </div>

      <div>
        <label>Token:</label>
        <input
          type="password"
          value={formData.token}
          onChange={(e) => setFormData((d) => ({ ...d, token: e.target.value }))}
          placeholder="Optional"
        />
      </div>

      {error && (
        <div className="error">
          {error}
        </div>
      )}

      <div>
        <button type="submit">
          Update Node
        </button>
        <button type="button" onClick={() => resetNetworkConfig(activeNetwork)}>
          Reset to Default
        </button>
      </div>
    </form>
  )
}

Last updated