How to Build a Decentralized Token Swap Interface with Web3.js
The idea that people can trade digital assets without a middleman might have seemed like a fantasy not long ago. But here we are. Swapping tokens directly from one wallet to another, with no bank or exchange in control, is a reality. If you’ve ever used Uniswap, PancakeSwap, or any other decentralized exchange (DEX), you know how powerful this is. The best part? You can build your own decentralized token swap interface using Web3.js.
It’s not as complicated as it sounds. This guide will walk you through the key steps, from connecting a wallet to executing a token swap. Whether you’re a developer looking to create a new trading tool or just someone curious about how these swaps work under the hood, you’ll get something useful out of this.
Setting Up the Project
Before jumping into the actual code, let’s set up the environment. You’ll need:
- Node.js and npm – Web3.js relies on JavaScript, and Node.js makes package management easy.
- A test Ethereum wallet – MetaMask is a solid choice.
- Access to a blockchain network – Use Alchemy or Infura for a smooth experience.
- Web3.js – The JavaScript library for interacting with smart contracts.
- A Uniswap-like smart contract – Either deploy your own or use an existing one.
Installing Dependencies
Start by creating a new project and installing the necessary dependencies.
mkdir token-swap-interface
cd token-swap-interface
npm init -y
npm install web3 dotenv
You’ll also need a front-end framework like React if you want to build a user-friendly interface. Install it with:
npx create-react-app client
cd client
npm install web3 dotenv
Now, you’re ready to start writing some code.
Connecting a Wallet
To interact with a blockchain, users need a wallet connection. MetaMask is the go-to choice for most users, and Web3.js makes it simple to connect.
Adding Web3.js
Inside your project, create a file named web3.js
and set up the connection:
import Web3 from 'web3';
const getWeb3 = () => {
return new Promise((resolve, reject) => {
if (window.ethereum) {
const web3 = new Web3(window.ethereum);
window.ethereum.request({ method: 'eth_requestAccounts' })
.then(() => resolve(web3))
.catch(reject);
} else {
reject(new Error("MetaMask not found"));
}
});
};
export default getWeb3;
This function checks if MetaMask is available and requests permission to access accounts. If MetaMask isn’t installed, it throws an error.
Connecting in React
Modify App.js
to integrate the wallet connection:
import React, { useState, useEffect } from 'react';
import getWeb3 from './web3';
function App() {
const [web3, setWeb3] = useState(null);
const [account, setAccount] = useState(null);
useEffect(() => {
async function init() {
try {
const web3Instance = await getWeb3();
setWeb3(web3Instance);
const accounts = await web3Instance.eth.getAccounts();
setAccount(accounts[0]);
} catch (error) {
console.error(error);
}
}
init();
}, []);
return (
<div>
<h1>Token Swap Interface</h1>
<p>Connected Account: {account || "Not connected"}</p>
</div>
);
}
export default App;
Now, when users open the page, they’ll be prompted to connect their wallet.
Fetching Token Data
To swap tokens, we need contract addresses, symbols, and balances. This data comes from the Ethereum blockchain via Web3.js.
Loading Token Details
You’ll interact with ERC-20 token contracts to fetch user balances and token details.
const tokenABI = [ /* ERC-20 ABI */ ];
const getTokenData = async (web3, tokenAddress, userAddress) => {
const tokenContract = new web3.eth.Contract(tokenABI, tokenAddress);
const name = await tokenContract.methods.name().call();
const symbol = await tokenContract.methods.symbol().call();
const balance = await tokenContract.methods.balanceOf(userAddress).call();
return { name, symbol, balance };
};
Pass in a token contract address, and it will return essential details like the token’s name, symbol, and how much the user holds.
Swapping Tokens
A token swap involves sending tokens to a liquidity pool and receiving another token in return. You’ll interact with a smart contract like Uniswap’s Router.
Setting Up the Swap Function
Here’s how you interact with a swap contract:
const swapTokens = async (web3, fromToken, toToken, amount, userAddress, routerAddress) => {
const routerABI = [ /* Uniswap Router ABI */ ];
const router = new web3.eth.Contract(routerABI, routerAddress);
const amountIn = web3.utils.toWei(amount, 'ether');
const path = [fromToken, toToken];
const deadline = Math.floor(Date.now() / 1000) + 60 * 20; // 20 minutes from now
await router.methods.swapExactTokensForTokens(
amountIn,
0,
path,
userAddress,
deadline
).send({ from: userAddress });
};
This function:
- Converts the token amount to the correct format
- Defines the swap path (from token to token)
- Sets a deadline to avoid getting stuck in an old transaction
- Executes the swap
Building the UI
A simple React form can make this swap process user-friendly.
<form onSubmit={handleSwap}>
<input type="text" placeholder="Amount" value={amount} onChange={(e) => setAmount(e.target.value)} />
<button type="submit">Swap</button>
</form>
Handling Errors
If the swap fails, it’s usually because:
- The user hasn’t approved the contract
- The token balance is too low
- Gas fees are too high
Make sure to catch errors in your swap function:
try {
await swapTokens(web3, fromToken, toToken, amount, userAddress, routerAddress);
} catch (error) {
console.error("Swap failed:", error);
}
Security and Best Practices
Building a token swap is one thing, making it secure is another.
- Always use a test network (Ropsten, Goerli) before deploying on mainnet.
- Verify contract addresses – Using the wrong one could result in lost funds.
- Limit user approvals – Don’t allow unlimited token spending permissions.
- Keep API keys private – Use
.env
files to store sensitive data.
Final Thoughts
Building a decentralized token swap interface with Web3.js isn’t as overwhelming as it seems. Start by setting up Web3.js, connect wallets, fetch token data, and interact with a swap contract. The more you experiment, the better you’ll understand how decentralized trading works.
While security is always a concern, following best practices will keep your swap interface safe and functional. If you’re serious about Web3 development, building tools like this is a great way to dive deeper into decentralized finance.