Nimiq
Tutorials

Build Your First Nimiq Mini App

Guide to setting up a Nimiq Pay minimal mini app dev

In this tutorial, you’ll build a minimal mini app that runs inside Nimiq Pay and calls three Nimiq provider methods:

MethodDescription
listAccounts()Get available Nimiq addresses from the wallet
isConsensusEstablished()Check if the wallet has network consensus
getBlockNumber()Get the current blockchain height

1. Create the project

Scaffold your app with one of these framework options:

npm create vite@latest my-mini-app -- --template vue-ts
cd my-mini-app
npm install

2. Install the Nimiq Mini App SDK

Install the Nimiq Mini App SDK. For package details, see @nimiq/mini-app-sdk.

Shell
npm install @nimiq/mini-app-sdk

3. Configure the dev server

Enable network access so Nimiq Pay on your device can reach the app:

import vue from '@vitejs/plugin-vue'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [vue()],
  server: {
    port: 5173,
    host: true,
  },
})

4. Add mini app logic and UI

Replace the main app component with the variant for your framework:

<script setup lang="ts">
import { init } from '@nimiq/mini-app-sdk'
import { onMounted, ref } from 'vue'

let nimiqPromise: ReturnType<typeof init> | null = null
const isConnecting = ref(true)
const isReady = ref(false)
const accounts = ref<string[] | null>(null)
const consensus = ref<boolean | null>(null)
const blockNumber = ref<number | null>(null)
const errorMessage = ref<string | null>(null)

function getProviderErrorMessage(value: unknown): string | null {
  if (typeof value !== 'object' || value === null || !('error' in value))
    return null

  const maybeError = (value as { error?: { message?: unknown } }).error
  if (maybeError && typeof maybeError.message === 'string')
    return maybeError.message

  return 'Provider request failed.'
}

onMounted(async () => {
  try {
    nimiqPromise = init({ timeout: 10_000 })
    await nimiqPromise
    isReady.value = true
  }
  catch (error) {
    errorMessage.value = error instanceof Error ? error.message : String(error)
  }
  finally {
    isConnecting.value = false
  }
})

async function runThreeRequests() {
  if (!nimiqPromise)
    return

  errorMessage.value = null

  try {
    const nimiq = await nimiqPromise
    const [accountsResult, consensusResult, blockResult] = await Promise.all([
      nimiq.listAccounts(),
      nimiq.isConsensusEstablished(),
      nimiq.getBlockNumber(),
    ])

    const accountsError = getProviderErrorMessage(accountsResult)
    if (accountsError)
      throw new Error(accountsError)

    accounts.value = accountsResult as string[]
    consensus.value = consensusResult
    blockNumber.value = blockResult
  }
  catch (error) {
    errorMessage.value = error instanceof Error ? error.message : String(error)
  }
}
</script>

<template>
  <div style="padding: 24px; font-family: system-ui;">
    <h1>Nimiq Mini App</h1>

    <p v-if="isConnecting">
      Waiting for Nimiq Pay to initialize the provider...
    </p>

    <p v-else-if="!isReady">
      Open this mini app inside Nimiq Pay to connect to the Nimiq provider.
    </p>

    <button :disabled="isConnecting || !isReady" @click="runThreeRequests">
      Run 3 requests
    </button>

    <pre v-if="accounts">Accounts: {{ accounts }}</pre>
    <pre v-if="consensus !== null">Consensus: {{ consensus }}</pre>
    <pre v-if="blockNumber !== null">Block: {{ blockNumber }}</pre>

    <p v-if="errorMessage" style="color: #c00;">
      {{ errorMessage }}
    </p>
  </div>
</template>

5. Add localization

Nimiq Pay injects the user's selected language at window.nimiqPay.language. If you want your app to match the user's Nimiq Pay language, read it at the top of your script:

JavaScript
const language = window.nimiqPay?.language
  || navigator.language.split('-')[0]
  || 'en'

This reads the Nimiq Pay language first, falls back to the device locale, then to English. For a full translations setup with framework examples, see Localization in Mini Apps.

6. Run the mini app

Start the Vite dev server:

Shell
npm run dev -- --host

Note the Network URL in the terminal, for example:

Shell
http://192.168.1.42:5173

7. Test inside Nimiq Pay

  1. Make sure your phone and dev machine are on the same Wi-Fi network.
  2. Open Nimiq Pay.
  3. Go to Mini Apps.
  4. Enter your network URL: http://<your-ip>:5173

Open your mini app and wait for the provider to initialize. Once the button becomes enabled, tap Run 3 requests.

You should see:

  • Your Nimiq account address.
  • Whether consensus is established.
  • The current Nimiq block number.

If you see an error message, confirm:

  • You are opening the app inside Nimiq Pay and not a regular browser.
  • Your dev server is reachable from the device.
  • If your app uses secure-context-only Web APIs, check whether they are available over the local network URL. For example, crypto.randomUUID() may not be available at http://<your-ip>:5173. Add feature detection and a fallback.

For the full list of available methods and events, see the Nimiq Provider API and Ethereum Provider API.

You can also check this demo repository to see all supported methods.

Copyright © 2026