Skip to content

Truffle and Hardware Wallets

Using Truffle with Hardware Wallets is notoriously hard. I have a Ledger Nano S myself, but so far it was impossible to interact with Smart Contracts using Truffle via Hardware Wallets such as Ledger.

In this video we're trying something new: Truffle Dashboard. It's a cool new way to use Truffle.


This is the lab you've been looking for if you want a tutorial style guide for using Truffle with Truffle Dashboard and Hardware Wallets.

Limited Liability: This is for educational purposes only, do your own Audit when used in Production.

Contributor Truffle Kardinalschnitten 🍰

As this video was released before Truffle released their official Blog-Post and this video seems to have contributed a lot to the actual final release, I was named official contributor to the Truffle Project: 🎉

If you wonder what is a Kardinalschnitte, this is a Kardinalschnitte and was actually first invented by a Viennese Patissiere. Welcome to 🎡.

Real-World Use-Case for this Project

🔑 Deploy using Hardware Wallets

🌱 Seedless deployment and Smart Contract Interaction


🤔 Test-Drive Truffle Dashboard

No Liability - Educational Only!

Platforms change all the time and it is a very volatile marketplace. This example is for educational purposes only. Consult an expert before deploying anything in production

If you're ok with that, then let's get started!

Installation and preparation

Let's get started by installing the newest truffle version (which is 5.5.0 in our example):

npm install -g truffle

once this is finished, see which version is installed:

truffle version

It should output 5.5.0 or greater.

Let's then

  1. Create an empty folder
  2. Initialize a new truffle project
  3. install @openzeppelin/contracts
mkdir truffle-dashboard-test
cd truffle-dashboard-test
truffle init
npm install @openzeppelin/contracts

You should end up with something like this:

Truffle Dashboard

Truffle Dashboard is a cool idea: Instead of directly connecting to an RPC endpoint, it will open a webserver which is a DApp that can connect to MetaMask. From there, you can actually start Transactions via MetaMask. Let's see how that works:

truffle dashboard

This will open a webserver and provide a website to connect to MetaMask. Do that and it will basically wait for incoming transactions:

now we can, for example, start a Truffle console and interact with the blockchain as usual, just directly via the command line:

truffle console --network dashboard

We can type in classical web3 commands, such as sending Ether. Before directly sending transactions with the Ledger, let's first send Ether to it. I'm here on Rinkeby, but it should work the same on the Mainnet or any other network:

web3.eth.sendTransaction({from: accounts[0], to: "LEDGER_ACCOUNT", value: 1e18})

Substitute LEDGER_ACCOUNT with the actual account from your ledger.

This will result in a new transaction waiting on the truffle dashboard:

If you hit confirm, it will be sent using MetaMask. No HDWalletProvider necessary, let alone anything like @ledgerhq/hw-transport-*. If you have ever worked with the official LedgerHQ nodejs packages to get the Ledger working with Truffle, you probably know its notoriously hard to do so. I was unable to get that running at all using Windows 10. The furthest I got was to use @ledgerhq/hw-transport-node-hid-singleton just to see USB Device busy.

Once the Transaction is confirmed, we have Ether in our Ledger account. How do we get them out again?

Easy: Hook up our Ledger and send a transaction back using the same command in the console.

Let's try to send 0.5 Eth back.

  1. Make sure you copy the address of the NON-LEDGER-ACCOUNT to the clipboard
  2. Connect the Ledger to MetaMask and select the Ledger Account
  3. Exit the Truffle Console and Re-Open it
.exit //exit the console

truffle console --network dashboard
web3.eth.sendTransaction({from: accounts[0], to: "NON-LEDGER-ACCOUNT", value: 5e17 })

This will push again a transaction to the Truffle Dashboard. Confirm it and the transaction is again routed through MetaMask.

Of course you have to confirm it on your Ledger.

Truffle Dashboard is a Game Changer

In my opinion, Truffle Dashboard is a game changer. No more (insecure) copying of seed phrases, no more private keys, no .env files, everything ideally routed via a wallet you can connect to MetaMask and potentially more Wallets in the future.

Deploy Smart Contracts using Truffle and Ledger Hardware Wallet

Now its time to go one step further. We know that simple transactions are working, but how is it with Smart Contracts?

If you haven't, install OpenZeppelin Contracts first npm install @openzeppelin/contracts

Then add a new NFT ERC721 Contract:

// contracts/GameItem.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

contract MyToken is ERC721URIStorage {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;

    constructor() ERC721("TestItem", "TEST") {}

    function awardItem(address player, string memory tokenURI)
        returns (uint256)

        uint256 newItemId = _tokenIds.current();
        _mint(player, newItemId);
        _setTokenURI(newItemId, tokenURI);

        return newItemId;

and a Migrations file:

const Token = artifacts.require("MyToken");

module.exports = function (deployer) {

Let's see if we can deploy the contracts.

If you are still in the truffle console, simple type in migrate, otherwise start the whole process using truffle migrate --network dashboard.

Then head over again to the Dashboard and confirm the Transaction. It's several of them to confirm:

You can see the progress in the terminal window:

Console Log Statements

The "undefined" you see in this screenshot is already fixed by the Truffle team

Once its done, it will print the Total of the TX cost and is back at the terminal:

Interact with Smart Contracts using Truffle Dashboard

Now it is time to see if we can interact with Smart Contracts using the Truffle Dashboard.

That the Truffle Console if you haven't already:

truffle console --network dashboard

Then mint a new Item for one of your addresses. In the Video I am minting it for the Non-Ledger account, but you can mint it for any account you want, just make sure you remember the address.

let token = await MyToken.deployed();


This should trigger a new Transaction on the Dashboard which needs to be Processed:

Then you can see if the token was really minted:


Final Thoughts

I hope this shows how powerful this new feature is. Your Private Keys can reside where they should be: In a Hardware Wallet. Un-exportable and great for daily use.

If you like this kind of content and would like to learn how to use Ethereum and Solidity from the ground up, consider joining my course:

Ethereum Blockchain Developer - Build Projects in Solidity

Last update: March 28, 2022