IOTA Gas Station Workshop
In this hands-on workshop you will build Spark Mini, a fully functional, decentralized microblogging platform where anyone can post messages without owning a single token or paying gas fees.
Spark Mini is a sleek, gas-free microblogging platform built on IOTA testnet. Think Twitter, but with zero fees, no token required, and every post permanently stored on-chain. Using the IOTA Gas Station, the dApp operator quietly pays all transaction costs, so anyone with a wallet can simply connect, type a message, and post instantly, no faucet, no balance, no friction. In this workshop, you’ll build the entire thing from scratch: run your own Gas Station, fund it, and create a beautiful React frontend that delivers real, immutable, on-chain sparks with a single click.
Why IOTA Gas Station?
In traditional blockchains, users must buy tokens, fund wallets, and pay gas fees for every action, like posting a message. This creates massive friction, preventing adoption. IOTA Gas Station solves this by letting dApp operators cover fees, so users focus on creating content. Spark Mini demonstrates this with a Twitter-like platform: posts are immutable on IOTA testnet, but completely free.
Spark Mini – Sponsored Transaction Flow
Learning Objectives
By the end of this workshop, you will:
- Understand sponsored transactions and how the Gas Station enables gas-free UX.
- Deploy a local Gas Station and fund it for sponsorship.
- Build a React frontend with IOTA dApp Kit for wallet connection and UI.
- Implement on-chain posting using the IOTA TypeScript SDK.
- Integrate the full sponsored flow: reserve gas, user sign, Gas Station co-sign/submit.
- Test and debug your dApp with real testnet transactions.
Prerequisites
Before starting, ensure you have:
- Basic Knowledge: Familiarity with JavaScript/TypeScript, React, and command line. No prior IOTA experience needed.
- Tools:
- Node.js (v18+) and npm/yarn.
- Git.
- Docker Desktop (for Gas Station deployment).
- VS Code (recommended).
- Hardware: Mac/Linux/Windows with 4GB+ RAM.
If you're missing anything, install now:
Part 1 – Project Setup & Architecture
We'll build a full-stack dApp:
- Frontend (
spark-mini-frontend): React + Vite + dApp Kit for UI, wallet connect, and tx submission. - Gas Station (official Docker): Sponsors fees; no custom backend needed for this workshop.
- On-Chain Logic: Uses a demo Move package for storing posts (immutable on testnet).
1.1 Create the Workshop Folder
mkdir spark-mini-workshop && cd spark-mini-workshop
This creates a dedicated folder for the entire workshop. All code and services will live here.
1.2 Clone and Launch the Official IOTA Gas Station
git clone https://github.com/iotaledger/gas-station.git
cd gas-station
../utils/./gas-station-tool.sh generate-sample-config --config-path config.yaml --docker-compose -n testnet
GAS_STATION_AUTH=supersecret123 docker compose up -d
Explanation:
We are deploying the official, production-ready Gas Station using Docker. The generate-sample-config tool creates a testnet-ready configuration. The environment variable sets the auth token to supersecret123.
1.3 Verify the Gas Station is Healthy
curl http://localhost:9527/health
Expected output:
{"status":"healthy"}
Explanation:
A successful response confirms the RPC server is listening on port 9527 and ready to sponsor transactions.
1.4 Create the React Frontend
cd ..
npx create-vite@latest frontend --template react-ts
cd frontend
npm install
npm install @iota/dapp-kit @iota/iota-sdk @tanstack/react-query axios
Explanation:
We scaffold a modern Vite + React + TypeScript project and install:- @iota/dapp-kit – wallet connection and hooks
- @iota/iota-sdk – transaction building
axios– HTTP calls to the Gas Station
1.5 Start the Dev Server
npm run dev
Explanation:
Your frontend is now live at http://localhost:5173. You’ll see a blank page for now, that’s expected.Part 2 – Wallet Connection with dApp Kit
2.1 Replace src/main.tsx (Providers)
// src/main.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.tsx';
import {
createNetworkConfig,
IotaClientProvider,
WalletProvider,
} from '@iota/dapp-kit';
import { getFullnodeUrl } from '@iota/iota-sdk/client';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import '@iota/dapp-kit/dist/index.css';
const { networkConfig } = createNetworkConfig({
testnet: { url: getFullnodeUrl('testnet') },
});
const queryClient = new QueryClient();
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<QueryClientProvider client={queryClient}>
<IotaClientProvider networks={networkConfig} defaultNetwork="testnet">
<WalletProvider>
<App />
</WalletProvider>
</IotaClientProvider>
</QueryClientProvider>
</React.StrictMode>
);
Explanation:
These providers are mandatory for any dApp Kit hook to work (useWallets, useSignTransaction, etc.). The CSS import gives us the beautiful default ConnectButton styling.
2.2 Basic UI with ConnectButton
// src/App.tsx (replace everything)
import React from 'react';
import { ConnectButton, useWallets } from '@iota/dapp-kit';
export default function App() {
const wallets = useWallets();
const connectedWallet = wallets.find(w => w.accounts.length > 0);
const address = connectedWallet?.accounts[0]?.address;
return (
<div style={{ maxWidth: 600, margin: '40px auto', textAlign: 'center', fontFamily: 'system-ui' }}>
<h1>Spark Mini</h1>
<p>Gas-free microblogging on IOTA testnet</p>
{!connectedWallet ? (
<>
<h2>Connect your wallet to start posting</h2>
<ConnectButton />
</>
) : (
<p>Connected: {address?.slice(0, 12)}...{address?.slice(-8)}</p>
)}
</div>
);
}
Explanation:
useWallets returns all detected wallets. When a user connects, accounts.length > 0. The ConnectButton automatically opens the official modal and handles all wallet standards.
Test it: Click Connect → Choose IOTA Wallet → Success! You now see your address.