Introduction
Use Onmax Mini Apps SDK when your app runs inside Nimiq Pay, needs the injected Nimiq or Ethereum provider, or asks a Nimiq wallet to approve a Better Auth flow.
The SDK solves the integration work around the wallet, not the product logic around your app. It gives you typed provider access in the mini-app browser, Better Auth plugins for Nimiq-owned sessions, cross-device order primitives for desktop-to-phone approval, and local test helpers for the same flows. New apps can wire one layer at a time instead of mixing host detection, signature verification, session ownership, and simulator code in the same module.
The packages are small on purpose. Start with the package that owns your first decision, then add integrations only when the flow needs them.
Start with one job
| You need to | Install first | Then add |
|---|---|---|
Read window.nimiq, window.ethereum, host language, or simulator providers | @onmax/nimiq-mini-app-kit | @onmax/unerc20 for ERC-20 calls |
| Create a Better Auth session from the current Nimiq wallet | @onmax/better-auth-nimiq | @onmax/nimiq-mini-app-kit for provider detection |
| Start a desktop order that a phone approves | @onmax/better-auth-cross-device | @onmax/cross-device-nimiq for Nimiq proofs |
| Read balances, send NIM, format addresses, or test with a mock Nimiq driver | @onmax/unimiq | @onmax/unimiq/nuxt or @onmax/unimiq/vite when using those frameworks |
| Read ERC-20 metadata, balances, and transfers through an EIP-1193 provider | @onmax/unerc20 | @onmax/nimiq-mini-app-kit when the provider comes from Nimiq Pay |
| Store credits, points, gems, or app-local balances on Better Auth users | @onmax/better-auth-ledger | Your own payment/compliance flow for real-money top-ups |
| Run deterministic auth scenarios in Vitest | @onmax/better-auth-nimiq-pay-e2e | Bridge mode only when a real injected provider is available |
Use the mini-app kit when
You are writing browser code that expects host-published provider surfaces.
import { initMiniAppEthereumProvider, initMiniAppProvider } from '@onmax/nimiq-mini-app-kit'
export const nimiq = await initMiniAppProvider({ timeout: 10_000 })
export const ethereum = await initMiniAppEthereumProvider({ timeout: 10_000 })
Expected behavior: inside Nimiq Pay, both promises resolve to injected providers. Outside the host, they time out with a message that tells the user to open the app inside Nimiq Pay.
Do not use these provider waits in server code. Use @onmax/unimiq with an RPC URL for server-side Nimiq reads.
Use direct auth when
The same browser that starts the flow can ask window.nimiq to sign the login challenge.
import { betterAuth } from 'better-auth'
import { bearer } from 'better-auth/plugins'
import { nimiqAuth } from '@onmax/better-auth-nimiq'
export const auth = betterAuth({
plugins: [
bearer({ requireSignature: true }),
nimiqAuth({
appName: 'Arcade Rewards',
endpointPrefix: '/nimiq',
}),
],
})
Do not use direct auth for a desktop-to-phone QR flow. Use cross-device orders so the desktop owns the session and the phone only approves the proof.
Use cross-device auth when
A desktop browser starts the order, and the Nimiq Pay phone app approves it.
import { betterAuth } from 'better-auth'
import { crossDevice } from '@onmax/better-auth-cross-device'
import { createNimiqCrossDeviceAdapter } from '@onmax/cross-device-nimiq/server'
export const auth = betterAuth({
plugins: [
crossDevice({
endpointPrefix: '/cross-device',
adapters: [
createNimiqCrossDeviceAdapter({ appName: 'Arcade Rewards' }),
],
}),
],
})
Expected behavior: the desktop receives the Better Auth session after finalization. The phone does not become signed in just because it approved the order.
What this SDK does not do
It does not recover wallets, custody funds, settle fiat payments, or replace product-level payment policy.
It also does not make app-local ledger balances equivalent to regulated stored value. Treat top-up, refund, withdrawal, and compliance decisions as application code.