usdt-wallet-svelte Svelte Themes

Usdt Wallet Svelte

USDT Wallet Sepolia Testnet svelte

USDT Wallet (Sepolia Testnet)

Project goal: A lightweight Svelte‑Kit 5 dApp that lets a user connect / disconnect a wallet (MetaMask), read their USDT balance on Sepolia, and — if the balance is positive — send a transfer.
The UI supports light / dark themes, is fully responsive, and emits toast notifications for every important action or error.


Tech stack & why each library is here

Library / tool Version Purpose
Svelte‑Kit 5.x Application framework (file‑based routing, SSR, Vite under the hood).
TypeScript 5.x Static typing across the whole code‑base.
Vite 6 6.3.5 Dev‑server & bundler (comes with Svelte‑Kit).
Tailwind CSS 4 4.1.10 Utility‑first styling; dark‑mode via class strategy; custom palette.
@tailwindcss/vite 4.x Injects Tailwind into the Vite pipeline (zero PostCSS config).
Viem 2.31.x Low‑level EVM JSON‑RPC client (read‑only). Used for readContract, network check, and writing txs.
Ethers v6 6.14.x High‑level helper for signing & sending transfer transactions.
wagmi core 2.15.x (Optional) Helper hooks; we finally only used Viem + direct window.ethereum calls to keep bundle small.
svelte‑toast latest A11y‑friendly toast notifications.
@reown/appkit 1.7.x Internal design system (buttons / colors). Only a tiny subset is imported.

No additional backend or database is required – everything talks directly to the Sepolia RPC (https://rpc.sepolia.org).


Project structure (TL;DR)

usdt-wallet-fresh/
├─ src/
│  ├─ lib/
│  │  ├─ components/
│  │  │  ├─ ThemeToggle.svelte   // light / dark switcher
│  │  │  └─ Toast.svelte         // reusable toast component
│  │  ├─ stores/
│  │  │  └─ walletStore.ts       // (optional) Svelte stores, not mandatory
│  │  └─ constants.ts            // chain, RPC, contract ABI
│  ├─ routes/
│  │  ├─ +layout.svelte          // global CSS import & theme toggle
│  │  └─ +page.svelte            // main dApp logic (connect, balance, transfer)
│  ├─ app.css                    // Tailwind directives
│  └─ app.d.ts                   // augment Window.ethereum typings
├─ static/                       // 1‑trans.png, 2‑trans.png avatars
├─ tailwind.config.js            // custom palette + dark mode
├─ vite.config.ts                // adds tailwind plugin
└─ README.md                     // this file

Core features

Feature File(s) Notes
Connect / disconnect MetaMask +page.svelte Uses window.ethereum.request({method:'eth_requestAccounts'}) + accountsChanged listener.
Network guard (Sepolia only) +page.svelte On each connect checks publicClient.getChainId() – if !== 11155111 it notifies & aborts.
Live USDT balance constants.ts (ABI) + fetchBalance() Calls balanceOf(address) and formats with formatUnits(_, 6). Loading state shows animated dots.
Manual address input +page.svelte For users without MetaMask. Validates checksum/length before querying balance.
Transfer form +page.svelte ({#if balance>'0'}) Two inputs → receiver + amount; calls erc20.transfer() via an ethers.Wallet signer built from MetaMask provider. Gas‐safe decimals handling via parseUnits(_,6).
Toast notifications Toast.svelte Top‑right; auto‑dismiss after 3 s; color‑coded by type.
Light / dark theme ThemeToggle.svelte, Tailwind darkMode:'class' Persisted with localStorage; system preference on first load.
Responsive layout Tailwind grids Mobile hides avatar & collapses buttons.

Configuration files

File Purpose
tailwind.config.js Content glob, darkMode:'class', extended colors (primary, secondary, semantic tokens for card/button).
vite.config.ts Adds @tailwindcss/vite before sveltekit() plugin.
svelte.config.js Enables PostCSS preprocessing (postcss:true).
postcss.config.js Minimal – handled by @tailwindcss/vite, but present if editors need it.
app.d.ts Declares window.ethereum to avoid TS errors.

Getting started

pnpm install      # or npm i / yarn
pnpm dev          # Vite dev‑server on http://localhost:5173

Need test USDT? Use a Sepolia faucet for ETH, then the Tether USD (Sepolia) faucet or a peer‑to‑peer transfer.

Build & preview

pnpm build   # static SSR build in /build
pnpm preview # preview the production build

Key implementation details

1. Contract interaction (read)

const raw = await publicClient.readContract({
  address: USDT_ADDRESS,
  abi: ERC20_ABI,
  functionName: 'balanceOf',
  args: [address]
});

2. Contract interaction (write)

const tx = await erc20.write.transfer([recipient, parseUnits(amount, 6)]);
await tx.wait();
notify('Transfer sent');

The signer is injected by MetaMask; on manual‑address mode the transfer form is hidden.

3. Network enforcement

if (await publicClient.getChainId() !== 11155111) {
  notify('Switch MetaMask to Sepolia');
  return;
}

4. Account hot‑swap

window.ethereum.on('accountsChanged', async (accs:string[]) => {
  if(accs.length){ address = accs[0] as `0x${string}`; await fetchBalance(); }
  else disconnect();
});

Possible improvements / backlog

* Persist last‑used address in localStorage for instant balance on reload.
* Add unit tests with Vitest for helpers (address validator, decimal math).
* CI pipeline (GitHub Actions) for type‑check + Playwright e2e. * i18n (English / Spanish) via svelte‑i18n. * Progressive Web App manifest for mobile installation.


License

MIT – do whatever you want, no warranty.
Tether® logo used only for demonstration; trademarks belong to their respective owners.

Top categories

Loading Svelte Themes