Wallet Client
Write access to the Ethereum blockchain for signing and sending transactions
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 ( "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:
CreateWalletClient, WalletClientConfig, NewAddressAccount).transport.HTTP(...), transport.WebSocket(...)).definitions.Mainnet). Optional, but recommended.Import additional packages only when you need them:
accounts.PrivateKeyToAccount("0x...")).common.HexToAddress("0x...")), useful for address-only JSON-RPC accounts.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.
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.
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(...).
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()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"),})A Local Account performs signing of transactions & messages with a private key before executing a method over JSON-RPC.
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()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()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)}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)}_ = addressesclient.AccountThe Account to use for the Wallet Client. When provided, wallet actions can fall back to this account by default.
You can provide either:
client.NewAddressAccount(...) to defer signing to the node/wallet over JSON-RPC.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.ChainThe 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.TransportFactoryTransport 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"),})time.DurationPollingIntervalTime 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"),})string"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"),})string"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"),})time.Durationmin(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"),})CreateWalletClient returns (*WalletClient, error).