Build a Realtime Wallet
Create a multichain wallet that displays realtime balances, transactions, and NFTs using Sim APIs and Express.js
The final UI we'll build together in this guide
This is the first guide in our series on building a realtime, multichain wallet using Sim APIs. In this one, we will lay the foundation for our wallet. You will set up a Node project with Express.js, fetch and display token balances from 60+ EVM chains using the Balances API, and calculate the wallet’s total portfolio value in USD.
View Source Code
Access the complete source code for this wallet on GitHub
Try Live Demo
Interact with the finished wallet app
Prerequisites
Before we begin, make sure you have:
- Node.js >= 18.0.0
- A Sim API key
Get your API Key
Learn how to obtain your API key to properly authenticate requests.
Features
By the end of this series, our wallet will have four main features:
- Token Balances: Realtime balance tracking with USD values using the Balances API.
- Total Portfolio Value: Aggregated USD value across all chains.
- Wallet Activity: Comprehensive transaction history showing transfers and contract interactions using the Activity API
- NFTs: A display of owned NFTs using the Collectibles API
In this first guide, we will focus on implementing the first two: Token Balances and Total Portfolio Value.
Try the Live Demo
Before diving into building, you can interact with the finished wallet app below. Enter any Ethereum wallet address to explore its token balances, transaction history, and NFT collection across multiple chains.
Project Setup
Let’s start by scaffolding our project. This initial setup will provide a basic Express.js server and frontend templates, allowing us to focus on integrating Sim APIs.
Create Your Project Structure
Open your terminal and create a new directory for the project:
Now you are in the wallet-ui
directory.
Next, initialize a new Node.js project with npm:
These commands create a package.json
file with default values and configure it to use ES modules.
Afterward, install the required packages:
We are using three packages for our wallet:
- Express.js: A popular Node.js web framework for creating our server.
- EJS: A simple templating engine that lets us generate dynamic HTML.
- dotenv: A package to load environment variables from a
.env
file. - numbro: For formatting numbers and currency.
Configure Environment Variables
Create a new .env
file in your project root:
Open the .env
file in your code editor and add your Sim API key:
Never commit your .env
file to version control. If you are using Git, add .env
to your .gitignore
file.
Add Starter Code
Create the necessary directories for views and public assets:
views
will hold our EJS templates, and public
will serve static assets like CSS.
Now, create the core files:
Populate server.js
with this basic Express server code:
Add the initial frontend template to views/wallet.ejs
:
Add basic styles to public/styles.css
:
Verify Project Structure
Run ls
in your terminal. Your project directory wallet-ui/
should now contain:
Run node server.js
in the terminal to start the server.
Visit http://localhost:3001
to see the blank wallet.
Our scaffolded wallet UI without any data.
If you encounter errors, ensure your .env
file contains the correct SIM_API_KEY
and that it is loaded correctly.
Also, verify the walletAddress
in the URL is a valid EVM wallet address.
Check your terminal for any error messages from server.js
.
Now, let’s integrate the Sim API to fetch real data.
Fetch and Show Token Balances
We will use the Balances API to get realtime token balances for a given wallet address. This endpoint provides comprehensive details about native and ERC20 tokens, including metadata and USD values across more than 60+ EVM chains.
First, let’s create an async function in server.js
to fetch these balances. Add this function before your app.get('/')
route handler:
This function creates the API request using Node’s fetch
.
It includes your SIM_API_KEY
in the headers and sends a GET request to the /v1/evm/balances/{address}
endpoint.
The Balances API gives you access to various URL query parameters that you can include to modify the response.
We have included metadata=url,logo
to include a token’s URL and logo.
There’s also exclude_spam_tokens
to filter out common spam tokens.
The exclude_spam_tokens
parameter provides a good baseline to filter out low-value and potentially malicious tokens, but you may want to implement custom filtering for your use case.
Learn more in our Spam Filtering guide.
Next, modify your app.get('/')
route handler in server.js
to call getWalletBalances
and pass the fetched tokens to your template:
We’ve updated the route to:
- Call
getWalletBalances
if awalletAddress
is provided. - Pass the retrieved
balances
to thewallet.ejs
template.
The views/wallet.ejs
file you created earlier is already set up to display these tokens.
Restart your server with node server.js
and refresh your browser, providing a walletAddress
in the URL.
For example: http://localhost:3001/?walletAddress=0xd8da6bf26964af9d7eed9e03e53415d37aa96045
You should now see the wallet populated with token balances, logos, prices for each token, and how much of that token the wallet holds.
Wallet displaying token balances (in wei) with logos and prices.
Format Balances
The Balances API returns token amounts in their smallest denomination. This will be in wei for ETH-like tokens.
To display these amounts in a user-friendly way, like 1.23
ETH instead of 1230000000000000000
wei, we need to adjust the amount using the token’s decimals
property, which is also returned from the Balances API.
We can add a new property, balanceFormatted
, to each token object.
Modify your getWalletBalances
function in server.js
as follows. The main change is mapping over data.balances
to add the balanceFormatted
property:
Now, each token object returned by getWalletBalances
will include a balanceFormatted
string, which our EJS template (views/wallet.ejs
) already uses: <%= token.balanceFormatted || token.amount %>
.
Restart the server and refresh the browser. You will now see formatted balances.
Wallet displaying properly formatted token balances with logos.
Calculate Total Portfolio Value
The wallet’s total value at the top of the UI still says $0.00
.
Let’s calculate the total USD value of the wallet and properly show it.
The Balances API provides a value_usd
field with each token.
This field represents the total U.S. dollar value of the wallet’s entire holding for that specific token.
Let’s modify the app.get('/')
route handler to iterate through the fetched tokens and sum their individual value_usd
to calculate the totalWalletUSDValue
.
We use the reduce
method to iterate over the tokens
array.
For each token
, we access its value_usd
property, parse it as a float, and add it to the running sum
.
The calculated totalWalletUSDValue
is then formatted to two decimal places and passed to the template.
The views/wallet.ejs
template already has <p class="total-balance-amount"><%= totalWalletUSDValue %></p>
, so it will display the calculated total correctly.
Restart your server and refresh the browser page with a wallet address. You should now see the total wallet value at the top of the UI accurately reflecting the sum of all token balance USD values.
Wallet showing the correctly calculated total USD value.
Conclusion
You have successfully set up the basic structure of your multichain wallet and integrated Sim APIs Balances API
endpoint to display realtime token balances and total portfolio value.
In the next guide, Add Account Activity, we will enhance this wallet by adding a transaction history feature in the UI using the Activity API.