A secure, open-source browser wallet for testing smart contracts across multiple blockchains β never mainnet.
DevNet Wallet is a lightweight, privacy-preserving Chrome/Brave extension that lets blockchain developers test and debug dApps on devnets and other test networks without risking real assets.
- β Developer-only wallet β never stores or touches mainnet keys
- β Supports both ECDSA (secp256k1) and Ed25519 (Solana) key types
- β Ephemeral by default β private keys live in memory unless user encrypts
- β Multi-chain testing β single UI for EVM and Solana testnets
- β Extensible architecture β easy to add new testnets
| Network | Type | Chain/Cluster ID | RPC URL | Explorer | Faucet |
|---|---|---|---|---|---|
| Ethereum Sepolia | EVM | 11155111 | https://eth-sepolia.public.blastapi.io |
sepolia.etherscan.io | sepoliafaucet.com |
| Polygon Amoy | EVM | 80002 | https://rpc-amoy.polygon.technology |
amoy.polygonscan.com | faucet.polygon.technology |
| BSC Testnet | EVM | 97 | https://data-seed-prebsc-1-s1.binance.org:8545 |
testnet.bscscan.com | Binance Faucet |
| Avalanche Fuji | EVM | 43113 | https://api.avax-test.network/ext/bc/C/rpc |
testnet.snowtrace.io | faucet.avax.network |
| Local Hardhat/Anvil | EVM | 31337 | http://127.0.0.1:8545 |
Local Dev | Built-in |
| Solana Devnet | Ed25519 | devnet | https://api.devnet.solana.com |
explorer.solana.com | faucet.solana.com |
- Frontend: React + TypeScript + Tailwind CSS
- Blockchain Libraries:
ethers.jsβ EVM chains (secp256k1)@solana/web3.jsβ Solana Devnet (Ed25519)
- Extension APIs: Manifest V3 (
chrome.runtime,chrome.storage,chrome.action) - Crypto:
- EVM keys β BIP-39 / BIP-44 (HD wallets)
- Solana keys β Ed25519 Keypair (tweetnacl)
- Storage: In-memory (default) or AES-encrypted sessionStorage
devnet-wallet/
βββ manifest.json # Extension manifest (V3)
βββ package.json # Dependencies
βββ vite.config.ts # Build configuration
βββ tailwind.config.js # Tailwind CSS config
βββ tsconfig.json # TypeScript config
βββ index.html # Popup HTML
βββ public/
β βββ icons/ # Extension icons
β βββ inject.js # Injected wallet API
βββ src/
β βββ background/
β β βββ index.ts # Service worker
β βββ content/
β β βββ inject.ts # Content script
β βββ popup/
β β βββ index.tsx # Popup entry
β β βββ Popup.tsx # Main popup component
β β βββ components/ # UI components
β β βββ Header.tsx
β β βββ CreateWalletView.tsx
β β βββ WalletView.tsx
β β βββ SettingsView.tsx
β βββ utils/
β β βββ evm.ts # EVM wallet helpers
β β βββ solana.ts # Solana key & tx helpers
β β βββ network.ts # Network configurations
β β βββ faucet.ts # Faucet integrations
β β βββ crypto.ts # Encryption utilities
β β βββ storage.ts # Storage management
β βββ styles/
β βββ index.css # Global styles
βββ README.md
- Auto-generate new wallet on first load (ECDSA + Ed25519)
- Optional import (private key / seed phrase / Solana keypair)
- Optional encrypted export with "TESTNET ONLY" warning
- Auto-wipe keys on tab close
- Multi-format support:
0xhex (private key β EVM)- Mnemonic (12/24 words)
- Solana base58 secret key
- Preloaded testnets (see table above)
- Manual switch dropdown
- Custom RPC addition with explicit "TESTNET ONLY" checkbox
- Auto-reject
chainId 1(mainnet) or Solanamainnet-beta
- Per-network "Get Test Tokens" button
- Built-in local faucet for Hardhat/Anvil
- Direct links to external faucets
- Transaction preview modal (from/to/value/gas/data)
- EVM:
ethers.Wallet.signTransaction&sendTransaction - Solana:
Transactionvia@solana/web3.js - Logs all signed tx hashes for developer debugging
- Network selector
- Wallet address (copy icon)
- Balance display
- Buttons: Send / Receive / Faucet / Settings
- "Persist key (encrypted)" toggle
- Manage networks
- Clear wallet
- Export key (with warning)
- Debug logs toggle
- Red banner: "TESTNET ONLY β NO REAL FUNDS"
- Always display chain name and RPC URL in header
The extension injects window.devnetWallet (EVM) and window.solanaDevnetWallet (Solana) into web pages. Legacy aliases (window.testnetWallet, window.solanaTestnetWallet) remain available for compatibility.
// Request accounts
const accounts = await window.devnetWallet.request({
method: 'eth_requestAccounts'
});
// Get current chain
const chainId = await window.devnetWallet.request({
method: 'eth_chainId'
});
// Send transaction
const txHash = await window.devnetWallet.request({
method: 'eth_sendTransaction',
params: [{
from: accounts[0],
to: '0x...',
value: '0x...',
gas: '0x...',
}]
});
// Listen for network changes
window.devnetWallet.on('chainChanged', (chainId) => {
console.log('Network changed to:', chainId);
});// Connect wallet
const { publicKey } = await window.solanaDevnetWallet.connect();
// Send transaction
const connection = new solanaWeb3.Connection('https://api.devnet.solana.com');
const transaction = new solanaWeb3.Transaction().add(
solanaWeb3.SystemProgram.transfer({
fromPubkey: publicKey,
toPubkey: recipientPublicKey,
lamports: amount,
})
);
const { signature } = await window.solanaDevnetWallet.signAndSendTransaction(transaction);- β Handshake-authenticated messaging bridge between dApp, content script, and service worker
- β Strict RPC input validation before forwarding any call to external providers
- β
Block
chainId 1andmainnet-beta - β Keys never leave local context
- β All RPC calls HTTPS or localhost
- β No analytics or telemetry
- β Strong warnings for seed import/export
- β UI must show active network and testnet badge at all times
- Node.js 18+ and npm/yarn
- Chrome or Brave browser
# Clone the repository
git clone https://github.com/yourname/devnet-wallet
cd devnet-wallet
# Install dependencies
npm install
# Build the extension
npm run build- Open Chrome/Brave
- Navigate to
chrome://extensions/ - Enable Developer mode
- Click Load unpacked
- Select the
build/directory
# Run in watch mode
npm run dev- Developer installs extension
- On launch, wallet auto-generates EVM & Solana keys (in memory)
- Developer selects "Sepolia" or "Solana Devnet"
- Clicks Get Test Tokens to fund wallet
- Deploys contracts or runs CI tests
- Closes browser β keys wiped
- Tailwind CSS + Inter font
- Developer-centric dark theme
- Rounded corners (2xl), soft shadows, large padding
- Animated banner "TESTNET ONLY"
- Add Base Goerli, Linea, zkSync Testnet
- Multi-account management
- Built-in Solana airdrops button
- Local node manager (start/stop Anvil)
- Web dashboard for testnet analytics
MIT β Open source for educational / developer testing purposes.
Never use with mainnet funds. This wallet is for testnets only.
This extension is designed exclusively for development and testing purposes. It includes safeguards to prevent mainnet usage, but developers should always exercise caution.
Contributions are welcome! Please open an issue or submit a pull request.
npm install
npm run dev # Development mode
npm run build # Production buildThe contracts/ directory contains sample smart contracts to test the wallet's functionality:
cd contracts
npm install
npm run compile
# Start local Hardhat node
npm run node
# Deploy contracts (in another terminal)
npm run deploy:local- SimpleStorage - Test basic transactions and state changes
- TestToken - ERC20 token for testing transfers
- Guestbook - Test string parameters and events
See contracts/README.md for detailed instructions.
From the extension UI:
- Open the wallet popup β Settings.
- Under Export Keys, click Show Private Keys.
- Press Download Solana Keypair (.json).
The browser downloads solana-wallet-keypair.json containing the Uint8Array representation that Solana CLI, Solana Playground, and other tools expect.
Prefer the command line? You can still run:
node scripts/generate-keypair.js YOUR_BASE64_SECRET_KEYπ See docs/SOLANA_DEPLOY_GUIDE.md for full deployment guide.
import { ethers } from "ethers";
export async function createEvmWallet(rpcUrl: string) {
const provider = new ethers.providers.JsonRpcProvider(rpcUrl);
const net = await provider.getNetwork();
if (net.chainId === 1) throw new Error("Mainnet not allowed");
return ethers.Wallet.createRandom().connect(provider);
}import { Keypair, Connection } from "@solana/web3.js";
export function createSolanaWallet(cluster = "https://api.devnet.solana.com") {
const connection = new Connection(cluster, "confirmed");
const wallet = Keypair.generate();
return { wallet, connection };
}const BLOCKED = [1, 137, 56]; // Ethereum, Polygon, BSC mainnets
if (BLOCKED.includes(chainId) || cluster === "mainnet-beta") {
throw new Error("Mainnet not supported");
}Built with β€οΈ for the blockchain developer community.
Made for testing. Built for developers. Never for mainnet.