Skip to main content

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:
  1. Token Balances: Realtime balance tracking with USD values using the Balances API.
  2. Total Portfolio Value: Aggregated USD value across all chains.
  3. Wallet Activity: Comprehensive transaction history showing transfers and contract interactions using the Activity API
  4. 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.
1

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.
2

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:
.env
Never commit your .env file to version control. If you are using Git, add .env to your .gitignore file.
3

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:
server.js
Add the initial frontend template to views/wallet.ejs:
views/wallet.ejs
Add basic styles to public/styles.css:
public/styles.css
4

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:
server.js (getWalletBalances)
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. Next, modify your app.get('/') route handler in server.js to call getWalletBalances and pass the fetched tokens to your template:
server.js
We’ve updated the route to:
  1. Call getWalletBalances if a walletAddress is provided.
  2. Pass the retrieved balances to the wallet.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:
server.js (getWalletBalances with formatting)
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.
server.js (app.get('/') with total value calculation)
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.

Add Historical Price Tracking

Now let’s improve the wallet by showing price movement over time. Historical price context helps users understand how their tokens are gaining or losing value. The Balances API can return historical price points when you include the historical_prices query parameter, which lets you display price changes for any hour offset from 1 to 24 hours ago.

Token balances with twenty four hour price change indicators showing gains and losses.

To learn more about historical prices, visit the historical prices section in the Balances API documentation.

Understanding historical price data

When you pass the historical_prices query parameter, the API accepts a comma separated list of hour offsets such as 1,6,24. Each token in the response will then include a historical_prices array. Each entry contains an offset_hours value that indicates how many hours ago the price was recorded and a price_usd value that represents the token price at that time.

Create price utilities

Add a small utility module to calculate percentage changes and format them for display. Create utils/prices.js and include the following code.
utils/prices.js
These utility functions are necessary because the API returns only raw prices at specific times. You need these utilities to convert the price differences into percentage changes for display.

Request historical prices in your balances call

Update getWalletBalances to optionally include historical prices. Only request this data when viewing the tokens tab to keep responses fast.
server.js (getWalletBalances with historical prices)
This change adds an optional includeHistoricalPrices parameter, conditionally appends historical_prices=1,6,24 to the request, and preserves the existing formatting behavior.

Make price utilities available to the template

Import the utilities in server.js, request historical prices when the tokens tab is active, and pass the helpers into the template render context.
server.js (imports and route updates)

Show twenty four hour change in the UI

Add a compact badge below the amount display for each token. Insert this snippet in views/wallet.ejs within the tokens list item, after the amount text.
views/wallet.ejs (price change badges)

Style the badges

Add these styles to public/styles.css so the badges match the existing design system.
public/styles.css (price change styles)
Historical prices are not available for every token. If the API does not return historical data for a token, the badge will not appear and the layout remains consistent.

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.