Mini Apps
Build mini apps that run inside Nimiq Pay, with optional access to Nimiq and Ethereum wallet features.
What are Mini Apps?
Mini apps are web applications that run inside the Nimiq Pay app. They can support a wide range of in-app experiences, from general web tools to apps that interact with Nimiq and Ethereum wallets.
Think of it like a specialized web browser embedded within Nimiq Pay. Your mini app loads in the Nimiq Pay app and, when needed, can request wallet operations like listing accounts, signing messages, or sending payments, all while the user stays within the Nimiq Pay app. The wallet handles all the cryptographic operations securely, and users approve every sensitive action through native confirmation dialogs.
How It Works
Mini apps run in a WebView and talk to Nimiq Pay through injected providers.
For Nimiq provider access, the recommended pattern is to use the Mini App SDK init() helper to wait until the provider is ready:
import { init } from '@nimiq/mini-app-sdk'
const nimiq = await init()
const [accounts, consensus, blockNumber] = await Promise.all([
nimiq.listAccounts(),
nimiq.isConsensusEstablished(),
nimiq.getBlockNumber(),
])
Components
| Component | Lives in | What it does |
|---|---|---|
Injected Provider (window.ethereum, Nimiq provider) | WebView (injected by Nimiq Pay) | Exposes wallet APIs and sends requests to the host |
| Host-side API | Nimiq Pay (native) | Receives requests, validates them, shows approval dialogs, executes actions |
| Mini App SDK | WebView (your app or injected) | Waits for the Nimiq provider, adds typed access for TypeScript, and exposes Nimiq-native APIs |
Your mini app uses standard Web3 APIs via window.ethereum and Nimiq-specific APIs via the Mini App SDK init() helper.
Request lifecycle
- Your mini app calls a provider method (for example, request accounts or sign a message)
- The injected provider forwards a message to the Nimiq Pay app
- The Nimiq Pay app validates the request and shows a native confirmation dialog (when required)
- If approved, Nimiq Pay executes the wallet operation (keys never leave the wallet)
- The result is returned to your mini app through the provider
Supported Networks
The framework supports two blockchain ecosystems:
Nimiq
- Native support for NIM payments, message signing, and consensus checks
- Direct integration with Nimiq Pay's core wallet features
Ethereum + Layer 2 networks (EVM-compatible)
- Ethereum Mainnet
- Polygon
- Arbitrum One
- Optimism
- Base
- BNB Smart Chain (formerly Binance Smart Chain)
- Sepolia (testnet for developers)
ERC-20 tokens on any listed chain — including USDT on Polygon — are accessible through window.ethereum with no additional setup. See Using EVM Tokens in Mini Apps for a worked example.
Any EVM-compatible chain supported by our RPC provider can be added; the list above reflects what we currently expose in Nimiq Pay. Additional EVM networks can be added over time via configuration updates.
User Language
Nimiq Pay exposes the user's selected language to mini apps via window.nimiqPay.language. The value is a read-only ISO 639-1 two-letter code (e.g. 'en', 'de', 'es') that mirrors the user's Nimiq Pay language setting. It is injected before page scripts run, so it is safe to read during app initialization. The value is static for the lifetime of the session. If the user changes their language in Nimiq Pay, the mini app picks it up the next time it opens.
const language = window.nimiqPay?.language // e.g. 'en'
Use this instead of navigator.language, which returns the device locale and may not match the language the user selected in Nimiq Pay. For fallback patterns, translations setup, and framework examples, see Localization in Mini Apps.
Device Identifier
Nimiq Pay can issue a pseudonymous per-device identifier to mini apps that need a stable handle, for example for leaderboards, anti-spam, or save slots. The identifier is a 64-character hex SHA-256 string scoped to your mini app's origin. It identifies the device, not the user: a shared device returns the same value to every user, and the same user on two devices receives two different identifiers.
import { requestDeviceIdentifier } from '@nimiq/mini-app-sdk'
const id = await requestDeviceIdentifier({ reason: 'Leaderboard ranking' })
The first call per origin prompts the user with the reason you provide; subsequent calls resolve silently. For privacy properties, error handling, and TypeScript types, see Device Identifier in Mini Apps.
Security and Permissions
Every sensitive action requires explicit user approval through native dialogs that mini apps cannot bypass. Your app runs in a secure sandbox with no direct access to private keys. The Nimiq Pay app mediates all wallet operations.
Here's how security works:
- User consent is always required: Viewing accounts, signing messages, and sending NIM payments trigger native confirmation dialogs
- Sandboxed execution: Mini apps run in an isolated WebView with no access to the wallet's internal state or private keys
- Host app controls everything: Your app can only request actions. The Nimiq Pay app decides whether to fulfill them, always with user approval
- Wallet requests are mediated: Nimiq Pay handles wallet-related provider requests, while other RPC calls use the configured endpoint or your mini app's own RPC
Sharing Your Mini App
Once your mini app is published, you can share it using a deeplink that opens it directly inside Nimiq Pay. Two link formats are available:
Custom scheme
nimiqpay://miniapp?url=your-app.com
When a user taps this link on their phone, Nimiq Pay opens and loads your mini app with full provider access. If the URL is not in the Nimiq Pay mini app list or has never been accessed before, Nimiq Pay displays a warning before proceeding.
HTTPS link
https://nimpay.app/miniapps/open/your-app.com
Tapping this link opens the mini app the same way. It works with any domain.