Provider runtime
Use @onmax/nimiq-mini-app-kit when your app needs the Nimiq Pay window.nimiq provider. The helpers give you one typed entry point for the real host, the Nuxt simulator, and tests with custom sources.
Do not use these helpers for generic Nimiq RPC access. Use @onmax/unimiq when the app is not running as a Nimiq Pay mini app.
Choose the provider path
Use initMiniAppProvider() when an action cannot continue without the provider.
Use getMiniAppProvider() when you only need to render an available, loading, or unavailable state.
Use source or target only in tests, embedded shells, or non-window runtimes.
Wait before a wallet action
Put confirmation-requiring calls behind a user action. listAccounts(), sign(), and transaction methods can open host approval UI.
import {
initMiniAppProvider,
isMiniAppProviderError,
} from '@onmax/nimiq-mini-app-kit'
export async function signCheckout(orderId: string) {
const provider = await initMiniAppProvider({ timeout: 10_000 })
const result = await provider.sign(`Confirm checkout ${orderId}`)
if (isMiniAppProviderError(result))
throw new Error(result.error.message)
return {
publicKey: result.publicKey,
signature: result.signature,
}
}
Expected behavior:
- Inside Nimiq Pay or the simulator, the host asks the user to approve the signature.
- Outside the host, the promise rejects after the timeout with guidance to open the app inside Nimiq Pay.
Render provider state without prompting
Reading the provider synchronously does not ask for account access. Use it for UI state before the user clicks a wallet action.
import {
getMiniAppProvider,
hasMiniAppProvider,
} from '@onmax/nimiq-mini-app-kit'
export function readMiniAppRuntimeState() {
const provider = getMiniAppProvider()
return {
available: hasMiniAppProvider(),
canSign: Boolean(provider),
}
}
Expected result outside Nimiq Pay:
{
"available": false,
"canSign": false
}
Send a Nimiq payment with order data
Use Nimiq payment methods when the receiver expects Luna amounts. 1 NIM = 100000 Luna.
import {
initMiniAppProvider,
isMiniAppProviderError,
} from '@onmax/nimiq-mini-app-kit'
interface PayOrderInput {
orderId: string
recipient: string
amountLuna: number
feeLuna?: number
}
export async function payOrder(input: PayOrderInput) {
const provider = await initMiniAppProvider({ timeout: 10_000 })
const txHash = await provider.sendBasicTransactionWithData({
recipient: input.recipient,
value: input.amountLuna,
fee: input.feeLuna ?? 0,
data: `order:${input.orderId}`,
})
if (isMiniAppProviderError(txHash))
throw new Error(txHash.error.message)
return txHash
}
Expected behavior:
- The host previews the recipient, amount, fee, and attached data.
- The function resolves to a transaction hash when the user approves.
- The function throws a normal
Errorwhen the provider returns an error envelope.
Check read-only capabilities
Use capability checks for optional status UI. Do not block checkout only because status methods are missing.
import {
hasBlockNumberCapability,
hasConsensusCapability,
initMiniAppProvider,
} from '@onmax/nimiq-mini-app-kit'
export async function readNimiqStatus() {
const provider = await initMiniAppProvider({ timeout: 10_000 })
return {
consensusEstablished: hasConsensusCapability(provider)
? await provider.isConsensusEstablished()
: null,
blockNumber: hasBlockNumberCapability(provider)
? await provider.getBlockNumber()
: null,
}
}
Use custom sources in tests
Use source when your test controls when the provider appears.
import { expect, it } from 'vitest'
import { waitForMiniAppProvider } from '@onmax/nimiq-mini-app-kit'
import { createStubNimiqProvider } from '@onmax/nimiq-mini-app-kit/dev'
it('waits for delayed mini-app injection', async () => {
let provider = null as ReturnType<typeof createStubNimiqProvider> | null
setTimeout(() => {
provider = createStubNimiqProvider()
}, 10)
await expect(waitForMiniAppProvider({
source: () => provider,
timeout: 100,
intervalMs: 5,
})).resolves.toBe(provider)
})
Runtime rules
- Use
initMiniAppProvider()for user actions that require the provider. - Use
getMiniAppProvider()for synchronous rendering decisions. - Use
isMiniAppProviderError()before treating provider results as successful signatures or transaction hashes. - Do not trigger confirmation-requiring methods during page load.
- Do not access private keys. The host owns the wallet.