A simple decentralized message board powered by Arkiv. This is the starter template for the Serverless DApp 101 tutorial.
- Read path: Querying Arkiv entities via
createPublicClient+ query builder - Write path: Server-signed writes via Next.js API routes (Phase 0)
- Optimistic UI: Handling "submitted vs indexed" states gracefully
- Error handling: Timeout, rate limit, and network error classification
- Shared space: Uses
SPACE_ID=nsso all messages appear on the main demo page
-
Fork this repository on GitHub
-
Clone your fork:
git clone https://github.com/YOUR_USERNAME/arkiv-hello-world.git cd arkiv-hello-world -
Install dependencies:
npm install
-
Set up environment variables:
cp .env.example .env # Edit .env and set: # - SPACE_ID=ns (shared workshop space - already set) # - ARKIV_PRIVATE_KEY=0x... (your testnet wallet private key)
-
Get testnet tokens:
- Generate a wallet using the Arkiv Getting Started guide
- Get testnet tokens from the Braga Testnet Faucet
- Add your private key to
.env
-
Run development server:
npm run dev
-
Visit:
- Homepage:
http://localhost:3000 - Hello World Demo:
http://localhost:3000/hello-world
- Homepage:
This demo uses SPACE_ID=ns by default. This means:
- ✅ Messages from any wallet will appear on the main demo page
- ✅ All tutorial participants can see each other's messages
- ✅ Demonstrates the decentralized nature of Arkiv
- ✅ No central database - all data is on-chain
When you create a message from your local app, it will appear on:
- Your local app at
http://localhost:3000/hello-world - The main demo at
https://serverlessdapp101.vercel.app/hello-world - Any other app using
SPACE_ID=ns
arkiv-hello-world/
├── app/
│ ├── hello-world/page.tsx # Message board UI
│ ├── api/serverless-dapp101/
│ │ └── messages/route.ts # Messages API
│ ├── page.tsx # Homepage
│ └── layout.tsx # Root layout
├── lib/
│ ├── arkiv/
│ │ ├── client.ts # Arkiv client utilities
│ │ └── transaction-utils.ts # Transaction helpers
│ └── config.ts # Configuration (SPACE_ID, etc.)
├── .env.example # Environment variable template
└── README.md # This file
- Writing messages: When you submit a message, it's sent to
/api/serverless-dapp101/messages(POST) - Creating entities: The API creates a
workshop_messageentity on Arkiv with your message - Shared space: All entities use
spaceId='ns', so they're queryable by anyone - Reading messages: The page queries all
workshop_messageentities withspaceId='ns' - Decentralized: No central database - all data lives on Arkiv (Braga testnet)
- View on Explorer: Each message has both Entity and Transaction links to verify on-chain:
- Entity link: View the entity (data structure) on the explorer
- Transaction link: View the transaction (blockchain operation) on the explorer
- Shared visibility: Your messages appear on the main demo page immediately
- Independent verification: Anyone can query the same data independently
- Serverless DApp 101 Tutorial - Full tutorial
- Arkiv Network - Official documentation
- Arkiv Getting Started - Wallet generation
- Braga Testnet Faucet - Get testnet tokens
This template targets Braga, Arkiv's current public testnet. Snapshots, entities, and funded balances do not port between Arkiv testnets, so anyone running this code (and any agent helping with maintenance) should confirm the current network before assuming the configuration below is still up to date.
| Setting | Value |
|---|---|
| Chain export | braga from @arkiv-network/sdk/chains |
| Chain ID | 60138453102 |
| HTTP RPC | https://braga.hoodi.arkiv.network/rpc |
| WebSocket RPC | wss://braga.hoodi.arkiv.network/rpc/ws |
| Explorer | https://explorer.braga.hoodi.arkiv.network |
| Faucet | https://braga.hoodi.arkiv.network/faucet/ |
| Native gas token | test GLM |
| SDK requirement | @arkiv-network/sdk@^0.6.7 (the braga export requires >= 0.6.5) |
Arkiv has rotated its public testnet as the protocol matured:
- Mendoza (early testnet, ETH gas token)
- Kaolin (deprecated, scheduled to stop responding on May 15, 2026, ETH gas token)
- Braga (current, GLM gas token)
Official references:
- Braga overview: https://docs.arkiv.network/networks/braga/
- Kaolin to Braga migration notes: https://docs.arkiv.network/networks/migrate-from-kaolin/
The next time Arkiv announces a new testnet, the changes below are what this repository needs. The same checklist works whether you are a human maintainer or an AI assistant. Replace braga with the new chain name wherever it appears.
- Confirm the new chain is exported from
@arkiv-network/sdk/chains. Runnpm view @arkiv-network/sdk versionto see the latest published SDK and check the release notes for the minimum version that includes the new chain. - Bump
@arkiv-network/sdkinpackage.jsonto that version and runnpm installsopackage-lock.jsonupdates. - Edit
lib/arkiv/client.ts:- Replace the
import { braga } from "@arkiv-network/sdk/chains"line. - Replace both
chain: bragareferences ingetPublicClientandgetWalletClientFromPrivateKey. - Update the JSDoc comment that names the testnet.
- Replace the
- Edit
app/hello-world/page.tsx:- Two
hreftemplates point athttps://explorer.braga.hoodi.arkiv.network/entity/${...}and/tx/${...}. - One copy line reads
Connected to Braga Testnet.
- Two
- Edit
scripts/generate-wallet.mjs(one faucet URL in aconsole.log). - Edit this
README.md(Quick Start step 5, the "How It Works" line, the Resources list, and this Network and Migration section). - Refund the deployment signing wallet on the new faucet, since balances do not port across testnets. Update the
ARKIV_PRIVATE_KEYenvironment variable in your hosting provider if you rotate the wallet. - Run
npm run typecheckto confirm the new chain export resolves. - Smoke test locally with
npm run devand post a message at/hello-world. Verify the entity and transaction links open the new explorer.
Final check, useful as both the first and last step of a migration:
grep -rin "braga\|mendoza\|kaolin" --include="*.ts" --include="*.tsx" --include="*.md" --include="*.mjs" --include="*.json"Any hits outside this Network and Migration section indicate stragglers that still need to be updated.
MIT