Ethereum provider
Use the Ethereum helpers when your mini app needs the injected EIP-1193 window.ethereum provider for EVM accounts, chain switching, native transfers, or ERC-20 reads and writes.
Do not use these helpers when you only need the Nimiq provider. Use the provider runtime page for window.nimiq.
Choose the Ethereum helper
Use requestMiniAppEthereumAccount() when a button click needs one connected address. It first reads eth_accounts, then asks with eth_requestAccounts only when no account is connected.
Use getMiniAppEthereumAccounts() when you need a non-prompting account check.
Use discoverEip6963Providers() only when wallet discovery semantics matter. Direct window.ethereum access is enough for most mini apps.
Connect one account
import { requestMiniAppEthereumAccount } from '@onmax/nimiq-mini-app-kit'
export async function connectEthereumAccount() {
return await requestMiniAppEthereumAccount()
}
Expected behavior:
- If the account is already connected, the helper returns it without prompting.
- If no account is connected, Nimiq Pay asks the user to approve
eth_requestAccounts. - Concurrent callers share one pending account request.
Switch to Polygon before a USDT read
Use the active chain deliberately before token reads or writes. USDT on Polygon uses 6 decimals.
import {
initMiniAppEthereumProvider,
requestMiniAppEthereumAccount,
} from '@onmax/nimiq-mini-app-kit'
import { decodeFunctionResult, encodeFunctionData, formatUnits, parseAbi } from 'viem'
const USDT_POLYGON = '0xc2132D05D31c914a87C6611C10748AEb04B58e8F'
const ERC20_ABI = parseAbi([
'function balanceOf(address account) view returns (uint256)',
])
export async function readPolygonUsdtBalance() {
const ethereum = await initMiniAppEthereumProvider({ timeout: 10_000 })
const account = await requestMiniAppEthereumAccount({ provider: ethereum })
await ethereum.request({
method: 'wallet_switchEthereumChain',
params: [{ chainId: '0x89' }],
})
const data = encodeFunctionData({
abi: ERC20_ABI,
functionName: 'balanceOf',
args: [account as `0x${string}`],
})
const rawBalance = await ethereum.request<`0x${string}`>({
method: 'eth_call',
params: [{ to: USDT_POLYGON, data }, 'latest'],
})
const balance = decodeFunctionResult({
abi: ERC20_ABI,
functionName: 'balanceOf',
data: rawBalance,
})
return formatUnits(balance, 6)
}
Expected result in the deterministic simulator when the account has 1000000 raw units:
1
Add a missing chain after switch failure
Use wallet_addEthereumChain when wallet_switchEthereumChain fails because the chain is unknown to the host.
import { initMiniAppEthereumProvider } from '@onmax/nimiq-mini-app-kit'
const BASE = {
chainId: '0x2105',
chainName: 'Base',
nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
rpcUrls: ['https://mainnet.base.org'],
blockExplorerUrls: ['https://basescan.org'],
}
export async function ensureBaseChain() {
const ethereum = await initMiniAppEthereumProvider()
try {
await ethereum.request({
method: 'wallet_switchEthereumChain',
params: [{ chainId: BASE.chainId }],
})
}
catch (error) {
if ((error as { code?: number }).code !== 4902)
throw error
await ethereum.request({
method: 'wallet_addEthereumChain',
params: [BASE],
})
}
}
Expected behavior:
- Known chain: the host asks the user to approve the switch.
- Unknown chain with
4902: the host asks the user to add the chain. - Any other error stays visible to your app.
Discover announced providers
Use EIP-6963 discovery when an embedded wallet chooser or simulator shell needs provider announcements.
import { discoverEip6963Providers } from '@onmax/nimiq-mini-app-kit'
export async function listAnnouncedWallets() {
const providers = await discoverEip6963Providers({ waitMs: 50 })
return providers.map(({ info }) => ({
name: info.name,
rdns: info.rdns,
}))
}
Do not pass timeout here. The helper option is waitMs.
Announce a simulator provider
Use registerEip6963Provider() when a custom host shell owns the provider and wants app-side discovery to find it.
import {
registerEip6963Provider,
type MiniAppEthereumProvider,
} from '@onmax/nimiq-mini-app-kit'
export function registerSimulatorWallet(provider: MiniAppEthereumProvider) {
return registerEip6963Provider({
uuid: '9d95c7a2-20ef-4b6f-9df7-a77b151e8051',
name: 'Nimiq Pay Simulator',
icon: '',
rdns: 'com.nimiq.pay.simulator',
}, provider)
}
Expected behavior:
- The provider announces immediately.
- It announces again when the page dispatches
eip6963:requestProvider. - The returned cleanup function removes the event listener.
Runtime rules
- Use
eth_signTypedData_v4for structured approvals, permits, and typed login challenges. - Use
personal_signonly for plain text. - Switch to the intended chain before token reads or writes.
- Parse and format token amounts with the token's real decimals.
- Do not request accounts or signatures on page load.