viem-goviem-go

Wallet Client

Write access to the Ethereum blockchain for signing and sending transactions

A Wallet Client is an interface to interact with Ethereum accounts and provides the ability to sign messages, send transactions, deploy contracts, and manage permissions through JSON-RPC wallet methods.

The CreateWalletClient function sets up a Wallet Client with a given Transport and optional Chain.

Import

import (
"github.com/ChefBingbong/viem-go/client"
"github.com/ChefBingbong/viem-go/client/transport"
"github.com/ChefBingbong/viem-go/chain/definitions"
)

These are the most common imports for setting up a Wallet Client:

  • client: Client constructors and types (e.g. CreateWalletClient, WalletClientConfig, NewAddressAccount).
  • transport: Transport factories for JSON-RPC (e.g. transport.HTTP(...), transport.WebSocket(...)).
  • definitions: Prebuilt chain definitions (e.g. definitions.Mainnet). Optional, but recommended.

Import additional packages only when you need them:

  • accounts: Local account signing helpers (e.g. accounts.PrivateKeyToAccount("0x...")).
  • common: Address helpers from go-ethereum (e.g. common.HexToAddress("0x...")), useful for address-only JSON-RPC accounts.

Go notes

Closing the client

In viem-go, walletClient.Close() closes the underlying transport connection (especially important for WebSocket transports). It’s idiomatic to call it with defer right after successful construction.

Passing a context

Wallet Client actions accept a context.Context as the first argument (e.g. walletClient.SendTransaction(ctx, ...)). Use it to cancel requests or to set timeouts with context.WithTimeout.

JSON-RPC Accounts

A JSON-RPC account defers signing of transactions & messages to the target node/wallet over JSON-RPC.

In viem-go, you can represent a JSON-RPC account by hoisting an address-only account with client.NewAddressAccount(...).

1: Initialize a Wallet Client

Initialize a Wallet Client with your desired Chain (e.g. definitions.Mainnet) and Transport (e.g. transport.HTTP).

walletClient, err := client.CreateWalletClient(client.WalletClientConfig{
Chain: definitions.Mainnet,
Transport: transport.HTTP("https://eth.llamarpc.com"),
})
if err != nil {
log.Fatal(err)
}
defer walletClient.Close()

2: Optional: Hoist an address-only account

If your target node/wallet supports account-based JSON-RPC signing (e.g. eth_sendTransaction), you can hoist an address-only account into the client:

account := client.NewAddressAccount(common.HexToAddress("0x..."))
walletClient, err := client.CreateWalletClient(client.WalletClientConfig{
Account: account,
Chain: definitions.Mainnet,
Transport: transport.HTTP("https://eth.llamarpc.com"),
})
JSON-RPC accounts send signing requests to the connected node. Never use this approach with untrusted or public RPC endpoints -- the node has full control over signing. For production use, prefer local accounts instead.

Local Accounts (Private Key, Mnemonic, etc)

A Local Account performs signing of transactions & messages with a private key before executing a method over JSON-RPC.

1: Initialize a Wallet Client

walletClient, err := client.CreateWalletClient(client.WalletClientConfig{
Chain: definitions.Mainnet,
Transport: transport.HTTP("https://eth.llamarpc.com"),
})
if err != nil {
log.Fatal(err)
}
defer walletClient.Close()

2: Set up your Local Account

import "github.com/ChefBingbong/viem-go/accounts"
account, err := accounts.PrivateKeyToAccount("0x...")
if err != nil {
log.Fatal(err)
}
walletClient, err := client.CreateWalletClient(client.WalletClientConfig{
Account: account,
Chain: definitions.Mainnet,
Transport: transport.HTTP("https://eth.llamarpc.com"),
})
if err != nil {
log.Fatal(err)
}
defer walletClient.Close()
By providing a local Account (private key, mnemonic, or HD wallet), the client will sign transactions locally and send them via eth_sendRawTransaction — no private keys are ever sent to the RPC node.
Local accounts are the safest option for production use. Private keys never leave your application -- all signing happens in-process before the transaction is sent over the network.

2: Consume Wallet Actions

Now you can use that address within Wallet Actions that require a signature from the user:

import (
"github.com/ChefBingbong/viem-go/chain/definitions"
"github.com/ChefBingbong/viem-go/client"
"github.com/ChefBingbong/viem-go/client/transport"
)
WalletCl, err = client.CreateWalletClient(client.WalletClientConfig{
Account: LocalAccount,
Chain: &definitions.Mainnet,
Transport: transport.HTTP(),
})
if err != nil {
log.Fatal(err)
}
hash, err := WalletCl.SendTransaction(ctx, wallet.SendTransactionParameters{
Account: WalletCl.Account(),
Chain: &definitions.Mainnet,
To: to.Hex(),
Value: value,
})
if err != nil {
log.Fatal(err)
}

Error handling

Most viem-go APIs return (value, error). Always handle errors from CreateWalletClient and from each action call.

import (
"context"
"log"
"time"
"github.com/ChefBingbong/viem-go/client"
"github.com/ChefBingbong/viem-go/client/transport"
"github.com/ChefBingbong/viem-go/chain/definitions"
)
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
walletClient, err := client.CreateWalletClient(client.WalletClientConfig{
Chain: definitions.Mainnet,
Transport: transport.HTTP("https://eth.llamarpc.com"),
})
if err != nil {
log.Fatal(err)
}
defer func() { _ = walletClient.Close() }()
// Example action (all actions take a context.Context)
addresses, err := walletClient.GetAddresses(ctx)
if err != nil {
log.Fatal(err)
}
_ = addresses

Parameters

Account (optional)

  • Type: client.Account

The Account to use for the Wallet Client. When provided, wallet actions can fall back to this account by default.

You can provide either:

  • JSON-RPC (address-only): Use client.NewAddressAccount(...) to defer signing to the node/wallet over JSON-RPC.
  • Local account: Use accounts.PrivateKeyToAccount(...) (or similar) to sign locally before sending via JSON-RPC.
account := client.NewAddressAccount(common.HexToAddress("0x..."))
walletClient, err := client.CreateWalletClient(client.WalletClientConfig{
Account: account,
Chain: definitions.Mainnet,
Transport: transport.HTTP("https://eth.llamarpc.com"),
})

Chain (optional)

  • Type: *chain.Chain

The Chain configuration (e.g. definitions.Mainnet) for the Wallet Client.

This is used for chain-aware behavior (like validating chain ID where applicable) and it also influences defaults like PollingInterval (based on the chain's block time). See Clients & Transports.

walletClient, err := client.CreateWalletClient(client.WalletClientConfig{
Chain: definitions.Mainnet,
Transport: transport.HTTP("https://eth.llamarpc.com"),
})

Transport (required)

  • Type: transport.TransportFactory

Transport factory for JSON-RPC calls. This parameter is required.

If your transport needs its own configuration, keep it in the transport constructor and refer to the transport docs (e.g. HTTP Transport or WebSocket Transport).

walletClient, err := client.CreateWalletClient(client.WalletClientConfig{
Chain: definitions.Mainnet,
Transport: transport.HTTP("https://eth.llamarpc.com"),
})

CacheTime (optional)

  • Type: time.Duration
  • Default: PollingInterval

Time that cached data will remain in memory.

In viem-go, if CacheTime is not set, it defaults to the client PollingInterval. You typically only need to tune this when you’re making repeated reads/writes and want to control how long computed/derived values stay warm.

walletClient, err := client.CreateWalletClient(client.WalletClientConfig{
CacheTime: 10 * time.Second,
Chain: definitions.Mainnet,
Transport: transport.HTTP("https://eth.llamarpc.com"),
})

Key (optional)

  • Type: string
  • Default: "wallet"

A key for the Client.

This is primarily useful when you have multiple clients in the same process and want a stable identifier for debugging, logging, or internal bookkeeping. If not set, it defaults to "wallet".

walletClient, err := client.CreateWalletClient(client.WalletClientConfig{
Key: "foo",
Chain: definitions.Mainnet,
Transport: transport.HTTP("https://eth.llamarpc.com"),
})

Name (optional)

  • Type: string
  • Default: "Wallet Client"

A human-readable name for the Client.

This is useful for debugging (e.g. printing which client instance is in use) and for distinguishing multiple wallet client instances in your application. If not set, it defaults to "Wallet Client".

walletClient, err := client.CreateWalletClient(client.WalletClientConfig{
Name: "Foo Wallet Client",
Chain: definitions.Mainnet,
Transport: transport.HTTP("https://eth.llamarpc.com"),
})

PollingInterval (optional)

  • Type: time.Duration
  • Default: min(max(chain.BlockTime/2, 500ms), 4s) (defaults to 4s when Chain is not provided)

Frequency for polling-enabled behavior.

This value is used by polling-based logic (and it also becomes the default CacheTime when CacheTime is not explicitly set). By default, viem-go derives a sensible interval from the chain’s block time: min(max(chain.BlockTime/2, 500ms), 4s).

walletClient, err := client.CreateWalletClient(client.WalletClientConfig{
PollingInterval: 10 * time.Second,
Chain: definitions.Mainnet,
Transport: transport.HTTP("https://eth.llamarpc.com"),
})

Return Type

CreateWalletClient returns (*WalletClient, error).