A hardware wallet is a physical signing device that keeps private keys isolated from a general-purpose computer; a cold wallet is a custody posture in which keys are never exposed to an internet-connected environment. The two overlap heavily, but they are not synonyms: a hardware wallet can be used in a hot workflow, and a cold wallet can be built without dedicated hardware. This article gives you a mental model for key custody, a runnable procedure for verifying signing boundaries, and a troubleshooting path for common failures. It separates documented wallet behavior from recommendations and from measurements you must run yourself.
Direct answer and scope
A hardware wallet is a dedicated physical device that stores private keys and signs transactions internally, so the key material is designed never to leave the device. A cold wallet is a wallet whose private keys are kept offline and are not reachable from an internet-connected machine during normal operation. The practical difference is that hardware wallet describes a class of device, while cold wallet describes a security posture and key-location model.
This article covers the custody model, signing boundary, verification procedure, and operational tradeoffs. It does not recommend a specific vendor or model. For endpoint and network choices that connect your signing workflow to a chain, use the RPC Assistant resources linked below rather than treating this page as a provider list.
- Hardware wallet: physical device, internal key storage, on-device signing.
- Cold wallet: offline key custody, whether on hardware, paper, or an air-gapped machine.
- Hot wallet: keys present in an internet-connected environment, usually software.
- The overlap: most consumer cold wallets are hardware wallets, but not every hardware wallet is operated cold.
Assumptions and prerequisites
The procedures below assume you have a hardware signing device, a host computer, a test network or small-value account, and a way to broadcast signed transactions. You should be comfortable with seed phrase handling, address derivation, and reading a transaction before signing.
Use a testnet or a throwaway account for every step until you have verified the full flow. Never paste a production seed phrase into a shell, a browser console, or an environment variable that is visible to other processes. The code examples use placeholders such as RPC_URL and PRIVATE_KEY; replace them only in a controlled environment.
- A hardware wallet with a display and confirmation button.
- A host machine with a wallet companion app or CLI.
- An RPC endpoint for the target network, supplied by your infrastructure or provider.
- A small test balance on a testnet or a dedicated low-value account.
Mental model: key location, signing boundary, and exposure
Think of a wallet as three layers: key generation and storage, transaction construction, and signing. In a hot wallet, all three layers can run on the same internet-connected machine. In a hardware wallet, construction happens on the host but signing happens inside the device. In a cold wallet, the signing layer is isolated from the network entirely, and transactions move between the online and offline environments through a file, QR code, or manual transfer.
The security property that matters is not the label on the box but where the private key exists and what can reach it. A hardware wallet that is permanently connected to a browser extension and approves arbitrary contract calls is still a hardware wallet, but its operational exposure is closer to a hot wallet. A cold wallet that signs on an air-gapped machine and broadcasts from a separate online host has a narrower attack surface, at the cost of convenience.
- Key location: device secure element, offline machine, paper, or software keystore.
- Signing boundary: what code path can produce a signature without human confirmation.
- Exposure: which network-connected processes can request signatures or read addresses.
- Recovery: whether the seed or backup can restore the same addresses on another device.
Runnable check: verify the signing boundary with an RPC call
Before trusting any wallet setup, verify that your host can read chain state and prepare a transaction without ever seeing the private key. The following curl command queries an account balance through an RPC endpoint. It is a read-only check and does not require a key.
Run it against a testnet first. A successful response confirms that your endpoint is reachable and that your host can construct requests. It does not confirm that signing is isolated; that requires the device confirmation step described next.
- Expected result: a JSON object with a
resultfield containing a hexadecimal balance. - If the result is
0x0, the address may be valid but unfunded on that network. - If you receive an error, check the endpoint URL, network, and address checksum before changing anything else.
curl -s -X POST "$RPC_URL" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "eth_getBalance",
"params": ["0xYourAddressHere", "latest"]
}'Runnable check: prepare a transaction and confirm on-device signing
The next step is to prepare an unsigned transaction on the host and confirm that the signature is produced only after physical approval on the device. The JavaScript example below uses a placeholder provider and a placeholder private key to illustrate the shape of the flow. In a real hardware wallet flow, the signing call is delegated to the device bridge or companion app, and the private key never appears in the script.
Use this pattern to test the boundary: construct the transaction, request a signature, and observe whether the device displays the destination and amount before approval. If the host can sign without device interaction, the key is not isolated.
- Expected result: an unsigned transaction object printed to the console.
- In a hardware wallet flow, the next step is to pass this object to the device bridge, not to sign it locally.
- If the script signs locally, you are testing a hot wallet, not an isolated signing boundary.
const { ethers } = require("ethers");
async function prepareTransaction() {
const provider = new ethers.JsonRpcProvider(process.env.RPC_URL);
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
const tx = {
to: "0xRecipientAddressHere",
value: ethers.parseEther("0.001"),
gasLimit: 21000n,
chainId: Number(process.env.CHAIN_ID)
};
const populated = await wallet.populateTransaction(tx);
console.log("Unsigned transaction:", populated);
return populated;
}
prepareTransaction().catch(console.error);Results table: what to record during verification
Do not rely on memory or vendor claims. Record the following observations for each wallet configuration you test. The table below is a template; fill it with your own measurements rather than copying numbers from any article.
| Check | Hardware wallet (hot workflow) | Cold wallet (air-gapped) | Your result |
|---|---|---|---|
| Private key leaves device | No | No | |
| Host can sign without approval | No | No | |
| Device displays destination | Yes | Yes | |
| Network reachable during signing | Yes | No | |
| Recovery tested on second device | Required | Required | |
| Time to sign one transaction | Measure | Measure | |
| Failure mode when device disconnects | Measure | Measure |
The last two rows are intentionally blank. Measure them yourself with a stopwatch and a controlled test transaction. Report the network, device model, firmware version, and host OS alongside your numbers so the result is reproducible.
Troubleshooting common failures
Most wallet failures fall into a small number of categories: connectivity, derivation mismatch, firmware or app mismatch, and user error at the confirmation step. Work through them in that order before assuming the device is faulty.
If the device is not detected, check the cable, the companion app version, and whether another application has claimed the device. If addresses do not match after recovery, verify the derivation path and passphrase settings; a different passphrase produces a different wallet. If a transaction is rejected on-device, compare the displayed destination and amount with the unsigned transaction on the host.
- Device not detected: try a different cable and port, restart the companion app, and close competing wallet software.
- Address mismatch: confirm the derivation path and any passphrase before restoring funds.
- Transaction rejected: check the destination, amount, gas limit, and chain ID on the device display.
- Broadcast failure: verify the RPC endpoint and network; a signed transaction can be broadcast later from a different host.
- Unexpected contract interaction: stop and decode the calldata before approving.
Limitations and tradeoffs
Cold custody reduces online attack surface but increases operational friction. Every transaction requires a transfer between online and offline environments, and that transfer is itself a place where mistakes happen. Hardware wallets reduce key exposure but do not eliminate phishing, malicious contract approvals, or supply-chain risk.
Neither model protects against a compromised seed backup, a lost device without a recovery plan, or a user who approves a transaction without reading it. The strongest setup is usually tiered: a hot wallet for small operational balances, a hardware wallet for active signing, and a cold wallet for long-term holdings that are rarely moved.
- Convenience versus isolation: cold signing is slower and easier to get wrong.
- Recovery discipline: test restoration before you need it.
- Contract risk: a hardware wallet can still sign a malicious approval if you do not decode it.
- Supply chain: buy from a reputable source and verify firmware.
Connecting wallets to networks without weakening custody
Your signing boundary is only part of the system. The RPC endpoint you use to read state and broadcast transactions is another. A compromised or unreliable endpoint can feed you incorrect state or fail to broadcast a valid transaction, even when your keys are perfectly isolated.
For network-specific endpoint guidance, start with the multi-chain RPC endpoints guide and the RPC endpoints guide. If you are choosing a provider for a specific chain, the RPC Assistant pages for Ethereum RPC API and Solana RPC provider cover concrete choices. For dedicated infrastructure, review dedicated nodes and RPC pricing.
- Use a read-only endpoint for balance and nonce checks.
- Broadcast signed transactions from a host that never holds the key.
- Keep separate endpoints for testnet and mainnet to avoid chain-ID mistakes.
- Review supported networks before assuming a chain is available.
Next steps
Run the two checks above on a testnet, fill in the results table with your own measurements, and only then move a small amount to the configuration you intend to use. If you are building an application that integrates wallet signing, review the API service documentation and the blockchain node hosting guide to align your backend with your custody model.
For endpoint selection by network and workload, use the RPC Assistant rather than a generic list. The right endpoint depends on your chain, latency requirements, and whether you need archive data or dedicated throughput.
- Test recovery on a second device before relying on the backup.
- Document the derivation path, passphrase policy, and firmware version.
- Re-run the verification table after every firmware or app update.
- Separate hot, warm, and cold balances by purpose and value.